Mercurial > hg > svcore
diff 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 |
line wrap: on
line diff
--- a/data/fileio/BZipFileDevice.cpp Mon Dec 12 15:18:52 2016 +0000 +++ b/data/fileio/BZipFileDevice.cpp Mon Sep 17 13:51:14 2018 +0100 @@ -21,8 +21,16 @@ #include "base/Debug.h" +// for dup: +#ifdef _MSC_VER +#include <io.h> +#else +#include <unistd.h> +#endif + BZipFileDevice::BZipFileDevice(QString fileName) : m_fileName(fileName), + m_qfile(fileName), m_file(0), m_bzFile(0), m_atEnd(true), @@ -70,11 +78,39 @@ return false; } + // This is all going to be a bit silly. + // + // We open the file with QFile so as not to have to worry about locale + // support ourselves (especially on Windows). Then we get a fd from + // QFile and "convert" it to a FILE* using fdopen because that is what + // the bz2 library needs for reading and writing an already-open file. + // + // fdopen takes over the fd it is given, and will close it when fclose + // is called. (We must call fclose, because it's needed to avoid + // leaking the file stream structure.) + // + // But QFile will also close its fd, either when we call QFile::close + // or on destruction -- there doesn't seem to be a way to avoid that + // for a file that QFile opened. + // + // So we have to add an extra dup() in to the fdopen to avoid a double + // close. + // + // Note that bz2 will *not* fclose the FILE* it was passed, so we + // don't have a problem with calling both bzWriteClose and fclose. + if (mode & WriteOnly) { - m_file = fopen(m_fileName.toLocal8Bit().data(), "wb"); + if (!m_qfile.open(QIODevice::WriteOnly)) { + setErrorString(tr("Failed to open file for writing")); + m_ok = false; + return false; + } + + m_file = fdopen(dup(m_qfile.handle()), "wb"); if (!m_file) { - setErrorString(tr("Failed to open file for writing")); + setErrorString(tr("Failed to open file handle for writing")); + m_qfile.close(); m_ok = false; return false; } @@ -85,6 +121,7 @@ if (!m_bzFile) { fclose(m_file); m_file = 0; + m_qfile.close(); setErrorString(tr("Failed to open bzip2 stream for writing")); m_ok = false; return false; @@ -99,9 +136,15 @@ if (mode & ReadOnly) { - m_file = fopen(m_fileName.toLocal8Bit().data(), "rb"); + if (!m_qfile.open(QIODevice::ReadOnly)) { + setErrorString(tr("Failed to open file for reading")); + m_ok = false; + return false; + } + + m_file = fdopen(dup(m_qfile.handle()), "rb"); if (!m_file) { - setErrorString(tr("Failed to open file for reading")); + setErrorString(tr("Failed to open file handle for reading")); m_ok = false; return false; } @@ -112,6 +155,7 @@ if (!m_bzFile) { fclose(m_file); m_file = 0; + m_qfile.close(); setErrorString(tr("Failed to open bzip2 stream for reading")); m_ok = false; return false; @@ -145,11 +189,12 @@ if (openMode() & WriteOnly) { unsigned int in = 0, out = 0; BZ2_bzWriteClose(&bzError, m_bzFile, 0, &in, &out); -// cerr << "Wrote bzip2 stream (in=" << in << ", out=" << out << ")" << endl; - if (bzError != BZ_OK) { - setErrorString(tr("bzip2 stream write close error")); - } +// cerr << "Wrote bzip2 stream (in=" << in << ", out=" << out << ")" << endl; + if (bzError != BZ_OK) { + setErrorString(tr("bzip2 stream write close error")); + } fclose(m_file); + m_qfile.close(); m_bzFile = 0; m_file = 0; m_ok = false; @@ -162,6 +207,7 @@ setErrorString(tr("bzip2 stream read close error")); } fclose(m_file); + m_qfile.close(); m_bzFile = 0; m_file = 0; m_ok = false;