comparison data/fileio/BZipFileDevice.cpp @ 0:fc9323a41f5a

start base : Sonic Visualiser sv1-1.0rc1
author lbajardsilogic
date Fri, 11 May 2007 09:08:14 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:fc9323a41f5a
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 Sonic Visualiser
5 An audio file viewer and annotation editor.
6 Centre for Digital Music, Queen Mary, University of London.
7 This file copyright 2006 Chris Cannam.
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version. See the file
13 COPYING included with this distribution for more information.
14 */
15
16 #include "BZipFileDevice.h"
17
18 #include <bzlib.h>
19
20 #include <iostream>
21
22 BZipFileDevice::BZipFileDevice(QString fileName) :
23 m_fileName(fileName),
24 m_file(0),
25 m_bzFile(0),
26 m_atEnd(true),
27 m_ok(true)
28 {
29 }
30
31 BZipFileDevice::~BZipFileDevice()
32 {
33 // std::cerr << "BZipFileDevice::~BZipFileDevice(" << m_fileName.toStdString() << ")" << std::endl;
34 if (m_bzFile) close();
35 }
36
37 bool
38 BZipFileDevice::isOK() const
39 {
40 return m_ok;
41 }
42
43 bool
44 BZipFileDevice::open(OpenMode mode)
45 {
46 setErrorString("");
47
48 if (m_bzFile) {
49 setErrorString(tr("File is already open"));
50 return false;
51 }
52
53 if (mode & Append) {
54 setErrorString(tr("Append mode not supported"));
55 m_ok = false;
56 return false;
57 }
58
59 if ((mode & (ReadOnly | WriteOnly)) == 0) {
60 setErrorString(tr("File access mode not specified"));
61 m_ok = false;
62 return false;
63 }
64
65 if ((mode & ReadOnly) && (mode & WriteOnly)) {
66 setErrorString(tr("Read and write modes both specified"));
67 m_ok = false;
68 return false;
69 }
70
71 if (mode & WriteOnly) {
72
73 m_file = fopen(m_fileName.toLocal8Bit().data(), "wb");
74 if (!m_file) {
75 setErrorString(tr("Failed to open file for writing"));
76 m_ok = false;
77 return false;
78 }
79
80 int bzError = BZ_OK;
81 m_bzFile = BZ2_bzWriteOpen(&bzError, m_file, 9, 0, 0);
82
83 if (!m_bzFile) {
84 fclose(m_file);
85 m_file = 0;
86 setErrorString(tr("Failed to open bzip2 stream for writing"));
87 m_ok = false;
88 return false;
89 }
90
91 // std::cerr << "BZipFileDevice: opened \"" << m_fileName.toStdString() << "\" for writing" << std::endl;
92
93 setErrorString(QString());
94 setOpenMode(mode);
95 return true;
96 }
97
98 if (mode & ReadOnly) {
99
100 m_file = fopen(m_fileName.toLocal8Bit().data(), "rb");
101 if (!m_file) {
102 setErrorString(tr("Failed to open file for reading"));
103 m_ok = false;
104 return false;
105 }
106
107 int bzError = BZ_OK;
108 m_bzFile = BZ2_bzReadOpen(&bzError, m_file, 0, 0, NULL, 0);
109
110 if (!m_bzFile) {
111 fclose(m_file);
112 m_file = 0;
113 setErrorString(tr("Failed to open bzip2 stream for reading"));
114 m_ok = false;
115 return false;
116 }
117
118 // std::cerr << "BZipFileDevice: opened \"" << m_fileName.toStdString() << "\" for reading" << std::endl;
119
120 m_atEnd = false;
121
122 setErrorString(QString());
123 setOpenMode(mode);
124 return true;
125 }
126
127 setErrorString(tr("Internal error (open for neither read nor write)"));
128 m_ok = false;
129 return false;
130 }
131
132 void
133 BZipFileDevice::close()
134 {
135 if (!m_bzFile) {
136 setErrorString(tr("File not open"));
137 m_ok = false;
138 return;
139 }
140
141 int bzError = BZ_OK;
142
143 if (openMode() & WriteOnly) {
144 unsigned int in = 0, out = 0;
145 BZ2_bzWriteClose(&bzError, m_bzFile, 0, &in, &out);
146 // std::cerr << "Wrote bzip2 stream (in=" << in << ", out=" << out << ")" << std::endl;
147 if (bzError != BZ_OK) {
148 setErrorString(tr("bzip2 stream write close error"));
149 }
150 fclose(m_file);
151 m_bzFile = 0;
152 m_file = 0;
153 m_ok = false;
154 return;
155 }
156
157 if (openMode() & ReadOnly) {
158 BZ2_bzReadClose(&bzError, m_bzFile);
159 if (bzError != BZ_OK) {
160 setErrorString(tr("bzip2 stream read close error"));
161 }
162 fclose(m_file);
163 m_bzFile = 0;
164 m_file = 0;
165 m_ok = false;
166 return;
167 }
168
169 setErrorString(tr("Internal error (close for neither read nor write)"));
170 return;
171 }
172
173 qint64
174 BZipFileDevice::readData(char *data, qint64 maxSize)
175 {
176 if (m_atEnd) return 0;
177
178 int bzError = BZ_OK;
179 int read = BZ2_bzRead(&bzError, m_bzFile, data, maxSize);
180
181 // std::cerr << "BZipFileDevice::readData: requested " << maxSize << ", read " << read << std::endl;
182
183 if (bzError != BZ_OK) {
184 if (bzError != BZ_STREAM_END) {
185 std::cerr << "BZipFileDevice::readData: error condition" << std::endl;
186 setErrorString(tr("bzip2 stream read error"));
187 m_ok = false;
188 return -1;
189 } else {
190 // std::cerr << "BZipFileDevice::readData: reached end of file" << std::endl;
191 m_atEnd = true;
192 }
193 }
194
195 return read;
196 }
197
198 qint64
199 BZipFileDevice::writeData(const char *data, qint64 maxSize)
200 {
201 int bzError = BZ_OK;
202 BZ2_bzWrite(&bzError, m_bzFile, (void *)data, maxSize);
203
204 // std::cerr << "BZipFileDevice::writeData: " << maxSize << " to write" << std::endl;
205
206 if (bzError != BZ_OK) {
207 std::cerr << "BZipFileDevice::writeData: error condition" << std::endl;
208 setErrorString("bzip2 stream write error");
209 m_ok = false;
210 return -1;
211 }
212
213 // std::cerr << "BZipFileDevice::writeData: wrote " << maxSize << std::endl;
214
215 return maxSize;
216 }
217