VirtualBox

Ignore:
Timestamp:
Jun 15, 2016 1:25:52 PM (9 years ago)
Author:
vboxsync
Message:

Runtime/JSON: Fixes and start on a testcase

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/misc/json.cpp

    r61708 r61716  
    641641        rc = rtJsonTokenizerGetEos(pTokenizer, pToken);
    642642    else if (ch == '{')
    643         rc = pToken->enmClass == RTJSONTOKENCLASS_BEGIN_OBJECT;
     643    {
     644        pToken->enmClass = RTJSONTOKENCLASS_BEGIN_OBJECT;
     645        rtJsonTokenizerSkipCh(pTokenizer);
     646    }
    644647    else if (ch == '}')
    645         rc = pToken->enmClass == RTJSONTOKENCLASS_END_OBJECT;
     648    {
     649        pToken->enmClass = RTJSONTOKENCLASS_END_OBJECT;
     650        rtJsonTokenizerSkipCh(pTokenizer);
     651    }
    646652    else if (ch == '[')
    647         rc = pToken->enmClass == RTJSONTOKENCLASS_BEGIN_ARRAY;
     653    {
     654        pToken->enmClass = RTJSONTOKENCLASS_BEGIN_ARRAY;
     655        rtJsonTokenizerSkipCh(pTokenizer);
     656    }
    648657    else if (ch == ']')
    649         rc = pToken->enmClass == RTJSONTOKENCLASS_END_ARRAY;
     658    {
     659        pToken->enmClass = RTJSONTOKENCLASS_END_ARRAY;
     660        rtJsonTokenizerSkipCh(pTokenizer);
     661    }
    650662    else if (ch == ':')
    651         rc = pToken->enmClass == RTJSONTOKENCLASS_NAME_SEPARATOR;
     663    {
     664        pToken->enmClass = RTJSONTOKENCLASS_NAME_SEPARATOR;
     665        rtJsonTokenizerSkipCh(pTokenizer);
     666    }
    652667    else if (ch == ',')
    653         rc = pToken->enmClass == RTJSONTOKENCLASS_VALUE_SEPARATOR;
     668    {
     669        pToken->enmClass = RTJSONTOKENCLASS_VALUE_SEPARATOR;
     670        rtJsonTokenizerSkipCh(pTokenizer);
     671    }
    654672    else
    655673    {
     
    775793                RTJsonValueRelease(pThis->Type.Object.papValues[i]);
    776794            }
     795            RTMemFree(pThis->Type.Object.papszNames);
     796            RTMemFree(pThis->Type.Object.papValues);
    777797            break;
    778798        case RTJSONVALTYPE_ARRAY:
    779799            for (unsigned i = 0; i < pThis->Type.Array.cItems; i++)
    780800                RTJsonValueRelease(pThis->Type.Array.papItems[i]);
     801            RTMemFree(pThis->Type.Array.papItems);
    781802            break;
    782803        case RTJSONVALTYPE_STRING:
     
    826847    PRTJSONTOKEN pToken = NULL;
    827848    uint32_t cItems = 0;
     849    uint32_t cItemsMax = 0;
     850    PRTJSONVALINT *papItems = NULL;
    828851
    829852    rc = rtJsonTokenizerGetToken(pTokenizer, &pToken);
    830853    while (   RT_SUCCESS(rc)
    831            && pToken->enmClass != RTJSONTOKENCLASS_END_ARRAY)
     854           && pToken->enmClass != RTJSONTOKENCLASS_END_ARRAY
     855           && pToken->enmClass != RTJSONTOKENCLASS_EOS)
    832856    {
    833857        PRTJSONVALINT pVal = NULL;
     
    835859        if (RT_SUCCESS(rc))
    836860        {
     861            if (cItems == cItemsMax)
     862            {
     863                cItemsMax += 10;
     864                PRTJSONVALINT *papItemsNew = (PRTJSONVALINT *)RTMemRealloc(papItems, cItemsMax * sizeof(PRTJSONVALINT));
     865                if (RT_UNLIKELY(!papItemsNew))
     866                {
     867                    rc = VERR_NO_MEMORY;
     868                    break;
     869                }
     870                papItems = papItemsNew;
     871            }
     872
     873            Assert(cItems < cItemsMax);
     874            papItems[cItems] = pVal;
    837875            cItems++;
    838             /** @todo: Add value to array. */
    839876        }
    840877
    841         /* Next token. */
    842         rtJsonTokenizerConsume(pTokenizer);
    843         rc = rtJsonTokenizerGetToken(pTokenizer, &pToken);
     878        /* Skip value separator and continue with next token. */
     879        if (rtJsonTokenizerConsumeIfMatched(pTokenizer, RTJSONTOKENCLASS_VALUE_SEPARATOR))
     880            rc = rtJsonTokenizerGetToken(pTokenizer, &pToken);
     881        else
     882            rc = VERR_JSON_MALFORMED;
    844883    }
    845884
    846885    if (RT_SUCCESS(rc))
    847886    {
    848         Assert(pToken->enmClass == RTJSONTOKENCLASS_END_ARRAY);
    849         rtJsonTokenizerConsume(pTokenizer);
    850         pJsonVal->Type.Array.cItems = cItems;
     887        if (pToken->enmClass == RTJSONTOKENCLASS_END_ARRAY)
     888        {
     889            rtJsonTokenizerConsume(pTokenizer);
     890            pJsonVal->Type.Array.cItems = cItems;
     891            pJsonVal->Type.Array.papItems = papItems;
     892        }
     893        else
     894            rc = VERR_JSON_MALFORMED;
     895    }
     896
     897    if (RT_FAILURE(rc))
     898    {
     899        for (uint32_t i = 0; i < cItems; i++)
     900            RTJsonValueRelease(papItems[i]);
     901        RTMemFree(papItems);
    851902    }
    852903
     
    867918    PRTJSONTOKEN pToken = NULL;
    868919    uint32_t cMembers = 0;
     920    uint32_t cMembersMax = 0;
     921    PRTJSONVALINT *papValues = NULL;
     922    char **papszNames = NULL;
    869923
    870924    rc = rtJsonTokenizerGetToken(pTokenizer, &pToken);
     
    883937            if (RT_SUCCESS(rc))
    884938            {
     939                if (cMembers == cMembersMax)
     940                {
     941                    cMembersMax += 10;
     942                    PRTJSONVALINT *papValuesNew = (PRTJSONVALINT *)RTMemRealloc(papValues, cMembersMax * sizeof(PRTJSONVALINT));
     943                    char **papszNamesNew =  (char **)RTMemRealloc(papValues, cMembersMax * sizeof(char *));
     944                    if (RT_UNLIKELY(!papValuesNew || !papszNamesNew))
     945                    {
     946                        rc = VERR_NO_MEMORY;
     947                        break;
     948                    }
     949                }
     950
     951                Assert(cMembers < cMembers);
     952                papszNames[cMembers] = pszName;
     953                papValues[cMembers] = pVal;
    885954                cMembers++;
    886                 /** @todo: Add name/value pair to object. */
    887955
    888956                /* Next token. */
    889                 rtJsonTokenizerConsume(pTokenizer);
    890957                rc = rtJsonTokenizerGetToken(pTokenizer, &pToken);
    891958            }
     
    901968            rtJsonTokenizerConsume(pTokenizer);
    902969            pJsonVal->Type.Object.cMembers = cMembers;
     970            pJsonVal->Type.Object.papValues = papValues;
     971            pJsonVal->Type.Object.papszNames = papszNames;
    903972        }
    904973        else
    905974            rc = VERR_JSON_MALFORMED;
     975    }
     976
     977    if (RT_FAILURE(rc))
     978    {
     979        for (uint32_t i = 0; i < cMembers; i++)
     980        {
     981            RTJsonValueRelease(papValues[i]);
     982            RTStrFree(papszNames[i]);
     983        }
     984        RTMemFree(papValues);
     985        RTMemFree(papszNames);
    906986    }
    907987
     
    9271007    {
    9281008        case RTJSONTOKENCLASS_BEGIN_ARRAY:
     1009            rtJsonTokenizerConsume(pTokenizer);
    9291010            pVal = rtJsonValueCreate(RTJSONVALTYPE_ARRAY);
    9301011            if (RT_LIKELY(pVal))
     
    9321013            break;
    9331014        case RTJSONTOKENCLASS_BEGIN_OBJECT:
     1015            rtJsonTokenizerConsume(pTokenizer);
    9341016            pVal = rtJsonValueCreate(RTJSONVALTYPE_OBJECT);
    9351017            if (RT_LIKELY(pVal))
     
    9401022            if (RT_LIKELY(pVal))
    9411023                pVal->Type.String.pszStr = pToken->Class.String.pszStr;
     1024            rtJsonTokenizerConsume(pTokenizer);
    9421025            break;
    9431026        case RTJSONTOKENCLASS_NUMBER:
     
    9451028            if (RT_LIKELY(pVal))
    9461029                pVal->Type.Number.i64Num = pToken->Class.Number.i64Num;
     1030            rtJsonTokenizerConsume(pTokenizer);
    9471031            break;
    9481032        case RTJSONTOKENCLASS_NULL:
     1033            rtJsonTokenizerConsume(pTokenizer);
    9491034            pVal = rtJsonValueCreate(RTJSONVALTYPE_NULL);
    9501035            break;
    9511036        case RTJSONTOKENCLASS_FALSE:
     1037            rtJsonTokenizerConsume(pTokenizer);
    9521038            pVal = rtJsonValueCreate(RTJSONVALTYPE_FALSE);
    9531039            break;
    9541040        case RTJSONTOKENCLASS_TRUE:
     1041            rtJsonTokenizerConsume(pTokenizer);
    9551042            pVal = rtJsonValueCreate(RTJSONVALTYPE_TRUE);
    9561043            break;
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