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