SourceForge.jp

dkutilZlib.h

説明を見る。
00001 
00002 
00003 #ifndef _dkutil_ZLIB_h__
00004 #define _dkutil_ZLIB_h__
00005 
00006 #ifdef USE_DKINGYO_ZLIB
00007 
00008 #ifdef USE_DKINGYO_INCLUDE_SETTING_LIKE_BOOST
00009 #include <dkutil/dkutilCompileOption.h>
00010 #include <dkutil/dkutilDefinedC.h>
00011 #include <dkutil/dKingyoMacro.h>
00012 #include <dkutil/dkutilFileSystem.h>
00013 #else
00014 #include "../dkutilCompileOption.h"
00015 #include "../dkutilDefinedC.h"
00016 #include "../dKingyoMacro.h"
00017 #include "../dkutilFileSystem.h"
00018 #endif
00019 
00020 #include <zlib.h>
00021 #ifdef DKUTIL_COMPILE_OPTION_MSVC
00022 #   ifdef _MT
00023 #       pragma comment(lib,"zlibMT")
00024 #   else
00025 #       pragma comment(lib,"zlib")
00026 #   endif
00027 #endif
00028 
00029 
00030 
00031 namespace dkutil{
00032 
00033 
00034 
00035 
00036 
00038 inline const char *zlib_get_message(z_stream *z){
00039     static const char *mes="??? no message";
00040     static const char *logic_err="z_stream structure is null";
00041     if(!z) return logic_err;
00042     return ((z->msg) ? z->msg : mes);
00043 }
00044 
00045 inline void zlib_exception_throw(z_stream *z){
00046     throw dkutil_exception("zlib:%s",zlib_get_message(z));
00047 }
00048 
00049 template<typename PTR1>
00050 inline void zlib_set_output_buffer(z_stream *z,PTR1 *dest,size_t destsize)
00051 {
00052 #   ifdef _DEBUG
00053     if(dest==NULL || destsize==0)
00054         throw std::invalid_argument("zlib_set_output_buffer:argument is invalid!!");
00055 #   endif
00056     //output
00057     z->next_out = (BYTE *)dest;// 出力ポインタ //
00058     z->avail_out = destsize;    // 出力バッファのサイズ //
00059 }
00060 
00061 template<typename PTR1>
00062 inline void zlib_set_input_buffer(z_stream *z,PTR1 src,size_t srcsize)
00063 {
00064 #   ifdef _DEBUG
00065     if(src==NULL || srcsize==0)
00066         throw std::invalid_argument("zlib_set_input_buffer:argument is invalid!!");
00067 #   endif
00068     //input
00069     z->avail_in = srcsize;     // 入力バッファ中のデータのバイト数
00070     z->next_in = (BYTE *)src;
00071 
00072 }
00073 
00074 inline bool zlib_is_error(int result){
00075     if(Z_OK > result) return true;
00076     return false;
00077 }
00078 
00079 
00083 
00084 inline bool zlib_encode_init(z_stream *z,int compress_mode=Z_BEST_SPEED){
00085     z->zalloc = Z_NULL;
00086   z->zfree = Z_NULL;
00087   z->opaque = Z_NULL;
00088     /*if (::deflateInit(z, compress_mode) != Z_OK) {
00089         return false;
00090     }
00091     return true;*/
00092     return ::deflateInit(z, compress_mode) == Z_OK;
00093 }
00103 
00104 inline int zlib_encode(z_stream *z,int encode_option)
00105 {
00106     return ::deflate(z, encode_option); // 圧縮する
00107 }
00108 
00109 
00110 
00114 
00115 inline bool zlib_encode_end(z_stream *z){
00116     return (::deflateEnd(z) == Z_OK);
00117 }
00118 
00119 inline bool zlib_decode_init(z_stream *z){
00120     // すべてのメモリ管理をライブラリに任せる //
00121     z->zalloc = Z_NULL;
00122     z->zfree = Z_NULL;
00123     z->opaque = Z_NULL;
00124 
00125     // 初期化 //
00126     z->next_in = Z_NULL;
00127     z->avail_in = 0;
00128     return (::inflateInit(z) == Z_OK);
00129 }
00134 
00135 inline int zlib_decode(z_stream *z,int option)
00136 {
00137     return ::inflate(z, option ); // 展開 //
00138 }
00139 
00140 
00141 
00142 inline bool zlib_decode_end(z_stream *z){
00143     return (::inflateEnd(z) == Z_OK) ;
00144 }
00145 
00146 
00147 
00148 namespace policy{
00149 
00150 
00151 
00152 
00153 class zlib_encoder{
00154 protected:
00155     z_stream m_encode;
00156     bool m_flag;
00157     int m_state;
00158     void check_error(int result){
00159         if(zlib_is_error(result)){
00160             zlib_exception_throw(&m_encode);
00161         }
00162     }
00163 public:
00164     zlib_encoder(){m_flag=false;m_state = 0;}
00165     ~zlib_encoder(){end();}
00166 
00167     bool init(int mode=Z_BEST_SPEED ){
00168         if(m_flag){
00169             if(false==end())//一回終了
00170                 return false;//error
00171         }
00172         DKUTIL_RETURN_FALSE(zlib_encode_init(&m_encode,mode));
00173         m_flag = true;
00174         return true;
00175     }
00176     bool process(int encode_option)
00177     {
00178         if(false==m_flag) return false;
00179         int result=0;
00180         result = zlib_encode(&m_encode,encode_option);
00181         m_state = result;
00182         check_error(result);
00183         return true;
00184     }
00185     bool end(){
00186         if(false==m_flag){return false;}
00187         DKUTIL_RETURN_FALSE(zlib_encode_end(&m_encode));
00188         //check_error(r);
00189         m_flag=false;
00190         return true;
00191     }
00192     const int get_state()const{return m_state;}
00193     const z_stream &get_stream()const{return m_encode;}
00194     void set_stream(z_stream &s){m_encode = s;}
00195     z_stream *get_stream_ptr(){return &m_encode;}
00196 };
00197 
00198 class zlib_decoder{
00199 protected:
00200     z_stream m_decode;
00201     bool m_flag;
00202     int m_state;
00203     void check_error(int result){
00204         if(zlib_is_error(result)){
00205             zlib_exception_throw(&m_decode);
00206         }
00207     }
00208 public:
00209     zlib_decoder(){m_flag=false;m_state=0;}
00210     ~zlib_decoder(){end();}
00211     bool init(int mode=Z_BEST_SPEED ){
00212         if(m_flag){
00213             if(false==end())
00214                 return false;//error
00215         }
00216         DKUTIL_RETURN_FALSE(zlib_decode_init(&m_decode));
00217         m_flag = true;
00218         return true;
00219     }
00220     bool process(int flush_option=Z_NO_FLUSH){
00221         if(false==m_flag) return false;
00222         int result=0;
00223         //result = zlib_decode(&m_decode,flush_option);
00224         result = zlib_decode(&m_decode,Z_SYNC_FLUSH );
00225         m_state = result;
00226         check_error(result);
00227         return true;
00228     }
00229     bool end(){
00230         if(false==m_flag){return false;}
00231         DKUTIL_RETURN_FALSE(zlib_decode_end(&m_decode));
00232         //check_error(r);
00233         m_flag=false;
00234         return true;
00235     }
00236     const int get_state()const{return m_state;}
00237     const z_stream &get_stream()const{return m_decode;}
00238     void set_stream(z_stream &s){m_decode = s;}
00239     z_stream *get_stream_ptr(){return &m_decode;}
00240 };
00241 
00242 }//end of policy namespace
00243 
00259 template<class ZLIB_OPERATION,class READ_BUFFER_LISTENER,class WRITE_BUFFER_LISTENER>
00260 inline bool zlib_general_purpose_process(size_t srclocalbuffsize,size_t destlocalbuffsize,
00261                                  //ZLIB_OPERATION get_zlib,BUFFER_LISTENER get_listener,
00262                                  ZLIB_OPERATION zlib,READ_BUFFER_LISTENER read_listener,WRITE_BUFFER_LISTENER write_listener,
00263                                  int compress_mode=Z_BEST_SPEED )
00264 {
00265     //variable
00266 
00267     //get_listener listener;
00268     //get_zlib zlib;
00269     if(destlocalbuffsize==0 || srclocalbuffsize==0)
00270         throw dkutil_exception("dkutil::zlib_general_purpose_process::localbuffer size was zero");
00271     scoped_buffer destlocalbuff(destlocalbuffsize);
00272     scoped_buffer srclocalbuff(srclocalbuffsize);
00273     
00274 
00275     //procedure
00276     
00277      //initialize
00278     DKUTIL_RETURN_FALSE(zlib.init(compress_mode));
00279     //file open
00280     DKUTIL_RETURN_FALSE(read_listener.open());
00281     DKUTIL_RETURN_FALSE(write_listener.open());
00282     
00283     //最初はこのencodeオプションで
00284     int encode_option =  Z_NO_FLUSH;
00285     //実際に読み込んだサイズ
00286     size_t ReadSize = 0;
00287     //read data
00288     {
00289         size_t read_size;
00290         read_size=read_listener.read(
00291             srclocalbuff.get(),srclocalbuff.size()
00292             );
00293         if(read_size==0) return false;
00294         if( srclocalbuff.size() > read_size)
00295         {//少なく読み込んだ。
00296             //なのでエンコードオプションを最終用に変える。
00297             encode_option= Z_FINISH;
00298         }
00299         //読み込んだサイズを保存
00300         ReadSize = read_size;
00301         //読み込みバッファを設定する
00302         zlib_set_input_buffer(zlib.get_stream_ptr(),srclocalbuff.get(),read_size);
00303     }
00304     //書き込みバッファを設定する
00305     zlib_set_output_buffer(zlib.get_stream_ptr(),destlocalbuff.get(),destlocalbuff.size());
00306     
00307 
00308 
00309     while (true) 
00310     {
00311 
00312         //int result=0;
00313         int lre = zlib.get_state();
00314         z_stream *z = zlib.get_stream_ptr();
00315         if(z->avail_in == 0){
00316             size_t read_size;
00317             read_size = read_listener.read(srclocalbuff.get(),srclocalbuff.size());
00318             if( srclocalbuff.size() > read_size)
00319             {//少なく読み込んだ。
00320                 //なのでエンコードオプションを最終用に変える。
00321                 encode_option= Z_FINISH;
00322     
00323                 //zlib.process(encode_option);
00324                 //if(zlib.get_state()==Z_STREAM_END) break;
00325             }
00326             
00327             ReadSize = read_size;
00328             //読み込みバッファを設定する
00329             if(read_size != 0){
00330                 zlib_set_input_buffer(
00331                     zlib.get_stream_ptr(),srclocalbuff.get(),
00332                     read_size
00333                 );
00334             }
00335             //z->next_in = (BYTE *)srclocalbuff.get();  // 入力ポインタを入力バッファの先頭に //
00336             //z->avail_in = read_size;//読み込んだサイズでGO!!
00337         }
00338         zlib.process(encode_option);
00339         if(zlib.get_state()==Z_STREAM_END)
00340         {
00341             break;
00342         }
00343         /*if(zlib.get_state()==Z_NEED_DICT){
00344             MB("??");
00345         }*/
00346         if (z->avail_out == 0) 
00347         {
00348             //バッファがオーバーした。
00349             // まとめて書き出す //
00350             size_t Size;
00351             Size = destlocalbuff.size();
00352 
00353             DKUTIL_TRUE_ASSERT_OR_THROW(
00354                     write_listener.write(destlocalbuff.get(),Size) != Size,
00355                     std::runtime_error("zlib Write error\n")
00356                 );
00357 
00358             zlib_set_output_buffer(z,destlocalbuff.get(),destlocalbuff.size());
00359             //z->next_out = (BYTE *)destlocalbuff.get(); // 出力バッファ残量を元に戻す 
00360             //z->avail_out = destlocalbuff.size(); // 出力ポインタを元に戻す
00361         }
00362         
00363     }//end of loop
00364     // 残りを吐き出す
00365     {
00366         size_t count;
00367         if ((count = destlocalbuff.size() - zlib.get_stream().avail_out) != 0)
00368         {
00369             DKUTIL_TRUE_ASSERT_OR_THROW(
00370                 write_listener.write(destlocalbuff.get(),count) != count,
00371                 std::runtime_error("zlib Write error\n")
00372             );
00373         }
00374     }
00375     //あとはデストラクタに任せる^^;
00376     //zlib.end();
00377     //read_listener.close();
00378     //write_listener.close();
00379     return true;
00380 }
00381 
00382 
00383 namespace policy{
00384 
00385 class zlib_compress{
00386 protected:
00387 public:
00388     //bool init(
00394     bool encode(BYTE *src,size_t srcsize,byte_buffer &buff,
00395         int compress_mode=Z_BEST_SPEED ,bool isThrow=true)
00396     {
00397         
00398         
00399 
00400     }
00401     bool decode(BYTE *src,size_t srcsize,byte_buffer &buff){
00402         
00403     }
00404 };
00405 
00406 
00407 }//end of policy namespace
00408 
00409 
00410 namespace private_{
00411 
00415 /*
00416 class zlib_file_compressor{
00417 private:
00418 public:
00419     //
00420     bool compress(
00421         char *inbuff,size_t inbuffsize,char *outbuff,size_t outbuffsize,
00422         FILE *fin,FILE *fout,
00423         int compress_mode=Z_BEST_SPEED ,bool isThrow=true)
00424     {
00425         z_stream z; // ライブラリとやりとりするための構造体 
00426         int count, flush, status;
00427         if(fin==NULL || fout==NULL) return false;
00428 
00429         // すべてのメモリ管理をライブラリに任せる 
00430         z.zalloc = Z_NULL;
00431         z.zfree = Z_NULL;
00432         z.opaque = Z_NULL;
00433 
00434         // 初期化 
00435         // 第2引数は圧縮の度合。0〜9 の範囲の整数で,0 は無圧縮 
00436         // Z_BEST_SPEED  (= 6) が標準 
00437         if (::deflateInit(&z, compress_mode) != Z_OK) {
00438                 DKUTIL_TRUE_ASSERT_OR_THROW(
00439                     isThrow,
00440                 std::runtime_error("zlib deflateInit: %s\n", (z.msg) ? z.msg : "???")
00441                 );
00442             return false;
00443         }
00444 
00445         z.avail_in = 0;             // 入力バッファ中のデータのバイト数 //
00446         z.next_out = outbuff;        // 出力ポインタ //
00447         z.avail_out = outbuffsize;    // 出力バッファのサイズ //
00448 
00449         // 通常は ::deflate() の第2引数は Z_NO_FLUSH にして呼び出す //
00450         flush = Z_NO_FLUSH;
00451 
00452         while (1) {
00453                 if (z.avail_in == 0) {  // 入力が尽きれば //
00454                         z.next_in = inbuff;  // 入力ポインタを入力バッファの先頭に //
00455                         z.avail_in = fread(inbuff, 1, inbuffsize, fin); // データを読み込む //
00456 
00457                         // 入力が最後になったら ::deflate() の第2引数は Z_FINISH にする //
00458                         if (z.avail_in < inbuffsize) flush = Z_FINISH;
00459                 }
00460                 status = ::deflate(&z, flush); // 圧縮する //
00461                 if (status == Z_STREAM_END) break; // 完了 //
00462                 if (status != Z_OK) {   // エラー //
00463                         DKUTIL_TRUE_ASSERT_OR_THROW(
00464                                 isThrow,
00465                                 std::runtime_error("zlib deflate: %s\n", (z.msg) ? z.msg : "???")
00466                             );
00467                             return false;
00468                 }
00469                 if (z.avail_out == 0) { // 出力バッファが尽きれば //
00470                         // まとめて書き出す //
00471                         if (fwrite(outbuff, 1, outbuffsize, fout) != outbuffsize) {
00472                                 DKUTIL_TRUE_ASSERT_OR_THROW(
00473                                         isThrow,
00474                                         std::runtime_error("zlib Write error\n")
00475                                     );
00476                                     return false;
00477                         }
00478                         z.next_out = outbuff; // 出力バッファ残量を元に戻す //
00479                         z.avail_out = outbuffsize; // 出力ポインタを元に戻す //
00480                 }
00481         }
00482 
00483         // 残りを吐き出す //
00484         if ((count = outbuffsize - z.avail_out) != 0) {
00485                 if (fwrite(outbuff, 1, count, fout) != count) {
00486                         DKUTIL_TRUE_ASSERT_OR_THROW(
00487                                         isThrow,std::runtime_error("zlib Write error\n"));
00488                             return false;
00489                 }
00490         }
00491 
00492         // 後始末 //
00493         if (::deflateEnd(&z) != Z_OK) {
00494                 DKUTIL_TRUE_ASSERT_OR_THROW(
00495                         isThrow,
00496                         std::runtime_error("zlib deflateEnd: %s\n", (z.msg) ? z.msg : "???")
00497                     );
00498                     return false;
00499         }
00500             return true;
00501     }
00502     bool decompress(
00503         char *inbuff,size_t inbuffsize,char *outbuff,size_t outbuffsize,
00504         FILE *fin,FILE *fout,
00505         bool isThrow=true)        // 展開(復元) //
00506     {
00507         z_stream z;
00508         int count, status;
00509         if(fin==NULL || fout==NULL) return false;
00510 
00511         // すべてのメモリ管理をライブラリに任せる //
00512         z.zalloc = Z_NULL;
00513         z.zfree = Z_NULL;
00514         z.opaque = Z_NULL;
00515 
00516         // 初期化 //
00517         z.next_in = Z_NULL;
00518         z.avail_in = 0;
00519         if (inflateInit(&z) != Z_OK) {
00520                 DKUTIL_TRUE_ASSERT_OR_THROW(
00521                     isThrow,
00522                     std::runtime_error("zlib inflateInit: %s\n", (z.msg) ? z.msg : "???")
00523                 );
00524                 return false;
00525         }
00526 
00527         z.next_out = outbuff;        // 出力ポインタ //
00528         z.avail_out = outbuffsize;    // 出力バッファ残量 //
00529         status = Z_OK;
00530 
00531         while (status != Z_STREAM_END) {
00532             if (z.avail_in == 0) {  // 入力残量がゼロになれば //
00533                     z.next_in = inbuff;  // 入力ポインタを元に戻す //
00534                     z.avail_in = fread(inbuff, 1, inbuffsize, fin); // データを読む //
00535             }
00536             status = inflate(&z, Z_NO_FLUSH); // 展開 //
00537             if (status == Z_STREAM_END) break; // 完了 //
00538             if (status != Z_OK) {   // エラー //
00539                 DKUTIL_TRUE_ASSERT_OR_THROW(
00540                     isThrow,
00541                     std::runtime_error("zlib inflate: %s\n", (z.msg) ? z.msg : "???")
00542                 );
00543                     return false;
00544             }
00545             if (z.avail_out == 0) { // 出力バッファが尽きれば //
00546                 // まとめて書き出す //
00547                 if (fwrite(outbuff, 1, outbuffsize, fout) != outbuffsize) {
00548                         DKUTIL_TRUE_ASSERT_OR_THROW(isThrow,
00549                             std::runtime_error("zlib Write error\n");
00550                         return false;
00551                 }
00552                 z.next_out = outbuff; // 出力ポインタを元に戻す //
00553                 z.avail_out = outbuffsize; // 出力バッファ残量を元に戻す //
00554             }
00555         }
00556 
00557         // 残りを吐き出す //
00558         if ((count = outbuffsize - z.avail_out) != 0) {
00559                 if (fwrite(outbuff, 1, count, fout) != count) {
00560                         DKUTIL_TRUE_ASSERT_OR_THROW(isThrow,std::runtime_error("zlib Write error\n");
00561                         return false;
00562                 }
00563         }
00564 
00565         // 後始末 //
00566         if (inflateEnd(&z) != Z_OK) {
00567                 DKUTIL_TRUE_ASSERT_OR_THROW(isThrow,std::runtime_error("zlib inflateEnd: %s\n", (z.msg) ? z.msg : "???");
00568                 return false;
00569         }
00570         return true;
00571     }
00572 public:
00573     zlib_file_compressor(){
00574     }
00575     bool zlib_compressed_file_to_normal_file(const char *infilename,const char *outfilename,size_t buffsize=2048)
00576     {
00577         scoped_buffer inbuff(buffsize);
00578         scoped_buffer outbuff(buffsize);
00579         file_operator infile(infilename);
00580         file_operator outfile(outfilename);
00581         return decompress(inbuff.get(),inbuff.size(),
00582             outbuff.get(),outbuff.size(),
00583             infile.handle(),outfile.handle(),
00584             false);
00585 
00586 
00587 
00588         return true;
00589     }
00590     bool normal_file_to_zlib_compressed_file(const char *infilename,const char *outfilename,
00591         int compression_mode=Z_BEST_SPEED ,size_t buffsize=2048)
00592     {
00593         scoped_buffer inbuff(buffsize);
00594         scoped_buffer outbuff(buffsize);
00595         file_operator infile(infilename);
00596         file_operator outfile(outfilename);
00597         return compress(inbuff.get(),inbuff.size(),
00598             outbuff.get(),outbuff.size(),
00599             infile.handle(),outfile.handle(),
00600             false);
00601 
00602         return true;
00603     }
00604 
00605 };
00606 */      
00607 
00608 }//end of private_ namespace
00609 
00610 
00611 
00612 /*
00613 class zlib_file_operator : public file_operator{
00614 protected:
00615     policy::zlib_decoder m_decode;
00616     policy::zlib_encoder m_encode;
00617 
00618 
00619 
00620 public:
00621     typedef file_operator BASE_TYPE;
00622     zlib_file_operator(){
00623     }
00624     virtual ~zlib_file_operator(){
00625         close();
00626     }
00627 
00628     bool reset(const char *filename,const char *mode,const char *type,
00629         int compress_mode=Z_BEST_SPEED )
00630     {
00631         close();
00632         bool r=BASE_TYPE::reset(filename,mode,type);
00633         if(false==r) return r;
00634         m_encode.init();
00635         m_decode.init();
00636         return r;
00637     }
00638 
00639 //  const char *filename()const{return mfilename.c_str();}
00640 //  const char *mode()const{return mmode.c_str();}
00641     bool open(){
00642         bool r = BASE_TYPE::open();
00643         if(r==false) return r;
00644         return r;
00645     }
00646     size_t read(const void *buf,size_t size,size_t readsize=0){
00647         BASE_TYPE::read(lbuff.get(),lbuff.size());
00648         zlib_general_purpose_process(buf,size,destlocalbuffsize,
00649             decoder,file_operation);
00650         
00651 
00652     }
00653     size_t write(const void *buf,size_t size){
00654 
00655     }
00656     //
00657     bool eof()const{
00658 
00659     }
00660     bool error()const{
00661         return 
00662     }
00663     bool seek(long offset, int origin ){
00664         return BASE_TYPE::seek(offset,origin);
00665     }//
00666     
00667     void close(){
00668         BASE_TYPE::close();
00669         m_encode.end();
00670         m_decode.end();
00671     }
00672 };
00673 
00674 
00675 */
00676 
00677 }//end of dkutil namespace
00678 
00679 
00680 #endif//end of USE_DKINGYO_ZLIB
00681 #endif//end of include once

dkutil 1.02リリース前 d金魚専用マニュアルバージョンに対してSun Dec 28 21:23:08 2003に生成されました。 doxygen 1.3.5