Changeset 47516 in vbox for trunk/src/VBox
- Timestamp:
- Aug 1, 2013 6:33:39 PM (11 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/ApplianceImplPrivate.h
r47500 r47516 241 241 PVDINTERFACEIO FileCreateInterface(); 242 242 PVDINTERFACEIO TarCreateInterface(); 243 int copyFileAndCalcShaDigest(const char *pcszSourceFilename, const char *pcszTargetFilename, PVDINTERFACEIO pIfIo, void *pvUser);244 243 int ShaReadBuf(const char *pcszFilename, void **ppvBuf, size_t *pcbSize, PVDINTERFACEIO pIfIo, void *pvUser); 245 244 int ShaWriteBuf(const char *pcszFilename, void *pvBuf, size_t cbSize, PVDINTERFACEIO pIfIo, void *pvUser); 246 245 int decompressImageAndSave(const char *pcszFullFilenameIn, const char *pcszFullFilenameOut, PVDINTERFACEIO pIfIo, void *pvUser); 247 248 246 #endif // !____H_APPLIANCEIMPLPRIVATE 249 247 -
trunk/src/VBox/Main/src-server/ApplianceImplIO.cpp
r47500 r47516 34 34 #include <iprt/vfs.h> 35 35 #include <VBox/vd.h> 36 #include <zlib.h> 37 //#define VBOX_MAIN_USE_VFS /** @todo Replace as much as possible with IPRT VFS. */ 36 38 37 39 /****************************************************************************** … … 94 96 } SHASTORAGEINTERNAL, *PSHASTORAGEINTERNAL; 95 97 96 97 98 /****************************************************************************** 98 99 * Defined Constants And Macros * … … 116 117 * Internal Functions * 117 118 ******************************************************************************/ 118 /** 119 * dummy function is needed only for initialization PRTZIPDECOMP pZipDecomp. 120 * see the call/description of RTZipDecompCreate 121 */ 122 static DECLCALLBACK(int) FillBufferWithGzipData(void *pvUser, void *pvBuf, size_t cbBuf, size_t *pcbBuf) 123 { 124 return VINF_SUCCESS; 125 } 119 126 120 127 121 /****************************************************************************** … … 1247 1241 } 1248 1242 1249 1250 int copyFileAndCalcShaDigest(const char *pcszSourceFilename, const char *pcszTargetFilename, PVDINTERFACEIO pIfIo, void *pvUser)1251 {1252 /* Validate input. */1253 AssertPtrReturn(pIfIo, VERR_INVALID_POINTER);1254 1255 void *pvStorage;1256 RTFILE pFile = NULL;1257 1258 int rc = pIfIo->pfnOpen(pvUser, pcszSourceFilename,1259 RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE, 0,1260 &pvStorage);1261 if (RT_FAILURE(rc))1262 return rc;1263 1264 try1265 {1266 if (RTFileExists(pcszTargetFilename) == false)1267 {1268 /* ensure the directory exists */1269 rc = VirtualBox::ensureFilePathExists(pcszTargetFilename, true);1270 if (FAILED(rc))1271 throw rc;1272 1273 // create a new file and copy raw data into one from buffer pvTmpBuf1274 rc = RTFileOpen(&pFile,1275 pcszTargetFilename,1276 RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);1277 1278 if (RT_FAILURE(rc) || pFile == NULL)1279 {1280 throw rc;1281 }1282 }1283 else1284 {1285 rc = RTFileOpen(&pFile,1286 pcszTargetFilename,1287 RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE);1288 if (RT_FAILURE(rc) || pFile == NULL)1289 {1290 throw rc;1291 }1292 }1293 }1294 catch(...)1295 {1296 pIfIo->pfnClose(pvUser, pvStorage);1297 return rc;1298 }1299 1300 void *pvTmpBuf = 0;1301 uint64_t cbTmpSize = _1M;1302 size_t cbAllRead = 0;1303 do1304 {1305 pvTmpBuf = RTMemAlloc(cbTmpSize);1306 if (!pvTmpBuf)1307 {1308 rc = VERR_NO_MEMORY;1309 break;1310 }1311 1312 for (;;)1313 {1314 size_t cbRead = 0;1315 rc = pIfIo->pfnReadSync(pvUser, pvStorage, cbAllRead, pvTmpBuf, cbTmpSize, &cbRead);1316 if ( RT_FAILURE(rc)1317 || cbRead == 0)1318 break;1319 1320 size_t cbWritten = 0;1321 1322 rc = RTFileWrite(pFile, pvTmpBuf, cbRead, &cbWritten);1323 1324 if (RT_FAILURE(rc))1325 {1326 break;1327 }1328 1329 cbAllRead += cbRead;1330 }1331 } while (0);1332 1333 pIfIo->pfnClose(pvUser, pvStorage);1334 RTFileClose(pFile);1335 1336 if (rc == VERR_EOF)1337 rc = VINF_SUCCESS;1338 1339 if (pvTmpBuf)1340 RTMemFree(pvTmpBuf);1341 1342 return rc;1343 }1344 1345 1243 int ShaReadBuf(const char *pcszFilename, void **ppvBuf, size_t *pcbSize, PVDINTERFACEIO pIfIo, void *pvUser) 1346 1244 { … … 1442 1340 } 1443 1341 1342 static int zipDecompressBuffer(z_stream streamIn, 1343 uint32_t *cbDecompressed, 1344 bool *finished) 1345 { 1346 int rc; 1347 int sh = streamIn.avail_out; 1348 1349 *cbDecompressed = 0; 1350 1351 do 1352 { 1353 rc = inflate(&streamIn, Z_NO_FLUSH); 1354 1355 if (rc < 0) 1356 { 1357 switch (rc) 1358 { 1359 case Z_STREAM_ERROR: 1360 rc = VERR_ZIP_CORRUPTED; 1361 break; 1362 case Z_DATA_ERROR: 1363 rc = VERR_ZIP_CORRUPTED; 1364 break; 1365 case Z_MEM_ERROR: 1366 rc = VERR_ZIP_NO_MEMORY; 1367 break; 1368 case Z_BUF_ERROR: 1369 rc = VERR_ZIP_ERROR; 1370 break; 1371 case Z_VERSION_ERROR: 1372 rc = VERR_ZIP_UNSUPPORTED_VERSION; 1373 break; 1374 case Z_ERRNO: /* We shouldn't see this status! */ 1375 default: 1376 AssertMsgFailed(("%d\n", rc)); 1377 if (rc >= 0) 1378 rc = VINF_SUCCESS; 1379 rc = VERR_ZIP_ERROR; 1380 } 1381 1382 break; 1383 } 1384 1385 *cbDecompressed += (sh - streamIn.avail_out); 1386 sh = streamIn.avail_out; 1387 } 1388 while (streamIn.avail_out > 0 && streamIn.avail_in > 0 ); 1389 1390 if (RT_SUCCESS(rc)) 1391 { 1392 if (streamIn.avail_in == 0) 1393 *finished = true; 1394 else 1395 { 1396 if (streamIn.avail_out == 0) 1397 *finished = false; 1398 } 1399 } 1400 1401 return rc; 1402 } 1403 1444 1404 int decompressImageAndSave(const char *pcszFullFilenameIn, const char *pcszFullFilenameOut, PVDINTERFACEIO pIfIo, void *pvUser) 1445 1405 { … … 1456 1416 if (RT_FAILURE(rc)) 1457 1417 return rc; 1458 1459 uint8_t *compressedBuffer = 0; 1460 uint8_t *decompressedBuffer = 0; 1418 #ifdef VBOX_MAIN_USE_VFS 1419 1420 /* Turn the source file handle/whatever into a VFS stream. */ 1421 RTVFSIOSTREAM hVfsIosCompressedSrc; 1422 rc = VDIfCreateVfsStream(pIfIo, pvStorage, RTFILE_O_READ, &hVfsIosCompressedSrc); 1423 if (RT_SUCCESS(rc)) 1424 { 1425 /* Pass the source thru gunzip. */ 1426 RTVFSIOSTREAM hVfsIosSrc; 1427 rc = RTZipGzipDecompressIoStream(hVfsIosCompressedSrc, 0, &hVfsIosSrc); 1428 if (RT_SUCCESS(rc)) 1429 { 1430 /* 1431 * Create the output file, including necessary paths. 1432 * Any existing file will be overwritten. 1433 */ 1434 rc = VirtualBox::ensureFilePathExists(Utf8Str(pcszFullFilenameOut), true /*fCreate*/); 1435 if (RT_SUCCESS(rc)) 1436 { 1437 RTVFSIOSTREAM hVfsIosDst; 1438 rc = RTVfsIoStrmOpenNormal(pcszFullFilenameOut, 1439 RTFILE_O_CREATE_REPLACE | RTFILE_O_WRITE | RTFILE_O_DENY_ALL, 1440 &hVfsIosDst); 1441 if (RT_SUCCESS(rc)) 1442 { 1443 /* 1444 * Pump the bytes thru. If we fail, delete the output file. 1445 */ 1446 rc = RTVfsUtilPumpIoStreams(hVfsIosSrc, hVfsIosDst, 0); 1447 1448 RTVfsIoStrmRelease(hVfsIosDst); 1449 RTFileDelete(pcszFullFilenameOut); 1450 } 1451 } 1452 1453 RTVfsIoStrmRelease(hVfsIosSrc); 1454 } 1455 RTVfsIoStrmRelease(hVfsIosCompressedSrc); 1456 } 1457 pIfIo->pfnClose(pvUser, pvStorage); 1458 1459 #else 1460 1461 Bytef *decompressedBuffer = 0; 1462 Bytef *compressedBuffer = 0; 1461 1463 uint64_t cbTmpSize = _1M; 1462 1464 size_t cbAllRead = 0; 1463 1465 size_t cbAllWritten = 0; 1464 1466 RTFILE pFile = NULL; 1465 PRTZIPDECOMP pZipDecomp;1467 z_stream gzipStream; 1466 1468 1467 1469 Utf8Str pathOut(pcszFullFilenameOut); … … 1496 1498 } 1497 1499 1498 compressedBuffer = ( uint8_t*)RTMemAlloc(cbTmpSize);1500 compressedBuffer = (Bytef *)RTMemAlloc(cbTmpSize); 1499 1501 1500 1502 if (!compressedBuffer) … … 1504 1506 } 1505 1507 1506 decompressedBuffer = (uint8_t *)RTMemAlloc(cbTmpSize); 1508 1509 decompressedBuffer = (Bytef *)RTMemAlloc(cbTmpSize*10); 1507 1510 1508 1511 if (!decompressedBuffer) … … 1512 1515 } 1513 1516 1514 rc = RTZipDecompCreate(&pZipDecomp, NULL, FillBufferWithGzipData); 1517 gzipStream.zalloc = Z_NULL; 1518 gzipStream.zfree = Z_NULL; 1519 gzipStream.opaque = Z_NULL; 1520 gzipStream.next_in = compressedBuffer; 1521 gzipStream.avail_in = 0; 1522 gzipStream.next_out = decompressedBuffer; 1523 gzipStream.avail_out = cbTmpSize*10; 1524 1525 rc = inflateInit2(&gzipStream, MAX_WBITS + 16 /* autodetect gzip header */); 1515 1526 1516 1527 if (rc < 0) … … 1519 1530 } 1520 1531 1521 size_t cbRead = 0 , cbActuallyRead = 0;1532 size_t cbRead = 0; 1522 1533 size_t cbDecompressed = 0; 1523 bool fData = false; 1524 uint8_t *currentInput = compressedBuffer; 1534 bool fFinished = true; 1525 1535 1526 1536 for (;;) 1527 1537 { 1528 /* 1529 * skip reading a new chunk of compressed data in case if we decompressed not at all data from the buffer 1530 * 1531 */ 1532 if (fData == false) 1538 if (fFinished == true) 1533 1539 { 1534 1540 rc = pIfIo->pfnReadSync(pvUser, pvStorage, cbAllRead, compressedBuffer, cbTmpSize, &cbRead); 1535 if (RT_FAILURE(rc) || cbRead == 0) 1541 if ( RT_FAILURE(rc) 1542 || cbRead == 0) 1536 1543 break; 1537 1544 1538 currentInput = compressedBuffer; 1545 gzipStream.avail_in = cbRead; 1546 gzipStream.avail_out = cbTmpSize*10; 1539 1547 } 1540 1548 1541 rc = RTZipGzipFileBufferDecompress(pZipDecomp, 1542 currentInput, 1543 cbRead, 1544 &cbActuallyRead, 1545 decompressedBuffer, 1546 cbTmpSize, 1547 &cbDecompressed); 1549 /* decompress the buffer */ 1550 rc = zipDecompressBuffer(gzipStream, 1551 (uint32_t *)(&cbDecompressed), 1552 &fFinished); 1548 1553 1549 1554 if (RT_FAILURE(rc)) 1550 1555 break; 1551 1556 1552 cbAllRead += cbActuallyRead;1553 1554 if (cbRead == cbActuallyRead)1555 {1556 /* it means the input buffer is empty */1557 fData = false;1558 }1559 else1560 {1561 /* some data still leaves in the input buffer */1562 fData = true;1563 cbRead = cbRead - cbActuallyRead;1564 currentInput = ¤tInput[cbActuallyRead];1565 }1566 1567 /* write decompressed data to the output file */1568 1557 rc = RTFileWrite(pFile, decompressedBuffer, cbDecompressed, &cbDecompressed); 1569 1558 … … 1572 1561 1573 1562 cbAllWritten += cbDecompressed; 1563 cbAllRead += cbRead; 1574 1564 } 1575 1565 } while (0); … … 1580 1570 rc = VINF_SUCCESS; 1581 1571 1582 RTZipDecompDestroy(pZipDecomp); 1583 1584 RTFileClose(pFile); 1585 1572 rc = inflateEnd(&gzipStream); 1573 1574 rc = RTFileClose(pFile); 1575 1576 if (decompressedBuffer) 1577 RTMemFree(decompressedBuffer); 1586 1578 if (compressedBuffer) 1587 1579 RTMemFree(compressedBuffer); 1588 if (decompressedBuffer) 1589 RTMemFree(decompressedBuffer); 1580 #endif /* !VBOX_MAIN_USE_VFS */ 1590 1581 1591 1582 return rc; 1592 1583 } 1593 1584 1585 -
trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp
r47500 r47516 977 977 uint64_t maxFileSize = _1M; 978 978 size_t cbRead = 0; 979 void *pBuf; 979 void *pBuf; /** @todo r=bird: You leak this buffer! throwing stuff is evil. */ 980 980 981 981 vrc = RTFileGetSize(pFile, &cbFile); … … 1008 1008 vrc = RTManifestVerifyDigestType(pBuf, cbRead, &digestType); 1009 1009 1010 /* pBuf isn't needed more. Here we free the memory allocated by the pBuf */1011 if (pBuf)1012 RTMemFree(pBuf);1013 1014 1010 if (RT_FAILURE(vrc)) 1015 1011 { 1012 if (pBuf) 1013 RTMemFree(pBuf); 1016 1014 throw setError(VBOX_E_FILE_ERROR, 1017 1015 tr("Could not verify supported digest types in the manifest file '%s' (%Rrc)"), … … 1561 1559 1562 1560 size_t cbCertSize = 0; 1563 /* Save the SHA digest of the manifest file for the next validation */ 1564 Utf8Str manifestShaDigest = storage.strDigest; 1561 Utf8Str manifestShaDigest; 1565 1562 Utf8Str strCertFile = Utf8Str(pTask->locInfo.strPath).stripExt().append(".cert"); 1566 1563 if (RTFileExists(strCertFile.c_str())) … … 1568 1565 rc = readFileToBuf(strCertFile, &pvCertBuf, &cbCertSize, false, pShaIo, &storage); 1569 1566 if (FAILED(rc)) throw rc; 1567 1568 /* Save the SHA digest of the manifest file for the next validation */ 1569 manifestShaDigest = storage.strDigest; 1570 1570 1571 1571 /* verify Certificate */ … … 2259 2259 { 2260 2260 /* check read file to GZIP compression */ 2261 bool fGzipUsed = !(di.strCompression.compare("gzip",Utf8Str::CaseInsensitive));2262 2261 try 2263 2262 { 2264 if (fGzipUsed == true) 2265 { 2263 if (di.strCompression.compare("gzip",Utf8Str::CaseInsensitive) == 0) 2264 { 2265 /* 2266 * 1. extract a file to the local/temporary folder 2267 * 2. apply GZIP decompression for the file 2268 * 3. replace the value of strSrcFilePath with a new path to the file 2269 * 4. replace SHA-TAR I/O interface with File I/O interface 2270 * 5. save calculated SHA digest of GZIPed file for later validation 2271 */ 2272 2266 2273 /* Decompress the GZIP file and save a new file in the target path */ 2267 2274 strTargetDir = strTargetDir.stripFilename(); … … 2282 2289 RTPathFilename(strSrcFilePath.c_str()), vrc); 2283 2290 2284 /* 2285 * Create the necessary file access interfaces. 2286 * For the next step: 2287 * We need to replace the previously created chain of SHA-TAR or SHA-FILE interfaces 2288 * with simple FILE interface because we don't need SHA or TAR interfaces here anymore. 2289 * But we mustn't delete the chain of SHA-TAR or SHA-FILE interfaces. 2290 */ 2291 /* Create the necessary file access interfaces. */ 2291 2292 pFileIo = FileCreateInterface(); 2292 2293 if (!pFileIo) … … 2302 2303 tr("Creation of the VD interface failed (%Rrc)"), vrc); 2303 2304 2304 /* Correct the source and the target with the actual values */2305 2305 strSrcFilePath = strTargetDir; 2306 2306 strTargetDir = strTargetDir.stripFilename(); … … 2315 2315 ULONG lCabs = 0; 2316 2316 2317 char *pszExt = NULL;2318 2319 2317 if (RTPathHaveExt(strTargetPath->c_str())) 2320 2318 { 2321 pszExt = RTPathExt(strTargetPath->c_str()); 2322 2319 char *pszExt = RTPathExt(strTargetPath->c_str()); 2323 2320 /* Figure out which format the user like to have. Default is VMDK. */ 2324 2321 ComObjPtr<MediumFormat> trgFormat = pSysProps->mediumFormatFromExtension(&pszExt[1]); … … 2350 2347 strTrgFormat = Utf8Str(bstrFormatName); 2351 2348 } 2352 else2353 {2354 throw setError(VBOX_E_FILE_ERROR,2355 tr("The target disk '%s' has no extension "),2356 strTargetPath->c_str(), VERR_INVALID_NAME);2357 }2358 2349 2359 2350 /* Create an IMedium object. */ … … 2364 2355 { 2365 2356 void *pvTmpBuf = 0; 2366 2357 size_t cbSize = 0; 2367 2358 try 2368 2359 { 2369 if (fGzipUsed == true) 2360 /* Read the ISO file into a memory buffer */ 2361 vrc = ShaReadBuf(strSrcFilePath.c_str(), &pvTmpBuf, &cbSize, pCallbacks, pRealUsedStorage); 2362 2363 if ( RT_FAILURE(vrc) || !pvTmpBuf) 2364 throw setError(VBOX_E_FILE_ERROR, 2365 tr("Could not read ISO file '%s' listed in the OVF file (%Rrc)"), 2366 RTPathFilename(strSourceOVF.c_str()), vrc); 2367 2368 if (RTFileExists(strTargetPath->c_str()) == false) 2370 2369 { 2371 /* 2372 * The source and target pathes are the same. 2373 * It means that we have the needed file already. 2374 * For example, in GZIP case, we decompress the file and save it in the target path, 2375 * but with some prefix like "temp_". See part "check read file to GZIP compression" earlier 2376 * in this function. 2377 * Just rename the file by deleting "temp_" from it's name 2378 */ 2379 vrc = RTFileRename(strSrcFilePath.c_str(), strTargetPath->c_str(), RTPATHRENAME_FLAGS_NO_REPLACE); 2380 if (RT_FAILURE(vrc)) 2381 throw setError(VBOX_E_FILE_ERROR, 2382 tr("Could not rename the file '%s' (%Rrc)"), 2383 RTPathFilename(strSourceOVF.c_str()), vrc); 2384 2385 } 2386 else 2387 { 2388 /* Calculating SHA digest for ISO file while copying one */ 2389 vrc = copyFileAndCalcShaDigest(strSrcFilePath.c_str(), 2390 strTargetPath->c_str(), 2391 pCallbacks, 2392 pRealUsedStorage); 2393 2394 if (RT_FAILURE(vrc)) 2395 throw setError(VBOX_E_FILE_ERROR, 2396 tr("Could not copy ISO file '%s' listed in the OVF file (%Rrc)"), 2397 RTPathFilename(strSourceOVF.c_str()), vrc); 2370 2371 /* ensure the directory exists */ 2372 if (lCabs & MediumFormatCapabilities_File) 2373 { 2374 rc = VirtualBox::ensureFilePathExists(*strTargetPath, true); 2375 if (FAILED(rc)) 2376 throw rc; 2377 } 2378 2379 // create a new file and copy raw data into one from buffer pvTmpBuf 2380 RTFILE pFile = NULL; 2381 vrc = RTFileOpen(&pFile, 2382 strTargetPath->c_str(), 2383 RTFILE_O_OPEN_CREATE | RTFILE_O_WRITE | RTFILE_O_DENY_NONE); 2384 2385 if (RT_SUCCESS(vrc) && pFile != NULL) 2386 { 2387 size_t cbWritten = 0; 2388 2389 vrc = RTFileWrite(pFile, pvTmpBuf, cbSize, &cbWritten); 2390 2391 if (RT_FAILURE(vrc)) 2392 { 2393 Utf8Str path(*strTargetPath); 2394 path = path.stripFilename(); 2395 2396 throw setError(VBOX_E_FILE_ERROR, 2397 tr("Could not write the ISO file '%s' into the folder %s (%Rrc)"), 2398 strSrcFilePath.stripPath().c_str(), 2399 path.c_str(), 2400 vrc); 2401 } 2402 } 2403 RTFileClose(pFile); 2398 2404 } 2399 2405 } … … 2487 2493 ComPtr<IProgress> pp(pProgress); 2488 2494 waitForAsyncProgress(stack.pProgress, pp); 2489 2490 if (fGzipUsed == true)2491 {2492 /*2493 * Just delete the temporary file2494 */2495 vrc = RTFileDelete(strSrcFilePath.c_str());2496 if (RT_FAILURE(vrc))2497 setWarning(VBOX_E_FILE_ERROR,2498 tr("Could not delete the file '%s' (%Rrc)"),2499 RTPathFilename(strSrcFilePath.c_str()), vrc);2500 }2501 2495 } 2502 2496 } -
trunk/src/VBox/Runtime/common/zip/zip.cpp
r47500 r47516 616 616 } 617 617 618 /**619 * pZip->u.Zlib.avail_in must be correctly initialized before620 * calling this function621 * pZip->u.Zlib.next_in must be correctly initialized before622 * calling this function623 *624 * @param pZip The decompressor instance.625 * @param pvBufOut Where to store the decompressed data.626 * @param cbBufOut Number of bytes to produce.627 * @param pcbWritten Number of bytes actually written to the628 * buffer629 *630 * @return iprt status code.631 */632 static DECLCALLBACK(int) rtZipZlibBufferDecompress(PRTZIPDECOMP pZip, void *pvBufOut, size_t cbBufOut, size_t *pcbWritten)633 {634 int rc = VINF_SUCCESS;635 pZip->u.Zlib.next_out = (Bytef *)pvBufOut;636 pZip->u.Zlib.avail_out = (uInt)cbBufOut;637 int sh = pZip->u.Zlib.avail_out;638 639 *pcbWritten = 0;640 641 do642 {643 rc = inflate(&pZip->u.Zlib, Z_SYNC_FLUSH);644 645 if (rc != Z_OK && rc != Z_STREAM_END)646 {647 rc = zipErrConvertFromZlib(rc, false /*fCompressing*/);648 break;649 }650 651 *pcbWritten += (sh - pZip->u.Zlib.avail_out);652 sh = pZip->u.Zlib.avail_out;653 }654 while (pZip->u.Zlib.avail_out > 0 && pZip->u.Zlib.avail_in > 0 );655 656 return rc;657 }658 618 659 619 /** … … 1677 1637 } 1678 1638 1679 /**1680 * Lazy init of the decompressor for the Gzip file.1681 * @return iprt status code.1682 * @param pZip The decompressor instance.1683 */1684 static int rtzipGzipFileDecompInit(PRTZIPDECOMP pZip)1685 {1686 int rc = 0;1687 #ifdef RTZIP_USE_ZLIB1688 pZip->pfnDecompress = rtZipZlibBufferDecompress;1689 pZip->pfnDestroy = rtZipZlibDecompDestroy;1690 1691 memset(&pZip->u.Zlib, 0, sizeof(pZip->u.Zlib));1692 pZip->enmType = RTZIPTYPE_ZLIB;1693 pZip->u.Zlib.opaque = pZip;1694 1695 rc = inflateInit2(&pZip->u.Zlib, MAX_WBITS + 16 /* autodetect gzip header */);1696 rc >= 0 ? VINF_SUCCESS : zipErrConvertFromZlib(rc, false /*fCompressing*/);1697 #else1698 AssertMsgFailed(("Zlib is not include in this build!\n"));1699 #endif1700 1701 if (RT_FAILURE(rc))1702 {1703 pZip->pfnDecompress = rtZipStubDecompress;1704 pZip->pfnDestroy = rtZipStubDecompDestroy;1705 }1706 1707 return rc;1708 }1709 1710 /**1711 * Decompresses a chunk of Gzip file.1712 *1713 * @returns iprt status code.1714 * @param pZip The stream decompressor instance.1715 * @param pvBufIn Where to read the compressed data from.1716 * @param cbBufIn Number of bytes to read.1717 * @param pcbRead Number of bytes actually read from the1718 * buffer1719 * @param pvBufOut Where to store the decompressed data.1720 * @param cbBufOut Number of bytes to produce.1721 * @param pcbWritten Number of bytes actually written to the1722 * buffer.1723 */1724 RTDECL(int) RTZipGzipFileBufferDecompress(PRTZIPDECOMP pZip,1725 void *pvBufIn,1726 size_t cbBufIn,1727 size_t *pcbRead,1728 void *pvBufOut,1729 size_t cbBufOut,1730 size_t *pcbWritten)1731 {1732 int rc;1733 /*1734 * Skip empty requests.1735 */1736 if (!cbBufIn)1737 return VINF_SUCCESS;1738 1739 if (!pZip->pfnDecompress)1740 {1741 rc = rtzipGzipFileDecompInit(pZip);1742 if (RT_FAILURE(rc))1743 return rc;1744 }1745 1746 pZip->u.Zlib.avail_in = (uInt)cbBufIn;1747 pZip->u.Zlib.next_in = (Bytef *)pvBufIn;1748 1749 /*1750 * 'Read' the decompressed stream.1751 */1752 rc = pZip->pfnDecompress(pZip, pvBufOut, cbBufOut, pcbWritten);1753 1754 *pcbRead = cbBufIn - pZip->u.Zlib.avail_in;1755 1756 return rc;1757 }1758 RT_EXPORT_SYMBOL(RTZipGzipFileBufferDecompress);1759 1639 1760 1640 /**
Note:
See TracChangeset
for help on using the changeset viewer.