VirtualBox

Changeset 74170 in vbox for trunk/src


Ignore:
Timestamp:
Sep 10, 2018 7:26:17 AM (6 years ago)
Author:
vboxsync
Message:

IPRT/rest: Added testcase for RTCRestDouble, fixing issues found. bugref:9167

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

Legend:

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

    r74027 r74170  
    558558        {
    559559            szTmp[cchNum++] = 'e';
     560            rtJsonTokenizerSkipCh(pTokenizer);
    560561            ch = rtJsonTokenizerGetCh(pTokenizer);
    561562            if (ch == '+' || ch == '-')
  • trunk/src/VBox/Runtime/common/rest/rest-primary-object-types.cpp

    r74161 r74170  
    306306
    307307
    308 /** Default destructor. */
     308/** Default constructor. */
    309309RTCRestInt64::RTCRestInt64()
    310310    : RTCRestObjectBase()
     
    470470
    471471
    472 /** Default destructor. */
     472/** Default constructor. */
    473473RTCRestInt32::RTCRestInt32()
    474474    : RTCRestObjectBase()
     
    640640
    641641
    642 /** Default destructor. */
     642/** Default constructor. */
    643643RTCRestInt16::RTCRestInt16()
    644644    : RTCRestObjectBase()
     
    809809}
    810810
    811 /** Default destructor. */
     811/** Default constructor. */
    812812RTCRestDouble::RTCRestDouble()
    813813    : RTCRestObjectBase()
     
    881881        char szValue[128];
    882882#ifdef _MSC_VER
    883         _snprintf(szValue, sizeof(szValue), "%g", m_rdValue);
     883        _snprintf(szValue, sizeof(szValue), "%.18g", m_rdValue);
    884884#else
    885         snprintf(szValue, sizeof(szValue), "%g", m_rdValue);
     885        snprintf(szValue, sizeof(szValue), "%.18g", m_rdValue);
    886886#endif
     887        size_t cchValue = strlen(szValue);
     888        while (cchValue > 0 && szValue[-1] == '0')
     889            cchValue--;
     890        szValue[cchValue] = '\0';
     891
    887892        a_rDst.printf("%s", szValue);
    888893    }
     
    944949        char szValue[128];
    945950#ifdef _MSC_VER
    946         _snprintf(szValue, sizeof(szValue), "%g", m_rdValue);
     951        _snprintf(szValue, sizeof(szValue), "%.18g", m_rdValue);
    947952#else
    948         snprintf(szValue, sizeof(szValue), "%g", m_rdValue);
     953        snprintf(szValue, sizeof(szValue), "%.18g", m_rdValue);
    949954#endif
    950         size_t const cchValue = strlen(szValue);
     955        size_t cchValue = strlen(szValue);
     956        while (cchValue > 0 && szValue[-1] == '0')
     957            cchValue--;
     958        szValue[cchValue] = '\0';
    951959
    952960        if (!(a_fFlags & kToString_Append))
     
    965973{
    966974    RT_NOREF(a_fFlags);
     975
     976    if (a_rValue.startsWithWord("null", RTCString::CaseInsensitive))
     977    {
     978        m_rdValue = 0.0;
     979        m_fNullIndicator = true;
     980        return VINF_SUCCESS;
     981    }
    967982
    968983    m_fNullIndicator = false;
     
    972987    char *pszNext = NULL;
    973988    m_rdValue = strtod(pszValue, &pszNext);
    974     if (errno == 0)
    975         return VINF_SUCCESS;
    976 
    977     if (a_rValue.startsWithWord("null", RTCString::CaseInsensitive))
    978     {
    979         m_rdValue = 0.0;
    980         m_fNullIndicator = true;
    981         return VINF_SUCCESS;
    982     }
    983 
     989    if (errno == 0 && pszNext != pszValue)
     990    {
     991        if (!pszNext || *pszNext == '\0')
     992            return VINF_SUCCESS;
     993
     994        while (RT_C_IS_SPACE(*pszNext))
     995            pszNext++;
     996        if (*pszNext == '\0')
     997            return VINF_SUCCESS;
     998
     999        return RTErrInfoSetF(a_pErrInfo, VERR_TRAILING_CHARS, "%s: error VERR_TRAILING_CHARS parsing '%s' as double",
     1000                             a_pszName, a_rValue.c_str());
     1001    }
     1002
     1003    if (!RT_C_IS_DIGIT(*pszValue) && *pszValue != '.')
     1004        return RTErrInfoSetF(a_pErrInfo, VERR_NO_DIGITS, "%s: error VERR_NO_DIGITS parsing '%s' as double",
     1005                             a_pszName, a_rValue.c_str());
    9841006    int rc = RTErrConvertFromErrno(errno);
    9851007    return RTErrInfoSetF(a_pErrInfo, rc, "%s: error %Rrc parsing '%s' as double", a_pszName, rc, a_rValue.c_str());
     
    10111033
    10121034
    1013 /** Default destructor. */
     1035/** Default constructor. */
    10141036RTCRestString::RTCRestString()
    10151037    : RTCString()
  • trunk/src/VBox/Runtime/testcase/tstRTCRest-1.cpp

    r74162 r74170  
    3636#include <iprt/test.h>
    3737
     38#include <float.h> /* DBL_MIN, DBL_MAX */
     39
    3840
    3941/*********************************************************************************************************************************
     
    362364        RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
    363365        RTTESTI_CHECK(obj3.isNull() == true);
     366        RTTESTI_CHECK(obj3.m_iValue == 0);
    364367        obj3.assignValue(-1);
    365368        RTTESTI_CHECK(obj3.m_iValue == -1);
     
    514517
    515518        RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "null", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
    516         RTTESTI_CHECK(obj4.m_iValue == false);
     519        RTTESTI_CHECK(obj4.m_iValue == 0);
    517520        RTTESTI_CHECK(obj4.isNull() == true);
    518521
     
    584587
    585588
     589void testDouble(void)
     590{
     591    RTTestSub(g_hTest, "RTCRestDouble");
     592#define DBL_MAX_STRING  "1.7976931348623157e+308"
     593#define DBL_MIN_STRING  "2.2250738585072014e-308"
     594
     595    {
     596        RTCRestDouble obj1;
     597        RTTESTI_CHECK(obj1.m_rdValue == 0.0);
     598        RTTESTI_CHECK(obj1.isNull() == false);
     599        RTTESTI_CHECK(strcmp(obj1.typeName(), "double") == 0);
     600        RTTESTI_CHECK(obj1.typeClass() == RTCRestObjectBase::kTypeClass_Double);
     601    }
     602
     603    {
     604        RTCRestDouble obj2(2398.1);
     605        RTTESTI_CHECK(obj2.m_rdValue == 2398.1);
     606        RTTESTI_CHECK(obj2.isNull() == false);
     607    }
     608
     609    {
     610        RTCRestDouble obj2(-7345.2);
     611        RTTESTI_CHECK(obj2.m_rdValue == -7345.2);
     612        RTTESTI_CHECK(obj2.isNull() == false);
     613    }
     614
     615    {
     616        /* Value assignments: */
     617        RTCRestDouble obj3;
     618        RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
     619        RTTESTI_CHECK(obj3.isNull() == true);
     620        RTTESTI_CHECK(obj3.m_rdValue == 0.0);
     621        obj3.assignValue(-1.0);
     622        RTTESTI_CHECK(obj3.m_rdValue == -1.0);
     623        RTTESTI_CHECK(obj3.isNull() == false);
     624
     625        RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
     626        RTTESTI_CHECK(obj3.isNull() == true);
     627        obj3.assignValue(42.42);
     628        RTTESTI_CHECK(obj3.m_rdValue == 42.42);
     629        RTTESTI_CHECK(obj3.isNull() == false);
     630
     631        obj3.assignValue(DBL_MAX);
     632        RTTESTI_CHECK(obj3.m_rdValue == DBL_MAX);
     633        RTTESTI_CHECK(obj3.isNull() == false);
     634
     635        obj3.assignValue(DBL_MIN);
     636        RTTESTI_CHECK(obj3.m_rdValue == DBL_MIN);
     637        RTTESTI_CHECK(obj3.isNull() == false);
     638
     639        RTTESTI_CHECK_RC(obj3.resetToDefault(), VINF_SUCCESS);
     640        RTTESTI_CHECK(obj3.m_rdValue == 0.0);
     641        RTTESTI_CHECK(obj3.isNull() == false);
     642
     643        obj3.assignValue(42);
     644        RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
     645        RTTESTI_CHECK_RC(obj3.resetToDefault(), VINF_SUCCESS);
     646        RTTESTI_CHECK(obj3.m_rdValue == 0.0);
     647        RTTESTI_CHECK(obj3.isNull() == false);
     648
     649        /* Copy assignments: */
     650        RTCRestDouble obj3Max(DBL_MAX);
     651        RTTESTI_CHECK(obj3Max.m_rdValue == DBL_MAX);
     652        RTTESTI_CHECK(obj3Max.isNull() == false);
     653        RTCRestDouble obj3Min(DBL_MIN);
     654        RTTESTI_CHECK(obj3Min.m_rdValue == DBL_MIN);
     655        RTTESTI_CHECK(obj3Min.isNull() == false);
     656        RTCRestDouble obj3Null;
     657        obj3Null.setNull();
     658        RTTESTI_CHECK(obj3Null.m_rdValue == 0.0);
     659        RTTESTI_CHECK(obj3Null.isNull() == true);
     660
     661        RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
     662        RTTESTI_CHECK_RC(obj3.assignCopy(obj3Max), VINF_SUCCESS);
     663        RTTESTI_CHECK(obj3.m_rdValue == DBL_MAX);
     664        RTTESTI_CHECK(obj3.isNull() == false);
     665
     666        RTTESTI_CHECK_RC(obj3.assignCopy(obj3Null), VINF_SUCCESS);
     667        RTTESTI_CHECK(obj3.m_rdValue == 0.0);
     668        RTTESTI_CHECK(obj3.isNull() == true);
     669
     670        RTTESTI_CHECK_RC(obj3.assignCopy(obj3Min), VINF_SUCCESS);
     671        RTTESTI_CHECK(obj3.m_rdValue == DBL_MIN);
     672        RTTESTI_CHECK(obj3.isNull() == false);
     673
     674        obj3 = obj3Null;
     675        RTTESTI_CHECK(obj3.m_rdValue == 0.0);
     676        RTTESTI_CHECK(obj3.isNull() == true);
     677
     678        obj3 = obj3Max;
     679        RTTESTI_CHECK(obj3.m_rdValue == DBL_MAX);
     680        RTTESTI_CHECK(obj3.isNull() == false);
     681
     682        obj3 = obj3Null;
     683        RTTESTI_CHECK(obj3.m_rdValue == 0.0);
     684        RTTESTI_CHECK(obj3.isNull() == true);
     685
     686        obj3 = obj3Min;
     687        RTTESTI_CHECK(obj3.m_rdValue == DBL_MIN);
     688        RTTESTI_CHECK(obj3.isNull() == false);
     689
     690        /* setNull implies resetToDefault: */
     691        obj3 = obj3Max;
     692        RTTESTI_CHECK(obj3.m_rdValue == DBL_MAX);
     693        RTTESTI_CHECK(obj3.isNull() == false);
     694        RTTESTI_CHECK_RC(obj3.setNull(), VINF_SUCCESS);
     695        RTTESTI_CHECK(obj3.isNull() == true);
     696        RTTESTI_CHECK(obj3.m_rdValue == 0.0);
     697
     698        /* Copy constructors: */
     699        {
     700            RTCRestDouble obj3a(obj3Max);
     701            RTTESTI_CHECK(obj3a.m_rdValue == DBL_MAX);
     702            RTTESTI_CHECK(obj3a.isNull() == false);
     703        }
     704        {
     705            RTCRestDouble obj3b(obj3Min);
     706            RTTESTI_CHECK(obj3b.m_rdValue == DBL_MIN);
     707            RTTESTI_CHECK(obj3b.isNull() == false);
     708        }
     709        {
     710            RTCRestDouble obj3c(obj3Null);
     711            RTTESTI_CHECK(obj3c.m_rdValue == 0.0);
     712            RTTESTI_CHECK(obj3c.isNull() == true);
     713        }
     714
     715        /* Serialization to json: */
     716        const char *pszJson = toJson(&obj3Max);
     717        RTTESTI_CHECK_MSG(strcmp(pszJson, DBL_MAX_STRING) == 0, ("pszJson=%s\n", pszJson));
     718        pszJson = toJson(&obj3Min);
     719        RTTESTI_CHECK_MSG(strcmp(pszJson, DBL_MIN_STRING) == 0, ("pszJson=%s\n", pszJson));
     720        pszJson = toJson(&obj3Null);
     721        RTTESTI_CHECK_MSG(strcmp(pszJson, "null") == 0, ("pszJson=%s\n", pszJson));
     722
     723        /* Serialization to string. */
     724        RTCString str;
     725        RTCString strExpect;
     726        str = "lead-in:";
     727        RTTESTI_CHECK_RC(obj3Max.toString(&str, RTCRestObjectBase::kToString_Append), VINF_SUCCESS);
     728        strExpect.printf("lead-in:%s", DBL_MAX_STRING);
     729        RTTESTI_CHECK_MSG(str.equals(strExpect), ("str=%s strExpect=%s\n", str.c_str(), strExpect.c_str()));
     730        RTTESTI_CHECK_RC(obj3Max.toString(&str), VINF_SUCCESS);
     731        RTTESTI_CHECK_MSG(str.equals(DBL_MAX_STRING), ("str=%s\n", str.c_str()));
     732
     733        str = "lead-in:";
     734        RTTESTI_CHECK_RC(obj3Min.toString(&str, RTCRestObjectBase::kToString_Append), VINF_SUCCESS);
     735        strExpect.printf("lead-in:%s", DBL_MIN_STRING);
     736        RTTESTI_CHECK_MSG(str.equals(strExpect), ("str=%s strExpect=%s\n", str.c_str(), strExpect.c_str()));
     737        RTTESTI_CHECK_RC(obj3Min.toString(&str), VINF_SUCCESS);
     738        RTTESTI_CHECK_MSG(str.equals(DBL_MIN_STRING), ("str=%s\n", str.c_str()));
     739
     740        str = "lead-in:";
     741        RTTESTI_CHECK_RC(obj3Null.toString(&str, RTCRestObjectBase::kToString_Append), VINF_SUCCESS);
     742        RTTESTI_CHECK_MSG(str.equals("lead-in:null"), ("str=%s\n", str.c_str()));
     743        RTTESTI_CHECK_RC(obj3Null.toString(&str), VINF_SUCCESS);
     744        RTTESTI_CHECK_MSG(str.equals("null"), ("str=%s\n", str.c_str()));
     745    }
     746
     747    /* deserialize: */
     748    RTERRINFOSTATIC ErrInfo;
     749    {
     750        /* from json: */
     751        RTCRestDouble obj4;
     752        obj4.setNull();
     753        RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "42.42", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
     754        RTTESTI_CHECK(obj4.m_rdValue == 42.42);
     755        RTTESTI_CHECK(obj4.isNull() == false);
     756
     757        obj4.setNull();
     758        RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "-22.22", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
     759        RTTESTI_CHECK(obj4.m_rdValue == -22.22);
     760        RTTESTI_CHECK(obj4.isNull() == false);
     761
     762        obj4.setNull();
     763        RTTESTI_CHECK_RC(deserializeFromJson(&obj4, DBL_MAX_STRING, &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
     764        RTTESTI_CHECK(obj4.m_rdValue == DBL_MAX);
     765        RTTESTI_CHECK(obj4.isNull() == false);
     766
     767        obj4.setNull();
     768        RTTESTI_CHECK_RC(deserializeFromJson(&obj4, DBL_MIN_STRING, &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
     769        RTTESTI_CHECK(obj4.m_rdValue == DBL_MIN);
     770        RTTESTI_CHECK(obj4.isNull() == false);
     771
     772        RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "null", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
     773        RTTESTI_CHECK(obj4.m_rdValue == 0.0);
     774        RTTESTI_CHECK(obj4.isNull() == true);
     775
     776        obj4.setNull();
     777        RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "14323", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
     778        RTTESTI_CHECK(obj4.m_rdValue == 14323.0);
     779        RTTESTI_CHECK(obj4.isNull() == false);
     780
     781        obj4.setNull();
     782        RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "-234875", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
     783        RTTESTI_CHECK(obj4.m_rdValue == -234875.0);
     784        RTTESTI_CHECK(obj4.isNull() == false);
     785
     786        /* object goes to default state on failure: */
     787        obj4.assignValue(DBL_MIN);
     788        RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "false", &ErrInfo, RT_XSTR(__LINE__)), VERR_REST_WRONG_JSON_TYPE_FOR_DOUBLE);
     789        RTTESTI_CHECK(obj4.m_rdValue == 0.0);
     790        RTTESTI_CHECK(obj4.isNull() == false);
     791        RTTESTI_CHECK(RTErrInfoIsSet(&ErrInfo.Core));
     792
     793        obj4.assignValue(DBL_MAX);
     794        RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "\"false\"", &ErrInfo, RT_XSTR(__LINE__)), VERR_REST_WRONG_JSON_TYPE_FOR_DOUBLE);
     795        RTTESTI_CHECK(obj4.m_rdValue == 0.0);
     796        RTTESTI_CHECK(obj4.isNull() == false);
     797        RTTESTI_CHECK(RTErrInfoIsSet(&ErrInfo.Core));
     798
     799        obj4.setNull();
     800        RTTESTI_CHECK_RC(deserializeFromJson(&obj4, "[ null ]", NULL, RT_XSTR(__LINE__)), VERR_REST_WRONG_JSON_TYPE_FOR_DOUBLE);
     801        RTTESTI_CHECK(obj4.m_rdValue == 0.0);
     802        RTTESTI_CHECK(obj4.isNull() == false);
     803
     804        /* from string: */
     805        obj4.setNull();
     806        RTTESTI_CHECK_RC(fromString(&obj4, "22.42", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
     807        RTTESTI_CHECK(obj4.m_rdValue == 22.42);
     808        RTTESTI_CHECK(obj4.isNull() == false);
     809
     810        RTTESTI_CHECK_RC(fromString(&obj4, "-42.22", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
     811        RTTESTI_CHECK(obj4.m_rdValue == -42.22);
     812        RTTESTI_CHECK(obj4.isNull() == false);
     813
     814        RTTESTI_CHECK_RC(fromString(&obj4, DBL_MAX_STRING, &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
     815        RTTESTI_CHECK(obj4.m_rdValue == DBL_MAX);
     816        RTTESTI_CHECK(obj4.isNull() == false);
     817
     818        RTTESTI_CHECK_RC(fromString(&obj4, DBL_MIN_STRING, &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
     819        RTTESTI_CHECK(obj4.m_rdValue == DBL_MIN);
     820        RTTESTI_CHECK(obj4.isNull() == false);
     821
     822        obj4.m_rdValue = 33.33;
     823        RTTESTI_CHECK_RC(fromString(&obj4, "null", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
     824        RTTESTI_CHECK(obj4.m_rdValue == 0.0);
     825        RTTESTI_CHECK(obj4.isNull() == true);
     826
     827        obj4.m_rdValue = 33.33;
     828        RTTESTI_CHECK_RC(fromString(&obj4, " nULl;", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
     829        RTTESTI_CHECK(obj4.m_rdValue == 0.0);
     830        RTTESTI_CHECK(obj4.isNull() == true);
     831
     832        obj4.setNull();
     833        RTTESTI_CHECK_RC(fromString(&obj4, " 42.22 ", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
     834        RTTESTI_CHECK(obj4.m_rdValue == 42.22);
     835        RTTESTI_CHECK(obj4.isNull() == false);
     836
     837        RTTESTI_CHECK_RC(fromString(&obj4, "\t010\t", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
     838        RTTESTI_CHECK(obj4.m_rdValue ==10.0);
     839        RTTESTI_CHECK(obj4.isNull() == false);
     840
     841        RTTESTI_CHECK_RC(fromString(&obj4, "\r\t03495.344\t\r\n", &ErrInfo, RT_XSTR(__LINE__)), VINF_SUCCESS);
     842        RTTESTI_CHECK(obj4.m_rdValue == 3495.344);
     843        RTTESTI_CHECK(obj4.isNull() == false);
     844
     845        RTTESTI_CHECK_RC(fromString(&obj4, "1.1;", &ErrInfo, RT_XSTR(__LINE__)), VERR_TRAILING_CHARS);
     846        RTTESTI_CHECK(RTErrInfoIsSet(&ErrInfo.Core));
     847
     848        RTTESTI_CHECK_RC(fromString(&obj4, "false", NULL, RT_XSTR(__LINE__)), VERR_NO_DIGITS);
     849
     850        RTTESTI_CHECK_RC(fromString(&obj4, " 0x42 ", &ErrInfo, RT_XSTR(__LINE__)), VERR_TRAILING_CHARS);
     851        RTTESTI_CHECK(obj4.m_rdValue == 0.0);
     852        RTTESTI_CHECK(obj4.isNull() == false);
     853    }
     854}
     855
     856
    586857int main()
    587858{
     
    593864        testInteger<RTCRestInt32, int32_t, Int32Constants>();
    594865        testInteger<RTCRestInt16, int16_t, Int16Constants>();
     866        testDouble();
    595867
    596868
     
    600872}
    601873
    602 
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