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