annotate data/fileio/BZipFileDevice.cpp @ 1308:80c77916fe85 mp3-gapless

Update m4a files to exports from CoreAudio, rather than FAAC; update tests accordingly, and add test for spurious data after end of decode
author Chris Cannam <cannam@all-day-breakfast.com>
date Tue, 29 Nov 2016 14:25:57 +0000
parents cc27f35aa75c
children b3cb0edc25cd
rev   line source
Chris@148 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@148 2
Chris@148 3 /*
Chris@148 4 Sonic Visualiser
Chris@148 5 An audio file viewer and annotation editor.
Chris@148 6 Centre for Digital Music, Queen Mary, University of London.
Chris@148 7 This file copyright 2006 Chris Cannam.
Chris@148 8
Chris@148 9 This program is free software; you can redistribute it and/or
Chris@148 10 modify it under the terms of the GNU General Public License as
Chris@148 11 published by the Free Software Foundation; either version 2 of the
Chris@148 12 License, or (at your option) any later version. See the file
Chris@148 13 COPYING included with this distribution for more information.
Chris@148 14 */
Chris@148 15
Chris@148 16 #include "BZipFileDevice.h"
Chris@148 17
Chris@148 18 #include <bzlib.h>
Chris@148 19
Chris@148 20 #include <iostream>
Chris@148 21
Chris@843 22 #include "base/Debug.h"
Chris@843 23
Chris@148 24 BZipFileDevice::BZipFileDevice(QString fileName) :
Chris@148 25 m_fileName(fileName),
Chris@148 26 m_file(0),
Chris@148 27 m_bzFile(0),
Chris@207 28 m_atEnd(true),
Chris@207 29 m_ok(true)
Chris@148 30 {
Chris@148 31 }
Chris@148 32
Chris@148 33 BZipFileDevice::~BZipFileDevice()
Chris@148 34 {
Chris@690 35 // SVDEBUG << "BZipFileDevice::~BZipFileDevice(" << m_fileName << ")" << endl;
Chris@148 36 if (m_bzFile) close();
Chris@148 37 }
Chris@148 38
Chris@148 39 bool
Chris@207 40 BZipFileDevice::isOK() const
Chris@207 41 {
Chris@207 42 return m_ok;
Chris@207 43 }
Chris@207 44
Chris@207 45 bool
Chris@148 46 BZipFileDevice::open(OpenMode mode)
Chris@148 47 {
Chris@203 48 setErrorString("");
Chris@203 49
Chris@148 50 if (m_bzFile) {
Chris@148 51 setErrorString(tr("File is already open"));
Chris@148 52 return false;
Chris@148 53 }
Chris@148 54
Chris@148 55 if (mode & Append) {
Chris@148 56 setErrorString(tr("Append mode not supported"));
Chris@207 57 m_ok = false;
Chris@148 58 return false;
Chris@148 59 }
Chris@148 60
Chris@148 61 if ((mode & (ReadOnly | WriteOnly)) == 0) {
Chris@148 62 setErrorString(tr("File access mode not specified"));
Chris@207 63 m_ok = false;
Chris@148 64 return false;
Chris@148 65 }
Chris@148 66
Chris@148 67 if ((mode & ReadOnly) && (mode & WriteOnly)) {
Chris@148 68 setErrorString(tr("Read and write modes both specified"));
Chris@207 69 m_ok = false;
Chris@148 70 return false;
Chris@148 71 }
Chris@148 72
Chris@148 73 if (mode & WriteOnly) {
Chris@148 74
Chris@148 75 m_file = fopen(m_fileName.toLocal8Bit().data(), "wb");
Chris@148 76 if (!m_file) {
Chris@148 77 setErrorString(tr("Failed to open file for writing"));
Chris@207 78 m_ok = false;
Chris@148 79 return false;
Chris@148 80 }
Chris@148 81
Chris@148 82 int bzError = BZ_OK;
Chris@148 83 m_bzFile = BZ2_bzWriteOpen(&bzError, m_file, 9, 0, 0);
Chris@148 84
Chris@148 85 if (!m_bzFile) {
Chris@148 86 fclose(m_file);
Chris@148 87 m_file = 0;
Chris@148 88 setErrorString(tr("Failed to open bzip2 stream for writing"));
Chris@207 89 m_ok = false;
Chris@148 90 return false;
Chris@148 91 }
Chris@148 92
Chris@843 93 // cerr << "BZipFileDevice: opened \"" << m_fileName << "\" for writing" << endl;
Chris@148 94
Chris@148 95 setErrorString(QString());
Chris@148 96 setOpenMode(mode);
Chris@148 97 return true;
Chris@148 98 }
Chris@148 99
Chris@148 100 if (mode & ReadOnly) {
Chris@148 101
Chris@148 102 m_file = fopen(m_fileName.toLocal8Bit().data(), "rb");
Chris@148 103 if (!m_file) {
Chris@148 104 setErrorString(tr("Failed to open file for reading"));
Chris@207 105 m_ok = false;
Chris@148 106 return false;
Chris@148 107 }
Chris@148 108
Chris@148 109 int bzError = BZ_OK;
Chris@148 110 m_bzFile = BZ2_bzReadOpen(&bzError, m_file, 0, 0, NULL, 0);
Chris@148 111
Chris@148 112 if (!m_bzFile) {
Chris@148 113 fclose(m_file);
Chris@148 114 m_file = 0;
Chris@148 115 setErrorString(tr("Failed to open bzip2 stream for reading"));
Chris@207 116 m_ok = false;
Chris@148 117 return false;
Chris@148 118 }
Chris@148 119
Chris@843 120 // cerr << "BZipFileDevice: opened \"" << m_fileName << "\" for reading" << endl;
Chris@148 121
Chris@148 122 m_atEnd = false;
Chris@148 123
Chris@148 124 setErrorString(QString());
Chris@148 125 setOpenMode(mode);
Chris@148 126 return true;
Chris@148 127 }
Chris@148 128
Chris@148 129 setErrorString(tr("Internal error (open for neither read nor write)"));
Chris@207 130 m_ok = false;
Chris@148 131 return false;
Chris@148 132 }
Chris@148 133
Chris@148 134 void
Chris@148 135 BZipFileDevice::close()
Chris@148 136 {
Chris@148 137 if (!m_bzFile) {
Chris@148 138 setErrorString(tr("File not open"));
Chris@207 139 m_ok = false;
Chris@148 140 return;
Chris@148 141 }
Chris@148 142
Chris@148 143 int bzError = BZ_OK;
Chris@148 144
Chris@148 145 if (openMode() & WriteOnly) {
Chris@148 146 unsigned int in = 0, out = 0;
Chris@148 147 BZ2_bzWriteClose(&bzError, m_bzFile, 0, &in, &out);
Chris@843 148 // cerr << "Wrote bzip2 stream (in=" << in << ", out=" << out << ")" << endl;
Chris@148 149 if (bzError != BZ_OK) {
Chris@148 150 setErrorString(tr("bzip2 stream write close error"));
Chris@148 151 }
Chris@148 152 fclose(m_file);
Chris@148 153 m_bzFile = 0;
Chris@148 154 m_file = 0;
Chris@207 155 m_ok = false;
Chris@148 156 return;
Chris@148 157 }
Chris@148 158
Chris@148 159 if (openMode() & ReadOnly) {
Chris@148 160 BZ2_bzReadClose(&bzError, m_bzFile);
Chris@148 161 if (bzError != BZ_OK) {
Chris@148 162 setErrorString(tr("bzip2 stream read close error"));
Chris@148 163 }
Chris@148 164 fclose(m_file);
Chris@148 165 m_bzFile = 0;
Chris@148 166 m_file = 0;
Chris@207 167 m_ok = false;
Chris@148 168 return;
Chris@148 169 }
Chris@148 170
Chris@148 171 setErrorString(tr("Internal error (close for neither read nor write)"));
Chris@148 172 return;
Chris@148 173 }
Chris@148 174
Chris@148 175 qint64
Chris@148 176 BZipFileDevice::readData(char *data, qint64 maxSize)
Chris@148 177 {
Chris@148 178 if (m_atEnd) return 0;
Chris@148 179
Chris@148 180 int bzError = BZ_OK;
Chris@1038 181 int read = BZ2_bzRead(&bzError, m_bzFile, data, int(maxSize));
Chris@148 182
Chris@690 183 // SVDEBUG << "BZipFileDevice::readData: requested " << maxSize << ", read " << read << endl;
Chris@148 184
Chris@148 185 if (bzError != BZ_OK) {
Chris@148 186 if (bzError != BZ_STREAM_END) {
Chris@843 187 cerr << "BZipFileDevice::readData: error condition" << endl;
Chris@148 188 setErrorString(tr("bzip2 stream read error"));
Chris@207 189 m_ok = false;
Chris@148 190 return -1;
Chris@148 191 } else {
Chris@690 192 // SVDEBUG << "BZipFileDevice::readData: reached end of file" << endl;
Chris@148 193 m_atEnd = true;
Chris@148 194 }
Chris@148 195 }
Chris@148 196
Chris@148 197 return read;
Chris@148 198 }
Chris@148 199
Chris@148 200 qint64
Chris@148 201 BZipFileDevice::writeData(const char *data, qint64 maxSize)
Chris@148 202 {
Chris@148 203 int bzError = BZ_OK;
Chris@1038 204 BZ2_bzWrite(&bzError, m_bzFile, (void *)data, int(maxSize));
Chris@148 205
Chris@690 206 // SVDEBUG << "BZipFileDevice::writeData: " << maxSize << " to write" << endl;
Chris@148 207
Chris@148 208 if (bzError != BZ_OK) {
Chris@843 209 cerr << "BZipFileDevice::writeData: error condition" << endl;
Chris@148 210 setErrorString("bzip2 stream write error");
Chris@207 211 m_ok = false;
Chris@148 212 return -1;
Chris@148 213 }
Chris@148 214
Chris@690 215 // SVDEBUG << "BZipFileDevice::writeData: wrote " << maxSize << endl;
Chris@148 216
Chris@148 217 return maxSize;
Chris@148 218 }
Chris@148 219