svcore
1.9
|
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 00002 00003 /* 00004 Sonic Visualiser 00005 An audio file viewer and annotation editor. 00006 Centre for Digital Music, Queen Mary, University of London. 00007 This file copyright 2006 Chris Cannam. 00008 00009 This program is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU General Public License as 00011 published by the Free Software Foundation; either version 2 of the 00012 License, or (at your option) any later version. See the file 00013 COPYING included with this distribution for more information. 00014 */ 00015 00016 #include "BZipFileDevice.h" 00017 00018 #include <bzlib.h> 00019 00020 #include <iostream> 00021 00022 #include "base/Debug.h" 00023 00024 BZipFileDevice::BZipFileDevice(QString fileName) : 00025 m_fileName(fileName), 00026 m_file(0), 00027 m_bzFile(0), 00028 m_atEnd(true), 00029 m_ok(true) 00030 { 00031 } 00032 00033 BZipFileDevice::~BZipFileDevice() 00034 { 00035 // SVDEBUG << "BZipFileDevice::~BZipFileDevice(" << m_fileName << ")" << endl; 00036 if (m_bzFile) close(); 00037 } 00038 00039 bool 00040 BZipFileDevice::isOK() const 00041 { 00042 return m_ok; 00043 } 00044 00045 bool 00046 BZipFileDevice::open(OpenMode mode) 00047 { 00048 setErrorString(""); 00049 00050 if (m_bzFile) { 00051 setErrorString(tr("File is already open")); 00052 return false; 00053 } 00054 00055 if (mode & Append) { 00056 setErrorString(tr("Append mode not supported")); 00057 m_ok = false; 00058 return false; 00059 } 00060 00061 if ((mode & (ReadOnly | WriteOnly)) == 0) { 00062 setErrorString(tr("File access mode not specified")); 00063 m_ok = false; 00064 return false; 00065 } 00066 00067 if ((mode & ReadOnly) && (mode & WriteOnly)) { 00068 setErrorString(tr("Read and write modes both specified")); 00069 m_ok = false; 00070 return false; 00071 } 00072 00073 if (mode & WriteOnly) { 00074 00075 m_file = fopen(m_fileName.toLocal8Bit().data(), "wb"); 00076 if (!m_file) { 00077 setErrorString(tr("Failed to open file for writing")); 00078 m_ok = false; 00079 return false; 00080 } 00081 00082 int bzError = BZ_OK; 00083 m_bzFile = BZ2_bzWriteOpen(&bzError, m_file, 9, 0, 0); 00084 00085 if (!m_bzFile) { 00086 fclose(m_file); 00087 m_file = 0; 00088 setErrorString(tr("Failed to open bzip2 stream for writing")); 00089 m_ok = false; 00090 return false; 00091 } 00092 00093 // cerr << "BZipFileDevice: opened \"" << m_fileName << "\" for writing" << endl; 00094 00095 setErrorString(QString()); 00096 setOpenMode(mode); 00097 return true; 00098 } 00099 00100 if (mode & ReadOnly) { 00101 00102 m_file = fopen(m_fileName.toLocal8Bit().data(), "rb"); 00103 if (!m_file) { 00104 setErrorString(tr("Failed to open file for reading")); 00105 m_ok = false; 00106 return false; 00107 } 00108 00109 int bzError = BZ_OK; 00110 m_bzFile = BZ2_bzReadOpen(&bzError, m_file, 0, 0, NULL, 0); 00111 00112 if (!m_bzFile) { 00113 fclose(m_file); 00114 m_file = 0; 00115 setErrorString(tr("Failed to open bzip2 stream for reading")); 00116 m_ok = false; 00117 return false; 00118 } 00119 00120 // cerr << "BZipFileDevice: opened \"" << m_fileName << "\" for reading" << endl; 00121 00122 m_atEnd = false; 00123 00124 setErrorString(QString()); 00125 setOpenMode(mode); 00126 return true; 00127 } 00128 00129 setErrorString(tr("Internal error (open for neither read nor write)")); 00130 m_ok = false; 00131 return false; 00132 } 00133 00134 void 00135 BZipFileDevice::close() 00136 { 00137 if (!m_bzFile) { 00138 setErrorString(tr("File not open")); 00139 m_ok = false; 00140 return; 00141 } 00142 00143 int bzError = BZ_OK; 00144 00145 if (openMode() & WriteOnly) { 00146 unsigned int in = 0, out = 0; 00147 BZ2_bzWriteClose(&bzError, m_bzFile, 0, &in, &out); 00148 // cerr << "Wrote bzip2 stream (in=" << in << ", out=" << out << ")" << endl; 00149 if (bzError != BZ_OK) { 00150 setErrorString(tr("bzip2 stream write close error")); 00151 } 00152 fclose(m_file); 00153 m_bzFile = 0; 00154 m_file = 0; 00155 m_ok = false; 00156 return; 00157 } 00158 00159 if (openMode() & ReadOnly) { 00160 BZ2_bzReadClose(&bzError, m_bzFile); 00161 if (bzError != BZ_OK) { 00162 setErrorString(tr("bzip2 stream read close error")); 00163 } 00164 fclose(m_file); 00165 m_bzFile = 0; 00166 m_file = 0; 00167 m_ok = false; 00168 return; 00169 } 00170 00171 setErrorString(tr("Internal error (close for neither read nor write)")); 00172 return; 00173 } 00174 00175 qint64 00176 BZipFileDevice::readData(char *data, qint64 maxSize) 00177 { 00178 if (m_atEnd) return 0; 00179 00180 int bzError = BZ_OK; 00181 int read = BZ2_bzRead(&bzError, m_bzFile, data, maxSize); 00182 00183 // SVDEBUG << "BZipFileDevice::readData: requested " << maxSize << ", read " << read << endl; 00184 00185 if (bzError != BZ_OK) { 00186 if (bzError != BZ_STREAM_END) { 00187 cerr << "BZipFileDevice::readData: error condition" << endl; 00188 setErrorString(tr("bzip2 stream read error")); 00189 m_ok = false; 00190 return -1; 00191 } else { 00192 // SVDEBUG << "BZipFileDevice::readData: reached end of file" << endl; 00193 m_atEnd = true; 00194 } 00195 } 00196 00197 return read; 00198 } 00199 00200 qint64 00201 BZipFileDevice::writeData(const char *data, qint64 maxSize) 00202 { 00203 int bzError = BZ_OK; 00204 BZ2_bzWrite(&bzError, m_bzFile, (void *)data, maxSize); 00205 00206 // SVDEBUG << "BZipFileDevice::writeData: " << maxSize << " to write" << endl; 00207 00208 if (bzError != BZ_OK) { 00209 cerr << "BZipFileDevice::writeData: error condition" << endl; 00210 setErrorString("bzip2 stream write error"); 00211 m_ok = false; 00212 return -1; 00213 } 00214 00215 // SVDEBUG << "BZipFileDevice::writeData: wrote " << maxSize << endl; 00216 00217 return maxSize; 00218 } 00219