annotate data/fileio/BZipFileDevice.cpp @ 184:5a916fee6d2d

* Handle generator transforms (plugins whose channel count isn't dependent on number of audio inputs, as they have none) * Be less keen to suspend writing FFT data in spectrogram repaint -- only do it if we find we actually need to query the FFT data (i.e. we aren't repainting an area that hasn't been generated at all yet)
author Chris Cannam
date Tue, 10 Oct 2006 19:04:57 +0000
parents 1a42221a1522
children 11e107062a2b
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@148 22 BZipFileDevice::BZipFileDevice(QString fileName) :
Chris@148 23 m_fileName(fileName),
Chris@148 24 m_file(0),
Chris@148 25 m_bzFile(0),
Chris@148 26 m_atEnd(true)
Chris@148 27 {
Chris@148 28 }
Chris@148 29
Chris@148 30 BZipFileDevice::~BZipFileDevice()
Chris@148 31 {
Chris@148 32 // std::cerr << "BZipFileDevice::~BZipFileDevice(" << m_fileName.toStdString() << ")" << std::endl;
Chris@148 33 if (m_bzFile) close();
Chris@148 34 }
Chris@148 35
Chris@148 36 bool
Chris@148 37 BZipFileDevice::open(OpenMode mode)
Chris@148 38 {
Chris@148 39 if (m_bzFile) {
Chris@148 40 setErrorString(tr("File is already open"));
Chris@148 41 return false;
Chris@148 42 }
Chris@148 43
Chris@148 44 if (mode & Append) {
Chris@148 45 setErrorString(tr("Append mode not supported"));
Chris@148 46 return false;
Chris@148 47 }
Chris@148 48
Chris@148 49 if ((mode & (ReadOnly | WriteOnly)) == 0) {
Chris@148 50 setErrorString(tr("File access mode not specified"));
Chris@148 51 return false;
Chris@148 52 }
Chris@148 53
Chris@148 54 if ((mode & ReadOnly) && (mode & WriteOnly)) {
Chris@148 55 setErrorString(tr("Read and write modes both specified"));
Chris@148 56 return false;
Chris@148 57 }
Chris@148 58
Chris@148 59 if (mode & WriteOnly) {
Chris@148 60
Chris@148 61 m_file = fopen(m_fileName.toLocal8Bit().data(), "wb");
Chris@148 62 if (!m_file) {
Chris@148 63 setErrorString(tr("Failed to open file for writing"));
Chris@148 64 return false;
Chris@148 65 }
Chris@148 66
Chris@148 67 int bzError = BZ_OK;
Chris@148 68 m_bzFile = BZ2_bzWriteOpen(&bzError, m_file, 9, 0, 0);
Chris@148 69
Chris@148 70 if (!m_bzFile) {
Chris@148 71 fclose(m_file);
Chris@148 72 m_file = 0;
Chris@148 73 setErrorString(tr("Failed to open bzip2 stream for writing"));
Chris@148 74 return false;
Chris@148 75 }
Chris@148 76
Chris@148 77 // std::cerr << "BZipFileDevice: opened \"" << m_fileName.toStdString() << "\" for writing" << std::endl;
Chris@148 78
Chris@148 79 setErrorString(QString());
Chris@148 80 setOpenMode(mode);
Chris@148 81 return true;
Chris@148 82 }
Chris@148 83
Chris@148 84 if (mode & ReadOnly) {
Chris@148 85
Chris@148 86 m_file = fopen(m_fileName.toLocal8Bit().data(), "rb");
Chris@148 87 if (!m_file) {
Chris@148 88 setErrorString(tr("Failed to open file for reading"));
Chris@148 89 return false;
Chris@148 90 }
Chris@148 91
Chris@148 92 int bzError = BZ_OK;
Chris@148 93 m_bzFile = BZ2_bzReadOpen(&bzError, m_file, 0, 0, NULL, 0);
Chris@148 94
Chris@148 95 if (!m_bzFile) {
Chris@148 96 fclose(m_file);
Chris@148 97 m_file = 0;
Chris@148 98 setErrorString(tr("Failed to open bzip2 stream for reading"));
Chris@148 99 return false;
Chris@148 100 }
Chris@148 101
Chris@148 102 // std::cerr << "BZipFileDevice: opened \"" << m_fileName.toStdString() << "\" for reading" << std::endl;
Chris@148 103
Chris@148 104 m_atEnd = false;
Chris@148 105
Chris@148 106 setErrorString(QString());
Chris@148 107 setOpenMode(mode);
Chris@148 108 return true;
Chris@148 109 }
Chris@148 110
Chris@148 111 setErrorString(tr("Internal error (open for neither read nor write)"));
Chris@148 112 return false;
Chris@148 113 }
Chris@148 114
Chris@148 115 void
Chris@148 116 BZipFileDevice::close()
Chris@148 117 {
Chris@148 118 if (!m_bzFile) {
Chris@148 119 setErrorString(tr("File not open"));
Chris@148 120 return;
Chris@148 121 }
Chris@148 122
Chris@148 123 int bzError = BZ_OK;
Chris@148 124
Chris@148 125 if (openMode() & WriteOnly) {
Chris@148 126 unsigned int in = 0, out = 0;
Chris@148 127 BZ2_bzWriteClose(&bzError, m_bzFile, 0, &in, &out);
Chris@148 128 // std::cerr << "Wrote bzip2 stream (in=" << in << ", out=" << out << ")" << std::endl;
Chris@148 129 if (bzError != BZ_OK) {
Chris@148 130 setErrorString(tr("bzip2 stream write close error"));
Chris@148 131 }
Chris@148 132 fclose(m_file);
Chris@148 133 m_bzFile = 0;
Chris@148 134 m_file = 0;
Chris@148 135 return;
Chris@148 136 }
Chris@148 137
Chris@148 138 if (openMode() & ReadOnly) {
Chris@148 139 BZ2_bzReadClose(&bzError, m_bzFile);
Chris@148 140 if (bzError != BZ_OK) {
Chris@148 141 setErrorString(tr("bzip2 stream read close error"));
Chris@148 142 }
Chris@148 143 fclose(m_file);
Chris@148 144 m_bzFile = 0;
Chris@148 145 m_file = 0;
Chris@148 146 return;
Chris@148 147 }
Chris@148 148
Chris@148 149 setErrorString(tr("Internal error (close for neither read nor write)"));
Chris@148 150 return;
Chris@148 151 }
Chris@148 152
Chris@148 153 qint64
Chris@148 154 BZipFileDevice::readData(char *data, qint64 maxSize)
Chris@148 155 {
Chris@148 156 if (m_atEnd) return 0;
Chris@148 157
Chris@148 158 int bzError = BZ_OK;
Chris@148 159 int read = BZ2_bzRead(&bzError, m_bzFile, data, maxSize);
Chris@148 160
Chris@148 161 // std::cerr << "BZipFileDevice::readData: requested " << maxSize << ", read " << read << std::endl;
Chris@148 162
Chris@148 163 if (bzError != BZ_OK) {
Chris@148 164 if (bzError != BZ_STREAM_END) {
Chris@148 165 std::cerr << "BZipFileDevice::readData: error condition" << std::endl;
Chris@148 166 setErrorString(tr("bzip2 stream read error"));
Chris@148 167 return -1;
Chris@148 168 } else {
Chris@148 169 // std::cerr << "BZipFileDevice::readData: reached end of file" << std::endl;
Chris@148 170 m_atEnd = true;
Chris@148 171 }
Chris@148 172 }
Chris@148 173
Chris@148 174 return read;
Chris@148 175 }
Chris@148 176
Chris@148 177 qint64
Chris@148 178 BZipFileDevice::writeData(const char *data, qint64 maxSize)
Chris@148 179 {
Chris@148 180 int bzError = BZ_OK;
Chris@148 181 BZ2_bzWrite(&bzError, m_bzFile, (void *)data, maxSize);
Chris@148 182
Chris@148 183 // std::cerr << "BZipFileDevice::writeData: " << maxSize << " to write" << std::endl;
Chris@148 184
Chris@148 185 if (bzError != BZ_OK) {
Chris@148 186 std::cerr << "BZipFileDevice::writeData: error condition" << std::endl;
Chris@148 187 setErrorString("bzip2 stream write error");
Chris@148 188 return -1;
Chris@148 189 }
Chris@148 190
Chris@148 191 // std::cerr << "BZipFileDevice::writeData: wrote " << maxSize << std::endl;
Chris@148 192
Chris@148 193 return maxSize;
Chris@148 194 }
Chris@148 195