VirtualBox

Changeset 47516 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Aug 1, 2013 6:33:39 PM (11 years ago)
Author:
vboxsync
Message:

Backed out r87679: Still working on the wrong solution... Sigh.

Location:
trunk/src/VBox
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/include/ApplianceImplPrivate.h

    r47500 r47516  
    241241PVDINTERFACEIO FileCreateInterface();
    242242PVDINTERFACEIO TarCreateInterface();
    243 int copyFileAndCalcShaDigest(const char *pcszSourceFilename, const char *pcszTargetFilename, PVDINTERFACEIO pIfIo, void *pvUser);
    244243int ShaReadBuf(const char *pcszFilename, void **ppvBuf, size_t *pcbSize, PVDINTERFACEIO pIfIo, void *pvUser);
    245244int ShaWriteBuf(const char *pcszFilename, void *pvBuf, size_t cbSize, PVDINTERFACEIO pIfIo, void *pvUser);
    246245int decompressImageAndSave(const char *pcszFullFilenameIn, const char *pcszFullFilenameOut, PVDINTERFACEIO pIfIo, void *pvUser);
    247 
    248246#endif // !____H_APPLIANCEIMPLPRIVATE
    249247
  • trunk/src/VBox/Main/src-server/ApplianceImplIO.cpp

    r47500 r47516  
    3434#include <iprt/vfs.h>
    3535#include <VBox/vd.h>
     36#include <zlib.h>
     37//#define VBOX_MAIN_USE_VFS /** @todo Replace as much as possible with IPRT VFS. */
    3638
    3739/******************************************************************************
     
    9496} SHASTORAGEINTERNAL, *PSHASTORAGEINTERNAL;
    9597
    96 
    9798/******************************************************************************
    9899 *   Defined Constants And Macros                                             *
     
    116117 *   Internal Functions                                                       *
    117118 ******************************************************************************/
    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
    126120
    127121/******************************************************************************
     
    12471241}
    12481242
    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     try
    1265     {
    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 pvTmpBuf
    1274             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         else
    1284         {
    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     do
    1304     {
    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 
    13451243int ShaReadBuf(const char *pcszFilename, void **ppvBuf, size_t *pcbSize, PVDINTERFACEIO pIfIo, void *pvUser)
    13461244{
     
    14421340}
    14431341
     1342static 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
    14441404int decompressImageAndSave(const char *pcszFullFilenameIn, const char *pcszFullFilenameOut, PVDINTERFACEIO pIfIo, void *pvUser)
    14451405{
     
    14561416    if (RT_FAILURE(rc))
    14571417        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;
    14611463    uint64_t cbTmpSize = _1M;
    14621464    size_t cbAllRead = 0;
    14631465    size_t cbAllWritten = 0;
    14641466    RTFILE pFile = NULL;
    1465     PRTZIPDECOMP pZipDecomp;
     1467    z_stream gzipStream;
    14661468
    14671469    Utf8Str pathOut(pcszFullFilenameOut);
     
    14961498        }
    14971499
    1498         compressedBuffer = (uint8_t *)RTMemAlloc(cbTmpSize);
     1500        compressedBuffer = (Bytef *)RTMemAlloc(cbTmpSize);
    14991501
    15001502        if (!compressedBuffer)
     
    15041506        }
    15051507
    1506         decompressedBuffer = (uint8_t *)RTMemAlloc(cbTmpSize);
     1508
     1509        decompressedBuffer = (Bytef *)RTMemAlloc(cbTmpSize*10);
    15071510
    15081511        if (!decompressedBuffer)
     
    15121515        }
    15131516
    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 */);
    15151526
    15161527        if (rc < 0)
     
    15191530        }
    15201531
    1521         size_t cbRead = 0, cbActuallyRead = 0;
     1532        size_t cbRead = 0;
    15221533        size_t cbDecompressed = 0;
    1523         bool fData = false;
    1524         uint8_t *currentInput = compressedBuffer;
     1534        bool fFinished = true;
    15251535
    15261536        for (;;)
    15271537        {
    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)
    15331539            {
    15341540                rc = pIfIo->pfnReadSync(pvUser, pvStorage, cbAllRead, compressedBuffer, cbTmpSize, &cbRead);
    1535                 if (RT_FAILURE(rc) || cbRead == 0)
     1541                if (   RT_FAILURE(rc)
     1542                    || cbRead == 0)
    15361543                    break;
    15371544
    1538                 currentInput = compressedBuffer;
     1545                gzipStream.avail_in = cbRead;
     1546                gzipStream.avail_out = cbTmpSize*10;
    15391547            }
    15401548
    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);
    15481553
    15491554            if (RT_FAILURE(rc))
    15501555                break;
    15511556
    1552             cbAllRead += cbActuallyRead;
    1553 
    1554             if (cbRead == cbActuallyRead)
    1555             {
    1556                 /* it means the input buffer is empty */
    1557                 fData = false;
    1558             }
    1559             else
    1560             {
    1561                 /* some data still leaves in the input buffer */
    1562                 fData = true;
    1563                 cbRead = cbRead - cbActuallyRead;
    1564                 currentInput = &currentInput[cbActuallyRead];
    1565             }
    1566 
    1567             /* write decompressed data to the output file */
    15681557            rc = RTFileWrite(pFile, decompressedBuffer, cbDecompressed, &cbDecompressed);
    15691558
     
    15721561
    15731562            cbAllWritten += cbDecompressed;
     1563            cbAllRead += cbRead;
    15741564        }
    15751565    } while (0);
     
    15801570        rc = VINF_SUCCESS;
    15811571
    1582     RTZipDecompDestroy(pZipDecomp);
    1583 
    1584     RTFileClose(pFile);
    1585 
     1572    rc = inflateEnd(&gzipStream);
     1573
     1574    rc = RTFileClose(pFile);
     1575
     1576    if (decompressedBuffer)
     1577        RTMemFree(decompressedBuffer);
    15861578    if (compressedBuffer)
    15871579        RTMemFree(compressedBuffer);
    1588     if (decompressedBuffer)
    1589         RTMemFree(decompressedBuffer);
     1580#endif /* !VBOX_MAIN_USE_VFS */
    15901581
    15911582    return rc;
    15921583}
    15931584
     1585
  • trunk/src/VBox/Main/src-server/ApplianceImplImport.cpp

    r47500 r47516  
    977977                    uint64_t maxFileSize = _1M;
    978978                    size_t cbRead = 0;
    979                     void  *pBuf;
     979                    void  *pBuf; /** @todo r=bird: You leak this buffer! throwing stuff is evil. */
    980980
    981981                    vrc = RTFileGetSize(pFile, &cbFile);
     
    10081008                    vrc = RTManifestVerifyDigestType(pBuf, cbRead, &digestType);
    10091009
    1010                     /* pBuf isn't needed more. Here we free the memory allocated by the pBuf */
    1011                     if (pBuf)
    1012                         RTMemFree(pBuf);
    1013 
    10141010                    if (RT_FAILURE(vrc))
    10151011                    {
     1012                        if (pBuf)
     1013                            RTMemFree(pBuf);
    10161014                        throw setError(VBOX_E_FILE_ERROR,
    10171015                               tr("Could not verify supported digest types in the manifest file '%s' (%Rrc)"),
     
    15611559
    15621560            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;
    15651562            Utf8Str strCertFile = Utf8Str(pTask->locInfo.strPath).stripExt().append(".cert");
    15661563            if (RTFileExists(strCertFile.c_str()))
     
    15681565                rc = readFileToBuf(strCertFile, &pvCertBuf, &cbCertSize, false, pShaIo, &storage);
    15691566                if (FAILED(rc)) throw rc;
     1567
     1568                /* Save the SHA digest of the manifest file for the next validation */
     1569                manifestShaDigest = storage.strDigest;
    15701570
    15711571                /* verify Certificate */
     
    22592259    {
    22602260        /* check read file to GZIP compression */
    2261         bool fGzipUsed = !(di.strCompression.compare("gzip",Utf8Str::CaseInsensitive));
    22622261        try
    22632262        {
    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
    22662273                /* Decompress the GZIP file and save a new file in the target path */
    22672274                strTargetDir = strTargetDir.stripFilename();
     
    22822289                                   RTPathFilename(strSrcFilePath.c_str()), vrc);
    22832290
    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. */
    22912292                pFileIo = FileCreateInterface();
    22922293                if (!pFileIo)
     
    23022303                                   tr("Creation of the VD interface failed (%Rrc)"), vrc);
    23032304
    2304                 /* Correct the source and the target with the actual values */
    23052305                strSrcFilePath = strTargetDir;
    23062306                strTargetDir = strTargetDir.stripFilename();
     
    23152315            ULONG lCabs = 0;
    23162316
    2317             char *pszExt = NULL;
    2318 
    23192317            if (RTPathHaveExt(strTargetPath->c_str()))
    23202318            {
    2321                 pszExt = RTPathExt(strTargetPath->c_str());
    2322 
     2319                char *pszExt = RTPathExt(strTargetPath->c_str());
    23232320                /* Figure out which format the user like to have. Default is VMDK. */
    23242321                ComObjPtr<MediumFormat> trgFormat = pSysProps->mediumFormatFromExtension(&pszExt[1]);
     
    23502347                strTrgFormat = Utf8Str(bstrFormatName);
    23512348            }
    2352             else
    2353             {
    2354                 throw setError(VBOX_E_FILE_ERROR,
    2355                                tr("The target disk '%s' has no extension "),
    2356                                strTargetPath->c_str(), VERR_INVALID_NAME);
    2357             }
    23582349
    23592350            /* Create an IMedium object. */
     
    23642355            {
    23652356                void *pvTmpBuf = 0;
    2366 
     2357                size_t cbSize = 0;
    23672358                try
    23682359                {
    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)
    23702369                    {
    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);
    23982404                    }
    23992405                }
     
    24872493                ComPtr<IProgress> pp(pProgress);
    24882494                waitForAsyncProgress(stack.pProgress, pp);
    2489 
    2490                 if (fGzipUsed == true)
    2491                 {
    2492                     /*
    2493                      * Just delete the temporary file
    2494                      */
    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                 }
    25012495            }
    25022496        }
  • trunk/src/VBox/Runtime/common/zip/zip.cpp

    r47500 r47516  
    616616}
    617617
    618 /**
    619  * pZip->u.Zlib.avail_in must be correctly initialized before
    620  * calling this function
    621  * pZip->u.Zlib.next_in must be correctly initialized before
    622  * calling this function
    623  * 
    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 the
    628  *                    buffer
    629  *
    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     do
    642     {
    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 }
    658618
    659619/**
     
    16771637}
    16781638
    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_ZLIB
    1688     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 #else
    1698     AssertMsgFailed(("Zlib is not include in this build!\n"));
    1699 #endif
    1700 
    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 the
    1718  *                      buffer
    1719  * @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 the
    1722  *                      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);
    17591639
    17601640/**
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette