BZipFileDevice.cpp

Go to the documentation of this file.
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 BZipFileDevice::BZipFileDevice(QString fileName) :
00023     m_fileName(fileName),
00024     m_file(0),
00025     m_bzFile(0),
00026     m_atEnd(true),
00027     m_ok(true)
00028 {
00029 }
00030 
00031 BZipFileDevice::~BZipFileDevice()
00032 {
00033 //    std::cerr << "BZipFileDevice::~BZipFileDevice(" << m_fileName.toStdString() << ")" << std::endl;
00034     if (m_bzFile) close();
00035 }
00036 
00037 bool
00038 BZipFileDevice::isOK() const
00039 {
00040     return m_ok;
00041 }
00042 
00043 bool
00044 BZipFileDevice::open(OpenMode mode)
00045 {
00046     setErrorString("");
00047 
00048     if (m_bzFile) {
00049         setErrorString(tr("File is already open"));
00050         return false;
00051     }
00052 
00053     if (mode & Append) {
00054         setErrorString(tr("Append mode not supported"));
00055         m_ok = false;
00056         return false;
00057     }
00058 
00059     if ((mode & (ReadOnly | WriteOnly)) == 0) {
00060         setErrorString(tr("File access mode not specified"));
00061         m_ok = false;
00062         return false;
00063     }
00064 
00065     if ((mode & ReadOnly) && (mode & WriteOnly)) {
00066         setErrorString(tr("Read and write modes both specified"));
00067         m_ok = false;
00068         return false;
00069     }
00070 
00071     if (mode & WriteOnly) {
00072 
00073         m_file = fopen(m_fileName.toLocal8Bit().data(), "wb");
00074         if (!m_file) {
00075             setErrorString(tr("Failed to open file for writing"));
00076             m_ok = false;
00077             return false;
00078         }
00079 
00080         int bzError = BZ_OK;
00081         m_bzFile = BZ2_bzWriteOpen(&bzError, m_file, 9, 0, 0);
00082 
00083         if (!m_bzFile) {
00084             fclose(m_file);
00085             m_file = 0;
00086             setErrorString(tr("Failed to open bzip2 stream for writing"));
00087             m_ok = false;
00088             return false;
00089         }
00090 
00091 //        std::cerr << "BZipFileDevice: opened \"" << m_fileName.toStdString() << "\" for writing" << std::endl;
00092 
00093         setErrorString(QString());
00094         setOpenMode(mode);
00095         return true;
00096     }
00097 
00098     if (mode & ReadOnly) {
00099 
00100         m_file = fopen(m_fileName.toLocal8Bit().data(), "rb");
00101         if (!m_file) {
00102             setErrorString(tr("Failed to open file for reading"));
00103             m_ok = false;
00104             return false;
00105         }
00106 
00107         int bzError = BZ_OK;
00108         m_bzFile = BZ2_bzReadOpen(&bzError, m_file, 0, 0, NULL, 0);
00109 
00110         if (!m_bzFile) {
00111             fclose(m_file);
00112             m_file = 0;
00113             setErrorString(tr("Failed to open bzip2 stream for reading"));
00114             m_ok = false;
00115             return false;
00116         }
00117 
00118 //        std::cerr << "BZipFileDevice: opened \"" << m_fileName.toStdString() << "\" for reading" << std::endl;
00119 
00120         m_atEnd = false;
00121 
00122         setErrorString(QString());
00123         setOpenMode(mode);
00124         return true;
00125     }
00126 
00127     setErrorString(tr("Internal error (open for neither read nor write)"));
00128     m_ok = false;
00129     return false;
00130 }
00131 
00132 void
00133 BZipFileDevice::close()
00134 {
00135     if (!m_bzFile) {
00136         setErrorString(tr("File not open"));
00137         m_ok = false;
00138         return;
00139     }
00140 
00141     int bzError = BZ_OK;
00142 
00143     if (openMode() & WriteOnly) {
00144         unsigned int in = 0, out = 0;
00145         BZ2_bzWriteClose(&bzError, m_bzFile, 0, &in, &out);
00146 //      std::cerr << "Wrote bzip2 stream (in=" << in << ", out=" << out << ")" << std::endl;
00147         if (bzError != BZ_OK) {
00148             setErrorString(tr("bzip2 stream write close error"));
00149         }
00150         fclose(m_file);
00151         m_bzFile = 0;
00152         m_file = 0;
00153         m_ok = false;
00154         return;
00155     }
00156 
00157     if (openMode() & ReadOnly) {
00158         BZ2_bzReadClose(&bzError, m_bzFile);
00159         if (bzError != BZ_OK) {
00160             setErrorString(tr("bzip2 stream read close error"));
00161         }
00162         fclose(m_file);
00163         m_bzFile = 0;
00164         m_file = 0;
00165         m_ok = false;
00166         return;
00167     }
00168 
00169     setErrorString(tr("Internal error (close for neither read nor write)"));
00170     return;
00171 }
00172 
00173 qint64
00174 BZipFileDevice::readData(char *data, qint64 maxSize)
00175 {
00176     if (m_atEnd) return 0;
00177 
00178     int bzError = BZ_OK;
00179     int read = BZ2_bzRead(&bzError, m_bzFile, data, maxSize);
00180 
00181 //    std::cerr << "BZipFileDevice::readData: requested " << maxSize << ", read " << read << std::endl;
00182 
00183     if (bzError != BZ_OK) {
00184         if (bzError != BZ_STREAM_END) {
00185             std::cerr << "BZipFileDevice::readData: error condition" << std::endl;
00186             setErrorString(tr("bzip2 stream read error"));
00187             m_ok = false;
00188             return -1;
00189         } else {
00190 //            std::cerr << "BZipFileDevice::readData: reached end of file" << std::endl;
00191             m_atEnd = true;
00192         }            
00193     }
00194 
00195     return read;
00196 }
00197 
00198 qint64
00199 BZipFileDevice::writeData(const char *data, qint64 maxSize)
00200 {
00201     int bzError = BZ_OK;
00202     BZ2_bzWrite(&bzError, m_bzFile, (void *)data, maxSize);
00203 
00204 //    std::cerr << "BZipFileDevice::writeData: " << maxSize << " to write" << std::endl;
00205 
00206     if (bzError != BZ_OK) {
00207         std::cerr << "BZipFileDevice::writeData: error condition" << std::endl;
00208         setErrorString("bzip2 stream write error");
00209         m_ok = false;
00210         return -1;
00211     }
00212 
00213 //    std::cerr << "BZipFileDevice::writeData: wrote " << maxSize << std::endl;
00214 
00215     return maxSize;
00216 }
00217 

Generated on Wed Feb 20 15:45:25 2008 for SonicVisualiser by  doxygen 1.5.1