VirtualBox

Changeset 73978 in vbox


Ignore:
Timestamp:
Aug 30, 2018 1:19:36 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
124714
Message:

IPRT/rest: Fixed empty array & map handling by making the begin iteration functions return VERR_JSON_IS_EMPTY rather than letter the query method do that. Made query parameter processing table driven and made it use the right escapeing. bugref:9167

Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/cpp/restbase.h

    r73977 r73978  
    303303        kCollectionFormat_tsv,              /**< Tab-separated list. */
    304304        kCollectionFormat_pipes,            /**< Pipe-separated list. */
     305        kCollectionFormat_multi,            /**< Special collection type that must be handled by caller of toString. */
    305306        kCollectionFormat_Mask = 7,         /**< Collection type mask. */
    306307
     
    13701371
    13711372    /**
     1373     * Do path parameters.
    13721374     *
    13731375     * @returns IPRT status code
     
    13801382    int doPathParameters(RTCString *a_pStrPath, const char *a_pszPathTemplate, size_t a_cchPathTemplate,
    13811383                         PATHREPLACEENTRY *a_paPathParams, size_t a_cPathParams) const;
     1384
     1385    /** Query parameter descriptor. */
     1386    typedef struct
     1387    {
     1388        const char                 *pszName;    /**< The parameter name. */
     1389        uint32_t                    fFlags;     /**< The toString flags. */
     1390        bool                        fRequired;  /**< Required or not. */
     1391    } QUERYPARAMDESC;
     1392
     1393    /**
     1394     * Do query parameters.
     1395     *
     1396     * @returns IPRT status code
     1397     * @param   a_pStrQuery         The destination string.
     1398     * @param   a_paQueryParams     The query parameter descriptors.
     1399     * @param   a_papQueryParamObjs The query parameter objects, parallel to @a a_paQueryParams.
     1400     * @param   a_cQueryParams      Number of query parameters.
     1401     */
     1402    int doQueryParameters(RTCString *a_pStrQuery, QUERYPARAMDESC const *a_paQueryParams,
     1403                          RTCRestObjectBase const **a_papQueryParamObjs, size_t a_cQueryParams) const;
    13821404};
    13831405
  • trunk/include/iprt/err.h

    r73933 r73978  
    28772877/** The JSON document is malformed. */
    28782878#define VERR_JSON_MALFORMED                         (-24702)
     2879/** Object or array is empty. */
     2880#define VERR_JSON_IS_EMPTY                          (-24703)
    28792881/** @} */
    28802882
  • trunk/include/iprt/json.h

    r73956 r73978  
    277277 * @param   hJsonVal        The JSON value handle.
    278278 * @param   phJsonIt        Where to store the JSON iterator handle on success.
     279 * @todo    Make return VERR_JSON_IS_EMPTY (or remove it).
    279280 */
    280281RTDECL(int) RTJsonIteratorBegin(RTJSONVAL hJsonVal, PRTJSONIT phJsonIt);
     
    285286 * @returns IPRT status code.
    286287 * @retval  VERR_JSON_VALUE_INVALID_TYPE if the JSON value is not an array.
     288 * @retval  VERR_JSON_IS_EMPTY if no members.
    287289 * @param   hJsonVal        The JSON value handle.
    288290 * @param   phJsonIt        Where to store the JSON iterator handle on success.
     
    295297 * @returns IPRT status code.
    296298 * @retval  VERR_JSON_VALUE_INVALID_TYPE if the JSON value is not an object.
     299 * @retval  VERR_JSON_IS_EMPTY if no members.
    297300 * @param   hJsonVal        The JSON value handle.
    298301 * @param   phJsonIt        Where to store the JSON iterator handle on success.
  • trunk/src/VBox/Runtime/common/misc/json.cpp

    r73956 r73978  
    15181518    RTJSON_TYPECHECK_RETURN(pThis, RTJSONVALTYPE_ARRAY);
    15191519
    1520     return rtJsonIteratorBeginWorker(pThis, phJsonIt);
     1520    if (pThis->Type.Array.cItems > 0)
     1521        return rtJsonIteratorBeginWorker(pThis, phJsonIt);
     1522    return VERR_JSON_IS_EMPTY;
    15211523}
    15221524
     
    15281530    RTJSON_TYPECHECK_RETURN(pThis, RTJSONVALTYPE_OBJECT);
    15291531
    1530     return rtJsonIteratorBeginWorker(pThis, phJsonIt);
     1532    if (pThis->Type.Object.cMembers > 0)
     1533        return rtJsonIteratorBeginWorker(pThis, phJsonIt);
     1534    return VERR_JSON_IS_EMPTY;
    15311535}
    15321536
  • trunk/src/VBox/Runtime/common/rest/RTCRestArrayBase.cpp

    r73977 r73978  
    179179        RTJsonIteratorFree(hIterator);
    180180    }
     181    else if (rcRet == VERR_JSON_IS_EMPTY)
     182        rcRet = VINF_SUCCESS;
    181183    else
    182184        rcRet = a_rCursor.m_pPrimary->addError(a_rCursor, rcRet, "RTJsonIteratorBeginArray failed: %Rrc", rcRet);
  • trunk/src/VBox/Runtime/common/rest/RTCRestClientApiBase.cpp

    r73977 r73978  
    117117                if (strQuery.isNotEmpty())
    118118                {
    119                     if (RT_SUCCESS(rc))
    120                         rc = strFullUrl.appendNoThrow('?');
    121                     if (RT_SUCCESS(rc))
    122                         rc = strFullUrl.appendNoThrow(strQuery);
     119                    Assert(strQuery.startsWith("?"));
     120                    rc = strFullUrl.appendNoThrow(strQuery);
    123121                    strQuery.setNull();
    124122                }
  • trunk/src/VBox/Runtime/common/rest/RTCRestClientRequestBase.cpp

    r73977 r73978  
    112112}
    113113
     114
     115int RTCRestClientRequestBase::doQueryParameters(RTCString *a_pStrQuery, QUERYPARAMDESC const *a_paQueryParams,
     116                                                RTCRestObjectBase const **a_papQueryParamObjs, size_t a_cQueryParams) const
     117{
     118    RTCString strTmpVal;
     119    char chSep = a_pStrQuery->isEmpty() ? '?' : '&';
     120    for (size_t i = 0; i < a_cQueryParams; i++)
     121    {
     122        if ((a_paQueryParams[i].fFlags & RTCRestObjectBase::kCollectionFormat_Mask) != RTCRestObjectBase::kCollectionFormat_multi)
     123        {
     124            int rc = a_papQueryParamObjs[i]->toString(&strTmpVal, a_paQueryParams[i].fFlags);
     125            AssertRCReturn(rc, rc);
     126
     127            rc = a_pStrQuery->appendPrintfNoThrow("%c%RMpq=%RMpq", chSep, a_paQueryParams[i].pszName, strTmpVal.c_str());
     128            AssertRCReturn(rc, rc);
     129
     130            chSep = '&';
     131        }
     132        else
     133        {
     134            AssertFailedReturn(VERR_NOT_IMPLEMENTED);
     135        }
     136    }
     137    return VINF_SUCCESS;
     138}
     139
  • trunk/src/VBox/Runtime/common/rest/RTCRestStringMapBase.cpp

    r73977 r73978  
    175175        RTJsonIteratorFree(hIterator);
    176176    }
     177    else if (rcRet == VERR_JSON_IS_EMPTY)
     178        rcRet = VINF_SUCCESS;
    177179    else
    178180        rcRet = a_rCursor.m_pPrimary->addError(a_rCursor, rcRet, "RTJsonIteratorBegin failed: %Rrc", rcRet);
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