Add gzfilebuf::approxOffset() and sg_gzifstream::approxOffset()

gzfilebuf::approxOffset() is a wrapper for zlib's offset() function.
It can be useful to implement progress indicators and such.
This commit is contained in:
Florent Rougon
2016-10-19 00:30:55 +02:00
parent 412111ba5a
commit 8277857827
4 changed files with 50 additions and 0 deletions

View File

@@ -25,6 +25,8 @@
#include <ctype.h> // isspace()
#include <cerrno>
#include <zlib.h>
#include "sgstream.hxx"
#include <simgear/misc/sg_path.hxx>
@@ -95,6 +97,11 @@ sg_gzifstream::attach( int fd, ios_openmode io_mode )
gzbuf.attach( fd, io_mode );
}
z_off_t
sg_gzifstream::approxOffset() {
return gzbuf.approxOffset();
}
//
// Manipulators
//

View File

@@ -39,6 +39,7 @@
#include <string>
#include <zlib.h>
#include <simgear/misc/zfstream.hxx>
class SGPath;
@@ -91,6 +92,15 @@ public:
/** @return true if the file is successfully opened, false otherwise. */
bool is_open() { return gzbuf.is_open(); }
/**
* @return the current offset in the file being read or written.
* The offset corresponds to compressed data if the file is compressed,
* and is influenced by buffering performed in zlib, hence the "approx"
* qualifier. It should be suitable for progress indicators and such,
* though.
*/
z_off_t approxOffset();
private:
// Not defined!
sg_gzifstream( const sg_gzifstream& );

View File

@@ -30,7 +30,10 @@
#include <fcntl.h>
#include <simgear/misc/strutils.hxx>
#include <simgear/debug/logstream.hxx>
#include <simgear/structure/exception.hxx>
#include <zlib.h>
#include "zfstream.hxx"
//
@@ -180,6 +183,27 @@ gzfilebuf::setcompressionstrategy( int comp_strategy )
return gzsetparams(file, -2, comp_strategy);
}
z_off_t
gzfilebuf::approxOffset() {
z_off_t res = gzoffset(file);
if (res == -1) {
int errnum;
std::string errMsg = "gzoffset() error: ";
const char *gzMsg = gzerror(file, &errnum);
if (errnum == Z_ERRNO) {
errMsg += simgear::strutils::error_string(errno);
} else {
errMsg += std::string(gzMsg);
}
SG_LOG( SG_GENERAL, SG_ALERT, errMsg );
throw sg_io_exception(errMsg);
}
return res;
}
std::streampos
gzfilebuf::seekoff( std::streamoff, ios_seekdir, ios_openmode )

View File

@@ -89,6 +89,15 @@ public:
/** @return true if open, false otherwise */
bool is_open() const { return (file != NULL); }
/**
* @return the current offset in the file being read or written.
* The offset corresponds to compressed data if the file is compressed,
* and is influenced by buffering performed in zlib, hence the "approx"
* qualifier. It should be suitable for progress indicators and such,
* though.
*/
z_off_t approxOffset();
/** @return stream position */
virtual std::streampos seekoff( std::streamoff off, ios_seekdir way, ios_openmode which );