VirtualBox

Ignore:
Timestamp:
Apr 17, 2017 3:29:05 PM (8 years ago)
Author:
vboxsync
Message:

iprt: Reworked and implemented VFS chains, adding stdfile, gzip and gunzip element provider/factories.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/zip/gzipvfs.cpp

    r62477 r66594  
    3333
    3434#include <iprt/assert.h>
     35#include <iprt/ctype.h>
    3536#include <iprt/file.h>
    3637#include <iprt/err.h>
     
    828829}
    829830
     831
     832
     833/**
     834 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnValidate}
     835 */
     836static DECLCALLBACK(int) rtVfsChainGunzip_Validate(PCRTVFSCHAINELEMENTREG pProviderReg, PRTVFSCHAINSPEC pSpec,
     837                                                   PRTVFSCHAINELEMSPEC pElement, uint32_t *poffError)
     838{
     839    RT_NOREF(pProviderReg, poffError);
     840
     841    if (pElement->enmTypeIn == RTVFSOBJTYPE_INVALID)
     842        return VERR_VFS_CHAIN_CANNOT_BE_FIRST_ELEMENT;
     843    if (pElement->cArgs != 0)
     844        return VERR_VFS_CHAIN_NO_ARGS;
     845    if (pElement->enmType != RTVFSOBJTYPE_IO_STREAM)
     846        return VERR_VFS_CHAIN_ONLY_IOS;
     847    if (pSpec->fOpenFile & RTFILE_O_WRITE)
     848        return VERR_VFS_CHAIN_READ_ONLY_IOS;
     849
     850    return VINF_SUCCESS;
     851}
     852
     853
     854/**
     855 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnInstantiate}
     856 */
     857static DECLCALLBACK(int) rtVfsChainGunzip_Instantiate(PCRTVFSCHAINELEMENTREG pProviderReg, PCRTVFSCHAINSPEC pSpec,
     858                                                      PCRTVFSCHAINELEMSPEC pElement, RTVFSOBJ hPrevVfsObj,
     859                                                      PRTVFSOBJ phVfsObj, uint32_t *poffError)
     860{
     861    RT_NOREF(pProviderReg, pSpec, pElement, poffError);
     862    AssertReturn(hPrevVfsObj != NIL_RTVFSOBJ, VERR_VFS_CHAIN_IPE);
     863
     864    RTVFSIOSTREAM hVfsIosIn = RTVfsObjToIoStream(hPrevVfsObj);
     865    if (hVfsIosIn == NIL_RTVFSIOSTREAM)
     866        return VERR_VFS_CHAIN_CAST_FAILED;
     867
     868    RTVFSIOSTREAM hVfsIos = NIL_RTVFSIOSTREAM;
     869    int rc = RTZipGzipDecompressIoStream(hVfsIosIn, 0 /*fFlags*/, &hVfsIos);
     870    if (RT_SUCCESS(rc))
     871    {
     872        *phVfsObj = RTVfsObjFromIoStream(hVfsIos);
     873        RTVfsIoStrmRelease(hVfsIos);
     874        if (*phVfsObj != NIL_RTVFSOBJ)
     875            return VINF_SUCCESS;
     876        rc = VERR_VFS_CHAIN_CAST_FAILED;
     877    }
     878    return rc;
     879}
     880
     881
     882/**
     883 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnCanReuseElement}
     884 */
     885static DECLCALLBACK(bool) rtVfsChainGunzip_CanReuseElement(PCRTVFSCHAINELEMENTREG pProviderReg,
     886                                                           PCRTVFSCHAINSPEC pSpec, PCRTVFSCHAINELEMSPEC pElement,
     887                                                           PCRTVFSCHAINSPEC pReuseSpec, PCRTVFSCHAINELEMSPEC pReuseElement)
     888{
     889    RT_NOREF(pProviderReg, pSpec, pElement, pReuseSpec, pReuseElement);
     890    return false;
     891}
     892
     893
     894/** VFS chain element 'gunzip'. */
     895static RTVFSCHAINELEMENTREG g_rtVfsChainGunzipReg =
     896{
     897    /* uVersion = */            RTVFSCHAINELEMENTREG_VERSION,
     898    /* fReserved = */           0,
     899    /* pszName = */             "gunzip",
     900    /* ListEntry = */           { NULL, NULL },
     901    /* pszHelp = */             "Takes an I/O stream and gunzips it. No arguments.",
     902    /* pfnValidate = */         rtVfsChainGunzip_Validate,
     903    /* pfnInstantiate = */      rtVfsChainGunzip_Instantiate,
     904    /* pfnCanReuseElement = */  rtVfsChainGunzip_CanReuseElement,
     905    /* uEndMarker = */          RTVFSCHAINELEMENTREG_VERSION
     906};
     907
     908RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER(&g_rtVfsChainGunzipReg, rtVfsChainGunzipReg);
     909
     910
     911
     912/**
     913 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnValidate}
     914 */
     915static DECLCALLBACK(int) rtVfsChainGzip_Validate(PCRTVFSCHAINELEMENTREG pProviderReg, PRTVFSCHAINSPEC pSpec,
     916                                                 PRTVFSCHAINELEMSPEC pElement, uint32_t *poffError)
     917{
     918    RT_NOREF(pProviderReg);
     919
     920    /*
     921     * Basics.
     922     */
     923    if (pElement->enmTypeIn == RTVFSOBJTYPE_INVALID)
     924        return VERR_VFS_CHAIN_CANNOT_BE_FIRST_ELEMENT;
     925    if (pElement->cArgs > 1)
     926        return VERR_VFS_CHAIN_AT_MOST_ONE_ARG;
     927    if (pElement->enmType != RTVFSOBJTYPE_IO_STREAM)
     928        return VERR_VFS_CHAIN_ONLY_IOS;
     929    if (pSpec->fOpenFile & RTFILE_O_READ)
     930        return VERR_VFS_CHAIN_WRITE_ONLY_IOS;
     931
     932    /*
     933     * Optional argument 1..9 indicating the compression level.
     934     * We store it in pSpec->uProvider.
     935     */
     936    if (pElement->cArgs > 0)
     937    {
     938        const char *psz = pElement->paArgs[0].psz;
     939        if (!*psz || !strcmp(psz, "default"))
     940            pSpec->uProvider = 6;
     941        else if (!strcmp(psz, "fast"))
     942            pSpec->uProvider = 3;
     943        else if (   RT_C_IS_DIGIT(*psz)
     944                 && *psz != '0'
     945                 && *RTStrStripL(psz + 1) == '\0')
     946            pSpec->uProvider = *psz - '0';
     947        else
     948        {
     949            *poffError = pElement->paArgs[0].offSpec;
     950            return VERR_VFS_CHAIN_INVALID_ARGUMENT;
     951        }
     952    }
     953    else
     954        pSpec->uProvider = 6;
     955
     956    return VINF_SUCCESS;
     957}
     958
     959
     960/**
     961 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnInstantiate}
     962 */
     963static DECLCALLBACK(int) rtVfsChainGzip_Instantiate(PCRTVFSCHAINELEMENTREG pProviderReg, PCRTVFSCHAINSPEC pSpec,
     964                                                    PCRTVFSCHAINELEMSPEC pElement, RTVFSOBJ hPrevVfsObj,
     965                                                    PRTVFSOBJ phVfsObj, uint32_t *poffError)
     966{
     967    RT_NOREF(pProviderReg, pSpec, pElement, poffError);
     968    AssertReturn(hPrevVfsObj != NIL_RTVFSOBJ, VERR_VFS_CHAIN_IPE);
     969
     970    RTVFSIOSTREAM hVfsIosOut = RTVfsObjToIoStream(hPrevVfsObj);
     971    if (hVfsIosOut == NIL_RTVFSIOSTREAM)
     972        return VERR_VFS_CHAIN_CAST_FAILED;
     973
     974    RTVFSIOSTREAM hVfsIos = NIL_RTVFSIOSTREAM;
     975    int rc = RTZipGzipCompressIoStream(hVfsIosOut, 0 /*fFlags*/, pSpec->uProvider, &hVfsIos);
     976    if (RT_SUCCESS(rc))
     977    {
     978        *phVfsObj = RTVfsObjFromIoStream(hVfsIos);
     979        RTVfsIoStrmRelease(hVfsIos);
     980        if (*phVfsObj != NIL_RTVFSOBJ)
     981            return VINF_SUCCESS;
     982        rc = VERR_VFS_CHAIN_CAST_FAILED;
     983    }
     984    return rc;
     985}
     986
     987
     988/**
     989 * @interface_method_impl{RTVFSCHAINELEMENTREG,pfnCanReuseElement}
     990 */
     991static DECLCALLBACK(bool) rtVfsChainGzip_CanReuseElement(PCRTVFSCHAINELEMENTREG pProviderReg,
     992                                                         PCRTVFSCHAINSPEC pSpec, PCRTVFSCHAINELEMSPEC pElement,
     993                                                         PCRTVFSCHAINSPEC pReuseSpec, PCRTVFSCHAINELEMSPEC pReuseElement)
     994{
     995    RT_NOREF(pProviderReg, pSpec, pElement, pReuseSpec, pReuseElement);
     996    return false;
     997}
     998
     999
     1000/** VFS chain element 'gzip'. */
     1001static RTVFSCHAINELEMENTREG g_rtVfsChainGzipReg =
     1002{
     1003    /* uVersion = */            RTVFSCHAINELEMENTREG_VERSION,
     1004    /* fReserved = */           0,
     1005    /* pszName = */             "gzip",
     1006    /* ListEntry = */           { NULL, NULL },
     1007    /* pszHelp = */             "Takes an I/O stream and gzips it.\n"
     1008                                "Optional argument specifying compression level: 1-9, default, fast",
     1009    /* pfnValidate = */         rtVfsChainGzip_Validate,
     1010    /* pfnInstantiate = */      rtVfsChainGzip_Instantiate,
     1011    /* pfnCanReuseElement = */  rtVfsChainGzip_CanReuseElement,
     1012    /* uEndMarker = */          RTVFSCHAINELEMENTREG_VERSION
     1013};
     1014
     1015RTVFSCHAIN_AUTO_REGISTER_ELEMENT_PROVIDER(&g_rtVfsChainGzipReg, rtVfsChainGzipReg);
     1016
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