comparison data/fileio/BZipFileDevice.cpp @ 1527:710e6250a401 zoom

Merge from default branch
author Chris Cannam
date Mon, 17 Sep 2018 13:51:14 +0100
parents 48e9f538e6e9
children 70e172e6cc59
comparison
equal deleted inserted replaced
1324:d4a28d1479a8 1527:710e6250a401
19 19
20 #include <iostream> 20 #include <iostream>
21 21
22 #include "base/Debug.h" 22 #include "base/Debug.h"
23 23
24 // for dup:
25 #ifdef _MSC_VER
26 #include <io.h>
27 #else
28 #include <unistd.h>
29 #endif
30
24 BZipFileDevice::BZipFileDevice(QString fileName) : 31 BZipFileDevice::BZipFileDevice(QString fileName) :
25 m_fileName(fileName), 32 m_fileName(fileName),
33 m_qfile(fileName),
26 m_file(0), 34 m_file(0),
27 m_bzFile(0), 35 m_bzFile(0),
28 m_atEnd(true), 36 m_atEnd(true),
29 m_ok(true) 37 m_ok(true)
30 { 38 {
68 setErrorString(tr("Read and write modes both specified")); 76 setErrorString(tr("Read and write modes both specified"));
69 m_ok = false; 77 m_ok = false;
70 return false; 78 return false;
71 } 79 }
72 80
81 // This is all going to be a bit silly.
82 //
83 // We open the file with QFile so as not to have to worry about locale
84 // support ourselves (especially on Windows). Then we get a fd from
85 // QFile and "convert" it to a FILE* using fdopen because that is what
86 // the bz2 library needs for reading and writing an already-open file.
87 //
88 // fdopen takes over the fd it is given, and will close it when fclose
89 // is called. (We must call fclose, because it's needed to avoid
90 // leaking the file stream structure.)
91 //
92 // But QFile will also close its fd, either when we call QFile::close
93 // or on destruction -- there doesn't seem to be a way to avoid that
94 // for a file that QFile opened.
95 //
96 // So we have to add an extra dup() in to the fdopen to avoid a double
97 // close.
98 //
99 // Note that bz2 will *not* fclose the FILE* it was passed, so we
100 // don't have a problem with calling both bzWriteClose and fclose.
101
73 if (mode & WriteOnly) { 102 if (mode & WriteOnly) {
74 103
75 m_file = fopen(m_fileName.toLocal8Bit().data(), "wb"); 104 if (!m_qfile.open(QIODevice::WriteOnly)) {
105 setErrorString(tr("Failed to open file for writing"));
106 m_ok = false;
107 return false;
108 }
109
110 m_file = fdopen(dup(m_qfile.handle()), "wb");
76 if (!m_file) { 111 if (!m_file) {
77 setErrorString(tr("Failed to open file for writing")); 112 setErrorString(tr("Failed to open file handle for writing"));
113 m_qfile.close();
78 m_ok = false; 114 m_ok = false;
79 return false; 115 return false;
80 } 116 }
81 117
82 int bzError = BZ_OK; 118 int bzError = BZ_OK;
83 m_bzFile = BZ2_bzWriteOpen(&bzError, m_file, 9, 0, 0); 119 m_bzFile = BZ2_bzWriteOpen(&bzError, m_file, 9, 0, 0);
84 120
85 if (!m_bzFile) { 121 if (!m_bzFile) {
86 fclose(m_file); 122 fclose(m_file);
87 m_file = 0; 123 m_file = 0;
124 m_qfile.close();
88 setErrorString(tr("Failed to open bzip2 stream for writing")); 125 setErrorString(tr("Failed to open bzip2 stream for writing"));
89 m_ok = false; 126 m_ok = false;
90 return false; 127 return false;
91 } 128 }
92 129
97 return true; 134 return true;
98 } 135 }
99 136
100 if (mode & ReadOnly) { 137 if (mode & ReadOnly) {
101 138
102 m_file = fopen(m_fileName.toLocal8Bit().data(), "rb"); 139 if (!m_qfile.open(QIODevice::ReadOnly)) {
140 setErrorString(tr("Failed to open file for reading"));
141 m_ok = false;
142 return false;
143 }
144
145 m_file = fdopen(dup(m_qfile.handle()), "rb");
103 if (!m_file) { 146 if (!m_file) {
104 setErrorString(tr("Failed to open file for reading")); 147 setErrorString(tr("Failed to open file handle for reading"));
105 m_ok = false; 148 m_ok = false;
106 return false; 149 return false;
107 } 150 }
108 151
109 int bzError = BZ_OK; 152 int bzError = BZ_OK;
110 m_bzFile = BZ2_bzReadOpen(&bzError, m_file, 0, 0, NULL, 0); 153 m_bzFile = BZ2_bzReadOpen(&bzError, m_file, 0, 0, NULL, 0);
111 154
112 if (!m_bzFile) { 155 if (!m_bzFile) {
113 fclose(m_file); 156 fclose(m_file);
114 m_file = 0; 157 m_file = 0;
158 m_qfile.close();
115 setErrorString(tr("Failed to open bzip2 stream for reading")); 159 setErrorString(tr("Failed to open bzip2 stream for reading"));
116 m_ok = false; 160 m_ok = false;
117 return false; 161 return false;
118 } 162 }
119 163
143 int bzError = BZ_OK; 187 int bzError = BZ_OK;
144 188
145 if (openMode() & WriteOnly) { 189 if (openMode() & WriteOnly) {
146 unsigned int in = 0, out = 0; 190 unsigned int in = 0, out = 0;
147 BZ2_bzWriteClose(&bzError, m_bzFile, 0, &in, &out); 191 BZ2_bzWriteClose(&bzError, m_bzFile, 0, &in, &out);
148 // cerr << "Wrote bzip2 stream (in=" << in << ", out=" << out << ")" << endl; 192 // cerr << "Wrote bzip2 stream (in=" << in << ", out=" << out << ")" << endl;
149 if (bzError != BZ_OK) { 193 if (bzError != BZ_OK) {
150 setErrorString(tr("bzip2 stream write close error")); 194 setErrorString(tr("bzip2 stream write close error"));
151 } 195 }
152 fclose(m_file); 196 fclose(m_file);
197 m_qfile.close();
153 m_bzFile = 0; 198 m_bzFile = 0;
154 m_file = 0; 199 m_file = 0;
155 m_ok = false; 200 m_ok = false;
156 return; 201 return;
157 } 202 }
160 BZ2_bzReadClose(&bzError, m_bzFile); 205 BZ2_bzReadClose(&bzError, m_bzFile);
161 if (bzError != BZ_OK) { 206 if (bzError != BZ_OK) {
162 setErrorString(tr("bzip2 stream read close error")); 207 setErrorString(tr("bzip2 stream read close error"));
163 } 208 }
164 fclose(m_file); 209 fclose(m_file);
210 m_qfile.close();
165 m_bzFile = 0; 211 m_bzFile = 0;
166 m_file = 0; 212 m_file = 0;
167 m_ok = false; 213 m_ok = false;
168 return; 214 return;
169 } 215 }