svcore  1.9
BZipFileDevice.cpp
Go to the documentation of this file.
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 #include "base/Debug.h"
23 
24 BZipFileDevice::BZipFileDevice(QString fileName) :
25  m_fileName(fileName),
26  m_file(0),
27  m_bzFile(0),
28  m_atEnd(true),
29  m_ok(true)
30 {
31 }
32 
34 {
35 // SVDEBUG << "BZipFileDevice::~BZipFileDevice(" << m_fileName << ")" << endl;
36  if (m_bzFile) close();
37 }
38 
39 bool
41 {
42  return m_ok;
43 }
44 
45 bool
46 BZipFileDevice::open(OpenMode mode)
47 {
48  setErrorString("");
49 
50  if (m_bzFile) {
51  setErrorString(tr("File is already open"));
52  return false;
53  }
54 
55  if (mode & Append) {
56  setErrorString(tr("Append mode not supported"));
57  m_ok = false;
58  return false;
59  }
60 
61  if ((mode & (ReadOnly | WriteOnly)) == 0) {
62  setErrorString(tr("File access mode not specified"));
63  m_ok = false;
64  return false;
65  }
66 
67  if ((mode & ReadOnly) && (mode & WriteOnly)) {
68  setErrorString(tr("Read and write modes both specified"));
69  m_ok = false;
70  return false;
71  }
72 
73  if (mode & WriteOnly) {
74 
75  m_file = fopen(m_fileName.toLocal8Bit().data(), "wb");
76  if (!m_file) {
77  setErrorString(tr("Failed to open file for writing"));
78  m_ok = false;
79  return false;
80  }
81 
82  int bzError = BZ_OK;
83  m_bzFile = BZ2_bzWriteOpen(&bzError, m_file, 9, 0, 0);
84 
85  if (!m_bzFile) {
86  fclose(m_file);
87  m_file = 0;
88  setErrorString(tr("Failed to open bzip2 stream for writing"));
89  m_ok = false;
90  return false;
91  }
92 
93 // cerr << "BZipFileDevice: opened \"" << m_fileName << "\" for writing" << endl;
94 
95  setErrorString(QString());
96  setOpenMode(mode);
97  return true;
98  }
99 
100  if (mode & ReadOnly) {
101 
102  m_file = fopen(m_fileName.toLocal8Bit().data(), "rb");
103  if (!m_file) {
104  setErrorString(tr("Failed to open file for reading"));
105  m_ok = false;
106  return false;
107  }
108 
109  int bzError = BZ_OK;
110  m_bzFile = BZ2_bzReadOpen(&bzError, m_file, 0, 0, NULL, 0);
111 
112  if (!m_bzFile) {
113  fclose(m_file);
114  m_file = 0;
115  setErrorString(tr("Failed to open bzip2 stream for reading"));
116  m_ok = false;
117  return false;
118  }
119 
120 // cerr << "BZipFileDevice: opened \"" << m_fileName << "\" for reading" << endl;
121 
122  m_atEnd = false;
123 
124  setErrorString(QString());
125  setOpenMode(mode);
126  return true;
127  }
128 
129  setErrorString(tr("Internal error (open for neither read nor write)"));
130  m_ok = false;
131  return false;
132 }
133 
134 void
136 {
137  if (!m_bzFile) {
138  setErrorString(tr("File not open"));
139  m_ok = false;
140  return;
141  }
142 
143  int bzError = BZ_OK;
144 
145  if (openMode() & WriteOnly) {
146  unsigned int in = 0, out = 0;
147  BZ2_bzWriteClose(&bzError, m_bzFile, 0, &in, &out);
148 // cerr << "Wrote bzip2 stream (in=" << in << ", out=" << out << ")" << endl;
149  if (bzError != BZ_OK) {
150  setErrorString(tr("bzip2 stream write close error"));
151  }
152  fclose(m_file);
153  m_bzFile = 0;
154  m_file = 0;
155  m_ok = false;
156  return;
157  }
158 
159  if (openMode() & ReadOnly) {
160  BZ2_bzReadClose(&bzError, m_bzFile);
161  if (bzError != BZ_OK) {
162  setErrorString(tr("bzip2 stream read close error"));
163  }
164  fclose(m_file);
165  m_bzFile = 0;
166  m_file = 0;
167  m_ok = false;
168  return;
169  }
170 
171  setErrorString(tr("Internal error (close for neither read nor write)"));
172  return;
173 }
174 
175 qint64
176 BZipFileDevice::readData(char *data, qint64 maxSize)
177 {
178  if (m_atEnd) return 0;
179 
180  int bzError = BZ_OK;
181  int read = BZ2_bzRead(&bzError, m_bzFile, data, maxSize);
182 
183 // SVDEBUG << "BZipFileDevice::readData: requested " << maxSize << ", read " << read << endl;
184 
185  if (bzError != BZ_OK) {
186  if (bzError != BZ_STREAM_END) {
187  cerr << "BZipFileDevice::readData: error condition" << endl;
188  setErrorString(tr("bzip2 stream read error"));
189  m_ok = false;
190  return -1;
191  } else {
192 // SVDEBUG << "BZipFileDevice::readData: reached end of file" << endl;
193  m_atEnd = true;
194  }
195  }
196 
197  return read;
198 }
199 
200 qint64
201 BZipFileDevice::writeData(const char *data, qint64 maxSize)
202 {
203  int bzError = BZ_OK;
204  BZ2_bzWrite(&bzError, m_bzFile, (void *)data, maxSize);
205 
206 // SVDEBUG << "BZipFileDevice::writeData: " << maxSize << " to write" << endl;
207 
208  if (bzError != BZ_OK) {
209  cerr << "BZipFileDevice::writeData: error condition" << endl;
210  setErrorString("bzip2 stream write error");
211  m_ok = false;
212  return -1;
213  }
214 
215 // SVDEBUG << "BZipFileDevice::writeData: wrote " << maxSize << endl;
216 
217  return maxSize;
218 }
219 
virtual qint64 writeData(const char *data, qint64 maxSize)
virtual qint64 readData(char *data, qint64 maxSize)
virtual bool isOK() const
BZipFileDevice(QString fileName)
virtual ~BZipFileDevice()
virtual bool open(OpenMode mode)
virtual void close()
QString m_fileName
BZFILE * m_bzFile