annotate data/fileio/BZipFileDevice.cpp @ 197:11cacfe5d127

...
author Chris Cannam
date Mon, 30 Oct 2006 16:49:42 +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