Mercurial > hg > svcore
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 } |