zipstreamimpl.h

Go to the documentation of this file.
00001 /*
00002 zipstream Library License:
00003 --------------------------
00004 
00005 The zlib/libpng License Copyright (c) 2003 Jonathan de Halleux.
00006 
00007 This software is provided 'as-is', without any express or implied warranty. In
00008 no event will the authors be held liable for any damages arising from the use
00009 of this software.
00010 
00011 Permission is granted to anyone to use this software for any purpose,
00012 including commercial applications, and to alter it and redistribute it freely,
00013 subject to the following restrictions:
00014 
00015 1. The origin of this software must not be misrepresented; you must not claim
00016    that you wrote the original software. If you use this software in a
00017    product, an acknowledgment in the product documentation would be
00018    appreciated but is not required.
00019 
00020 2. Altered source versions must be plainly marked as such, and must not be
00021    misrepresented as being the original software.
00022 
00023 3. This notice may not be removed or altered from any source distribution
00024 
00025 Author: Jonathan de Halleux, dehalleux@pelikhan.com, 2003
00026 
00027 Altered by: Andreas Zieringer 2003 for OpenSG project
00028             made it platform independent, gzip conform, fixed gzip footer
00029 
00030 Altered by: Geoffrey Hutchison 2005 for Open Babel project
00031             minor namespace modifications, VC++ compatibility
00032 
00033 Altered by: Mathieu Malaterre 2008, for GDCM project
00034             when reading deflate bit stream in DICOM special handling of \0 is needed
00035             also when writing deflate back to disk, the add_footer must be called
00036 */
00037 
00038 /*
00039 Code is from:
00040 
00041 http://www.codeproject.com/KB/stl/zipstream.aspx
00042 
00043  TODO:
00044    
00045 zran.c
00046     index a zlib or gzip stream and randomly access it
00047     - illustrates the use of Z_BLOCK, inflatePrime(), and
00048       inflateSetDictionary() to provide random access
00049 
00050   So I might after all be able to implement seeking :)
00051 */
00052 #ifndef _ZIPSTREAM_H_
00053 #define _ZIPSTREAM_H_
00054 
00055 #include <vector>
00056 #include <string>
00057 #include <streambuf>
00058 #include <sstream>
00059 #include <iostream>
00060 #include <algorithm>
00061 
00062 #include <string.h> // memcpy
00063 #include <stdio.h> // EOF
00064 
00065 #include <gdcm_zlib.h>
00066 
00067 #ifdef WIN32 /* Window 95 & Windows NT */
00068 #  define OS_CODE  0x0b
00069 #endif
00070 #if defined(MACOS) || defined(TARGET_OS_MAC)
00071 #  define OS_CODE  0x07
00072 #endif
00073 #ifndef OS_CODE
00074 #  define OS_CODE  0x03  /* assume Unix */
00075 #endif
00076 
00077 namespace zlib_stream {
00078 
00079 namespace detail
00080 {
00081     const int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
00082 
00083     /* gzip flag byte */
00084     const int gz_ascii_flag =  0x01; /* bit 0 set: file probably ascii text */
00085     const int gz_head_crc    = 0x02; /* bit 1 set: header CRC present */
00086     const int gz_extra_field = 0x04; /* bit 2 set: extra field present */
00087     const int gz_orig_name  =  0x08; /* bit 3 set: original file name present */
00088     const int gz_comment    =  0x10; /* bit 4 set: file comment present */
00089     const int gz_reserved   =  0xE0; /* bits 5..7: reserved */    
00090 }
00091 
00094 const size_t zstream_default_buffer_size = 4096;
00095 
00097 enum EStrategy
00098 {
00099     StrategyFiltered = 1,
00100     StrategyHuffmanOnly = 2,
00101     DefaultStrategy = 0
00102 };
00103 
00104 //*****************************************************************************
00105 //  template class basic_zip_streambuf
00106 //*****************************************************************************
00107 
00112 template <class charT,
00113           class traits = std::char_traits<charT> >
00114 class basic_zip_streambuf : public std::basic_streambuf<charT, traits>
00115 {
00116 public:
00117     typedef std::basic_ostream<charT, traits>& ostream_reference;
00118     typedef unsigned char byte_type;
00119     typedef char          char_type;
00120     typedef byte_type* byte_buffer_type;
00121     typedef std::vector<byte_type> byte_vector_type;
00122     typedef std::vector<char_type> char_vector_type;
00123     typedef int int_type;
00124 
00125     basic_zip_streambuf(ostream_reference ostream,
00126                             int level,
00127                             EStrategy strategy,
00128                             int window_size,
00129                             int memory_level,
00130                             size_t buffer_size);
00131 
00132     ~basic_zip_streambuf(void);
00133 
00134     int               sync        (void);
00135     int_type          overflow    (int_type c);
00136     std::streamsize   flush       (void);
00137     inline 
00138     ostream_reference get_ostream (void) const;
00139     inline 
00140     int               get_zerr    (void) const;
00141     inline
00142     unsigned long     get_crc     (void) const;
00143     inline
00144     unsigned long     get_in_size (void) const;
00145     inline
00146     long              get_out_size(void) const;
00147 
00148 private:
00149     
00150     bool              zip_to_stream(char_type *buffer,
00151                                     std::streamsize buffer_size);
00152     
00153     ostream_reference   _ostream;
00154     z_stream            _zip_stream;
00155     int                 _err;
00156     byte_vector_type    _output_buffer;
00157     char_vector_type    _buffer;
00158     unsigned long       _crc;
00159 };
00160 
00161 
00162 //*****************************************************************************
00163 //  template class basic_unzip_streambuf
00164 //*****************************************************************************
00165 
00170 template <class charT,
00171           class traits = std::char_traits<charT> >
00172 class basic_unzip_streambuf :
00173     public std::basic_streambuf<charT, traits>
00174 {
00175 public:
00176     typedef std::basic_istream<charT,traits>& istream_reference;
00177     typedef unsigned char byte_type;
00178     typedef charT          char_type;
00179     typedef byte_type* byte_buffer_type;
00180     typedef std::vector<byte_type> byte_vector_type;
00181     typedef std::vector<char_type> char_vector_type;
00182     typedef int int_type;
00183 
00187     basic_unzip_streambuf(istream_reference istream,
00188                           int window_size,
00189                           size_t read_buffer_size,
00190                           size_t input_buffer_size);
00191 
00192     ~basic_unzip_streambuf(void);
00193 
00194     int_type underflow(void);
00195 
00197     inline
00198     istream_reference get_istream              (void);
00199     inline
00200     z_stream&         get_zip_stream           (void);
00201     inline
00202     int               get_zerr                 (void) const;
00203     inline
00204     unsigned long     get_crc                  (void) const;
00205     inline
00206     long              get_out_size             (void) const;
00207     inline
00208     long              get_in_size              (void) const;
00209    
00210 
00211 private:
00212     
00213     void              put_back_from_zip_stream (void);
00214     
00215     std::streamsize   unzip_from_stream        (char_type* buffer,
00216                                                 std::streamsize buffer_size);
00217 
00218     size_t            fill_input_buffer        (void);
00219 
00220     istream_reference   _istream;
00221     z_stream            _zip_stream;
00222     int                 _err;
00223     byte_vector_type    _input_buffer;
00224     char_vector_type    _buffer;
00225     unsigned long       _crc;
00226 };
00227 
00228 //*****************************************************************************
00229 //  template class basic_zip_ostream
00230 //*****************************************************************************
00231 
00232 template <class charT,
00233           class traits = std::char_traits<charT> >
00234 class basic_zip_ostream :
00235     public basic_zip_streambuf<charT, traits>,
00236     public std::basic_ostream<charT, traits>
00237 {
00238 public:
00239     
00240     typedef char char_type;
00241     typedef std::basic_ostream<charT, traits>& ostream_reference;
00242     typedef std::basic_ostream<charT, traits> ostream_type;
00243 
00244     inline
00245     explicit basic_zip_ostream(ostream_reference ostream,
00246                                bool is_gzip = false,
00247                                int level = Z_DEFAULT_COMPRESSION,
00248                                EStrategy strategy = DefaultStrategy,
00249                                int window_size = -15 /*windowBits is passed < 0 to suppress zlib header */,
00250                                int memory_level = 8,
00251                                size_t buffer_size = zstream_default_buffer_size);
00252 
00253     ~basic_zip_ostream(void);
00254 
00255     inline
00256     bool                              is_gzip   (void) const;
00257     inline
00258     basic_zip_ostream<charT, traits>& zflush    (void);
00259     void                              finished  (void);
00260 
00261 //    void                              make_gzip() 
00262 //       { add_header(); _is_gzip = true; }
00263 
00264 private:
00265 
00266     basic_zip_ostream<charT,traits>&  add_header(void);
00267     basic_zip_ostream<charT,traits>&  add_footer(void);
00268     
00269     bool _is_gzip;
00270     bool _added_footer;
00271 };
00272 
00273 //*****************************************************************************
00274 //  template class basic_zip_istream
00275 //*****************************************************************************
00276 
00277 template <class charT,
00278           class traits = std::char_traits<charT> >
00279 class basic_zip_istream :
00280     public basic_unzip_streambuf<charT, traits>,
00281     public std::basic_istream<charT, traits>
00282 {
00283 public:
00284     typedef std::basic_istream<charT, traits>& istream_reference;
00285     typedef std::basic_istream<charT, traits> istream_type;
00286 
00287     explicit basic_zip_istream(istream_reference istream,
00288                                int window_size = -15 /*windowBits is passed < 0 to suppress zlib header */,
00289                                size_t read_buffer_size = zstream_default_buffer_size,
00290                                size_t input_buffer_size = zstream_default_buffer_size);
00291 
00292     inline
00293     bool     is_gzip           (void) const;    
00294     inline
00295     bool     check_crc         (void);
00296     inline
00297     bool     check_data_size   (void) const;
00298     inline
00299     long     get_gzip_crc      (void) const;
00300     inline
00301     long     get_gzip_data_size(void) const;
00302     
00303 protected:
00304     
00305     int      check_header      (void);
00306     void     read_footer       (void);   
00307     
00308     bool _is_gzip;
00309     long _gzip_crc;
00310     long _gzip_data_size;
00311 };
00312 
00314 typedef basic_zip_ostream<char> zip_ostream;
00316 typedef basic_zip_istream<char> zip_istream;
00317 
00319 //typedef basic_zip_ostream<wchar_t> zip_wostream;
00321 //typedef basic_zip_istream<wchar_t> zip_wistream;
00322 
00324 inline bool isGZip(std::istream &is)
00325 {
00326     const int gz_magic[2] = {0x1f, 0x8b};
00327     
00328     int c1 = (int) is.get();
00329     if(c1 != gz_magic[0])
00330     {
00331         is.putback(c1);
00332         return false;
00333     }
00334     
00335     int c2 = (int) is.get();
00336     if(c2 != gz_magic[1])
00337     {
00338         is.putback(c2);
00339         is.putback(c1);
00340         return false;
00341     }
00342     
00343     is.putback(c2);
00344     is.putback(c1);
00345     return true;
00346 }
00347 
00348 #include "zipstreamimpl.hpp"
00349 
00350 }
00351 
00352 #endif // _ZIPSTREAM_H_
00353 

Generated on Sun Mar 7 03:17:21 2010 for GDCM by doxygen 1.6.3
SourceForge.net Logo