00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "BZipFileDevice.h"
00017
00018 #include <bzlib.h>
00019
00020 #include <iostream>
00021
00022 BZipFileDevice::BZipFileDevice(QString fileName) :
00023 m_fileName(fileName),
00024 m_file(0),
00025 m_bzFile(0),
00026 m_atEnd(true),
00027 m_ok(true)
00028 {
00029 }
00030
00031 BZipFileDevice::~BZipFileDevice()
00032 {
00033
00034 if (m_bzFile) close();
00035 }
00036
00037 bool
00038 BZipFileDevice::isOK() const
00039 {
00040 return m_ok;
00041 }
00042
00043 bool
00044 BZipFileDevice::open(OpenMode mode)
00045 {
00046 setErrorString("");
00047
00048 if (m_bzFile) {
00049 setErrorString(tr("File is already open"));
00050 return false;
00051 }
00052
00053 if (mode & Append) {
00054 setErrorString(tr("Append mode not supported"));
00055 m_ok = false;
00056 return false;
00057 }
00058
00059 if ((mode & (ReadOnly | WriteOnly)) == 0) {
00060 setErrorString(tr("File access mode not specified"));
00061 m_ok = false;
00062 return false;
00063 }
00064
00065 if ((mode & ReadOnly) && (mode & WriteOnly)) {
00066 setErrorString(tr("Read and write modes both specified"));
00067 m_ok = false;
00068 return false;
00069 }
00070
00071 if (mode & WriteOnly) {
00072
00073 m_file = fopen(m_fileName.toLocal8Bit().data(), "wb");
00074 if (!m_file) {
00075 setErrorString(tr("Failed to open file for writing"));
00076 m_ok = false;
00077 return false;
00078 }
00079
00080 int bzError = BZ_OK;
00081 m_bzFile = BZ2_bzWriteOpen(&bzError, m_file, 9, 0, 0);
00082
00083 if (!m_bzFile) {
00084 fclose(m_file);
00085 m_file = 0;
00086 setErrorString(tr("Failed to open bzip2 stream for writing"));
00087 m_ok = false;
00088 return false;
00089 }
00090
00091
00092
00093 setErrorString(QString());
00094 setOpenMode(mode);
00095 return true;
00096 }
00097
00098 if (mode & ReadOnly) {
00099
00100 m_file = fopen(m_fileName.toLocal8Bit().data(), "rb");
00101 if (!m_file) {
00102 setErrorString(tr("Failed to open file for reading"));
00103 m_ok = false;
00104 return false;
00105 }
00106
00107 int bzError = BZ_OK;
00108 m_bzFile = BZ2_bzReadOpen(&bzError, m_file, 0, 0, NULL, 0);
00109
00110 if (!m_bzFile) {
00111 fclose(m_file);
00112 m_file = 0;
00113 setErrorString(tr("Failed to open bzip2 stream for reading"));
00114 m_ok = false;
00115 return false;
00116 }
00117
00118
00119
00120 m_atEnd = false;
00121
00122 setErrorString(QString());
00123 setOpenMode(mode);
00124 return true;
00125 }
00126
00127 setErrorString(tr("Internal error (open for neither read nor write)"));
00128 m_ok = false;
00129 return false;
00130 }
00131
00132 void
00133 BZipFileDevice::close()
00134 {
00135 if (!m_bzFile) {
00136 setErrorString(tr("File not open"));
00137 m_ok = false;
00138 return;
00139 }
00140
00141 int bzError = BZ_OK;
00142
00143 if (openMode() & WriteOnly) {
00144 unsigned int in = 0, out = 0;
00145 BZ2_bzWriteClose(&bzError, m_bzFile, 0, &in, &out);
00146
00147 if (bzError != BZ_OK) {
00148 setErrorString(tr("bzip2 stream write close error"));
00149 }
00150 fclose(m_file);
00151 m_bzFile = 0;
00152 m_file = 0;
00153 m_ok = false;
00154 return;
00155 }
00156
00157 if (openMode() & ReadOnly) {
00158 BZ2_bzReadClose(&bzError, m_bzFile);
00159 if (bzError != BZ_OK) {
00160 setErrorString(tr("bzip2 stream read close error"));
00161 }
00162 fclose(m_file);
00163 m_bzFile = 0;
00164 m_file = 0;
00165 m_ok = false;
00166 return;
00167 }
00168
00169 setErrorString(tr("Internal error (close for neither read nor write)"));
00170 return;
00171 }
00172
00173 qint64
00174 BZipFileDevice::readData(char *data, qint64 maxSize)
00175 {
00176 if (m_atEnd) return 0;
00177
00178 int bzError = BZ_OK;
00179 int read = BZ2_bzRead(&bzError, m_bzFile, data, maxSize);
00180
00181
00182
00183 if (bzError != BZ_OK) {
00184 if (bzError != BZ_STREAM_END) {
00185 std::cerr << "BZipFileDevice::readData: error condition" << std::endl;
00186 setErrorString(tr("bzip2 stream read error"));
00187 m_ok = false;
00188 return -1;
00189 } else {
00190
00191 m_atEnd = true;
00192 }
00193 }
00194
00195 return read;
00196 }
00197
00198 qint64
00199 BZipFileDevice::writeData(const char *data, qint64 maxSize)
00200 {
00201 int bzError = BZ_OK;
00202 BZ2_bzWrite(&bzError, m_bzFile, (void *)data, maxSize);
00203
00204
00205
00206 if (bzError != BZ_OK) {
00207 std::cerr << "BZipFileDevice::writeData: error condition" << std::endl;
00208 setErrorString("bzip2 stream write error");
00209 m_ok = false;
00210 return -1;
00211 }
00212
00213
00214
00215 return maxSize;
00216 }
00217