VirtualBox

Ignore:
Timestamp:
Sep 14, 2018 12:53:18 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
125066
Message:

IPRT/rest: Reimplement RTCRestArrayBase::fromString and adjusted response header handling of arrays to deal with multiple headers for the same field (just in case). bugref:9167

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/rest/RTCRestArrayBase.cpp

    r74244 r74263  
    3636
    3737
     38/*********************************************************************************************************************************
     39*   Global Variables                                                                                                             *
     40*********************************************************************************************************************************/
     41/** Separator characters. */
     42static char const g_szSep[RTCRestObjectBase::kCollectionFormat_Mask + 1] = ",, \t|,,";
     43
    3844
    3945/**
     
    210216        if (m_cElements)
    211217        {
    212             static char const s_szSep[kCollectionFormat_Mask + 1] = ",, \t|,,";
    213             char const chSep = s_szSep[a_fFlags & kCollectionFormat_Mask];
     218            char const chSep = g_szSep[a_fFlags & kCollectionFormat_Mask];
    214219
    215220            rc = m_papElements[0]->toString(a_pDst, a_fFlags);
     
    240245                                 uint32_t a_fFlags /*= kCollectionFormat_Unspecified*/)
    241246{
    242     /** @todo proper fromString implementation for arrays. */
    243     return RTCRestObjectBase::fromString(a_rValue, a_pszName, a_pErrInfo, a_fFlags);
     247    /*
     248     * Clear the array.  If the string is empty, we have an empty array and is done.
     249     */
     250    if (!(a_fFlags & kToString_Append))
     251        clear();
     252    if (a_rValue.isEmpty())
     253        return VINF_SUCCESS;
     254
     255    /*
     256     * Look for a separator so we don't mistake a initial null element for a null array.
     257     */
     258    char const chSep = g_szSep[a_fFlags & kCollectionFormat_Mask];
     259    size_t offSep = a_rValue.find(chSep);
     260    if (   offSep != RTCString::npos
     261        || !a_rValue.startsWithWord("null", RTCString::CaseInsensitive))
     262    {
     263        RTCString strTmp;
     264        size_t    offStart = 0;
     265        int       rcRet    = VINF_SUCCESS;
     266        for (;;)
     267        {
     268            /* Copy the element value into its own string buffer. */
     269            int rc = strTmp.assignNoThrow(a_rValue, offStart, (offSep == RTCString::npos ? a_rValue.length() : offSep) - offStart);
     270            AssertRCReturn(rc, rc);
     271
     272            /* Create a new element, insert it and pass it the value string. */
     273            RTCRestObjectBase *pObj = createValue();
     274            AssertPtrReturn(pObj, VERR_NO_MEMORY);
     275
     276            rc = insertWorker(~(size_t)0, pObj, false);
     277            AssertRCReturnStmt(rc, delete pObj, rc);
     278
     279            char szName[128];
     280            RTStrPrintf(szName, sizeof(szName), "%.*s[%zu]", 116, a_pszName ? a_pszName : "", size());
     281            rc = pObj->fromString(strTmp, a_pszName, a_pErrInfo, 0);
     282            if (RT_SUCCESS(rc))
     283            { /* likely */ }
     284            else if (RT_SUCCESS(rcRet))
     285                rcRet = rc;
     286
     287            /*
     288             * Done? Otherwise advance.
     289             */
     290            if (offSep == RTCString::npos)
     291                break;
     292            offStart = offSep + 1;
     293            offSep = a_rValue.find(chSep, offStart);
     294        }
     295        return rcRet;
     296    }
     297
     298    /*
     299     * Consider this a null array even if it could also be an array with a single
     300     * null element.  This is just an artifact of an imperfect serialization format.
     301     */
     302    setNull();
     303    return VINF_SUCCESS;
    244304}
    245305
Note: See TracChangeset for help on using the changeset viewer.

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