annotate data/fileio/BZipFileDevice.cpp @ 1008:d9e0e59a1581

When using an aggregate model to pass data to a transform, zero-pad the shorter input to the duration of the longer rather than truncating the longer. (This is better behaviour for e.g. MATCH, and in any case the code was previously truncating incorrectly and ending up with garbage data at the end.)
author Chris Cannam
date Fri, 14 Nov 2014 13:51:33 +0000
parents e802e550a1f2
children cc27f35aa75c
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@148 181 int read = BZ2_bzRead(&bzError, m_bzFile, data, 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@148 204 BZ2_bzWrite(&bzError, m_bzFile, (void *)data, 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