VirtualBox

Changeset 74008 in vbox for trunk/src/VBox/Runtime


Ignore:
Timestamp:
Aug 31, 2018 7:08:02 PM (6 years ago)
Author:
vboxsync
Message:

IPRT/rest: Deal (more) properly with 'null'. bugref:9167

Location:
trunk/src/VBox/Runtime/common/rest
Files:
3 edited

Legend:

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

    r73995 r74008  
    8888    /* The default state of an array is empty. At least for now. */
    8989    clear();
     90    m_fNullIndicator = false;
    9091    return VINF_SUCCESS;
    9192}
     
    9495RTCRestOutputBase &RTCRestArrayBase::serializeAsJson(RTCRestOutputBase &a_rDst) const
    9596{
    96     a_rDst.printf("[\n");
    97     unsigned const uOldIndent = a_rDst.incrementIndent();
    98 
    99     for (size_t i = 0; i < m_cElements; i++)
    100     {
    101         m_papElements[i]->serializeAsJson(a_rDst);
    102         if (i < m_cElements)
    103             a_rDst.printf(",\n");
    104         else
    105             a_rDst.printf("\n");
    106     }
    107 
    108     a_rDst.setIndent(uOldIndent);
    109     a_rDst.printf("]");
     97    if (!m_fNullIndicator)
     98    {
     99        a_rDst.printf("[\n");
     100        unsigned const uOldIndent = a_rDst.incrementIndent();
     101
     102        for (size_t i = 0; i < m_cElements; i++)
     103        {
     104            m_papElements[i]->serializeAsJson(a_rDst);
     105            if (i < m_cElements)
     106                a_rDst.printf(",\n");
     107            else
     108                a_rDst.printf("\n");
     109        }
     110
     111        a_rDst.setIndent(uOldIndent);
     112        a_rDst.printf("]");
     113    }
     114    else
     115        a_rDst.printf("null");
    110116    return a_rDst;
    111117}
     
    119125    if (m_cElements > 0)
    120126        clear();
     127    m_fNullIndicator = false;
    121128
    122129    /*
     
    179186        RTJsonIteratorFree(hIterator);
    180187    }
    181     else if (   rcRet == VERR_JSON_IS_EMPTY
    182              || (   rcRet == VERR_JSON_VALUE_INVALID_TYPE
    183                  && RTJsonValueGetType(a_rCursor.m_hValue) == RTJSONVALTYPE_NULL) )
     188    else if (rcRet == VERR_JSON_IS_EMPTY)
    184189        rcRet = VINF_SUCCESS;
     190    else if (   rcRet == VERR_JSON_VALUE_INVALID_TYPE
     191             && RTJsonValueGetType(a_rCursor.m_hValue) == RTJSONVALTYPE_NULL)
     192    {
     193        m_fNullIndicator = true;
     194        rcRet = VINF_SUCCESS;
     195    }
    185196    else
    186197        rcRet = a_rCursor.m_pPrimary->addError(a_rCursor, rcRet,
     
    195206{
    196207    int rc;
    197     if (m_cElements)
    198     {
    199         static char const s_szSep[kCollectionFormat_Mask + 1] = ",, \t|,,";
    200         char const chSep = s_szSep[a_fFlags & kCollectionFormat_Mask];
    201 
    202         rc = m_papElements[0]->toString(a_pDst, a_fFlags);
    203         for (size_t i = 1; RT_SUCCESS(rc) && i < m_cElements; i++)
    204         {
    205             rc = a_pDst->appendNoThrow(chSep);
    206             if (RT_SUCCESS(rc))
    207                 rc = m_papElements[i]->toString(a_pDst, a_fFlags | kToString_Append);
    208         }
    209     }
     208    if (!m_fNullIndicator)
     209    {
     210        if (m_cElements)
     211        {
     212            static char const s_szSep[kCollectionFormat_Mask + 1] = ",, \t|,,";
     213            char const chSep = s_szSep[a_fFlags & kCollectionFormat_Mask];
     214
     215            rc = m_papElements[0]->toString(a_pDst, a_fFlags);
     216            for (size_t i = 1; RT_SUCCESS(rc) && i < m_cElements; i++)
     217            {
     218                rc = a_pDst->appendNoThrow(chSep);
     219                if (RT_SUCCESS(rc))
     220                    rc = m_papElements[i]->toString(a_pDst, a_fFlags | kToString_Append);
     221            }
     222        }
     223        else
     224        {
     225            if (!(a_fFlags & kToString_Append))
     226                a_pDst->setNull();
     227            rc = VINF_SUCCESS;
     228        }
     229    }
     230    else if (a_fFlags & kToString_Append)
     231        rc = a_pDst->appendNoThrow(RT_STR_TUPLE("null"));
    210232    else
    211     {
    212         a_pDst->setNull();
    213         rc = VINF_SUCCESS;
    214     }
     233        rc = a_pDst->appendNoThrow(RT_STR_TUPLE("null"));
     234
    215235    return rc;
    216236}
     
    239259    }
    240260    m_cElements = 0;
     261    m_fNullIndicator = false;
    241262}
    242263
     
    291312    clear();
    292313    if (a_rThat.m_cElements == 0)
     314    {
     315        m_fNullIndicator = a_rThat.m_fNullIndicator;
    293316        rc = VINF_SUCCESS;
     317    }
    294318    else
    295319    {
     320        Assert(!a_rThat.m_fNullIndicator);
    296321        rc = ensureCapacity(a_rThat.m_cElements);
    297322        if (RT_SUCCESS(rc))
     
    346371                AssertPtr(m_papElements[i]);
    347372#endif
     373            m_fNullIndicator = false;
    348374            return VINF_SUCCESS;
    349375        }
     
    352378        delete m_papElements[a_idx];
    353379        m_papElements[a_idx] = a_pValue;
     380        m_fNullIndicator = false;
    354381        return VWRN_ALREADY_EXISTS;
    355382    }
  • trunk/src/VBox/Runtime/common/rest/RTCRestStringMapBase.cpp

    r73995 r74008  
    4040 */
    4141RTCRestStringMapBase::RTCRestStringMapBase()
    42     : m_Map(NULL)
     42    : RTCRestObjectBase()
     43    , m_Map(NULL)
    4344    , m_cEntries(0)
    4445{
     
    7778    /* Default is an empty map. */
    7879    clear();
     80    m_fNullIndicator = false;
    7981    return VINF_SUCCESS;
    8082}
     
    8385RTCRestOutputBase &RTCRestStringMapBase::serializeAsJson(RTCRestOutputBase &a_rDst) const
    8486{
    85     a_rDst.printf("{\n");
    86     unsigned const uOldIndent = a_rDst.incrementIndent();
    87 
    88     MapEntry const * const pLast = RTListGetLastCpp(&m_ListHead, MapEntry, ListEntry);
    89     MapEntry const * pCur;
    90     RTListForEachCpp(&m_ListHead, pCur, MapEntry, ListEntry)
    91     {
    92         a_rDst.printf("%RJs: ", pCur->strKey.c_str());
    93         pCur->pValue->serializeAsJson(a_rDst);
    94 
    95         if (pCur != pLast)
    96             a_rDst.printf(",\n");
    97         else
    98             a_rDst.printf("\n");
    99     }
    100 
    101     a_rDst.setIndent(uOldIndent);
    102     a_rDst.printf("}");
     87    if (!m_fNullIndicator)
     88    {
     89        a_rDst.printf("{\n");
     90        unsigned const uOldIndent = a_rDst.incrementIndent();
     91
     92        MapEntry const * const pLast = RTListGetLastCpp(&m_ListHead, MapEntry, ListEntry);
     93        MapEntry const * pCur;
     94        RTListForEachCpp(&m_ListHead, pCur, MapEntry, ListEntry)
     95        {
     96            a_rDst.printf("%RJs: ", pCur->strKey.c_str());
     97            pCur->pValue->serializeAsJson(a_rDst);
     98
     99            if (pCur != pLast)
     100                a_rDst.printf(",\n");
     101            else
     102                a_rDst.printf("\n");
     103        }
     104
     105        a_rDst.setIndent(uOldIndent);
     106        a_rDst.printf("}");
     107    }
     108    else
     109        a_rDst.printf("null");
    103110    return a_rDst;
    104111}
     
    112119    if (m_cEntries > 0)
    113120        clear();
     121    m_fNullIndicator = false;
    114122
    115123    /*
     
    175183        RTJsonIteratorFree(hIterator);
    176184    }
    177     else if (   rcRet == VERR_JSON_IS_EMPTY
    178              || (   rcRet == VERR_JSON_VALUE_INVALID_TYPE
    179                  && RTJsonValueGetType(a_rCursor.m_hValue) == RTJSONVALTYPE_NULL) )
     185    else if (rcRet == VERR_JSON_IS_EMPTY)
    180186        rcRet = VINF_SUCCESS;
     187    else if (   rcRet == VERR_JSON_VALUE_INVALID_TYPE
     188             && RTJsonValueGetType(a_rCursor.m_hValue) == RTJSONVALTYPE_NULL)
     189    {
     190        m_fNullIndicator = true;
     191        rcRet = VINF_SUCCESS;
     192    }
    181193    else
    182194        rcRet = a_rCursor.m_pPrimary->addError(a_rCursor, rcRet, "RTJsonIteratorBegin failed: %Rrc (type %s)",
     
    220232    RTListInit(&m_ListHead);
    221233    m_cEntries = 0;
     234    m_fNullIndicator = false;
    222235}
    223236
     
    267280    Assert(this != &a_rThat);
    268281    clear();
    269 
    270     MapEntry const *pCur;
    271     RTListForEachCpp(&a_rThat.m_ListHead, pCur, MapEntry, ListEntry)
    272     {
    273         int rc = putCopyWorker(pCur->strKey.c_str(), *pCur->pValue, true /*a_fReplace*/);
    274         if (RT_SUCCESS(rc))
    275         { /* likely */ }
    276         else if (a_fThrow)
    277             throw std::bad_alloc();
    278         else
    279             return rc;
     282    m_fNullIndicator = a_rThat.m_fNullIndicator;
     283
     284    if (!a_rThat.m_fNullIndicator)
     285    {
     286        MapEntry const *pCur;
     287        RTListForEachCpp(&a_rThat.m_ListHead, pCur, MapEntry, ListEntry)
     288        {
     289            int rc = putCopyWorker(pCur->strKey.c_str(), *pCur->pValue, true /*a_fReplace*/);
     290            if (RT_SUCCESS(rc))
     291            { /* likely */ }
     292            else if (a_fThrow)
     293                throw std::bad_alloc();
     294            else
     295                return rc;
     296        }
    280297    }
    281298
     
    299316            {
    300317                m_cEntries++;
     318                m_fNullIndicator = false;
    301319                return VINF_SUCCESS;
    302320            }
    303321
     322            Assert(!m_fNullIndicator);
    304323            if (!a_fReplace)
    305324                rc = VERR_ALREADY_EXISTS;
  • trunk/src/VBox/Runtime/common/rest/rest-primary-object-types.cpp

    r73977 r74008  
    4747/** Default constructor. */
    4848RTCRestObjectBase::RTCRestObjectBase()
     49    : m_fNullIndicator(false)
     50{
     51}
     52
     53
     54/** Copy constructor. */
     55RTCRestObjectBase::RTCRestObjectBase(RTCRestObjectBase const &a_rThat)
     56    : m_fNullIndicator(a_rThat.m_fNullIndicator)
    4957{
    5058}
     
    5563{
    5664    /* nothing to do */
     65}
     66
     67
     68int RTCRestObjectBase::setNull()
     69{
     70    int rc = resetToDefault();
     71    m_fNullIndicator = true;
     72    return rc;
     73}
     74
     75
     76void RTCRestObjectBase::setNotNull()
     77{
     78    m_fNullIndicator = false;
    5779}
    5880
     
    107129
    108130
    109 /** Default destructor. */
     131/** Default constructor. */
    110132RTCRestBool::RTCRestBool()
    111     : m_fValue(false)
     133    : RTCRestObjectBase()
     134    , m_fValue(false)
    112135{
    113136}
     
    139162RTCRestBool &RTCRestBool::operator=(RTCRestBool const &a_rThat)
    140163{
     164    m_fNullIndicator = a_rThat.m_fNullIndicator;
    141165    m_fValue = a_rThat.m_fValue;
    142166    return *this;
     
    146170int RTCRestBool::assignCopy(RTCRestBool const &a_rThat)
    147171{
     172    m_fNullIndicator = a_rThat.m_fNullIndicator;
    148173    m_fValue = a_rThat.m_fValue;
    149174    return VINF_SUCCESS;
     
    154179{
    155180    m_fValue = false;
     181    m_fNullIndicator = false;
    156182    return VINF_SUCCESS;
    157183}
     
    160186RTCRestOutputBase &RTCRestBool::serializeAsJson(RTCRestOutputBase &a_rDst) const
    161187{
    162     a_rDst.printf(m_fValue ? "true" : "false");
     188    a_rDst.printf(!m_fNullIndicator ? m_fValue ? "true" : "false" : "null");
    163189    return a_rDst;
    164190}
     
    172198    {
    173199        m_fValue = true;
     200        m_fNullIndicator = false;
    174201        return VINF_SUCCESS;
    175202    }
     
    178205    {
    179206        m_fValue = false;
    180         return VINF_SUCCESS;
    181     }
    182 
    183     /* This is probably non-sense... */
     207        m_fNullIndicator = false;
     208        return VINF_SUCCESS;
     209    }
     210
    184211    if (enmType == RTJSONVALTYPE_NULL)
     212    {
    185213        m_fValue = false;
     214        m_fNullIndicator = true;
     215        return VINF_SUCCESS;
     216    }
    186217
    187218    return a_rCursor.m_pPrimary->addError(a_rCursor, VERR_WRONG_TYPE, "wrong JSON type %s for boolean",
     
    194225    if (!(a_fFlags & kToString_Append))
    195226    {
     227        if (!m_fNullIndicator)
     228        {
     229            if (m_fValue)
     230                return a_pDst->assignNoThrow(RT_STR_TUPLE("true"));
     231            return a_pDst->assignNoThrow(RT_STR_TUPLE("false"));
     232        }
     233        return a_pDst->assignNoThrow(RT_STR_TUPLE("null"));
     234    }
     235
     236    if (!m_fNullIndicator)
     237    {
    196238        if (m_fValue)
    197             return a_pDst->assignNoThrow(RT_STR_TUPLE("true"));
    198         return a_pDst->assignNoThrow(RT_STR_TUPLE("false"));
    199     }
    200     if (m_fValue)
    201         return a_pDst->appendNoThrow(RT_STR_TUPLE("true"));
    202     return a_pDst->appendNoThrow(RT_STR_TUPLE("false"));
     239            return a_pDst->appendNoThrow(RT_STR_TUPLE("true"));
     240        return a_pDst->appendNoThrow(RT_STR_TUPLE("false"));
     241    }
     242    return a_pDst->appendNoThrow(RT_STR_TUPLE("null"));
    203243}
    204244
     
    210250
    211251    if (a_rValue.startsWithWord("true", RTCString::CaseInsensitive))
     252    {
    212253        m_fValue = true;
     254        m_fNullIndicator = false;
     255    }
    213256    else if (a_rValue.startsWithWord("false", RTCString::CaseInsensitive))
     257    {
    214258        m_fValue = false;
     259        m_fNullIndicator = false;
     260    }
     261    else if (a_rValue.startsWithWord("null", RTCString::CaseInsensitive))
     262    {
     263        m_fValue = false;
     264        m_fNullIndicator = true;
     265    }
    215266    else
    216267        return RTErrInfoSetF(a_pErrInfo, VERR_INVALID_PARAMETER, "%s: unable to parse '%s' as bool", a_pszName, a_rValue.c_str());
     
    239290/** Default destructor. */
    240291RTCRestInt64::RTCRestInt64()
    241     : m_iValue(0)
     292    : RTCRestObjectBase()
     293    , m_iValue(0)
    242294{
    243295}
     
    254306/** From value constructor. */
    255307RTCRestInt64::RTCRestInt64(int64_t iValue)
    256     : m_iValue(iValue)
     308    : RTCRestObjectBase()
     309    , m_iValue(iValue)
    257310{
    258311}
     
    269322RTCRestInt64 &RTCRestInt64::operator=(RTCRestInt64 const &a_rThat)
    270323{
     324    m_fNullIndicator = a_rThat.m_fNullIndicator;
    271325    m_iValue = a_rThat.m_iValue;
    272326    return *this;
     
    276330int RTCRestInt64::assignCopy(RTCRestInt64 const &a_rThat)
    277331{
     332    m_fNullIndicator = a_rThat.m_fNullIndicator;
    278333    m_iValue = a_rThat.m_iValue;
    279334    return VINF_SUCCESS;
     
    284339{
    285340    m_iValue = 0;
     341    m_fNullIndicator = false;
    286342    return VINF_SUCCESS;
    287343}
     
    290346RTCRestOutputBase &RTCRestInt64::serializeAsJson(RTCRestOutputBase &a_rDst) const
    291347{
    292     a_rDst.printf("%RI64", m_iValue);
     348    if (!m_fNullIndicator)
     349        a_rDst.printf("%RI64", m_iValue);
     350    else
     351        a_rDst.printf("null");
    293352    return a_rDst;
    294353}
     
    297356int RTCRestInt64::deserializeFromJson(RTCRestJsonCursor const &a_rCursor)
    298357{
     358    m_iValue = 0;
     359    m_fNullIndicator = false;
     360
    299361    RTJSONVALTYPE enmType = RTJsonValueGetType(a_rCursor.m_hValue);
    300362    if (enmType == RTJSONVALTYPE_NUMBER)
     
    306368    }
    307369
     370    if (enmType == RTJSONVALTYPE_NULL)
     371    {
     372        m_fNullIndicator = true;
     373        return VINF_SUCCESS;
     374    }
     375
    308376    /* This is probably non-sense... */
    309     if (enmType == RTJSONVALTYPE_NULL || enmType == RTJSONVALTYPE_FALSE)
    310         m_iValue = 0;
    311     else if (enmType == RTJSONVALTYPE_TRUE)
     377    if (enmType == RTJSONVALTYPE_TRUE)
    312378        m_iValue = 1;
    313379
     
    320386{
    321387    if (!(a_fFlags & kToString_Append))
    322         return a_pDst->printfNoThrow("%RI64", m_iValue);
    323     return a_pDst->appendPrintfNoThrow("%RI64", m_iValue);
     388    {
     389        if (!m_fNullIndicator)
     390            return a_pDst->printfNoThrow("%RI64", m_iValue);
     391        return a_pDst->assignNoThrow(RT_STR_TUPLE("null"));
     392    }
     393    if (!m_fNullIndicator)
     394        return a_pDst->appendPrintfNoThrow("%RI64", m_iValue);
     395    return a_pDst->appendNoThrow(RT_STR_TUPLE("null"));
    324396}
    325397
     
    330402    RT_NOREF(a_fFlags);
    331403
     404    m_iValue = 0;
     405    m_fNullIndicator = false;
     406
    332407    int rc = RTStrToInt64Full(RTStrStripL(a_rValue.c_str()), 10, &m_iValue);
    333408    if (rc == VINF_SUCCESS || rc == VERR_TRAILING_SPACES)
    334409        return VINF_SUCCESS;
     410
     411    if (a_rValue.startsWithWord("null", RTCString::CaseInsensitive))
     412    {
     413        m_iValue = 0;
     414        m_fNullIndicator = true;
     415        return VINF_SUCCESS;
     416    }
     417
    335418    return RTErrInfoSetF(a_pErrInfo, rc, "%s: error %Rrc parsing '%s' as int64_t", a_pszName, rc, a_rValue.c_str());
    336419}
     
    357440/** Default destructor. */
    358441RTCRestInt32::RTCRestInt32()
    359     : m_iValue(0)
     442    : RTCRestObjectBase()
     443    , m_iValue(0)
    360444{
    361445}
     
    372456/** From value constructor. */
    373457RTCRestInt32::RTCRestInt32(int32_t iValue)
    374     : m_iValue(iValue)
     458    : RTCRestObjectBase()
     459    , m_iValue(iValue)
    375460{
    376461}
     
    387472RTCRestInt32 &RTCRestInt32::operator=(RTCRestInt32 const &a_rThat)
    388473{
     474    m_fNullIndicator = a_rThat.m_fNullIndicator;
    389475    m_iValue = a_rThat.m_iValue;
    390476    return *this;
     
    394480int RTCRestInt32::assignCopy(RTCRestInt32 const &a_rThat)
    395481{
     482    m_fNullIndicator = a_rThat.m_fNullIndicator;
    396483    m_iValue = a_rThat.m_iValue;
    397484    return VINF_SUCCESS;
     
    402489{
    403490    m_iValue = 0;
     491    m_fNullIndicator = false;
    404492    return VINF_SUCCESS;
    405493}
     
    408496RTCRestOutputBase &RTCRestInt32::serializeAsJson(RTCRestOutputBase &a_rDst) const
    409497{
    410     a_rDst.printf("%RI32", m_iValue);
     498    if (!m_fNullIndicator)
     499        a_rDst.printf("%RI32", m_iValue);
     500    else
     501        a_rDst.printf("null");
    411502    return a_rDst;
    412503}
     
    415506int RTCRestInt32::deserializeFromJson(RTCRestJsonCursor const &a_rCursor)
    416507{
     508    m_iValue = 0;
     509    m_fNullIndicator = false;
     510
    417511    RTJSONVALTYPE enmType = RTJsonValueGetType(a_rCursor.m_hValue);
    418512    if (enmType == RTJSONVALTYPE_NUMBER)
     
    430524    }
    431525
     526    if (enmType == RTJSONVALTYPE_NULL)
     527    {
     528        m_fNullIndicator = true;
     529        return VINF_SUCCESS;
     530    }
     531
    432532    /* This is probably non-sense... */
    433     if (enmType == RTJSONVALTYPE_NULL || enmType == RTJSONVALTYPE_FALSE)
    434         m_iValue = 0;
    435     else if (enmType == RTJSONVALTYPE_TRUE)
     533    if (enmType == RTJSONVALTYPE_TRUE)
    436534        m_iValue = 1;
    437535
     
    444542{
    445543    if (!(a_fFlags & kToString_Append))
    446         return a_pDst->printfNoThrow("%RI32", m_iValue);
    447     return a_pDst->appendPrintfNoThrow("%RI32", m_iValue);
     544    {
     545        if (!m_fNullIndicator)
     546            return a_pDst->printfNoThrow("%RI32", m_iValue);
     547        return a_pDst->assignNoThrow(RT_STR_TUPLE("null"));
     548    }
     549    if (!m_fNullIndicator)
     550        return a_pDst->appendPrintfNoThrow("%RI32", m_iValue);
     551    return a_pDst->appendNoThrow(RT_STR_TUPLE("null"));
    448552}
    449553
     
    454558    RT_NOREF(a_fFlags);
    455559
     560    m_iValue = 0;
     561    m_fNullIndicator = false;
     562
    456563    int rc = RTStrToInt32Full(RTStrStripL(a_rValue.c_str()), 10, &m_iValue);
    457564    if (rc == VINF_SUCCESS || rc == VERR_TRAILING_SPACES)
    458565        return VINF_SUCCESS;
     566
     567    if (a_rValue.startsWithWord("null", RTCString::CaseInsensitive))
     568    {
     569        m_iValue = 0;
     570        m_fNullIndicator = true;
     571        return VINF_SUCCESS;
     572    }
     573
    459574    return RTErrInfoSetF(a_pErrInfo, rc, "%s: error %Rrc parsing '%s' as int32_t", a_pszName, rc, a_rValue.c_str());
    460575}
     
    481596/** Default destructor. */
    482597RTCRestInt16::RTCRestInt16()
    483     : m_iValue(0)
     598    : RTCRestObjectBase()
     599    , m_iValue(0)
    484600{
    485601}
     
    496612/** From value constructor. */
    497613RTCRestInt16::RTCRestInt16(int16_t iValue)
    498     : m_iValue(iValue)
     614    : RTCRestObjectBase()
     615    , m_iValue(iValue)
    499616{
    500617}
     
    511628RTCRestInt16 &RTCRestInt16::operator=(RTCRestInt16 const &a_rThat)
    512629{
     630    m_fNullIndicator = a_rThat.m_fNullIndicator;
    513631    m_iValue = a_rThat.m_iValue;
    514632    return *this;
     
    518636int RTCRestInt16::assignCopy(RTCRestInt16 const &a_rThat)
    519637{
     638    m_fNullIndicator = a_rThat.m_fNullIndicator;
    520639    m_iValue = a_rThat.m_iValue;
    521640    return VINF_SUCCESS;
     
    526645{
    527646    m_iValue = 0;
     647    m_fNullIndicator = false;
    528648    return VINF_SUCCESS;
    529649}
     
    532652RTCRestOutputBase &RTCRestInt16::serializeAsJson(RTCRestOutputBase &a_rDst) const
    533653{
    534     a_rDst.printf("%RI16", m_iValue);
     654    if (!m_fNullIndicator)
     655        a_rDst.printf("%RI16", m_iValue);
     656    else
     657        a_rDst.printf("null");
    535658    return a_rDst;
    536659}
     
    539662int RTCRestInt16::deserializeFromJson(RTCRestJsonCursor const &a_rCursor)
    540663{
     664    m_iValue = 0;
     665    m_fNullIndicator = false;
     666
    541667    RTJSONVALTYPE enmType = RTJsonValueGetType(a_rCursor.m_hValue);
    542668    if (enmType == RTJSONVALTYPE_NUMBER)
     
    554680    }
    555681
     682    if (enmType == RTJSONVALTYPE_NULL)
     683    {
     684        m_fNullIndicator = true;
     685        return VINF_SUCCESS;
     686    }
     687
    556688    /* This is probably non-sense... */
    557     if (enmType == RTJSONVALTYPE_NULL || enmType == RTJSONVALTYPE_FALSE)
    558         m_iValue = 0;
    559     else if (enmType == RTJSONVALTYPE_TRUE)
     689    if (enmType == RTJSONVALTYPE_TRUE)
    560690        m_iValue = 1;
    561691
     
    568698{
    569699    if (!(a_fFlags & kToString_Append))
    570         return a_pDst->printfNoThrow("%RI16", m_iValue);
    571     return a_pDst->appendPrintfNoThrow("%RI16", m_iValue);
     700    {
     701        if (!m_fNullIndicator)
     702            return a_pDst->printfNoThrow("%RI16", m_iValue);
     703        return a_pDst->assignNoThrow(RT_STR_TUPLE("null"));
     704    }
     705    if (!m_fNullIndicator)
     706        return a_pDst->appendPrintfNoThrow("%RI16", m_iValue);
     707    return a_pDst->appendNoThrow(RT_STR_TUPLE("null"));
    572708}
    573709
     
    578714    RT_NOREF(a_fFlags);
    579715
     716    m_iValue = 0;
     717    m_fNullIndicator = false;
     718
    580719    int rc = RTStrToInt16Full(RTStrStripL(a_rValue.c_str()), 10, &m_iValue);
    581720    if (rc == VINF_SUCCESS || rc == VERR_TRAILING_SPACES)
    582721        return VINF_SUCCESS;
     722
     723    if (a_rValue.startsWithWord("null", RTCString::CaseInsensitive))
     724    {
     725        m_iValue = 0;
     726        m_fNullIndicator = true;
     727        return VINF_SUCCESS;
     728    }
     729
    583730    return RTErrInfoSetF(a_pErrInfo, rc, "%s: error %Rrc parsing '%s' as int16_t", a_pszName, rc, a_rValue.c_str());
    584731}
     
    604751/** Default destructor. */
    605752RTCRestDouble::RTCRestDouble()
    606     : m_rdValue(0.0)
     753    : RTCRestObjectBase()
     754    , m_rdValue(0.0)
    607755{
    608756}
     
    619767/** From value constructor. */
    620768RTCRestDouble::RTCRestDouble(double rdValue)
    621     : m_rdValue(rdValue)
     769    : RTCRestObjectBase()
     770    , m_rdValue(rdValue)
    622771{
    623772}
     
    634783RTCRestDouble &RTCRestDouble::operator=(RTCRestDouble const &a_rThat)
    635784{
     785    m_fNullIndicator = a_rThat.m_fNullIndicator;
    636786    m_rdValue = a_rThat.m_rdValue;
    637787    return *this;
     
    641791int RTCRestDouble::assignCopy(RTCRestDouble const &a_rThat)
    642792{
     793    m_fNullIndicator = a_rThat.m_fNullIndicator;
    643794    m_rdValue = a_rThat.m_rdValue;
    644795    return VINF_SUCCESS;
     
    649800{
    650801    m_rdValue = 0.0;
     802    m_fNullIndicator = false;
    651803    return VINF_SUCCESS;
    652804}
     
    655807RTCRestOutputBase &RTCRestDouble::serializeAsJson(RTCRestOutputBase &a_rDst) const
    656808{
    657     /* Just a simple approximation here. */
    658     /** @todo implement floating point values for json. */
    659     char szValue[128];
     809    if (!m_fNullIndicator)
     810    {
     811
     812        /* Just a simple approximation here. */
     813        /** @todo implement floating point values for json. */
     814        char szValue[128];
    660815#ifdef _MSC_VER
    661     _snprintf(szValue, sizeof(szValue), "%g", m_rdValue);
     816        _snprintf(szValue, sizeof(szValue), "%g", m_rdValue);
    662817#else
    663     snprintf(szValue, sizeof(szValue), "%g", m_rdValue);
     818        snprintf(szValue, sizeof(szValue), "%g", m_rdValue);
    664819#endif
    665     a_rDst.printf("%s", szValue);
     820        a_rDst.printf("%s", szValue);
     821    }
     822    else
     823        a_rDst.printf("null");
    666824    return a_rDst;
    667825}
     
    678836int RTCRestDouble::toString(RTCString *a_pDst, uint32_t a_fFlags /*= kCollectionFormat_Unspecified*/) const
    679837{
    680     /* Just a simple approximation here. */
    681     /** @todo implement floating point values for json. */
    682     char szValue[128];
     838    if (!m_fNullIndicator)
     839    {
     840        /* Just a simple approximation here. */
     841        /** @todo implement floating point values for json. */
     842        char szValue[128];
    683843#ifdef _MSC_VER
    684     _snprintf(szValue, sizeof(szValue), "%g", m_rdValue);
     844        _snprintf(szValue, sizeof(szValue), "%g", m_rdValue);
    685845#else
    686     snprintf(szValue, sizeof(szValue), "%g", m_rdValue);
     846        snprintf(szValue, sizeof(szValue), "%g", m_rdValue);
    687847#endif
    688     size_t const cchValue = strlen(szValue);
     848        size_t const cchValue = strlen(szValue);
     849
     850        if (!(a_fFlags & kToString_Append))
     851            return a_pDst->assignNoThrow(szValue, cchValue);
     852        return a_pDst->appendNoThrow(szValue, cchValue);
     853    }
    689854
    690855    if (!(a_fFlags & kToString_Append))
    691         return a_pDst->assignNoThrow(szValue, cchValue);
    692     return a_pDst->appendNoThrow(szValue, cchValue);
     856        return a_pDst->assignNoThrow(RT_STR_TUPLE("null"));
     857    return a_pDst->appendNoThrow(RT_STR_TUPLE("null"));
    693858}
    694859
     
    698863{
    699864    RT_NOREF(a_fFlags);
     865
     866    m_fNullIndicator = false;
    700867
    701868    const char *pszValue = RTStrStripL(a_rValue.c_str());
     
    705872    if (errno == 0)
    706873        return VINF_SUCCESS;
     874
     875    if (a_rValue.startsWithWord("null", RTCString::CaseInsensitive))
     876    {
     877        m_rdValue = 0.0;
     878        m_fNullIndicator = true;
     879        return VINF_SUCCESS;
     880    }
     881
    707882    int rc = RTErrConvertFromErrno(errno);
    708883    return RTErrInfoSetF(a_pErrInfo, rc, "%s: error %Rrc parsing '%s' as double", a_pszName, rc, a_rValue.c_str());
     
    731906RTCRestString::RTCRestString()
    732907    : RTCString()
     908    , RTCRestObjectBase()
    733909{
    734910}
     
    753929RTCRestString::RTCRestString(const char *a_pszSrc)
    754930    : RTCString(a_pszSrc)
     931    , RTCRestObjectBase()
    755932{
    756933}
     
    764941
    765942
     943int RTCRestString::assignCopy(RTCRestString const &a_rThat)
     944{
     945    m_fNullIndicator = a_rThat.m_fNullIndicator;
     946    return assignNoThrow(a_rThat);
     947}
     948
     949
    766950int RTCRestString::assignCopy(RTCString const &a_rThat)
    767951{
     952    m_fNullIndicator = false;
    768953    return assignNoThrow(a_rThat);
    769954}
     
    772957int RTCRestString::assignCopy(const char *a_pszThat)
    773958{
     959    m_fNullIndicator = false;
    774960    return assignNoThrow(a_pszThat);
    775961}
    776962
    777963
     964int RTCRestString::setNull()
     965{
     966    RTCString::setNull();
     967    m_fNullIndicator = true;
     968    return VINF_SUCCESS;
     969}
     970
     971
    778972int RTCRestString::resetToDefault()
    779973{
    780     setNull();
     974    RTCString::setNull();
     975    m_fNullIndicator = false;
    781976    return VINF_SUCCESS;
    782977}
     
    785980RTCRestOutputBase &RTCRestString::serializeAsJson(RTCRestOutputBase &a_rDst) const
    786981{
    787     a_rDst.printf("%RMjs", m_psz);
     982    if (!m_fNullIndicator)
     983        a_rDst.printf("%RMjs", m_psz);
     984    else
     985        a_rDst.printf("null");
    788986    return a_rDst;
    789987}
     
    792990int RTCRestString::deserializeFromJson(RTCRestJsonCursor const &a_rCursor)
    793991{
     992    m_fNullIndicator = false;
     993
    794994    RTJSONVALTYPE enmType = RTJsonValueGetType(a_rCursor.m_hValue);
    795995    if (enmType == RTJSONVALTYPE_STRING)
     
    8031003    }
    8041004
    805     if (enmType == RTJSONVALTYPE_NULL) /** @todo RTJSONVALTYPE_NULL for strings??? */
    806     {
    807         setNull();
     1005    RTCString::setNull();
     1006
     1007    if (enmType == RTJSONVALTYPE_NULL)
     1008    {
     1009        m_fNullIndicator = true;
    8081010        return VINF_SUCCESS;
    8091011    }
     
    8161018int RTCRestString::toString(RTCString *a_pDst, uint32_t a_fFlags /*= kCollectionFormat_Unspecified*/) const
    8171019{
     1020    /* Note! m_fNullIndicator == true: empty string. */
    8181021    if (!(a_fFlags & kToString_Append))
    8191022        return a_pDst->assignNoThrow(*this);
     
    8271030    RT_NOREF(a_fFlags); RT_NOREF(a_pszName); RT_NOREF(a_pErrInfo);
    8281031
     1032    /* Note! Unable to set m_fNullIndicator = true here. */
     1033    m_fNullIndicator = false;
    8291034    return assignNoThrow(a_rValue);
    8301035}
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