symbian-qemu-0.9.1-12/zlib-1.2.3/contrib/iostream2/zstream.h
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2  *
       
     3  * Copyright (c) 1997
       
     4  * Christian Michelsen Research AS
       
     5  * Advanced Computing
       
     6  * Fantoftvegen 38, 5036 BERGEN, Norway
       
     7  * http://www.cmr.no
       
     8  *
       
     9  * Permission to use, copy, modify, distribute and sell this software
       
    10  * and its documentation for any purpose is hereby granted without fee,
       
    11  * provided that the above copyright notice appear in all copies and
       
    12  * that both that copyright notice and this permission notice appear
       
    13  * in supporting documentation.  Christian Michelsen Research AS makes no
       
    14  * representations about the suitability of this software for any
       
    15  * purpose.  It is provided "as is" without express or implied warranty.
       
    16  *
       
    17  */
       
    18 
       
    19 #ifndef ZSTREAM__H
       
    20 #define ZSTREAM__H
       
    21 
       
    22 /*
       
    23  * zstream.h - C++ interface to the 'zlib' general purpose compression library
       
    24  * $Id: zstream.h 1.1 1997-06-25 12:00:56+02 tyge Exp tyge $
       
    25  */
       
    26 
       
    27 #include <strstream.h>
       
    28 #include <string.h>
       
    29 #include <stdio.h>
       
    30 #include "zlib.h"
       
    31 
       
    32 #if defined(_WIN32)
       
    33 #   include <fcntl.h>
       
    34 #   include <io.h>
       
    35 #   define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
       
    36 #else
       
    37 #   define SET_BINARY_MODE(file)
       
    38 #endif
       
    39 
       
    40 class zstringlen {
       
    41 public:
       
    42     zstringlen(class izstream&);
       
    43     zstringlen(class ozstream&, const char*);
       
    44     size_t value() const { return val.word; }
       
    45 private:
       
    46     struct Val { unsigned char byte; size_t word; } val;
       
    47 };
       
    48 
       
    49 //  ----------------------------- izstream -----------------------------
       
    50 
       
    51 class izstream
       
    52 {
       
    53     public:
       
    54         izstream() : m_fp(0) {}
       
    55         izstream(FILE* fp) : m_fp(0) { open(fp); }
       
    56         izstream(const char* name) : m_fp(0) { open(name); }
       
    57         ~izstream() { close(); }
       
    58 
       
    59         /* Opens a gzip (.gz) file for reading.
       
    60          * open() can be used to read a file which is not in gzip format;
       
    61          * in this case read() will directly read from the file without
       
    62          * decompression. errno can be checked to distinguish two error
       
    63          * cases (if errno is zero, the zlib error is Z_MEM_ERROR).
       
    64          */
       
    65         void open(const char* name) {
       
    66             if (m_fp) close();
       
    67             m_fp = ::gzopen(name, "rb");
       
    68         }
       
    69 
       
    70         void open(FILE* fp) {
       
    71             SET_BINARY_MODE(fp);
       
    72             if (m_fp) close();
       
    73             m_fp = ::gzdopen(fileno(fp), "rb");
       
    74         }
       
    75 
       
    76         /* Flushes all pending input if necessary, closes the compressed file
       
    77          * and deallocates all the (de)compression state. The return value is
       
    78          * the zlib error number (see function error() below).
       
    79          */
       
    80         int close() {
       
    81             int r = ::gzclose(m_fp);
       
    82             m_fp = 0; return r;
       
    83         }
       
    84 
       
    85         /* Binary read the given number of bytes from the compressed file.
       
    86          */
       
    87         int read(void* buf, size_t len) {
       
    88             return ::gzread(m_fp, buf, len);
       
    89         }
       
    90 
       
    91         /* Returns the error message for the last error which occurred on the
       
    92          * given compressed file. errnum is set to zlib error number. If an
       
    93          * error occurred in the file system and not in the compression library,
       
    94          * errnum is set to Z_ERRNO and the application may consult errno
       
    95          * to get the exact error code.
       
    96          */
       
    97         const char* error(int* errnum) {
       
    98             return ::gzerror(m_fp, errnum);
       
    99         }
       
   100 
       
   101         gzFile fp() { return m_fp; }
       
   102 
       
   103     private:
       
   104         gzFile m_fp;
       
   105 };
       
   106 
       
   107 /*
       
   108  * Binary read the given (array of) object(s) from the compressed file.
       
   109  * If the input file was not in gzip format, read() copies the objects number
       
   110  * of bytes into the buffer.
       
   111  * returns the number of uncompressed bytes actually read
       
   112  * (0 for end of file, -1 for error).
       
   113  */
       
   114 template <class T, class Items>
       
   115 inline int read(izstream& zs, T* x, Items items) {
       
   116     return ::gzread(zs.fp(), x, items*sizeof(T));
       
   117 }
       
   118 
       
   119 /*
       
   120  * Binary input with the '>' operator.
       
   121  */
       
   122 template <class T>
       
   123 inline izstream& operator>(izstream& zs, T& x) {
       
   124     ::gzread(zs.fp(), &x, sizeof(T));
       
   125     return zs;
       
   126 }
       
   127 
       
   128 
       
   129 inline zstringlen::zstringlen(izstream& zs) {
       
   130     zs > val.byte;
       
   131     if (val.byte == 255) zs > val.word;
       
   132     else val.word = val.byte;
       
   133 }
       
   134 
       
   135 /*
       
   136  * Read length of string + the string with the '>' operator.
       
   137  */
       
   138 inline izstream& operator>(izstream& zs, char* x) {
       
   139     zstringlen len(zs);
       
   140     ::gzread(zs.fp(), x, len.value());
       
   141     x[len.value()] = '\0';
       
   142     return zs;
       
   143 }
       
   144 
       
   145 inline char* read_string(izstream& zs) {
       
   146     zstringlen len(zs);
       
   147     char* x = new char[len.value()+1];
       
   148     ::gzread(zs.fp(), x, len.value());
       
   149     x[len.value()] = '\0';
       
   150     return x;
       
   151 }
       
   152 
       
   153 // ----------------------------- ozstream -----------------------------
       
   154 
       
   155 class ozstream
       
   156 {
       
   157     public:
       
   158         ozstream() : m_fp(0), m_os(0) {
       
   159         }
       
   160         ozstream(FILE* fp, int level = Z_DEFAULT_COMPRESSION)
       
   161             : m_fp(0), m_os(0) {
       
   162             open(fp, level);
       
   163         }
       
   164         ozstream(const char* name, int level = Z_DEFAULT_COMPRESSION)
       
   165             : m_fp(0), m_os(0) {
       
   166             open(name, level);
       
   167         }
       
   168         ~ozstream() {
       
   169             close();
       
   170         }
       
   171 
       
   172         /* Opens a gzip (.gz) file for writing.
       
   173          * The compression level parameter should be in 0..9
       
   174          * errno can be checked to distinguish two error cases
       
   175          * (if errno is zero, the zlib error is Z_MEM_ERROR).
       
   176          */
       
   177         void open(const char* name, int level = Z_DEFAULT_COMPRESSION) {
       
   178             char mode[4] = "wb\0";
       
   179             if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level;
       
   180             if (m_fp) close();
       
   181             m_fp = ::gzopen(name, mode);
       
   182         }
       
   183 
       
   184         /* open from a FILE pointer.
       
   185          */
       
   186         void open(FILE* fp, int level = Z_DEFAULT_COMPRESSION) {
       
   187             SET_BINARY_MODE(fp);
       
   188             char mode[4] = "wb\0";
       
   189             if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level;
       
   190             if (m_fp) close();
       
   191             m_fp = ::gzdopen(fileno(fp), mode);
       
   192         }
       
   193 
       
   194         /* Flushes all pending output if necessary, closes the compressed file
       
   195          * and deallocates all the (de)compression state. The return value is
       
   196          * the zlib error number (see function error() below).
       
   197          */
       
   198         int close() {
       
   199             if (m_os) {
       
   200                 ::gzwrite(m_fp, m_os->str(), m_os->pcount());
       
   201                 delete[] m_os->str(); delete m_os; m_os = 0;
       
   202             }
       
   203             int r = ::gzclose(m_fp); m_fp = 0; return r;
       
   204         }
       
   205 
       
   206         /* Binary write the given number of bytes into the compressed file.
       
   207          */
       
   208         int write(const void* buf, size_t len) {
       
   209             return ::gzwrite(m_fp, (voidp) buf, len);
       
   210         }
       
   211 
       
   212         /* Flushes all pending output into the compressed file. The parameter
       
   213          * _flush is as in the deflate() function. The return value is the zlib
       
   214          * error number (see function gzerror below). flush() returns Z_OK if
       
   215          * the flush_ parameter is Z_FINISH and all output could be flushed.
       
   216          * flush() should be called only when strictly necessary because it can
       
   217          * degrade compression.
       
   218          */
       
   219         int flush(int _flush) {
       
   220             os_flush();
       
   221             return ::gzflush(m_fp, _flush);
       
   222         }
       
   223 
       
   224         /* Returns the error message for the last error which occurred on the
       
   225          * given compressed file. errnum is set to zlib error number. If an
       
   226          * error occurred in the file system and not in the compression library,
       
   227          * errnum is set to Z_ERRNO and the application may consult errno
       
   228          * to get the exact error code.
       
   229          */
       
   230         const char* error(int* errnum) {
       
   231             return ::gzerror(m_fp, errnum);
       
   232         }
       
   233 
       
   234         gzFile fp() { return m_fp; }
       
   235 
       
   236         ostream& os() {
       
   237             if (m_os == 0) m_os = new ostrstream;
       
   238             return *m_os;
       
   239         }
       
   240 
       
   241         void os_flush() {
       
   242             if (m_os && m_os->pcount()>0) {
       
   243                 ostrstream* oss = new ostrstream;
       
   244                 oss->fill(m_os->fill());
       
   245                 oss->flags(m_os->flags());
       
   246                 oss->precision(m_os->precision());
       
   247                 oss->width(m_os->width());
       
   248                 ::gzwrite(m_fp, m_os->str(), m_os->pcount());
       
   249                 delete[] m_os->str(); delete m_os; m_os = oss;
       
   250             }
       
   251         }
       
   252 
       
   253     private:
       
   254         gzFile m_fp;
       
   255         ostrstream* m_os;
       
   256 };
       
   257 
       
   258 /*
       
   259  * Binary write the given (array of) object(s) into the compressed file.
       
   260  * returns the number of uncompressed bytes actually written
       
   261  * (0 in case of error).
       
   262  */
       
   263 template <class T, class Items>
       
   264 inline int write(ozstream& zs, const T* x, Items items) {
       
   265     return ::gzwrite(zs.fp(), (voidp) x, items*sizeof(T));
       
   266 }
       
   267 
       
   268 /*
       
   269  * Binary output with the '<' operator.
       
   270  */
       
   271 template <class T>
       
   272 inline ozstream& operator<(ozstream& zs, const T& x) {
       
   273     ::gzwrite(zs.fp(), (voidp) &x, sizeof(T));
       
   274     return zs;
       
   275 }
       
   276 
       
   277 inline zstringlen::zstringlen(ozstream& zs, const char* x) {
       
   278     val.byte = 255;  val.word = ::strlen(x);
       
   279     if (val.word < 255) zs < (val.byte = val.word);
       
   280     else zs < val;
       
   281 }
       
   282 
       
   283 /*
       
   284  * Write length of string + the string with the '<' operator.
       
   285  */
       
   286 inline ozstream& operator<(ozstream& zs, const char* x) {
       
   287     zstringlen len(zs, x);
       
   288     ::gzwrite(zs.fp(), (voidp) x, len.value());
       
   289     return zs;
       
   290 }
       
   291 
       
   292 #ifdef _MSC_VER
       
   293 inline ozstream& operator<(ozstream& zs, char* const& x) {
       
   294     return zs < (const char*) x;
       
   295 }
       
   296 #endif
       
   297 
       
   298 /*
       
   299  * Ascii write with the << operator;
       
   300  */
       
   301 template <class T>
       
   302 inline ostream& operator<<(ozstream& zs, const T& x) {
       
   303     zs.os_flush();
       
   304     return zs.os() << x;
       
   305 }
       
   306 
       
   307 #endif