VirtualBox

Changeset 13551

Show
Ignore:
Timestamp:
10/24/08 14:10:08 (3 months ago)
Author:
vboxsync
Message:

HostServices/GuestProperties? and Main (Guest Properties): use the new iprt pattern matching APIs

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/include/VBox/HostServices/GuestPropertySvc.h

    r13376 r13551  
    5757/** Maximum number of properties per guest */ 
    5858enum { MAX_PROPS = 256 }; 
     59/** Maximum size for enumeration patterns */ 
     60enum { MAX_PATTERN_LEN = 1024 }; 
    5961 
    6062/** 
  • trunk/src/VBox/HostServices/GuestProperties/service.cpp

    r13376 r13551  
    203203        AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER); 
    204204        SELF *pSelf = reinterpret_cast<SELF *>(pvService); 
    205         // pSelf->mpfnHostCallback = pfnExtension; 
     205        pSelf->mpfnHostCallback = pfnExtension; 
    206206        pSelf->mpvHostData = pvExtension; 
    207207        return VINF_SUCCESS; 
     
    614614 
    615615/** 
    616  * Matches a sample name against a pattern. 
    617  * 
    618  * @returns True if matches, false if not. 
    619  * @param   pszPat      Pattern. 
    620  * @param   pszName     Name to match against the pattern. 
    621  * @todo move this into IPRT 
    622  */ 
    623 static bool matchesSinglePattern(const char *pszPat, const char *pszName) 
    624 { 
    625     /* ASSUMES ASCII */ 
    626     for (;;) 
    627     { 
    628         char chPat = *pszPat; 
    629         switch (chPat) 
    630         { 
    631             default: 
    632                 if (*pszName != chPat) 
    633                     return false; 
    634                 break; 
    635  
    636             case '*': 
    637             { 
    638                 while ((chPat = *++pszPat) == '*' || chPat == '?') 
    639                     /* nothing */; 
    640  
    641                 for (;;) 
    642                 { 
    643                     char ch = *pszName++; 
    644                     if (    ch == chPat 
    645                         &&  (   !chPat 
    646                              || matchesSinglePattern(pszPat + 1, pszName))) 
    647                         return true; 
    648                     if (!ch) 
    649                         return false; 
    650                 } 
    651                 /* won't ever get here */ 
    652                 break; 
    653             } 
    654  
    655             case '?': 
    656                 if (!*pszName) 
    657                     return false; 
    658                 break; 
    659  
    660             case '\0': 
    661                 return !*pszName; 
    662         } 
    663         pszName++; 
    664         pszPat++; 
    665     } 
    666     return true; 
    667 } 
    668  
    669  
    670 /* Checks to see if the given string matches against one of the patterns in 
    671  * the list. */ 
    672 static bool matchesPattern(const char *paszPatterns, size_t cchPatterns, 
    673                            const char *pszString) 
    674 { 
    675     size_t iOffs = 0; 
    676     /* If the first pattern in the list is empty, treat it as "match all". */ 
    677     bool matched = (cchPatterns > 0) && (0 == *paszPatterns) ? true : false; 
    678     while ((iOffs < cchPatterns) && !matched) 
    679     { 
    680         size_t cchCurrent; 
    681         if (   RT_SUCCESS(RTStrNLenEx(paszPatterns + iOffs, 
    682                                       cchPatterns - iOffs, &cchCurrent)) 
    683             && (cchCurrent > 0) 
    684            ) 
    685         { 
    686             matched = matchesSinglePattern(paszPatterns + iOffs, pszString); 
    687             iOffs += cchCurrent + 1; 
    688         } 
    689         else 
    690             iOffs = cchPatterns; 
    691     } 
    692     return matched; 
    693 } 
    694  
    695  
    696 /** 
    697616 * Enumerate guest properties by mask, checking the validity 
    698617 * of the arguments passed. 
     
    730649    if (RT_SUCCESS(rc)) 
    731650        rc = VBoxHGCMParmPtrGet(&paParms[0], (void **) &paszPatterns, &cchPatterns); 
     651    if (RT_SUCCESS(rc) && cchPatterns > MAX_PATTERN_LEN + 1) 
     652        rc = VERR_TOO_MUCH_DATA; 
    732653    if (RT_SUCCESS(rc)) 
    733654        rc = VBoxHGCMParmPtrGet(&paParms[1], (void **) &pchBuf, &cchBuf); 
    734655 
    735656/* 
    736  * Start by enumerating all values in the current node into a temporary buffer. 
     657 * First repack the patterns into the format expected by RTStrSimplePatternMatch() 
     658 */ 
     659    bool matchAll = false; 
     660    char pszPatterns[MAX_PATTERN_LEN + 1]; 
     661    if (   (NULL == paszPatterns) 
     662        || (cchPatterns < 2)  /* An empty pattern string means match all */ 
     663       ) 
     664        matchAll = true; 
     665    else 
     666    { 
     667        for (unsigned i = 0; i < cchPatterns - 1; ++i) 
     668            if (paszPatterns[i] != '\0') 
     669                pszPatterns[i] = paszPatterns[i]; 
     670            else 
     671                pszPatterns[i] = '|'; 
     672        pszPatterns[cchPatterns - 1] = '\0'; 
     673    } 
     674 
     675/* 
     676 * Next enumerate all values in the current node into a temporary buffer. 
    737677 */ 
    738678    RTMemAutoPtr<char> TmpBuf; 
     
    756696         * overwrite it next iteration. */ 
    757697        if (   RT_SUCCESS(rc) 
    758             && matchesPattern(paszPatterns, cchPatterns, &TmpBuf[iTmpBuf]) 
     698            && (   matchAll 
     699                || RTStrSimplePatternMultiMatch(pszPatterns, RTSTR_MAX, 
     700                                                &TmpBuf[iTmpBuf], RTSTR_MAX, 
     701                                                NULL) 
     702               ) 
    759703           ) 
    760704        { 
  • trunk/src/VBox/Main/ConsoleImpl.cpp

    r13417 r13551  
    36593659    VBOXHGCMSVCPARM parm[3]; 
    36603660 
    3661     /* 
    3662      * Set up the pattern parameter, translating the comma-separated list to a 
    3663      * double-terminated zero-separated one. 
    3664      */ 
    3665     Utf8Str utf8In(aPatterns); 
    3666     Utf8Str utf8Out(utf8In.length() + 2);  /* Double terminator */ 
    3667     if (   ((aPatterns != NULL) && (utf8In.isNull())) 
    3668         || utf8Out.isNull()) 
    3669         return E_OUTOFMEMORY; 
    3670     const char *pcszIn = utf8In.raw(); 
    3671     char *pszzOut = utf8Out.mutableRaw(); 
    3672     size_t iIn = 0, iOut = 0; 
    3673     if (aPatterns != NULL) 
    3674         while (pcszIn[iIn] != '\0') 
    3675         { 
    3676             if (pcszIn[iIn] != ',') 
    3677             { 
    3678                 pszzOut[iOut] = pcszIn[iIn]; 
    3679                 ++iIn; 
    3680             } 
    3681             else 
    3682             { 
    3683                 pszzOut[iOut] = '\0'; 
    3684                 while ((',' == pcszIn[iIn]) || (' ' == pcszIn[iIn])) 
    3685                     ++iIn; 
    3686             } 
    3687             ++iOut; 
    3688         } 
    3689     pszzOut[iOut] = '\0'; 
    3690  
     3661    Utf8Str utf8Patterns(aPatterns); 
    36913662    parm[0].type = VBOX_HGCM_SVC_PARM_PTR; 
    3692     parm[0].u.pointer.addr = pszzOut
    3693     parm[0].u.pointer.size = iOut + 1; 
     3663    parm[0].u.pointer.addr = utf8Patterns.mutableRaw()
     3664    parm[0].u.pointer.size = utf8Patterns.length() + 1; 
    36943665 
    36953666    /* 
  • trunk/src/VBox/Main/MachineImpl.cpp

    r13461 r13551  
    7171#include <iprt/cpputils.h> 
    7272#include <iprt/env.h> 
     73#include <iprt/string.h> 
    7374 
    7475#include <VBox/err.h> 
     
    28302831} 
    28312832 
    2832 /** 
    2833  * Matches a sample name against a pattern. 
    2834  * 
    2835  * @returns True if matches, false if not. 
    2836  * @param   pszPat      Pattern. 
    2837  * @param   cchPat      Number of characters in pszPat 
    2838  * @param   pszName     Name to match against the pattern. 
    2839  * @todo move this into IPRT 
    2840  */ 
    2841 static bool matchesSinglePatternEx(const char *pszPat, size_t cchPat, const char *pszName) 
    2842 { 
    2843     /* ASSUMES ASCII */ 
    2844     for (;;) 
    2845     { 
    2846         char chPat = *pszPat; 
    2847         switch (chPat) 
    2848         { 
    2849             default: 
    2850                 if (*pszName != chPat) 
    2851                     return false; 
    2852                 break; 
    2853  
    2854             case '*': 
    2855             { 
    2856                 while (   (--cchPat > 0) 
    2857                        && ((chPat = *++pszPat) == '*' || chPat == '?') 
    2858                       ) 
    2859                     /* nothing */; 
    2860  
    2861                 for (;;) 
    2862                 { 
    2863                     char ch = *pszName++; 
    2864                     if (   cchPat == 0 
    2865                         || (cchPat == 1 && ch == chPat) 
    2866                         || matchesSinglePatternEx(pszPat, cchPat, pszName) 
    2867                        ) 
    2868                         return true; 
    2869                     if (!ch) 
    2870                         return false; 
    2871                 } 
    2872                 /* won't ever get here */ 
    2873                 break; 
    2874             } 
    2875  
    2876             case '?': 
    2877                 if (!*pszName) 
    2878                     return false; 
    2879                 break; 
    2880  
    2881             case '\0': 
    2882                 return !*pszName; 
    2883         } 
    2884         pszName++; 
    2885         pszPat++; 
    2886         if (--cchPat == 0) 
    2887             return !*pszName; 
    2888         Assert(cchPat > 0); 
    2889     } 
    2890     return true; 
    2891 } 
    2892  
    2893 /* Checks to see if a pattern matches a name. */ 
    2894 static bool matchesSinglePattern(const char *pszPat, const char *pszName) 
    2895 { 
    2896     return matchesSinglePatternEx(pszPat, strlen(pszPat), pszName); 
    2897 } 
    2898  
    2899 /* Checks to see if the given string matches against one of the patterns in 
    2900  * the list. */ 
    2901 static bool matchesPattern(const char *paszPatterns, size_t cchPatterns, 
    2902                            const char *pszString) 
    2903 { 
    2904     size_t iOffs = 0; 
    2905     /* If the first pattern in the list is empty, treat it as "match all". */ 
    2906     bool matched = (cchPatterns > 0) && (0 == *paszPatterns); 
    2907     while ((iOffs < cchPatterns) && !matched) 
    2908     { 
    2909         size_t cchCurrent; 
    2910         if (   RT_SUCCESS(RTStrNLenEx(paszPatterns + iOffs, 
    2911                                       cchPatterns - iOffs, &cchCurrent)) 
    2912             && (cchCurrent > 0) 
    2913            ) 
    2914         { 
    2915             matched = matchesSinglePattern(paszPatterns + iOffs, pszString); 
    2916             iOffs += cchCurrent + 1; 
    2917         } 
    2918         else 
    2919             iOffs = cchPatterns; 
    2920     } 
    2921     return matched; 
    2922 } 
    2923  
    2924 /* Checks to see if the given string matches against one of the patterns in 
    2925  * the comma-separated list.  Note that spaces at the beginning of patterns 
    2926  * are ignored - '?' should be used here if that is really needed. */ 
    2927 static bool matchesPatternComma(const char *pcszPatterns, const char *pcszString) 
    2928 { 
    2929     AssertPtr(pcszPatterns); 
    2930     const char *pcszCur = pcszPatterns; 
    2931     /* If list is empty, treat it as "match all". */ 
    2932     bool matched = (0 == *pcszPatterns); 
    2933     bool done = false; 
    2934     while (!done && !matched) 
    2935     { 
    2936         const char *pcszNext = strchr(pcszCur, ','); 
    2937         if (pcszNext != NULL) 
    2938         { 
    2939             matched = matchesSinglePatternEx(pcszCur, pcszNext - pcszCur, pcszString); 
    2940             pcszCur = pcszNext; 
    2941             while ((',' == *pcszCur) || (' ' == *pcszCur)) 
    2942                 ++pcszCur; 
    2943         } 
    2944         else 
    2945         { 
    2946             matched = matchesSinglePattern(pcszCur, pcszString); 
    2947             done = true; 
    2948         } 
    2949     } 
    2950     return matched; 
    2951 } 
    2952  
    29532833STDMETHODIMP Machine::SetGuestProperty (INPTR BSTR aName, INPTR BSTR aValue, INPTR BSTR aFlags) 
    29542834{ 
     
    29732853       ) 
    29742854        return E_OUTOFMEMORY; 
     2855    bool matchAll = false; 
     2856    if (0 == utf8Patterns.length()) 
     2857        matchAll = true; 
    29752858 
    29762859    uint32_t fFlags = NILFLAG; 
     
    30562939                                                 &dummy, &dummy64, &dummy); 
    30572940    } 
    3058     if (SUCCEEDED (rc) && matchesPatternComma (utf8Patterns.raw(), utf8Name.raw())) 
     2941    if (   SUCCEEDED (rc) 
     2942        && (   matchAll 
     2943            || RTStrSimplePatternMultiMatch (utf8Patterns.raw(), RTSTR_MAX, 
     2944                                             utf8Name.raw(), RTSTR_MAX, NULL) 
     2945           ) 
     2946       ) 
    30592947        mParent->onGuestPropertyChange (mData->mUuid, aName, aValue, aFlags); 
    30602948    return rc; 
     
    30912979    HRESULT rc = E_FAIL; 
    30922980 
     2981    bool matchAll = false; 
     2982    if ((NULL == aPatterns) || (0 == aPatterns[0])) 
     2983        matchAll = true; 
    30932984    if (!mHWData->mPropertyServiceActive) 
    30942985    { 
     
    31002991        for (HWData::GuestPropertyList::iterator it = mHWData->mGuestProperties.begin(); 
    31012992             it != mHWData->mGuestProperties.end(); ++it) 
    3102             if (matchesPatternComma(Utf8Str(aPatterns).raw(), Utf8Str(it->mName).raw())) 
     2993            if (   matchAll 
     2994                || RTStrSimplePatternMultiMatch (Utf8Str(aPatterns).raw(), 
     2995                                                 RTSTR_MAX, 
     2996                                                 Utf8Str(it->mName).raw(), 
     2997                                                 RTSTR_MAX, NULL) 
     2998               ) 
    31032999                propList.push_back(*it); 
    31043000 
     
    93479243        return E_POINTER;  /* aValue can be NULL to indicate deletion */ 
    93489244 
     9245    Utf8Str utf8Name(aName); 
     9246    Utf8Str utf8Flags(aFlags); 
     9247    Utf8Str utf8Patterns(mHWData->mGuestPropertyNotificationPatterns); 
     9248    if (   utf8Name.isNull() 
     9249        || ((aFlags != NULL) && utf8Flags.isNull()) 
     9250        || utf8Patterns.isNull() 
     9251       ) 
     9252        return E_OUTOFMEMORY; 
     9253 
    93499254    uint32_t fFlags = NILFLAG; 
    9350     if ((aFlags != NULL) && RT_FAILURE (validateFlags (Utf8Str(aFlags).raw(), &fFlags))) 
     9255    if ((aFlags != NULL) && RT_FAILURE (validateFlags (utf8Flags.raw(), &fFlags))) 
    93519256        return E_INVALIDARG; 
     9257 
     9258    bool matchAll = false; 
     9259    if (0 == utf8Patterns.length()) 
     9260        matchAll = true; 
    93529261 
    93539262    AutoCaller autoCaller (this); 
     
    93759284    /* send a callback notification if appropriate */ 
    93769285    alock.leave(); 
    9377     if (matchesPatternComma (Utf8Str(mHWData->mGuestPropertyNotificationPatterns).raw(), 
    9378                              Utf8Str(aName).raw())) 
     9286    if (   matchAll 
     9287        || RTStrSimplePatternMultiMatch (utf8Patterns.raw(), RTSTR_MAX, 
     9288                                         utf8Name.raw(), RTSTR_MAX, NULL) 
     9289       ) 
    93799290        mParent->onGuestPropertyChange (mData->mUuid, aName, aValue, aFlags); 
    93809291 

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy