VirtualBox

Changeset 72070 in vbox


Ignore:
Timestamp:
Apr 30, 2018 12:30:52 PM (6 years ago)
Author:
vboxsync
Message:

Main/GuestSessionImpl: Proposing more efficient and flexible copy flag parsing code. bugref:9135

Location:
trunk/src/VBox/Main
Files:
2 edited

Legend:

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

    r72067 r72070  
    267267                                          ComPtr<IProgress> &pProgress);
    268268    int                     i_closeSession(uint32_t uFlags, uint32_t uTimeoutMS, int *pGuestRc);
    269     static int              i_directoryCopyFlagFromStr(const com::Utf8Str &strFlags, DirectoryCopyFlag_T *pfFlags);
     269    HRESULT                 i_directoryCopyFlagFromStr(const com::Utf8Str &strFlags, DirectoryCopyFlag_T *pfFlags);
    270270    inline bool             i_directoryExists(uint32_t uDirID, ComObjPtr<GuestDirectory> *pDir);
    271271    int                     i_directoryUnregister(GuestDirectory *pDirectory);
     
    277277    int                     i_dispatchToObject(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
    278278    int                     i_dispatchToThis(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
    279     static int              i_fileCopyFlagFromStr(const com::Utf8Str &strFlags, FileCopyFlag_T *pfFlags);
     279    HRESULT                 i_fileCopyFlagFromStr(const com::Utf8Str &strFlags, FileCopyFlag_T *pfFlags);
    280280    inline bool             i_fileExists(uint32_t uFileID, ComObjPtr<GuestFile> *pFile);
    281281    int                     i_fileUnregister(GuestFile *pFile);
  • trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp

    r72067 r72070  
    4242
    4343#include <iprt/cpp/utils.h> /* For unconst(). */
     44#include <iprt/ctype.h>
    4445#include <iprt/env.h>
    4546#include <iprt/file.h> /* For CopyTo/From. */
     
    871872 * Validates and extracts directory copy flags from a comma-separated string.
    872873 *
    873  * @return VBox status code.
     874 * @return COM status, error set on failure
    874875 * @param  strFlags             String to extract flags from.
    875876 * @param  pfFlags              Where to store the extracted (and validated) flags.
    876877 */
    877 /* static */
    878 int GuestSession::i_directoryCopyFlagFromStr(const com::Utf8Str &strFlags, DirectoryCopyFlag_T *pfFlags)
    879 {
    880     DirectoryCopyFlag_T fFlags = DirectoryCopyFlag_None;
     878HRESULT GuestSession::i_directoryCopyFlagFromStr(const com::Utf8Str &strFlags, DirectoryCopyFlag_T *pfFlags)
     879{
     880    unsigned fFlags = DirectoryCopyFlag_None;
    881881
    882882    /* Validate and set flags. */
    883     if (strFlags.isEmpty())
    884     {
    885         *pfFlags = fFlags;
    886         return VINF_SUCCESS;
    887     }
    888 
    889     const char *pcszNext = strFlags.c_str();
    890     while (*pcszNext != '\0')
    891     {
    892         Utf8Str strFlag;
    893         const char *pcszComma = RTStrStr(pcszNext, ",");
    894         if (!pcszComma)
    895             strFlag = pcszNext;
    896         else
    897             strFlag = Utf8Str(pcszNext, pcszComma - pcszNext);
    898 
    899         const char *pcszEqual = RTStrStr(strFlag.c_str(), "=");
    900         if (   pcszEqual
    901             && pcszEqual != strFlag.c_str())
    902         {
    903             Utf8Str strKey(strFlag.c_str(), pcszEqual - strFlag.c_str());
    904             Utf8Str strValue(strFlag.c_str() + (pcszEqual - strFlag.c_str() + 1));
    905             RT_NOREF(strKey, strValue); /* We don't have any key=value pairs yet. */
    906         }
    907         else
    908         {
    909            if (strFlag == "CopyIntoExisting")
    910                fFlags |= DirectoryCopyFlag_CopyIntoExisting;
    911            else
    912                return VERR_INVALID_PARAMETER;
    913         }
    914 
    915         if (!pcszComma)
    916             pcszNext += strFlag.length();
    917         else
    918             pcszNext += strFlag.length() + 1;
     883    if (strFlags.isNotEmpty())
     884    {
     885        const char *pszNext = strFlags.c_str();
     886        for (;;)
     887        {
     888            /* Find the next keyword, ignoring all whitespace. */
     889            pszNext = RTStrStripL(pszNext);
     890
     891            const char * const pszComma = strchr(pszNext, ',');
     892            size_t cchKeyword = pszComma ? pszComma - pszNext : strlen(pszComma);
     893            while (cchKeyword > 0 && RT_C_IS_SPACE(pszNext[cchKeyword - 1]))
     894                cchKeyword--;
     895
     896            if (cchKeyword > 0)
     897            {
     898                /* Convert keyword to flag. */
     899#define MATCH_KEYWORD(a_szKeyword) (   cchKeyword == sizeof(a_szKeyword) - 1U \
     900                                    && memcmp(pszNext, a_szKeyword, sizeof(a_szKeyword) - 1U) == 0)
     901                if (MATCH_KEYWORD("CopyIntoExisting"))
     902                    fFlags |= (unsigned)DirectoryCopyFlag_CopyIntoExisting;
     903                else
     904                    return setError(E_INVALIDARG, tr("Invalid directory copy flag: %.*s"), (int)cchKeyword, pszNext);
     905#undef MATCH_KEYWORD
     906            }
     907            if (!pszComma)
     908                break;
     909            pszNext = pszComma + 1;
     910        }
    919911    }
    920912
    921913    if (pfFlags)
    922         *pfFlags = fFlags;
    923 
    924     return VINF_SUCCESS;
     914        *pfFlags = (DirectoryCopyFlag_T)fFlags;
     915    return S_OK;
    925916}
    926917
     
    13481339 * Validates and extracts file copy flags from a comma-separated string.
    13491340 *
    1350  * @return VBox status code.
     1341 * @return COM status, error set on failure
    13511342 * @param  strFlags             String to extract flags from.
    13521343 * @param  pfFlags              Where to store the extracted (and validated) flags.
    13531344 */
    1354 /* static */
    1355 int GuestSession::i_fileCopyFlagFromStr(const com::Utf8Str &strFlags, FileCopyFlag_T *pfFlags)
    1356 {
    1357     FileCopyFlag_T fFlags = FileCopyFlag_None;
     1345HRESULT GuestSession::i_fileCopyFlagFromStr(const com::Utf8Str &strFlags, FileCopyFlag_T *pfFlags)
     1346{
     1347    unsigned fFlags = (unsigned)FileCopyFlag_None;
    13581348
    13591349    /* Validate and set flags. */
    1360     if (strFlags.isEmpty())
    1361     {
    1362         *pfFlags = fFlags;
    1363         return VINF_SUCCESS;
    1364     }
    1365 
    1366     const char *pcszNext = strFlags.c_str();
    1367     while (*pcszNext != '\0')
    1368     {
    1369         Utf8Str strFlag;
    1370         const char *pcszComma = RTStrStr(pcszNext, ",");
    1371         if (!pcszComma)
    1372             strFlag = pcszNext;
    1373         else
    1374             strFlag = Utf8Str(pcszNext, pcszComma - pcszNext);
    1375 
    1376         const char *pcszEqual = RTStrStr(strFlag.c_str(), "=");
    1377         if (   pcszEqual
    1378             && pcszEqual != strFlag.c_str())
    1379         {
    1380             Utf8Str strKey(strFlag.c_str(), pcszEqual - strFlag.c_str());
    1381             Utf8Str strValue(strFlag.c_str() + (pcszEqual - strFlag.c_str() + 1));
    1382             RT_NOREF(strKey, strValue); /* We don't have any key=value pairs yet. */
    1383         }
    1384         else
    1385         {
    1386             if (strFlag == "NoReplace")
    1387                 fFlags |= FileCopyFlag_NoReplace;
    1388             else if (strFlag == "FollowLinks")
    1389                 fFlags |= FileCopyFlag_FollowLinks;
    1390             else if (strFlag == "Update")
    1391                 fFlags |= FileCopyFlag_Update;
    1392             else
    1393                 return VERR_INVALID_PARAMETER;
    1394         }
    1395 
    1396         if (!pcszComma)
    1397             pcszNext += strFlag.length();
    1398         else
    1399             pcszNext += strFlag.length() + 1;
     1350    if (strFlags.isNotEmpty())
     1351    {
     1352        const char *pszNext = strFlags.c_str();
     1353        for (;;)
     1354        {
     1355            /* Find the next keyword, ignoring all whitespace. */
     1356            pszNext = RTStrStripL(pszNext);
     1357
     1358            const char * const pszComma = strchr(pszNext, ',');
     1359            size_t cchKeyword = pszComma ? pszComma - pszNext : strlen(pszComma);
     1360            while (cchKeyword > 0 && RT_C_IS_SPACE(pszNext[cchKeyword - 1]))
     1361                cchKeyword--;
     1362
     1363            if (cchKeyword > 0)
     1364            {
     1365                /* Convert keyword to flag. */
     1366#define MATCH_KEYWORD(a_szKeyword) (   cchKeyword == sizeof(a_szKeyword) - 1U \
     1367                                    && memcmp(pszNext, a_szKeyword, sizeof(a_szKeyword) - 1U) == 0)
     1368                if (MATCH_KEYWORD("NoReplace"))
     1369                    fFlags |= (unsigned)FileCopyFlag_NoReplace;
     1370                else if (MATCH_KEYWORD("FollowLinks"))
     1371                    fFlags |= (unsigned)FileCopyFlag_FollowLinks;
     1372                else if (MATCH_KEYWORD("Update"))
     1373                    fFlags |= (unsigned)FileCopyFlag_Update;
     1374                else
     1375                    return setError(E_INVALIDARG, tr("Invalid file copy flag: %.*s"), (int)cchKeyword, pszNext);
     1376#undef MATCH_KEYWORD
     1377            }
     1378            if (!pszComma)
     1379                break;
     1380            pszNext = pszComma + 1;
     1381        }
    14001382    }
    14011383
    14021384    if (pfFlags)
    1403         *pfFlags = fFlags;
    1404 
    1405     return VINF_SUCCESS;
     1385        *pfFlags = (FileCopyFlag_T)fFlags;
     1386    return S_OK;
    14061387}
    14071388
     
    29402921        source.enmPathStyle = i_getPathStyle();
    29412922
     2923        HRESULT hrc;
    29422924        if (source.enmType == FsObjType_Directory)
    29432925        {
    2944             int rc2 = GuestSession::i_directoryCopyFlagFromStr(*itFlags, &source.Type.Dir.fCopyFlags);
    2945             if (RT_FAILURE(rc2))
    2946                 return setError(E_INVALIDARG, tr("Invalid / not (yet) implemented directory copy flags specified"));
    2947 
     2926            hrc = GuestSession::i_directoryCopyFlagFromStr(*itFlags, &source.Type.Dir.fCopyFlags);
    29482927            source.Type.Dir.fRecursive = true; /* Implicit. */
    29492928        }
    29502929        else if (source.enmType == FsObjType_File)
    2951         {
    2952             int rc2 = GuestSession::i_fileCopyFlagFromStr(*itFlags, &source.Type.File.fCopyFlags);
    2953             if (RT_FAILURE(rc2))
    2954                 return setError(E_NOTIMPL, tr("Invalid / not (yet) implemented file copy flag(s) specified"));
    2955         }
     2930            hrc = GuestSession::i_fileCopyFlagFromStr(*itFlags, &source.Type.File.fCopyFlags);
    29562931        else
    29572932            return setError(E_INVALIDARG, tr("Source type %d invalid / not supported"), source.enmType);
     2933        if (FAILED(hrc))
     2934            return hrc;
    29582935
    29592936        SourceSet.push_back(source);
     
    29982975        source.enmPathStyle = i_getPathStyle();
    29992976
     2977        HRESULT hrc;
    30002978        if (source.enmType == FsObjType_Directory)
    30012979        {
    3002             int rc2 = GuestSession::i_directoryCopyFlagFromStr(*itFlags, &source.Type.Dir.fCopyFlags);
    3003             if (RT_FAILURE(rc2))
    3004                 return setError(E_INVALIDARG, tr("Invalid / not (yet) implemented directory copy flags specified"));
    3005 
     2980            hrc = GuestSession::i_directoryCopyFlagFromStr(*itFlags, &source.Type.Dir.fCopyFlags);
    30062981            source.Type.Dir.fRecursive = true; /* Implicit. */
    30072982        }
    30082983        else if (source.enmType == FsObjType_File)
    3009         {
    3010             int rc2 = GuestSession::i_fileCopyFlagFromStr(*itFlags, &source.Type.File.fCopyFlags);
    3011             if (RT_FAILURE(rc2))
    3012                 return setError(E_NOTIMPL, tr("Invalid / not (yet) implemented file copy flag(s) specified"));
    3013         }
     2984            hrc = GuestSession::i_fileCopyFlagFromStr(*itFlags, &source.Type.File.fCopyFlags);
    30142985        else
    30152986            return setError(E_INVALIDARG, tr("Source type %d invalid / not supported"), source.enmType);
     2987        if (FAILED(hrc))
     2988            return hrc;
    30162989
    30172990        SourceSet.push_back(source);
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