From 82778578279cbd9a2fa3fe6045cceb680750193b Mon Sep 17 00:00:00 2001 From: Florent Rougon Date: Wed, 19 Oct 2016 00:30:55 +0200 Subject: [PATCH] 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. --- simgear/misc/sgstream.cxx | 7 +++++++ simgear/misc/sgstream.hxx | 10 ++++++++++ simgear/misc/zfstream.cxx | 24 ++++++++++++++++++++++++ simgear/misc/zfstream.hxx | 9 +++++++++ 4 files changed, 50 insertions(+) diff --git a/simgear/misc/sgstream.cxx b/simgear/misc/sgstream.cxx index 46d3eca7..59f756d5 100644 --- a/simgear/misc/sgstream.cxx +++ b/simgear/misc/sgstream.cxx @@ -25,6 +25,8 @@ #include // isspace() #include +#include + #include "sgstream.hxx" #include @@ -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 // diff --git a/simgear/misc/sgstream.hxx b/simgear/misc/sgstream.hxx index 057c1d31..edd6fd43 100644 --- a/simgear/misc/sgstream.hxx +++ b/simgear/misc/sgstream.hxx @@ -39,6 +39,7 @@ #include +#include #include 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& ); diff --git a/simgear/misc/zfstream.cxx b/simgear/misc/zfstream.cxx index f1a07d07..d0514f45 100644 --- a/simgear/misc/zfstream.cxx +++ b/simgear/misc/zfstream.cxx @@ -30,7 +30,10 @@ #include #include +#include +#include +#include #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 ) diff --git a/simgear/misc/zfstream.hxx b/simgear/misc/zfstream.hxx index 6500b8c5..996860ff 100644 --- a/simgear/misc/zfstream.hxx +++ b/simgear/misc/zfstream.hxx @@ -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 );