gzstream.cpp

Go to the documentation of this file.
00001 // ============================================================================
00002 // gzstream, C++ iostream classes wrapping the zlib compression library.
00003 // Copyright (C) 2001  Deepak Bandyopadhyay, Lutz Kettner
00004 //
00005 // This library is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 //
00010 // This library is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with this library; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 // ============================================================================
00019 //
00020 // File          : gzstream.C
00021 // Revision      : $Revision: 2.6 $
00022 // Revision_date : $Date: 2006/04/20 09:14:54 $
00023 // Author(s)     : Deepak Bandyopadhyay, Lutz Kettner
00024 // 
00025 // Standard streambuf implementation following Nicolai Josuttis, "The 
00026 // Standard C++ Library".
00027 // ============================================================================
00028 #include "PreCompiled.h"
00029 
00030 #include "gzstream.h"
00031 #include <assert.h>
00032 #include <string>
00033 #include <cstring>  // for memcpy
00034 
00035 
00036 namespace Base {
00037 
00038 
00039 // ----------------------------------------------------------------------------
00040 // Internal classes to implement gzstream. See header file for user classes.
00041 // ----------------------------------------------------------------------------
00042 
00043 const int gzstreambuf::bufferSize = BUFFERSIZE;
00044 
00045 // --------------------------------------
00046 // class gzstreambuf:
00047 // --------------------------------------
00048 
00049 gzstreambuf* gzstreambuf::open( const char* name, int open_mode, int comp) 
00050 {
00051     if ( is_open())
00052         return (gzstreambuf*)0;
00053     mode = open_mode;
00054     // no append nor read/write mode
00055     if ((mode & std::ios::ate) || (mode & std::ios::app)
00056         || ((mode & std::ios::in) && (mode & std::ios::out)))
00057         return (gzstreambuf*)0;
00058     char  fmode[10];
00059     char* fmodeptr = fmode;
00060     if ( mode & std::ios::in)
00061       *fmodeptr++ = 'r';
00062     else if ( mode & std::ios::out) {
00063       assert( comp >= 1 && comp <= 9);
00064       *fmodeptr++ = 'w';
00065       *fmodeptr++ = '1' + comp - 1 ;
00066     }
00067     *fmodeptr++ = 'b';
00068     *fmodeptr = '\0';
00069     file = gzopen( name, fmode);
00070     if (file == 0)
00071         return (gzstreambuf*)0;
00072     opened = 1;
00073     return this;
00074 }
00075 
00076 gzstreambuf * gzstreambuf::close() {
00077     if ( is_open()) {
00078         sync();
00079         opened = 0;
00080         if ( gzclose( file) == Z_OK)
00081             return this;
00082     }
00083     return (gzstreambuf*)0;
00084 }
00085 
00086 int gzstreambuf::underflow() { // used for input buffer only
00087     if ( gptr() && ( gptr() < egptr()))
00088         return * reinterpret_cast<unsigned char *>( gptr());
00089 
00090     if ( ! (mode & std::ios::in) || ! opened)
00091         return EOF;
00092     // Josuttis' implementation of inbuf
00093     int n_putback = gptr() - eback();
00094     if ( n_putback > 4)
00095         n_putback = 4;
00096     memcpy( buffer + (4 - n_putback), gptr() - n_putback, n_putback);
00097 
00098     int num = gzread( file, buffer+4, bufferSize-4);
00099     if (num <= 0) // ERROR or EOF
00100         return EOF;
00101 
00102     // reset buffer pointers
00103     setg( buffer + (4 - n_putback),   // beginning of putback area
00104           buffer + 4,                 // read position
00105           buffer + 4 + num);          // end of buffer
00106 
00107     // return next character
00108     return * reinterpret_cast<unsigned char *>( gptr());    
00109 }
00110 
00111 int gzstreambuf::flush_buffer() {
00112     // Separate the writing of the buffer from overflow() and
00113     // sync() operation.
00114     int w = pptr() - pbase();
00115     if ( gzwrite( file, pbase(), w) != w)
00116         return EOF;
00117     pbump( -w);
00118     return w;
00119 }
00120 
00121 int gzstreambuf::overflow( int c) { // used for output buffer only
00122     if ( ! ( mode & std::ios::out) || ! opened)
00123         return EOF;
00124     if (c != EOF) {
00125         *pptr() = c;
00126         pbump(1);
00127     }
00128     if ( flush_buffer() == EOF)
00129         return EOF;
00130     return c;
00131 }
00132 
00133 int gzstreambuf::sync() {
00134     // Changed to use flush_buffer() instead of overflow( EOF)
00135     // which caused improper behavior with std::endl and flush(),
00136     // bug reported by Vincent Ricard.
00137     if ( pptr() && pptr() > pbase()) {
00138         if ( flush_buffer() == EOF)
00139             return -1;
00140     }
00141     return 0;
00142 }
00143 
00144 // --------------------------------------
00145 // class gzstreambase:
00146 // --------------------------------------
00147 
00148 gzstreambase::gzstreambase( const char* name, int mode,int comp) {
00149     init( &buf);
00150     open( name, mode, comp);
00151 }
00152 
00153 gzstreambase::~gzstreambase() {
00154     buf.close();
00155 }
00156 
00157 void gzstreambase::open( const char* name, int open_mode, int comp) {
00158     if ( ! buf.open( name, open_mode, comp))
00159         clear( rdstate() | std::ios::badbit);
00160 }
00161 
00162 void gzstreambase::close() {
00163     if ( buf.is_open())
00164         if ( ! buf.close())
00165             clear( rdstate() | std::ios::badbit);
00166 }
00167 
00168 
00169 } // namespace Base
00170 
00171 // ============================================================================
00172 // EOF //

Generated on Wed Nov 23 19:00:17 2011 for FreeCAD by  doxygen 1.6.1