lbajardsilogic@0: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ lbajardsilogic@0: lbajardsilogic@0: /* lbajardsilogic@0: Sonic Visualiser lbajardsilogic@0: An audio file viewer and annotation editor. lbajardsilogic@0: Centre for Digital Music, Queen Mary, University of London. lbajardsilogic@0: This file copyright 2006 Chris Cannam. lbajardsilogic@0: lbajardsilogic@0: This program is free software; you can redistribute it and/or lbajardsilogic@0: modify it under the terms of the GNU General Public License as lbajardsilogic@0: published by the Free Software Foundation; either version 2 of the lbajardsilogic@0: License, or (at your option) any later version. See the file lbajardsilogic@0: COPYING included with this distribution for more information. lbajardsilogic@0: */ lbajardsilogic@0: lbajardsilogic@0: #include "BZipFileDevice.h" lbajardsilogic@0: lbajardsilogic@0: #include lbajardsilogic@0: lbajardsilogic@0: #include lbajardsilogic@0: lbajardsilogic@0: BZipFileDevice::BZipFileDevice(QString fileName) : lbajardsilogic@0: m_fileName(fileName), lbajardsilogic@0: m_file(0), lbajardsilogic@0: m_bzFile(0), lbajardsilogic@0: m_atEnd(true), lbajardsilogic@0: m_ok(true) lbajardsilogic@0: { lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: BZipFileDevice::~BZipFileDevice() lbajardsilogic@0: { lbajardsilogic@0: // std::cerr << "BZipFileDevice::~BZipFileDevice(" << m_fileName.toStdString() << ")" << std::endl; lbajardsilogic@0: if (m_bzFile) close(); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: bool lbajardsilogic@0: BZipFileDevice::isOK() const lbajardsilogic@0: { lbajardsilogic@0: return m_ok; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: bool lbajardsilogic@0: BZipFileDevice::open(OpenMode mode) lbajardsilogic@0: { lbajardsilogic@0: setErrorString(""); lbajardsilogic@0: lbajardsilogic@0: if (m_bzFile) { lbajardsilogic@0: setErrorString(tr("File is already open")); lbajardsilogic@0: return false; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: if (mode & Append) { lbajardsilogic@0: setErrorString(tr("Append mode not supported")); lbajardsilogic@0: m_ok = false; lbajardsilogic@0: return false; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: if ((mode & (ReadOnly | WriteOnly)) == 0) { lbajardsilogic@0: setErrorString(tr("File access mode not specified")); lbajardsilogic@0: m_ok = false; lbajardsilogic@0: return false; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: if ((mode & ReadOnly) && (mode & WriteOnly)) { lbajardsilogic@0: setErrorString(tr("Read and write modes both specified")); lbajardsilogic@0: m_ok = false; lbajardsilogic@0: return false; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: if (mode & WriteOnly) { lbajardsilogic@0: lbajardsilogic@0: m_file = fopen(m_fileName.toLocal8Bit().data(), "wb"); lbajardsilogic@0: if (!m_file) { lbajardsilogic@0: setErrorString(tr("Failed to open file for writing")); lbajardsilogic@0: m_ok = false; lbajardsilogic@0: return false; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: int bzError = BZ_OK; lbajardsilogic@0: m_bzFile = BZ2_bzWriteOpen(&bzError, m_file, 9, 0, 0); lbajardsilogic@0: lbajardsilogic@0: if (!m_bzFile) { lbajardsilogic@0: fclose(m_file); lbajardsilogic@0: m_file = 0; lbajardsilogic@0: setErrorString(tr("Failed to open bzip2 stream for writing")); lbajardsilogic@0: m_ok = false; lbajardsilogic@0: return false; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: // std::cerr << "BZipFileDevice: opened \"" << m_fileName.toStdString() << "\" for writing" << std::endl; lbajardsilogic@0: lbajardsilogic@0: setErrorString(QString()); lbajardsilogic@0: setOpenMode(mode); lbajardsilogic@0: return true; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: if (mode & ReadOnly) { lbajardsilogic@0: lbajardsilogic@0: m_file = fopen(m_fileName.toLocal8Bit().data(), "rb"); lbajardsilogic@0: if (!m_file) { lbajardsilogic@0: setErrorString(tr("Failed to open file for reading")); lbajardsilogic@0: m_ok = false; lbajardsilogic@0: return false; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: int bzError = BZ_OK; lbajardsilogic@0: m_bzFile = BZ2_bzReadOpen(&bzError, m_file, 0, 0, NULL, 0); lbajardsilogic@0: lbajardsilogic@0: if (!m_bzFile) { lbajardsilogic@0: fclose(m_file); lbajardsilogic@0: m_file = 0; lbajardsilogic@0: setErrorString(tr("Failed to open bzip2 stream for reading")); lbajardsilogic@0: m_ok = false; lbajardsilogic@0: return false; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: // std::cerr << "BZipFileDevice: opened \"" << m_fileName.toStdString() << "\" for reading" << std::endl; lbajardsilogic@0: lbajardsilogic@0: m_atEnd = false; lbajardsilogic@0: lbajardsilogic@0: setErrorString(QString()); lbajardsilogic@0: setOpenMode(mode); lbajardsilogic@0: return true; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: setErrorString(tr("Internal error (open for neither read nor write)")); lbajardsilogic@0: m_ok = false; lbajardsilogic@0: return false; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: BZipFileDevice::close() lbajardsilogic@0: { lbajardsilogic@0: if (!m_bzFile) { lbajardsilogic@0: setErrorString(tr("File not open")); lbajardsilogic@0: m_ok = false; lbajardsilogic@0: return; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: int bzError = BZ_OK; lbajardsilogic@0: lbajardsilogic@0: if (openMode() & WriteOnly) { lbajardsilogic@0: unsigned int in = 0, out = 0; lbajardsilogic@0: BZ2_bzWriteClose(&bzError, m_bzFile, 0, &in, &out); lbajardsilogic@0: // std::cerr << "Wrote bzip2 stream (in=" << in << ", out=" << out << ")" << std::endl; lbajardsilogic@0: if (bzError != BZ_OK) { lbajardsilogic@0: setErrorString(tr("bzip2 stream write close error")); lbajardsilogic@0: } lbajardsilogic@0: fclose(m_file); lbajardsilogic@0: m_bzFile = 0; lbajardsilogic@0: m_file = 0; lbajardsilogic@0: m_ok = false; lbajardsilogic@0: return; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: if (openMode() & ReadOnly) { lbajardsilogic@0: BZ2_bzReadClose(&bzError, m_bzFile); lbajardsilogic@0: if (bzError != BZ_OK) { lbajardsilogic@0: setErrorString(tr("bzip2 stream read close error")); lbajardsilogic@0: } lbajardsilogic@0: fclose(m_file); lbajardsilogic@0: m_bzFile = 0; lbajardsilogic@0: m_file = 0; lbajardsilogic@0: m_ok = false; lbajardsilogic@0: return; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: setErrorString(tr("Internal error (close for neither read nor write)")); lbajardsilogic@0: return; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: qint64 lbajardsilogic@0: BZipFileDevice::readData(char *data, qint64 maxSize) lbajardsilogic@0: { lbajardsilogic@0: if (m_atEnd) return 0; lbajardsilogic@0: lbajardsilogic@0: int bzError = BZ_OK; lbajardsilogic@0: int read = BZ2_bzRead(&bzError, m_bzFile, data, maxSize); lbajardsilogic@0: lbajardsilogic@0: // std::cerr << "BZipFileDevice::readData: requested " << maxSize << ", read " << read << std::endl; lbajardsilogic@0: lbajardsilogic@0: if (bzError != BZ_OK) { lbajardsilogic@0: if (bzError != BZ_STREAM_END) { lbajardsilogic@0: std::cerr << "BZipFileDevice::readData: error condition" << std::endl; lbajardsilogic@0: setErrorString(tr("bzip2 stream read error")); lbajardsilogic@0: m_ok = false; lbajardsilogic@0: return -1; lbajardsilogic@0: } else { lbajardsilogic@0: // std::cerr << "BZipFileDevice::readData: reached end of file" << std::endl; lbajardsilogic@0: m_atEnd = true; lbajardsilogic@0: } lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: return read; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: qint64 lbajardsilogic@0: BZipFileDevice::writeData(const char *data, qint64 maxSize) lbajardsilogic@0: { lbajardsilogic@0: int bzError = BZ_OK; lbajardsilogic@0: BZ2_bzWrite(&bzError, m_bzFile, (void *)data, maxSize); lbajardsilogic@0: lbajardsilogic@0: // std::cerr << "BZipFileDevice::writeData: " << maxSize << " to write" << std::endl; lbajardsilogic@0: lbajardsilogic@0: if (bzError != BZ_OK) { lbajardsilogic@0: std::cerr << "BZipFileDevice::writeData: error condition" << std::endl; lbajardsilogic@0: setErrorString("bzip2 stream write error"); lbajardsilogic@0: m_ok = false; lbajardsilogic@0: return -1; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: // std::cerr << "BZipFileDevice::writeData: wrote " << maxSize << std::endl; lbajardsilogic@0: lbajardsilogic@0: return maxSize; lbajardsilogic@0: } lbajardsilogic@0: