00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifndef _OSGZSTREAM_H_
00032 #define _OSGZSTREAM_H_
00033
00034 #undef OSG_ZSTREAM_SUPPORTED
00035
00036
00037
00038
00039 #if defined(OSG_WITH_PNG) && (defined(__hpux) || defined(__sgi) || defined(WIN32) || (defined(__linux) && __GNUC__ >= 3))
00040 #define OSG_ZSTREAM_SUPPORTED
00041 #endif
00042
00043 #include <vector>
00044 #include <string>
00045 #include <streambuf>
00046 #include <sstream>
00047 #include <iostream>
00048 #include <algorithm>
00049
00050 OSG_BEGIN_NAMESPACE
00052 inline bool isGZip(std::istream &is)
00053 {
00054 const int gz_magic[2] = {0x1f, 0x8b};
00055
00056 int c1 = (int) is.get();
00057 if(c1 != gz_magic[0])
00058 {
00059 is.putback(c1);
00060 return false;
00061 }
00062
00063 int c2 = (int) is.get();
00064 if(c2 != gz_magic[1])
00065 {
00066 is.putback(c2);
00067 is.putback(c1);
00068 return false;
00069 }
00070
00071 is.putback(c2);
00072 is.putback(c1);
00073 return true;
00074 }
00075 OSG_END_NAMESPACE
00076
00077 #ifdef OSG_ZSTREAM_SUPPORTED
00078
00079 #include <zlib.h>
00080
00081 #ifdef WIN32
00082 # define OS_CODE 0x0b
00083 #endif
00084 #if defined(MACOS) || defined(TARGET_OS_MAC)
00085 # define OS_CODE 0x07
00086 #endif
00087 #ifndef OS_CODE
00088 # define OS_CODE 0x03
00089 #endif
00090
00091 #ifdef OSG_WIN32_CL
00092 #pragma warning(disable : 4355)
00093 #endif
00094
00095 OSG_BEGIN_NAMESPACE
00096
00097
00098 namespace detail
00099 {
00100 const int gz_magic[2] = {0x1f, 0x8b};
00101
00102
00103 const int gz_ascii_flag = 0x01;
00104 const int gz_head_crc = 0x02;
00105 const int gz_extra_field = 0x04;
00106 const int gz_orig_name = 0x08;
00107 const int gz_comment = 0x10;
00108 const int gz_reserved = 0xE0;
00109 }
00110
00113 const size_t zstream_default_buffer_size = 4096;
00114
00116 enum EStrategy
00117 {
00118 StrategyFiltered = 1,
00119 StrategyHuffmanOnly = 2,
00120 DefaultStrategy = 0
00121 };
00122
00123
00124
00125
00126
00127
00128
00133 template <class charT,
00134 class traits = std::char_traits<charT> >
00135 class basic_zip_streambuf : public std::basic_streambuf<charT, traits>
00136 {
00137 public:
00138 typedef std::basic_ostream<charT, traits>& ostream_reference;
00139 typedef unsigned char byte_type;
00140 typedef char char_type;
00141 typedef byte_type* byte_buffer_type;
00142 typedef std::vector<byte_type> byte_vector_type;
00143 typedef std::vector<char_type> char_vector_type;
00144 typedef int int_type;
00145
00146 basic_zip_streambuf(ostream_reference ostream,
00147 int level,
00148 EStrategy strategy,
00149 int window_size,
00150 int memory_level,
00151 size_t buffer_size);
00152
00153 ~basic_zip_streambuf(void);
00154
00155 int sync (void);
00156 int_type overflow (int_type c);
00157 std::streamsize flush (void);
00158 inline
00159 ostream_reference get_ostream (void) const;
00160 inline
00161 int get_zerr (void) const;
00162 inline
00163 unsigned long get_crc (void) const;
00164 inline
00165 unsigned long get_in_size (void) const;
00166 inline
00167 long get_out_size(void) const;
00168
00169 private:
00170
00171 bool zip_to_stream(char_type *buffer,
00172 std::streamsize buffer_size);
00173
00174 ostream_reference _ostream;
00175 z_stream _zip_stream;
00176 int _err;
00177 byte_vector_type _output_buffer;
00178 char_vector_type _buffer;
00179 unsigned long _crc;
00180 };
00181
00182
00183
00184
00185
00186
00191 template <class charT,
00192 class traits = std::char_traits<charT> >
00193 class basic_unzip_streambuf :
00194 public std::basic_streambuf<charT, traits>
00195 {
00196 public:
00197 typedef std::basic_istream<charT,traits>& istream_reference;
00198 typedef unsigned char byte_type;
00199 typedef char char_type;
00200 typedef byte_type* byte_buffer_type;
00201 typedef std::vector<byte_type> byte_vector_type;
00202 typedef std::vector<char_type> char_vector_type;
00203 typedef int int_type;
00204
00208 basic_unzip_streambuf(istream_reference istream,
00209 int window_size,
00210 size_t read_buffer_size,
00211 size_t input_buffer_size);
00212
00213 ~basic_unzip_streambuf(void);
00214
00215 int_type underflow(void);
00216
00218 inline
00219 istream_reference get_istream (void);
00220 inline
00221 z_stream& get_zip_stream (void);
00222 inline
00223 int get_zerr (void) const;
00224 inline
00225 unsigned long get_crc (void) const;
00226 inline
00227 long get_out_size (void) const;
00228 inline
00229 long get_in_size (void) const;
00230
00231
00232 private:
00233
00234 void put_back_from_zip_stream (void);
00235
00236 std::streamsize unzip_from_stream (char_type* buffer,
00237 std::streamsize buffer_size);
00238
00239 size_t fill_input_buffer (void);
00240
00241 istream_reference _istream;
00242 z_stream _zip_stream;
00243 int _err;
00244 byte_vector_type _input_buffer;
00245 char_vector_type _buffer;
00246 unsigned long _crc;
00247 };
00248
00249
00250
00251
00252
00253 template <class charT,
00254 class traits = std::char_traits<charT> >
00255 class basic_zip_ostream :
00256 private basic_zip_streambuf<charT, traits>,
00257 public std::basic_ostream<charT, traits>
00258 {
00259 public:
00260
00261 typedef char char_type;
00262 typedef std::basic_ostream<charT, traits>& ostream_reference;
00263
00264 inline
00265 explicit basic_zip_ostream(ostream_reference ostream,
00266 bool is_gzip = false,
00267 int level = Z_DEFAULT_COMPRESSION,
00268 EStrategy strategy = DefaultStrategy,
00269 int window_size = -15 ,
00270 int memory_level = 8,
00271 size_t buffer_size = zstream_default_buffer_size);
00272
00273 ~basic_zip_ostream(void);
00274
00275 inline
00276 bool is_gzip (void) const;
00277 inline
00278 basic_zip_ostream<charT, traits>& zflush (void);
00279 void finished (void);
00280
00281 private:
00282
00283 basic_zip_ostream<charT,traits>& add_header(void);
00284 basic_zip_ostream<charT,traits>& add_footer(void);
00285
00286 bool _is_gzip;
00287 bool _added_footer;
00288 };
00289
00290
00291
00292
00293
00294 template <class charT,
00295 class traits = std::char_traits<charT> >
00296 class basic_zip_istream :
00297 private basic_unzip_streambuf<charT, traits>,
00298 public std::basic_istream<charT, traits>
00299 {
00300 public:
00301 typedef std::basic_istream<charT, traits>& istream_reference;
00302
00303 explicit basic_zip_istream(istream_reference istream,
00304 int window_size = -15 ,
00305 size_t read_buffer_size = zstream_default_buffer_size,
00306 size_t input_buffer_size = zstream_default_buffer_size);
00307
00308 inline
00309 bool is_gzip (void) const;
00310 inline
00311 bool check_crc (void);
00312 inline
00313 bool check_data_size (void) const;
00314 inline
00315 long get_gzip_crc (void) const;
00316 inline
00317 long get_gzip_data_size(void) const;
00318
00319 protected:
00320
00321 int check_header (void);
00322 void read_footer (void);
00323
00324 bool _is_gzip;
00325 long _gzip_crc;
00326 long _gzip_data_size;
00327 };
00328
00329
00330 #include "OSGZStream.inl"
00331
00333 typedef basic_zip_ostream<char> zip_ostream;
00334
00336
00337
00339 typedef basic_zip_istream<char> zip_istream;
00340
00342
00343
00344 OSG_END_NAMESPACE
00345
00346 #ifdef OSG_WIN32_CL
00347 #pragma warning(default : 4355)
00348 #endif
00349
00350 #endif // OSG_ZSTREAM_SUPPORTED
00351
00352 #endif // _OSGZSTREAM_H_