VirtualBox

Changeset 73956 in vbox


Ignore:
Timestamp:
Aug 29, 2018 3:09:34 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
124685
Message:

IPRT/rest: Added RTJsonIteratorBeginArray and RTJsonIteratorBeginObject for more accurate JSON decoding. Early RTCRestArray implementation. bugref:9167

Location:
trunk
Files:
1 added
8 edited

Legend:

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

    r73950 r73956  
    123123     * @param   a_pDst      Pointer to the destination string object.
    124124     *                      NULL is not accepted and will assert.
    125      */
    126     RTCRestOutputToString(RTCString *a_pDst);
     125     * @param   a_fAppend   Whether to append to the current string value, or
     126     *                      nuke the string content before starting the output.
     127     */
     128    RTCRestOutputToString(RTCString *a_pDst, bool a_fAppend = false);
    127129    virtual ~RTCRestOutputToString();
    128130
     
    289291     * The kCollectionFormat_xxx bunch controls multiple values in arrays
    290292     * are formatted.  They are ignored by everyone else.
     293     *
     294     * @note When adding collection format types, make sure to also
     295     *       update RTCRestArrayBase::toString().
    291296     */
    292297    enum
     
    297302        kCollectionFormat_tsv,              /**< Tab-separated list. */
    298303        kCollectionFormat_pipes,            /**< Pipe-separated list. */
    299         kCollectionFormat_Mask = 7          /**< Collection type mask. */
     304        kCollectionFormat_Mask = 7,         /**< Collection type mask. */
     305
     306        kToString_Append = 8                /**< Append to the string (rather than assigning). */
    300307    };
    301308
     
    543550    virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    544551    virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    545     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_OVERRIDE;
     552    virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_OVERRIDE;
    546553    virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    547554                           uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
     
    554561
    555562/**
     563 * Abstract base class for the RTCRestArray template.
     564 */
     565class RTCRestArrayBase : public RTCRestObjectBase
     566{
     567public:
     568    /** Default destructor. */
     569    RTCRestArrayBase();
     570    /** Copy constructor. */
     571    RTCRestArrayBase(RTCRestArrayBase const &a_rThat);
     572    /** Destructor. */
     573    virtual ~RTCRestArrayBase();
     574    /** Copy assignment operator. */
     575    RTCRestArrayBase &operator=(RTCRestArrayBase const &a_rThat);
     576
     577    /* Overridden methods: */
     578    virtual void resetToDefault() RT_OVERRIDE;
     579    virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
     580    virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
     581    virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_OVERRIDE;
     582    virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
     583                           uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
     584
     585    /**
     586     * Clear the content of the map.
     587     */
     588    void clear();
     589
     590    /**
     591     * Check if an list contains any items.
     592     *
     593     * @return   True if there is more than zero items, false otherwise.
     594     */
     595    bool isEmpty() const
     596    {
     597        return m_cElements == 0;
     598    }
     599
     600    /**
     601     * Gets the number of entries in the map.
     602     */
     603    size_t size() const
     604    {
     605        return m_cElements;
     606    }
     607
     608    /**
     609     * Removes the element at @a a_idx.
     610     * @returns true if @a a_idx is valid, false if out of range.
     611     * @param   a_idx       The index of the element to remove.
     612     */
     613    bool removeAt(size_t a_idx);
     614
     615
     616    /**
     617     * Makes sure the array can hold at the given number of entries.
     618     *
     619     * @returns VINF_SUCCESS or VERR_NO_MEMORY.
     620     * @param   a_cEnsureCapacity   The number of elements to ensure capacity to hold.
     621     */
     622    int ensureCapacity(size_t a_cEnsureCapacity);
     623
     624
     625protected:
     626    /** The array. */
     627    RTCRestObjectBase **m_papElements;
     628    /** Number of elements in the array. */
     629    size_t              m_cElements;
     630    /** The number of elements m_papElements can hold.
     631     * The difference between m_cCapacity and m_cElements are all NULLs. */
     632    size_t              m_cCapacity;
     633
     634    /**
     635     * Wrapper around the value constructor.
     636     *
     637     * @returns Pointer to new value object on success, NULL if out of memory.
     638     */
     639    virtual RTCRestObjectBase *createValue(void) = 0;
     640
     641    /**
     642     * Wrapper around the value copy constructor.
     643     *
     644     * @returns Pointer to copy on success, NULL if out of memory.
     645     * @param   a_pSrc      The value to copy.
     646     */
     647    virtual RTCRestObjectBase *createValueCopy(RTCRestObjectBase const *a_pSrc) = 0;
     648
     649    /**
     650     * Worker for the copy constructor and the assignment operator.
     651     *
     652     * This will use createEntryCopy to do the copying.
     653     *
     654     * @returns VINF_SUCCESS on success, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
     655     * @param   a_rThat     The array to copy.  Caller makes 100% sure the it has
     656     *                      the same type as the destination.
     657     * @param   a_fThrow    Whether to throw error.
     658     */
     659    int copyArrayWorker(RTCRestArrayBase const &a_rThat, bool fThrow);
     660
     661    /**
     662     * Worker for performing inserts.
     663     *
     664     * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
     665     *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
     666     * @param   a_idx           Where to insert it.
     667     * @param   a_pValue        The value to insert.  Ownership is transferred to the map on success.
     668     * @param   a_fReplace      Whether to replace existing entry rather than insert.
     669     */
     670    int insertWorker(size_t a_idx, RTCRestObjectBase *a_pValue, bool a_fReplace);
     671
     672    /**
     673     * Worker for performing inserts.
     674     *
     675     * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
     676     *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
     677     * @param   a_idx           Where to insert it.
     678     * @param   a_rValue        The value to copy into the map.
     679     * @param   a_fReplace      Whether to replace existing key-value pair with matching key.
     680     */
     681    int insertCopyWorker(size_t a_idx, RTCRestObjectBase const &a_rValue, bool a_fReplace);
     682};
     683
     684
     685
     686/**
    556687 * Limited array class.
    557688 */
    558 template<class ElementType> class RTCRestArray : public RTCRestObjectBase
    559 {
    560 public:
    561     RTCRestArray() {};
    562     ~RTCRestArray() {};
    563 /** @todo more later. */
    564 
    565     virtual void resetToDefault() RT_OVERRIDE
    566     {
    567     }
    568 
    569     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE
    570     {
    571         RT_NOREF(a_rDst);
    572         return a_rDst;
    573     }
    574 
    575     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE
    576     {
    577         RT_NOREF(a_rCursor);
    578         return VERR_NOT_IMPLEMENTED;
    579     }
    580 
    581     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    582                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE
    583     {
    584         RT_NOREF(a_rValue, a_pszName, a_pErrInfo, a_fFlags);
    585         return VERR_NOT_IMPLEMENTED;
     689template<class ElementType> class RTCRestArray : public RTCRestArrayBase
     690{
     691public:
     692    RTCRestArray()
     693        : RTCRestArrayBase()
     694    {
     695    }
     696    ~RTCRestArray()
     697    {
    586698    }
    587699
     
    601713    {
    602714        return new (std::nothrow) ElementType();
     715    }
     716
     717
     718    /**
     719     * Insert the given object at the specified index.
     720     *
     721     * @returns VINF_SUCCESS on success.
     722     *          VERR_INVALID_POINTER, VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
     723     * @param   a_idx           The insertion index.  ~(size_t)0 is an alias for the end.
     724     * @param   a_pThat         The object to insert.  The array takes ownership of the object on success.
     725     */
     726    int insert(size_t a_idx, ElementType *a_pThat)
     727    {
     728        return insertWorker(a_idx, a_pThat, false /*a_fReplace*/);
     729    }
     730
     731    /**
     732     * Insert a copy of the object at the specified index.
     733     *
     734     * @returns VINF_SUCCESS on success.
     735     *          VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
     736     * @param   a_idx           The insertion index.  ~(size_t)0 is an alias for the end.
     737     * @param   a_rThat         The object to insert a copy of.
     738     */
     739    int insertCopy(size_t a_idx, ElementType const &a_rThat)
     740    {
     741        return insertCopyWorker(a_idx, &a_rThat, false /*a_fReplace*/);
     742    }
     743
     744    /**
     745     * Appends the given object to the array.
     746     *
     747     * @returns VINF_SUCCESS on success.
     748     *          VERR_INVALID_POINTER, VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
     749     * @param   a_pThat         The object to insert.  The array takes ownership of the object on success.
     750     */
     751    int append(size_t a_idx, ElementType *a_pThat)
     752    {
     753        return insertWorker(~(size_t)0, a_pThat, false /*a_fReplace*/);
     754    }
     755
     756    /**
     757     * Appends a copy of the object at the specified index.
     758     *
     759     * @returns VINF_SUCCESS on success.
     760     *          VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
     761     * @param   a_rThat         The object to insert a copy of.
     762     */
     763    int appendCopy(ElementType const &a_rThat)
     764    {
     765        return insertCopyWorker(~(size_t)0, &a_rThat, false /*a_fReplace*/);
     766    }
     767
     768    /**
     769     * Prepends the given object to the array.
     770     *
     771     * @returns VINF_SUCCESS on success.
     772     *          VERR_INVALID_POINTER, VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
     773     * @param   a_pThat         The object to insert.  The array takes ownership of the object on success.
     774     */
     775    int prepend(size_t a_idx, ElementType *a_pThat)
     776    {
     777        return insertWorker(0, a_pThat, false /*a_fReplace*/);
     778    }
     779
     780    /**
     781     * Prepends a copy of the object at the specified index.
     782     *
     783     * @returns VINF_SUCCESS on success.
     784     *          VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
     785     * @param   a_rThat         The object to insert a copy of.
     786     */
     787    int prependCopy(ElementType const &a_rThat)
     788    {
     789        return insertCopyWorker(0, &a_rThat, false /*a_fReplace*/);
     790    }
     791
     792    /**
     793     * Insert the given object at the specified index.
     794     *
     795     * @returns VINF_SUCCESS on success.
     796     *          VERR_INVALID_POINTER, VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
     797     * @param   a_idx           The index of the existing object to replace.
     798     * @param   a_pThat         The replacement object.  The array takes ownership of the object on success.
     799     */
     800    int replace(size_t a_idx, ElementType *a_pThat)
     801    {
     802        return insertWorker(a_idx, a_pThat, true /*a_fReplace*/);
     803    }
     804
     805    /**
     806     * Insert a copy of the object at the specified index.
     807     *
     808     * @returns VINF_SUCCESS on success.
     809     *          VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
     810     * @param   a_idx           The index of the existing object to replace.
     811     * @param   a_rThat         The object to insert a copy of.
     812     */
     813    int replaceCopy(size_t a_idx, ElementType const &a_rThat)
     814    {
     815        return insertCopyWorker(a_idx, &a_rThat, true /*a_fReplace*/);
     816    }
     817
     818    /**
     819     * Returns the object at a given index.
     820     *
     821     * @returns The object at @a a_idx, NULL if out of range.
     822     * @param   a_idx           The array index.
     823     */
     824    ElementType *at(size_t a_idx)
     825    {
     826        if (a_idx < m_cElements)
     827            return (ElementType *)m_papElements[a_idx];
     828        return NULL;
     829    }
     830
     831    /**
     832     * Returns the object at a given index, const variant.
     833     *
     834     * @returns The object at @a a_idx, NULL if out of range.
     835     * @param   a_idx           The array index.
     836     */
     837    ElementType const *at(size_t a_idx) const
     838    {
     839        if (a_idx < m_cElements)
     840            return (ElementType const *)m_papElements[a_idx];
     841        return NULL;
     842    }
     843
     844    /**
     845     * Returns the first object in the array.
     846     * @returns The first object, NULL if empty.
     847     */
     848    ElementType *first(size_t a_idx)
     849    {
     850        return at(0);
     851    }
     852
     853    /**
     854     * Returns the first object in the array, const variant.
     855     * @returns The first object, NULL if empty.
     856     */
     857    ElementType const *first(size_t a_idx) const
     858    {
     859        return at(0);
     860    }
     861
     862    /**
     863     * Returns the last object in the array.
     864     * @returns The last object, NULL if empty.
     865     */
     866    ElementType *last(size_t a_idx)
     867    {
     868        return at(m_cElements - 1);
     869    }
     870
     871    /**
     872     * Returns the last object in the array, const variant.
     873     * @returns The last object, NULL if empty.
     874     */
     875    ElementType const *last(size_t a_idx) const
     876    {
     877        return at(m_cElements - 1);
     878    }
     879
     880
     881protected:
     882    virtual RTCRestObjectBase *createValue(void) RT_OVERRIDE
     883    {
     884        return new (std::nothrow) ElementType();
     885    }
     886
     887    virtual RTCRestObjectBase *createValueCopy(RTCRestObjectBase const *a_pSrc) RT_OVERRIDE
     888    {
     889        return new (std::nothrow) ElementType(*(ElementType const *)a_pSrc);
    603890    }
    604891};
     
    625912    virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    626913    // later?
    627     //virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_OVERRIDE;
     914    //virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_OVERRIDE;
    628915    //virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    629916    //                       uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
     
    9451232    virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    9461233    virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    947     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_OVERRIDE;
     1234    virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_OVERRIDE;
    9481235    virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    9491236                           uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
  • trunk/include/iprt/json.h

    r73930 r73956  
    281281
    282282/**
     283 * Creates an iterator for a given JSON array value.
     284 *
     285 * @returns IPRT status code.
     286 * @retval  VERR_JSON_VALUE_INVALID_TYPE if the JSON value is not an array.
     287 * @param   hJsonVal        The JSON value handle.
     288 * @param   phJsonIt        Where to store the JSON iterator handle on success.
     289 */
     290RTDECL(int) RTJsonIteratorBeginArray(RTJSONVAL hJsonVal, PRTJSONIT phJsonIt);
     291
     292/**
     293 * Creates an iterator for a given JSON object value.
     294 *
     295 * @returns IPRT status code.
     296 * @retval  VERR_JSON_VALUE_INVALID_TYPE if the JSON value is not an object.
     297 * @param   hJsonVal        The JSON value handle.
     298 * @param   phJsonIt        Where to store the JSON iterator handle on success.
     299 */
     300RTDECL(int) RTJsonIteratorBeginObject(RTJSONVAL hJsonVal, PRTJSONIT phJsonIt);
     301
     302/**
    283303 * Gets the value and optional name for the current iterator position.
    284304 *
  • trunk/include/iprt/mangling.h

    r73874 r73956  
    11021102# define RTIniFileQueryValue                            RT_MANGLER(RTIniFileQueryValue)
    11031103# define RTJsonIteratorBegin                            RT_MANGLER(RTJsonIteratorBegin)
     1104# define RTJsonIteratorBeginArray                       RT_MANGLER(RTJsonIteratorBeginArray)
     1105# define RTJsonIteratorBeginObject                      RT_MANGLER(RTJsonIteratorBeginObject)
    11041106# define RTJsonIteratorFree                             RT_MANGLER(RTJsonIteratorFree)
    11051107# define RTJsonIteratorNext                             RT_MANGLER(RTJsonIteratorNext)
  • trunk/src/VBox/Runtime/Makefile.kmk

    r73949 r73956  
    16531653        generic/http-curl.cpp \
    16541654        common/rest/rest-primary-object-types.cpp \
     1655        common/rest/RTCRestArrayBase.cpp \
    16551656        common/rest/RTCRestClientApiBase.cpp \
    16561657        common/rest/RTCRestClientRequestBase.cpp \
  • trunk/src/VBox/Runtime/common/misc/json.cpp

    r73930 r73956  
    14861486}
    14871487
     1488static int rtJsonIteratorBeginWorker(PRTJSONVALINT pThis, PRTJSONIT phJsonIt)
     1489{
     1490    PRTJSONITINT pIt = (PRTJSONITINT)RTMemTmpAllocZ(sizeof(RTJSONITINT));
     1491    if (pIt)
     1492    {
     1493        RTJsonValueRetain(pThis);
     1494        pIt->pJsonVal = pThis;
     1495        pIt->idxCur = 0;
     1496
     1497        *phJsonIt = pIt;
     1498        return VINF_SUCCESS;
     1499    }
     1500    return VERR_NO_MEMORY;
     1501}
     1502
    14881503RTDECL(int) RTJsonIteratorBegin(RTJSONVAL hJsonVal, PRTJSONIT phJsonIt)
    14891504{
     
    14911506    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
    14921507    AssertPtrReturn(phJsonIt, VERR_INVALID_POINTER);
    1493 
    14941508    RTJSON_TYPECHECK_CONTAINER_RETURN(pThis);
    14951509
    1496     PRTJSONITINT pIt = (PRTJSONITINT)RTMemTmpAllocZ(sizeof(RTJSONITINT));
    1497     if (RT_UNLIKELY(!pIt))
    1498         return VERR_NO_MEMORY;
    1499 
    1500     RTJsonValueRetain(hJsonVal);
    1501     pIt->pJsonVal = pThis;
    1502     pIt->idxCur = 0;
    1503     *phJsonIt = pIt;
    1504 
    1505     return VINF_SUCCESS;
     1510    return rtJsonIteratorBeginWorker(pThis, phJsonIt);
     1511}
     1512
     1513RTDECL(int) RTJsonIteratorBeginArray(RTJSONVAL hJsonVal, PRTJSONIT phJsonIt)
     1514{
     1515    PRTJSONVALINT pThis = hJsonVal;
     1516    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     1517    AssertPtrReturn(phJsonIt, VERR_INVALID_POINTER);
     1518    RTJSON_TYPECHECK_RETURN(pThis, RTJSONVALTYPE_ARRAY);
     1519
     1520    return rtJsonIteratorBeginWorker(pThis, phJsonIt);
     1521}
     1522
     1523RTDECL(int) RTJsonIteratorBeginObject(RTJSONVAL hJsonVal, PRTJSONIT phJsonIt)
     1524{
     1525    PRTJSONVALINT pThis = hJsonVal;
     1526    AssertPtrReturn(pThis, VERR_INVALID_HANDLE);
     1527    AssertPtrReturn(phJsonIt, VERR_INVALID_POINTER);
     1528    RTJSON_TYPECHECK_RETURN(pThis, RTJSONVALTYPE_OBJECT);
     1529
     1530    return rtJsonIteratorBeginWorker(pThis, phJsonIt);
    15061531}
    15071532
  • trunk/src/VBox/Runtime/common/rest/RTCRestOutputToString.cpp

    r73879 r73956  
    3535
    3636
    37 RTCRestOutputToString::RTCRestOutputToString(RTCString *a_pDst)
     37RTCRestOutputToString::RTCRestOutputToString(RTCString *a_pDst, bool a_fAppend /*= false*/)
    3838    : m_pDst(a_pDst)
    3939    , m_fOutOfMemory(false)
    4040{
     41    if (!a_fAppend)
     42        m_pDst->setNull();
    4143}
    4244
  • trunk/src/VBox/Runtime/common/rest/RTCRestStringMapBase.cpp

    r73951 r73956  
    115115     */
    116116    RTJSONIT hIterator;
    117     int rcRet = RTJsonIteratorBegin(a_rCursor.m_hValue, &hIterator);
     117    int rcRet = RTJsonIteratorBeginObject(a_rCursor.m_hValue, &hIterator);
    118118    if (RT_SUCCESS(rcRet))
    119119    {
     
    176176        rcRet = a_rCursor.m_pPrimary->addError(a_rCursor, rcRet, "RTJsonIteratorBegin failed: %Rrc", rcRet);
    177177    return rcRet;
    178 
    179178}
    180179
    181180// later?
    182 //    virtual int RTCRestStringMapBase::toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const ;
     181//    virtual int RTCRestStringMapBase::toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const ;
    183182//    virtual int RTCRestStringMapBase::fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    184183//                           uint32_t a_fFlags = kCollectionFormat_Unspecified) ;
  • trunk/src/VBox/Runtime/common/rest/rest-primary-object-types.cpp

    r73933 r73956  
    5959int RTCRestObjectBase::toString(RTCString *a_pDst, uint32_t a_fFlags /*= kCollectionFormat_Unspecified*/) const
    6060{
    61     Assert(a_fFlags == kCollectionFormat_Unspecified); RT_NOREF(a_fFlags);
    62 
    6361    /*
    6462     * Just wrap the JSON serialization method.
    6563     */
    66     RTCRestOutputToString Tmp(a_pDst);
     64    RTCRestOutputToString Tmp(a_pDst, RT_BOOL(a_fFlags & kToString_Append));
    6765    serializeAsJson(Tmp);
    6866    return Tmp.finalize() ? VINF_SUCCESS : VERR_NO_MEMORY;
     
    8179                                  uint32_t a_fFlags /*= kCollectionFormat_Unspecified*/)
    8280{
    83     Assert(a_fFlags == kCollectionFormat_Unspecified); RT_NOREF(a_fFlags);
     81    RT_NOREF(a_fFlags);
    8482
    8583    /*
     
    185183int RTCRestBool::toString(RTCString *a_pDst, uint32_t a_fFlags /*= kCollectionFormat_Unspecified*/) const
    186184{
    187     Assert(a_fFlags == 0); RT_NOREF(a_fFlags);
    188 
     185    if (!(a_fFlags & kToString_Append))
     186    {
     187        if (m_fValue)
     188            return a_pDst->assignNoThrow(RT_STR_TUPLE("true"));
     189        return a_pDst->assignNoThrow(RT_STR_TUPLE("false"));
     190    }
    189191    if (m_fValue)
    190         return a_pDst->assignNoThrow(RT_STR_TUPLE("true"));
    191     return a_pDst->assignNoThrow(RT_STR_TUPLE("false"));
     192        return a_pDst->appendNoThrow(RT_STR_TUPLE("true"));
     193    return a_pDst->appendNoThrow(RT_STR_TUPLE("false"));
    192194}
    193195
     
    196198                            uint32_t a_fFlags /*= kCollectionFormat_Unspecified*/)
    197199{
    198     Assert(a_fFlags == 0); RT_NOREF(a_fFlags);
     200    RT_NOREF(a_fFlags);
     201
    199202    if (a_rValue.startsWithWord("true", RTCString::CaseInsensitive))
    200203        m_fValue = true;
     
    299302int RTCRestInt64::toString(RTCString *a_pDst, uint32_t a_fFlags /*= kCollectionFormat_Unspecified*/) const
    300303{
    301     Assert(a_fFlags == 0); RT_NOREF(a_fFlags);
    302 
    303     return a_pDst->printfNoThrow("%RI64", m_iValue);
     304    if (!(a_fFlags & kToString_Append))
     305        return a_pDst->printfNoThrow("%RI64", m_iValue);
     306    return a_pDst->appendPrintfNoThrow("%RI64", m_iValue);
    304307}
    305308
     
    308311                             uint32_t a_fFlags /*= kCollectionFormat_Unspecified*/)
    309312{
    310     Assert(a_fFlags == 0); RT_NOREF(a_fFlags);
     313    RT_NOREF(a_fFlags);
    311314
    312315    int rc = RTStrToInt64Full(RTStrStripL(a_rValue.c_str()), 10, &m_iValue);
     
    415418int RTCRestInt32::toString(RTCString *a_pDst, uint32_t a_fFlags /*= kCollectionFormat_Unspecified*/) const
    416419{
    417     Assert(a_fFlags == 0); RT_NOREF(a_fFlags);
    418 
    419     return a_pDst->printfNoThrow("%RI32", m_iValue);
     420    if (!(a_fFlags & kToString_Append))
     421        return a_pDst->printfNoThrow("%RI32", m_iValue);
     422    return a_pDst->appendPrintfNoThrow("%RI32", m_iValue);
    420423}
    421424
     
    424427                             uint32_t a_fFlags /*= kCollectionFormat_Unspecified*/)
    425428{
    426     Assert(a_fFlags == 0); RT_NOREF(a_fFlags);
     429    RT_NOREF(a_fFlags);
    427430
    428431    int rc = RTStrToInt32Full(RTStrStripL(a_rValue.c_str()), 10, &m_iValue);
     
    531534int RTCRestInt16::toString(RTCString *a_pDst, uint32_t a_fFlags /*= kCollectionFormat_Unspecified*/) const
    532535{
    533     Assert(a_fFlags == 0); RT_NOREF(a_fFlags);
    534 
    535     return a_pDst->printfNoThrow("%RI16", m_iValue);
     536    if (!(a_fFlags & kToString_Append))
     537        return a_pDst->printfNoThrow("%RI16", m_iValue);
     538    return a_pDst->appendPrintfNoThrow("%RI16", m_iValue);
    536539}
    537540
     
    540543                             uint32_t a_fFlags /*= kCollectionFormat_Unspecified*/)
    541544{
    542     Assert(a_fFlags == 0); RT_NOREF(a_fFlags);
     545    RT_NOREF(a_fFlags);
    543546
    544547    int rc = RTStrToInt16Full(RTStrStripL(a_rValue.c_str()), 10, &m_iValue);
     
    626629int RTCRestDouble::toString(RTCString *a_pDst, uint32_t a_fFlags /*= kCollectionFormat_Unspecified*/) const
    627630{
    628     Assert(a_fFlags == 0); RT_NOREF(a_fFlags);
    629 
    630631    /* Just a simple approximation here. */
    631632    /** @todo implement floating point values for json. */
     
    638639    size_t const cchValue = strlen(szValue);
    639640
    640     return a_pDst->assignNoThrow(szValue, cchValue);
     641    if (!(a_fFlags & kToString_Append))
     642        return a_pDst->assignNoThrow(szValue, cchValue);
     643    return a_pDst->appendNoThrow(szValue, cchValue);
    641644}
    642645
     
    645648                              uint32_t a_fFlags /*= kCollectionFormat_Unspecified*/)
    646649{
    647     Assert(a_fFlags == 0); RT_NOREF(a_fFlags);
     650    RT_NOREF(a_fFlags);
    648651
    649652    const char *pszValue = RTStrStripL(a_rValue.c_str());
     
    751754int RTCRestString::toString(RTCString *a_pDst, uint32_t a_fFlags /*= kCollectionFormat_Unspecified*/) const
    752755{
    753     Assert(a_fFlags == 0); RT_NOREF(a_fFlags);
    754 
    755     return a_pDst->assignNoThrow(*this);
     756    if (!(a_fFlags & kToString_Append))
     757        return a_pDst->assignNoThrow(*this);
     758    return a_pDst->appendNoThrow(*this);
    756759}
    757760
     
    760763                              uint32_t a_fFlags /*= kCollectionFormat_Unspecified*/)
    761764{
    762     Assert(a_fFlags == 0); RT_NOREF(a_fFlags);
    763     RT_NOREF(a_pszName); RT_NOREF(a_pErrInfo);
     765    RT_NOREF(a_fFlags); RT_NOREF(a_pszName); RT_NOREF(a_pErrInfo);
    764766
    765767    return assignNoThrow(a_rValue);
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