annotate data/fileio/BZipFileDevice.cpp @ 205:05154c7bb90b

* Basics of an approximate way of managing memory that we've committed to using but haven't allocated yet
author Chris Cannam
date Fri, 15 Dec 2006 18:05:31 +0000
parents 11e107062a2b
children a75e678f5d37
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@203 39 setErrorString("");
Chris@203 40
Chris@148 41 if (m_bzFile) {
Chris@148 42 setErrorString(tr("File is already open"));
Chris@148 43 return false;
Chris@148 44 }
Chris@148 45
Chris@148 46 if (mode & Append) {
Chris@148 47 setErrorString(tr("Append mode not supported"));
Chris@148 48 return false;
Chris@148 49 }
Chris@148 50
Chris@148 51 if ((mode & (ReadOnly | WriteOnly)) == 0) {
Chris@148 52 setErrorString(tr("File access mode not specified"));
Chris@148 53 return false;
Chris@148 54 }
Chris@148 55
Chris@148 56 if ((mode & ReadOnly) && (mode & WriteOnly)) {
Chris@148 57 setErrorString(tr("Read and write modes both specified"));
Chris@148 58 return false;
Chris@148 59 }
Chris@148 60
Chris@148 61 if (mode & WriteOnly) {
Chris@148 62
Chris@148 63 m_file = fopen(m_fileName.toLocal8Bit().data(), "wb");
Chris@148 64 if (!m_file) {
Chris@148 65 setErrorString(tr("Failed to open file for writing"));
Chris@148 66 return false;
Chris@148 67 }
Chris@148 68
Chris@148 69 int bzError = BZ_OK;
Chris@148 70 m_bzFile = BZ2_bzWriteOpen(&bzError, m_file, 9, 0, 0);
Chris@148 71
Chris@148 72 if (!m_bzFile) {
Chris@148 73 fclose(m_file);
Chris@148 74 m_file = 0;
Chris@148 75 setErrorString(tr("Failed to open bzip2 stream for writing"));
Chris@148 76 return false;
Chris@148 77 }
Chris@148 78
Chris@148 79 // std::cerr << "BZipFileDevice: opened \"" << m_fileName.toStdString() << "\" for writing" << std::endl;
Chris@148 80
Chris@148 81 setErrorString(QString());
Chris@148 82 setOpenMode(mode);
Chris@148 83 return true;
Chris@148 84 }
Chris@148 85
Chris@148 86 if (mode & ReadOnly) {
Chris@148 87
Chris@148 88 m_file = fopen(m_fileName.toLocal8Bit().data(), "rb");
Chris@148 89 if (!m_file) {
Chris@148 90 setErrorString(tr("Failed to open file for reading"));
Chris@148 91 return false;
Chris@148 92 }
Chris@148 93
Chris@148 94 int bzError = BZ_OK;
Chris@148 95 m_bzFile = BZ2_bzReadOpen(&bzError, m_file, 0, 0, NULL, 0);
Chris@148 96
Chris@148 97 if (!m_bzFile) {
Chris@148 98 fclose(m_file);
Chris@148 99 m_file = 0;
Chris@148 100 setErrorString(tr("Failed to open bzip2 stream for reading"));
Chris@148 101 return false;
Chris@148 102 }
Chris@148 103
Chris@148 104 // std::cerr << "BZipFileDevice: opened \"" << m_fileName.toStdString() << "\" for reading" << std::endl;
Chris@148 105
Chris@148 106 m_atEnd = false;
Chris@148 107
Chris@148 108 setErrorString(QString());
Chris@148 109 setOpenMode(mode);
Chris@148 110 return true;
Chris@148 111 }
Chris@148 112
Chris@148 113 setErrorString(tr("Internal error (open for neither read nor write)"));
Chris@148 114 return false;
Chris@148 115 }
Chris@148 116
Chris@148 117 void
Chris@148 118 BZipFileDevice::close()
Chris@148 119 {
Chris@148 120 if (!m_bzFile) {
Chris@148 121 setErrorString(tr("File not open"));
Chris@148 122 return;
Chris@148 123 }
Chris@148 124
Chris@148 125 int bzError = BZ_OK;
Chris@148 126
Chris@148 127 if (openMode() & WriteOnly) {
Chris@148 128 unsigned int in = 0, out = 0;
Chris@148 129 BZ2_bzWriteClose(&bzError, m_bzFile, 0, &in, &out);
Chris@148 130 // std::cerr << "Wrote bzip2 stream (in=" << in << ", out=" << out << ")" << std::endl;
Chris@148 131 if (bzError != BZ_OK) {
Chris@148 132 setErrorString(tr("bzip2 stream write close error"));
Chris@148 133 }
Chris@148 134 fclose(m_file);
Chris@148 135 m_bzFile = 0;
Chris@148 136 m_file = 0;
Chris@148 137 return;
Chris@148 138 }
Chris@148 139
Chris@148 140 if (openMode() & ReadOnly) {
Chris@148 141 BZ2_bzReadClose(&bzError, m_bzFile);
Chris@148 142 if (bzError != BZ_OK) {
Chris@148 143 setErrorString(tr("bzip2 stream read close error"));
Chris@148 144 }
Chris@148 145 fclose(m_file);
Chris@148 146 m_bzFile = 0;
Chris@148 147 m_file = 0;
Chris@148 148 return;
Chris@148 149 }
Chris@148 150
Chris@148 151 setErrorString(tr("Internal error (close for neither read nor write)"));
Chris@148 152 return;
Chris@148 153 }
Chris@148 154
Chris@148 155 qint64
Chris@148 156 BZipFileDevice::readData(char *data, qint64 maxSize)
Chris@148 157 {
Chris@148 158 if (m_atEnd) return 0;
Chris@148 159
Chris@148 160 int bzError = BZ_OK;
Chris@148 161 int read = BZ2_bzRead(&bzError, m_bzFile, data, maxSize);
Chris@148 162
Chris@148 163 // std::cerr << "BZipFileDevice::readData: requested " << maxSize << ", read " << read << std::endl;
Chris@148 164
Chris@148 165 if (bzError != BZ_OK) {
Chris@148 166 if (bzError != BZ_STREAM_END) {
Chris@148 167 std::cerr << "BZipFileDevice::readData: error condition" << std::endl;
Chris@148 168 setErrorString(tr("bzip2 stream read error"));
Chris@148 169 return -1;
Chris@148 170 } else {
Chris@148 171 // std::cerr << "BZipFileDevice::readData: reached end of file" << std::endl;
Chris@148 172 m_atEnd = true;
Chris@148 173 }
Chris@148 174 }
Chris@148 175
Chris@148 176 return read;
Chris@148 177 }
Chris@148 178
Chris@148 179 qint64
Chris@148 180 BZipFileDevice::writeData(const char *data, qint64 maxSize)
Chris@148 181 {
Chris@148 182 int bzError = BZ_OK;
Chris@148 183 BZ2_bzWrite(&bzError, m_bzFile, (void *)data, maxSize);
Chris@148 184
Chris@148 185 // std::cerr << "BZipFileDevice::writeData: " << maxSize << " to write" << std::endl;
Chris@148 186
Chris@148 187 if (bzError != BZ_OK) {
Chris@148 188 std::cerr << "BZipFileDevice::writeData: error condition" << std::endl;
Chris@148 189 setErrorString("bzip2 stream write error");
Chris@148 190 return -1;
Chris@148 191 }
Chris@148 192
Chris@148 193 // std::cerr << "BZipFileDevice::writeData: wrote " << maxSize << std::endl;
Chris@148 194
Chris@148 195 return maxSize;
Chris@148 196 }
Chris@148 197