summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgraehl <graehl@ec762483-ff6d-05da-a07a-a48fb63a330f>2010-06-24 22:35:36 +0000
committergraehl <graehl@ec762483-ff6d-05da-a07a-a48fb63a330f>2010-06-24 22:35:36 +0000
commited704ce2e0ec5ebb64a07c68f977a830a8e7d161 (patch)
treeb23a8d43c184e7d7692f013cac527c5af82da334
parent2ee40ec414cf36a6de06eddd4ec570e47e8bfacb (diff)
robustness: throw exception on gzstream error
git-svn-id: https://ws10smt.googlecode.com/svn/trunk@22 ec762483-ff6d-05da-a07a-a48fb63a330f
-rw-r--r--decoder/gzstream.cc25
-rw-r--r--decoder/gzstream.h24
2 files changed, 35 insertions, 14 deletions
diff --git a/decoder/gzstream.cc b/decoder/gzstream.cc
index 9703e6ad..aa015bff 100644
--- a/decoder/gzstream.cc
+++ b/decoder/gzstream.cc
@@ -21,14 +21,15 @@
// Revision : $Revision: 1.1 $
// Revision_date : $Date: 2006/03/30 04:05:52 $
// Author(s) : Deepak Bandyopadhyay, Lutz Kettner
-//
-// Standard streambuf implementation following Nicolai Josuttis, "The
+//
+// Standard streambuf implementation following Nicolai Josuttis, "The
// Standard C++ Library".
// ============================================================================
#include "gzstream.h"
#include <iostream>
#include <cstring>
+#include <stdexcept>
#ifdef GZSTREAM_NAMESPACE
namespace GZSTREAM_NAMESPACE {
@@ -59,6 +60,7 @@ gzstreambuf* gzstreambuf::open( const char* name, int open_mode) {
*fmodeptr++ = 'b';
*fmodeptr = '\0';
file = gzopen( name, fmode);
+ if (!file) handle_gzerror();
if (file == 0)
return (gzstreambuf*)0;
opened = 1;
@@ -71,10 +73,19 @@ gzstreambuf * gzstreambuf::close() {
opened = 0;
if ( gzclose( file) == Z_OK)
return this;
+ else
+ handle_gzerror();
}
return (gzstreambuf*)0;
}
+void gzstreambuf::handle_gzerror() {
+ int errnum;
+ const char *errmsg=gzerror(file,&errnum);
+ if (errnum==Z_DATA_ERROR) errmsg="CRC error reading gzip";
+ throw std::runtime_error(std::string("gzstreambuf error: ")+errmsg);
+}
+
int gzstreambuf::underflow() { // used for input buffer only
if ( gptr() && ( gptr() < egptr()))
return * reinterpret_cast<unsigned char *>( gptr());
@@ -89,7 +100,11 @@ int gzstreambuf::underflow() { // used for input buffer only
int num = gzread( file, buffer+4, bufferSize-4);
if (num <= 0) // ERROR or EOF
- return EOF;
+ {
+ if (gzeof(file))
+ return EOF;
+ handle_gzerror();
+ }
// reset buffer pointers
setg( buffer + (4 - n_putback), // beginning of putback area
@@ -97,7 +112,7 @@ int gzstreambuf::underflow() { // used for input buffer only
buffer + 4 + num); // end of buffer
// return next character
- return * reinterpret_cast<unsigned char *>( gptr());
+ return * reinterpret_cast<unsigned char *>( gptr());
}
int gzstreambuf::flush_buffer() {
@@ -105,7 +120,7 @@ int gzstreambuf::flush_buffer() {
// sync() operation.
int w = pptr() - pbase();
if ( gzwrite( file, pbase(), w) != w)
- return EOF;
+ handle_gzerror();
pbump( -w);
return w;
}
diff --git a/decoder/gzstream.h b/decoder/gzstream.h
index ad9785fd..5c709490 100644
--- a/decoder/gzstream.h
+++ b/decoder/gzstream.h
@@ -21,8 +21,8 @@
// Revision : $Revision: 1.1 $
// Revision_date : $Date: 2006/03/30 04:05:52 $
// Author(s) : Deepak Bandyopadhyay, Lutz Kettner
-//
-// Standard streambuf implementation following Nicolai Josuttis, "The
+//
+// Standard streambuf implementation following Nicolai Josuttis, "The
// Standard C++ Library".
// ============================================================================
@@ -44,7 +44,7 @@ namespace GZSTREAM_NAMESPACE {
class gzstreambuf : public std::streambuf {
private:
- static const int bufferSize = 47+256; // size of data buff
+ static const int bufferSize = 47+(1024*256); // size of data buff
// totals 512 bytes under g++ for igzstream at the end.
gzFile file; // file handle for compressed file
@@ -53,19 +53,25 @@ private:
int mode; // I/O mode
int flush_buffer();
+ void handle_gzerror(); // throws exception
public:
+#if defined(_WIN32) && !defined(CYGWIN) && !defined(EOF)
+ enum {
+ EOF = -1
+ };
+#endif
gzstreambuf() : opened(0) {
setp( buffer, buffer + (bufferSize-1));
setg( buffer + 4, // beginning of putback area
buffer + 4, // read position
- buffer + 4); // end position
+ buffer + 4); // end position
// ASSERT: both input & output capabilities will not be used together
}
int is_open() { return opened; }
gzstreambuf* open( const char* name, int open_mode);
gzstreambuf* close();
~gzstreambuf() { close(); }
-
+
virtual int overflow( int c = EOF);
virtual int underflow();
virtual int sync();
@@ -85,15 +91,15 @@ public:
// ----------------------------------------------------------------------------
// User classes. Use igzstream and ogzstream analogously to ifstream and
-// ofstream respectively. They read and write files based on the gz*
+// ofstream respectively. They read and write files based on the gz*
// function interface of the zlib. Files are compatible with gzip compression.
// ----------------------------------------------------------------------------
class igzstream : public gzstreambase, public std::istream {
public:
- igzstream() : std::istream( &buf) {}
+ igzstream() : std::istream( &buf) {}
igzstream( const char* name, int open_mode = std::ios::in)
- : gzstreambase( name, open_mode), std::istream( &buf) {}
+ : gzstreambase( name, std::ios::in | open_mode), std::istream( &buf) {}
gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); }
void open( const char* name, int open_mode = std::ios::in) {
gzstreambase::open( name, open_mode);
@@ -104,7 +110,7 @@ class ogzstream : public gzstreambase, public std::ostream {
public:
ogzstream() : std::ostream( &buf) {}
ogzstream( const char* name, int mode = std::ios::out)
- : gzstreambase( name, mode), std::ostream( &buf) {}
+ : gzstreambase( name, mode), std::ostream( &buf) {}
gzstreambuf* rdbuf() { return gzstreambase::rdbuf(); }
void open( const char* name, int open_mode = std::ios::out) {
gzstreambase::open( name, open_mode);