Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlCore/ZippedFile.cpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
00029 /*                                                                                    */
00030 /**************************************************************************************/
00031 
00032 #include <vlCore/ZippedFile.hpp>
00033 #include <vlCore/CRC32CheckSum.hpp>
00034 #include <vlCore/Log.hpp>
00035 #include <vlCore/Say.hpp>
00036 #include <zlib.h>
00037 #include <stdio.h>
00038 
00039 using namespace vl;
00040 
00041 bool vl::compress(const void* data, size_t size, std::vector<unsigned char>& out_data, int level)
00042 {
00043   const size_t CHUNK_SIZE = 128*1024;
00044   int ret, flush;
00045   unsigned have;
00046   z_stream strm;
00047   const unsigned char* in = (const unsigned char*)data;
00048   unsigned char out[CHUNK_SIZE];
00049 
00050   strm.zalloc = Z_NULL;
00051   strm.zfree = Z_NULL;
00052   strm.opaque = Z_NULL;
00053   ret = deflateInit(&strm, level);
00054   if (ret != Z_OK)
00055     return false;
00056 
00057   size_t avail = size;
00058 
00059   do
00060   {
00061     strm.avail_in = std::min(avail, CHUNK_SIZE);
00062     avail -= strm.avail_in;
00063     strm.next_in = (unsigned char*)in;
00064     in += strm.avail_in;
00065     flush = avail == 0 ? Z_FINISH : Z_NO_FLUSH;
00066 
00067     do
00068     {
00069       strm.avail_out = CHUNK_SIZE;
00070       strm.next_out = out;
00071 
00072       ret = deflate(&strm, flush);
00073       if(ret == Z_STREAM_ERROR)
00074       {
00075         deflateEnd(&strm);
00076         return false;
00077       }
00078 
00079       have = CHUNK_SIZE - strm.avail_out;
00080       out_data.insert( out_data.end(), out, out+have );
00081     } while (strm.avail_out == 0);
00082 
00083     VL_CHECK(strm.avail_in == 0);
00084 
00085   } while (flush != Z_FINISH);
00086 
00087   VL_CHECK(ret == Z_STREAM_END);
00088 
00089   deflateEnd(&strm);
00090   return true;
00091 }
00092 
00093 bool vl::decompress(const void* cdata, size_t csize, void* data_out)
00094 {
00095   const size_t CHUNK_SIZE = 128*1024;
00096   int ret;
00097   unsigned have;
00098   z_stream strm;
00099   unsigned char* in = (unsigned char*)cdata;
00100   unsigned char out[CHUNK_SIZE];
00101   char* out_ptr = (char*)data_out;
00102 
00103   strm.zalloc = Z_NULL;
00104   strm.zfree = Z_NULL;
00105   strm.opaque = Z_NULL;
00106   strm.avail_in = 0;
00107   strm.next_in = Z_NULL;
00108   ret = inflateInit(&strm);
00109   if (ret != Z_OK)
00110       return false;
00111 
00112   size_t avail = csize;
00113 
00114   do
00115   {
00116     strm.avail_in = std::min(avail, CHUNK_SIZE);
00117     if (strm.avail_in == 0)
00118       break;
00119     avail -= strm.avail_in;
00120     strm.next_in = in;
00121     in += strm.avail_in;
00122 
00123     do
00124     {
00125       strm.avail_out = CHUNK_SIZE;
00126       strm.next_out = out;
00127 
00128       ret = inflate(&strm, Z_NO_FLUSH);
00129       VL_CHECK(ret != Z_STREAM_ERROR);
00130       switch (ret)
00131       {
00132       case Z_NEED_DICT:
00133       case Z_DATA_ERROR:
00134       case Z_MEM_ERROR:
00135         inflateEnd(&strm);
00136         return false;
00137       }
00138 
00139       have = CHUNK_SIZE - strm.avail_out;
00140       // data_out.insert( data_out.end(), out, out + have );
00141       memcpy(out_ptr, out, have);
00142       out_ptr += have;
00143     }
00144     while (strm.avail_out == 0);
00145 
00146     VL_CHECK(strm.avail_in == 0);
00147 
00148   } while (ret != Z_STREAM_END);
00149 
00150   inflateEnd(&strm);
00151 
00152   /*VL_CHECK(ret == Z_STREAM_END)*/
00153   return ret == Z_STREAM_END;
00154 }
00155 
00156 namespace
00157 {
00158 //-----------------------------------------------------------------------------
00159   inline int zcompress(FILE *source, FILE *dest, int level)
00160   {
00161     const int CHUNK_SIZE = 128*1024;
00162     int ret, flush;
00163     unsigned have;
00164     z_stream strm;
00165     unsigned char in[CHUNK_SIZE];
00166     unsigned char out[CHUNK_SIZE];
00167 
00168     strm.zalloc = Z_NULL;
00169     strm.zfree = Z_NULL;
00170     strm.opaque = Z_NULL;
00171     ret = deflateInit(&strm, level);
00172     if (ret != Z_OK)
00173       return ret;
00174 
00175     do
00176     {
00177       strm.avail_in = (uInt)fread(in, 1, CHUNK_SIZE, source);
00178       if (ferror(source))
00179       {
00180         deflateEnd(&strm);
00181         return Z_ERRNO;
00182       }
00183       flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
00184       strm.next_in = in;
00185 
00186       do
00187       {
00188         strm.avail_out = CHUNK_SIZE;
00189         strm.next_out = out;
00190 
00191         ret = deflate(&strm, flush);
00192         VL_CHECK(ret != Z_STREAM_ERROR);
00193 
00194         have = CHUNK_SIZE - strm.avail_out;
00195         if (fwrite(out, 1, have, dest) != have || ferror(dest))
00196         {
00197           deflateEnd(&strm);
00198           return Z_ERRNO;
00199         }
00200 
00201       } while (strm.avail_out == 0);
00202 
00203       VL_CHECK(strm.avail_in == 0);
00204 
00205     } while (flush != Z_FINISH);
00206 
00207     VL_CHECK(ret == Z_STREAM_END);
00208 
00209     (void)deflateEnd(&strm);
00210     return Z_OK;
00211   }
00212 //-----------------------------------------------------------------------------
00213   inline int zdecompress(FILE *source, FILE *dest)
00214   {
00215     const int CHUNK_SIZE = 128*1024;
00216     int ret;
00217     unsigned have;
00218     z_stream strm;
00219     unsigned char in[CHUNK_SIZE];
00220     unsigned char out[CHUNK_SIZE];
00221 
00222     strm.zalloc = Z_NULL;
00223     strm.zfree = Z_NULL;
00224     strm.opaque = Z_NULL;
00225     strm.avail_in = 0;
00226     strm.next_in = Z_NULL;
00227     ret = inflateInit(&strm);
00228     if (ret != Z_OK)
00229         return ret;
00230 
00231     do
00232     {
00233       strm.avail_in = (uInt)fread(in, 1, CHUNK_SIZE, source);
00234       if (ferror(source))
00235       {
00236         inflateEnd(&strm);
00237         return Z_ERRNO;
00238       }
00239       if (strm.avail_in == 0)
00240         break;
00241       strm.next_in = in;
00242 
00243       do
00244       {
00245         strm.avail_out = CHUNK_SIZE;
00246         strm.next_out = out;
00247 
00248         ret = inflate(&strm, Z_NO_FLUSH);
00249         VL_CHECK(ret != Z_STREAM_ERROR);
00250         switch (ret)
00251         {
00252         case Z_NEED_DICT:
00253           ret = Z_DATA_ERROR;
00254         case Z_DATA_ERROR:
00255         case Z_MEM_ERROR:
00256           inflateEnd(&strm);
00257           return ret;
00258         }
00259 
00260         have = CHUNK_SIZE - strm.avail_out;
00261         if (fwrite(out, 1, have, dest) != have || ferror(dest))
00262         {
00263           inflateEnd(&strm);
00264           return Z_ERRNO;
00265         }
00266       }
00267       while (strm.avail_out == 0);
00268 
00269       VL_CHECK(strm.avail_in == 0);
00270 
00271     } while (ret != Z_STREAM_END);
00272 
00273     inflateEnd(&strm);
00274     return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
00275   }
00276 //-----------------------------------------------------------------------------
00277   inline int zdecompress(VirtualFile *source, char *dest, unsigned int bytes_to_read)
00278   {
00279     const unsigned int CHUNK_SIZE = 128*1024;
00280     int ret;
00281     unsigned have;
00282     z_stream strm;
00283     unsigned char in[CHUNK_SIZE];
00284     unsigned char out[CHUNK_SIZE];
00285 
00286     strm.zalloc = Z_NULL;
00287     strm.zfree = Z_NULL;
00288     strm.opaque = Z_NULL;
00289     strm.avail_in = 0;
00290     strm.next_in = Z_NULL;
00291 
00292     ret = inflateInit2(&strm, -15);
00293     if (ret != Z_OK)
00294       return ret;
00295 
00296     do
00297     {
00298       unsigned int byte_count = CHUNK_SIZE < bytes_to_read  ? CHUNK_SIZE : bytes_to_read;
00299       strm.avail_in = (uInt)source->read(in, byte_count);
00300       bytes_to_read -= strm.avail_in;
00301 
00302       if (strm.avail_in == 0)
00303         break;
00304       strm.next_in = in;
00305 
00306       do
00307       {
00308         strm.avail_out = CHUNK_SIZE;
00309         strm.next_out = out;
00310 
00311         ret = inflate(&strm, Z_NO_FLUSH);
00312         VL_CHECK(ret != Z_STREAM_ERROR);
00313         switch (ret)
00314         {
00315         case Z_NEED_DICT:
00316           ret = Z_DATA_ERROR;
00317         case Z_DATA_ERROR:
00318         case Z_MEM_ERROR:
00319           inflateEnd(&strm);
00320           return ret;
00321         }
00322 
00323         have = CHUNK_SIZE - strm.avail_out;
00324         memcpy(dest, out, have);
00325         dest += have;
00326       }
00327       while (strm.avail_out == 0);
00328 
00329       VL_CHECK(strm.avail_in == 0);
00330 
00331     } while (ret != Z_STREAM_END);
00332 
00333     inflateEnd(&strm);
00334     return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
00335   }
00336 }
00337 //-----------------------------------------------------------------------------
00338 // ZippedFile
00339 //-----------------------------------------------------------------------------
00340 ZippedFile::ZippedFile() 
00341 { 
00342   mReadBytes = -1; 
00343   mZStream = new z_stream_s;
00344   memset(mZStream, 0, sizeof(z_stream_s));
00345 }
00346 //-----------------------------------------------------------------------------
00347 ZippedFile::~ZippedFile() 
00348 { 
00349   close();
00350   mReadBytes = -1; 
00351   delete mZStream; mZStream = NULL;
00352 }
00353 //-----------------------------------------------------------------------------
00354 const ZippedFileInfo* ZippedFile::zippedFileInfo() const { return mZippedFileInfo.get(); }
00355 //-----------------------------------------------------------------------------
00356 ZippedFileInfo* ZippedFile::zippedFileInfo() { return mZippedFileInfo.get(); }
00357 //-----------------------------------------------------------------------------
00358 void ZippedFile::setZippedFileInfo(ZippedFileInfo* info) { mZippedFileInfo = info; }
00359 //-----------------------------------------------------------------------------
00360 bool ZippedFile::exists() const
00361 {
00362   return zippedFileInfo() && zippedFileInfo()->sourceZipFile() && zippedFileInfo()->zippedFileOffset();
00363 }
00364 //-----------------------------------------------------------------------------
00365 bool ZippedFile::open(EOpenMode mode)
00366 {
00367   if ( zippedFileInfo()->versionNeeded() > 20 )
00368   {
00369     Log::error("ZippedFile::open(): unsupported archive version.\n");
00370     return false;
00371   }
00372 
00373   /*if ( zippedFileInfo()->generalPurposeFlag() & 1 )
00374   {
00375     Log::error("ZippedFile::extract(): encription not supported.\n");
00376     return false;
00377   }*/
00378 
00379   if ( zippedFileInfo()->compressionMethod() != 8 && zippedFileInfo()->compressionMethod() != 0 )
00380   {
00381     Log::error("ZippedFile::open(): unsupported compression method.\n");
00382     return false;
00383   }
00384 
00385   if ( isOpen() )
00386   {
00387     Log::error("ZippedFile::open(): file already open.\n");
00388     return false;
00389   }
00390 
00391   if ( mode != OM_ReadOnly )
00392   {
00393     Log::error("ZippedFile::open(): only OM_ReadOnly mode is supported.\n");
00394     return false;
00395   }
00396 
00397   if ( !zippedFileInfo()->sourceZipFile() )
00398   {
00399     Log::error("ZippedFile::open(): no source zip stream defined.\n");
00400     return false;
00401   }
00402 
00403   if ( zippedFileInfo()->sourceZipFile()->isOpen() )
00404   {
00405     Log::error("ZippedFile::open(): source zip stream is already open. Only one ZippedFile at a time can read from the same source.\n");
00406     return false;
00407   }
00408 
00409   if ( !zippedFileInfo()->sourceZipFile()->open(mode) )
00410   {
00411     Log::error("ZippedFile::open(): could not open source zip stream.\n");
00412     return false;
00413   }
00414 
00415   if ( !zippedFileInfo()->sourceZipFile()->seekSet( zippedFileInfo()->zippedFileOffset() ) )
00416   {
00417     Log::error("ZippedFile::open(): error seeking beginning of compressed file.\n");
00418     zippedFileInfo()->sourceZipFile()->close();
00419     return false;
00420   }
00421 
00422   /* inflate state */
00423   mZStream->zalloc   = Z_NULL;
00424   mZStream->zfree    = Z_NULL;
00425   mZStream->opaque   = Z_NULL;
00426   mZStream->avail_in = 0;
00427   mZStream->next_in  = Z_NULL;
00428   if ( zippedFileInfo()->compressionMethod() == 8 && inflateInit2(mZStream, -15) != Z_OK )
00429   {
00430     zippedFileInfo()->sourceZipFile()->close();
00431     return false;
00432   }
00433 
00434   mReadBytes = 0;
00435   mUncompressedBufferPtr = 0;
00436   mUncompressedBuffer.clear();
00437 
00438   return true;
00439 }
00440 //-----------------------------------------------------------------------------
00441 bool ZippedFile::isOpen() const { return mReadBytes != -1; }
00442 //-----------------------------------------------------------------------------
00443 void ZippedFile::close()
00444 {
00445   if ( mZStream->next_in != Z_NULL )
00446     inflateEnd(mZStream);
00447   memset(mZStream, 0, sizeof(z_stream_s));
00448   mReadBytes = -1;
00449   if (zippedFileInfo() && zippedFileInfo()->sourceZipFile())
00450     zippedFileInfo()->sourceZipFile()->close();
00451   mUncompressedBufferPtr = 0;
00452   mUncompressedBuffer.clear();
00453 }
00454 //-----------------------------------------------------------------------------
00455 long long ZippedFile::size() const
00456 {
00457   if ( mZippedFileInfo )
00458     return mZippedFileInfo->uncompressedSize();
00459   else
00460     return 0;
00461 }
00462 //-----------------------------------------------------------------------------
00463 void ZippedFile::resetStream()
00464 {
00465   close();
00466   open(OM_ReadOnly);
00467 }
00468 //-----------------------------------------------------------------------------
00469 bool ZippedFile::seekSet_Implementation(long long pos)
00470 {
00471   if (pos<position())
00472     resetStream();
00473 
00474   unsigned char buffer[CHUNK_SIZE];
00475   long long remained = pos - position();
00476   long long eat_bytes = remained < CHUNK_SIZE ? remained : CHUNK_SIZE;
00477   while ( (remained -= read(buffer, eat_bytes)) )
00478     eat_bytes = remained < CHUNK_SIZE ? remained : CHUNK_SIZE;
00479 
00480   return position() == pos;
00481 }
00482 //-----------------------------------------------------------------------------
00483 long long ZippedFile::read_Implementation(void* buffer, long long bytes_to_read)
00484 {
00485   if ( bytes_to_read < 1 )
00486     return 0;
00487 
00488   if (!isOpen())
00489     return 0;
00490 
00491   if ( mReadBytes >= zippedFileInfo()->uncompressedSize() )
00492     return 0;
00493 
00494   if ( zippedFileInfo()->compressionMethod() == 0 )
00495   {
00496     long long bytes = zippedFileInfo()->uncompressedSize() - mReadBytes;
00497     bytes = bytes < bytes_to_read ? bytes : bytes_to_read;
00498     long long read_bytes = zippedFileInfo()->sourceZipFile()->read(buffer, bytes);
00499     mReadBytes += read_bytes;
00500     return read_bytes;
00501   }
00502   else
00503   if ( zippedFileInfo()->compressionMethod() == 8 )
00504   {
00505 
00506     long long read_bytes = 0;
00507 
00508     if ( mUncompressedBuffer.empty() )
00509       fillUncompressedBuffer();
00510 
00511     do
00512     {
00513       long long bytes = bytes_to_read < (int)mUncompressedBuffer.size()-mUncompressedBufferPtr ? bytes_to_read : (int)mUncompressedBuffer.size()-mUncompressedBufferPtr;
00514       // copy uncompressed data
00515       VL_CHECK( mUncompressedBufferPtr < (int)mUncompressedBuffer.size() )
00516       if (bytes)
00517         memcpy((char*)buffer+read_bytes, &mUncompressedBuffer[0]+mUncompressedBufferPtr, (size_t)bytes);
00518 
00519       mReadBytes += bytes;
00520       read_bytes += bytes;
00521       mUncompressedBufferPtr += (int)bytes;
00522       bytes_to_read -= bytes;
00523       // remove read data from the buffer
00524       // mUncompressedBuffer.erase( mUncompressedBuffer.begin(), mUncompressedBuffer.begin() + (size_t)bytes );
00525       if(mUncompressedBufferPtr == (int)mUncompressedBuffer.size())
00526       {
00527         mUncompressedBuffer.clear();
00528         mUncompressedBufferPtr = 0;
00529       }
00530 
00531     } while( bytes_to_read && fillUncompressedBuffer() );
00532 
00533     return read_bytes;
00534   }
00535   else
00536     return 0;
00537 }
00538 //-----------------------------------------------------------------------------
00539 bool ZippedFile::extract(char* destination, bool check_sum)
00540 {
00541   ZippedFileInfo* zfile_info = zippedFileInfo();
00542 
00543   if ( zfile_info->mUncompressedSize == 0 )
00544     return true;
00545 
00546   if (isOpen())
00547   {
00548     Log::error("ZippedFile::extract(): the file is already open.\n");
00549     return false;
00550   }
00551 
00552   if ( zfile_info->versionNeeded() > 20 )
00553   {
00554     Log::error("ZippedFile::extract(): unsupported archive version.\n");
00555     return false;
00556   }
00557 
00558   if ( zfile_info->generalPurposeFlag() & 1 )
00559   {
00560     Log::error("ZippedFile::extract(): encription not supported.\n");
00561     return false;
00562   }
00563 
00564   ref<VirtualFile> zip = zfile_info->sourceZipFile();
00565 
00566   if ( !zip )
00567   {
00568     Log::error("ZippedFile::extract(): no source zip stream defined.\n");
00569     return false;
00570   }
00571 
00572   if ( zip->isOpen() )
00573   {
00574     Log::error("ZippedFile::extract(): source zip stream is already open. Only one ZippedFile at a time can read from the same source.\n");
00575     return false;
00576   }
00577 
00578   if ( !zip->open(OM_ReadOnly) )
00579   {
00580     Log::error("ZippedFile::extract(): could not open source zip stream.\n");
00581     return false;
00582   }
00583 
00584   if ( !zip->seekSet( zfile_info->zippedFileOffset() ) )
00585   {
00586     Log::error("ZippedFile::extract(): not a seek-able zip stream.\n");
00587     zip->close();
00588     return false;
00589   }
00590 
00591   switch(zfile_info->mCompressionMethod)
00592   {
00593     default:
00594       Log::error("ZippedFile::extract(): unsupported compression method.\n");
00595       break;
00596     case 0: // store
00597     case 8: // deflate 32K
00598     {
00599       if (zfile_info->mCompressionMethod == 8)
00600         zdecompress( zip.get(), destination, zfile_info->mCompressedSize );
00601       else
00602       if (zfile_info->mCompressionMethod == 0)
00603         zip->read( destination, zfile_info->mUncompressedSize );
00604 
00605       if (check_sum)
00606       {
00607         CRC32CheckSum checksum;
00608         unsigned int crc = checksum.compute( destination, (int)zfile_info->mUncompressedSize );
00609         // printf("crc = 0x%08x | 0x%08x -> %s\n", crc, zfile_info->mCRC32, zfile_info->mCRC32 == crc ? "MATCH" : "ERROR!");
00610         VL_CHECK( zfile_info->mCRC32 == crc );
00611         if ( zfile_info->mCRC32 != crc )
00612         {
00613           zip->close();
00614           return false;
00615         }
00616       }
00617     }
00618   }
00619 
00620   zip->close();
00621   return true;
00622 }
00623 //-----------------------------------------------------------------------------
00624 bool ZippedFile::fillUncompressedBuffer()
00625 {
00626   VL_CHECK(mUncompressedBufferPtr == (int)mUncompressedBuffer.size())
00627 
00628   VL_CHECK( mUncompressedBuffer.empty() )
00629 
00630   mUncompressedBufferPtr = 0;
00631 
00632   if (!isOpen())
00633     return false;
00634 
00635   if ( mReadBytes >= zippedFileInfo()->uncompressedSize() )
00636     return false;
00637 
00638   int have = 0;
00639   int ret  = 0;
00640 
00641   unsigned int compressed_read_bytes = (int)(zippedFileInfo()->sourceZipFile()->position() - zippedFileInfo()->zippedFileOffset());
00642 
00643   int bytes_to_read = (unsigned)CHUNK_SIZE < (zippedFileInfo()->compressedSize() - compressed_read_bytes)?
00644                       (unsigned)CHUNK_SIZE : (zippedFileInfo()->compressedSize() - compressed_read_bytes);
00645   mZStream->avail_in = (uInt)zippedFileInfo()->sourceZipFile()->read(mZipBufferIn, bytes_to_read);
00646 
00647   if (mZStream->avail_in == 0)
00648     return false;
00649   mZStream->next_in = mZipBufferIn;
00650 
00651   do
00652   {
00653     mZStream->avail_out = CHUNK_SIZE;
00654     mZStream->next_out  = mZipBufferOut;
00655 
00656     ret = inflate(mZStream, Z_NO_FLUSH);
00657     VL_CHECK(ret != Z_STREAM_ERROR);
00658     switch (ret)
00659     {
00660     case Z_NEED_DICT:
00661     case Z_DATA_ERROR:
00662     case Z_MEM_ERROR:
00663         inflateEnd(mZStream);
00664         memset(mZStream, 0, sizeof(z_stream_s));
00665         Log::error("ZippedFile::read(): error reading zip stream.\n");
00666         return false;
00667     }
00668 
00669     have = CHUNK_SIZE - mZStream->avail_out;
00670     if (!have)
00671       break;
00672     int start = (int)mUncompressedBuffer.size();
00673     mUncompressedBuffer.resize(start + have);
00674     memcpy(&mUncompressedBuffer[0] + start, mZipBufferOut, have);
00675   }
00676   while ( mZStream->avail_out == 0 );
00677 
00678   return true;
00679 }
00680 //-----------------------------------------------------------------------------
00681 ref<VirtualFile> ZippedFile::clone() const
00682 {
00683   ref<ZippedFile> file = new ZippedFile;
00684   file->operator=(*this);
00685   return file;
00686 }
00687 //-----------------------------------------------------------------------------

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:34.
Permission is granted to use this page to write and publish articles regarding Visualization Library.