VirtualBox

Changeset 73895 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Aug 26, 2018 3:47:58 PM (6 years ago)
Author:
vboxsync
Message:

IPRT/rest: Wrap primitive types to unify serializing, deserializing, formatting, array, maps, and whatnot. bugref:9167

Location:
trunk/src/VBox/Runtime
Files:
1 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/Makefile.kmk

    r73889 r73895  
    543543        common/rand/randadv.cpp \
    544544        common/rand/randparkmiller.cpp \
     545        common/rest/rest-primary-object-types.cpp \
    545546        common/rest/RTCRestClientApiBase.cpp \
    546547        common/rest/RTCRestJsonPrimaryCursor.cpp \
    547         common/rest/RTCRestObjectBase.cpp \
    548548        common/rest/RTCRestOutputToString.cpp \
    549549        common/sort/RTSortIsSorted.cpp \
  • trunk/src/VBox/Runtime/common/rest/rest-primary-object-types.cpp

    r73894 r73895  
    3838
    3939
    40 /*static*/ int
    41 RTCRestObjectBase::deserialize_RTCString_FromJson(RTCRestJsonCursor const &a_rCursor, RTCString *a_pDst)
     40
     41/*********************************************************************************************************************************
     42*   RTCRestObjectBase implementation                                                                                             *
     43*********************************************************************************************************************************/
     44
     45/** Default constructor. */
     46RTCRestObjectBase::RTCRestObjectBase()
     47{
     48}
     49
     50
     51/** Destructor. */
     52RTCRestObjectBase::~RTCRestObjectBase()
     53{
     54    /* nothing to do */
     55}
     56
     57
     58int RTCRestObjectBase::toString(RTCString *a_pDst, uint32_t fFlags)
     59{
     60    Assert(fFlags == 0);
     61
     62    /*
     63     * Just wrap the JSON serialization method.
     64     */
     65    RTCRestOutputToString Tmp(a_pDst);
     66    serializeAsJson(Tmp);
     67    return Tmp.finalize() ? VINF_SUCCESS : VERR_NO_MEMORY;
     68}
     69
     70
     71RTCString RTCRestObjectBase::toString()
     72{
     73    RTCString strRet;
     74    toString(&strRet, 0);
     75    return strRet;
     76}
     77
     78
     79
     80/*********************************************************************************************************************************
     81*   RTCRestBool implementation                                                                                                   *
     82*********************************************************************************************************************************/
     83
     84/** Default destructor. */
     85RTCRestBool::RTCRestBool()
     86    : m_fValue(false)
     87{
     88}
     89
     90
     91/** Copy constructor. */
     92RTCRestBool::RTCRestBool(RTCRestBool const &a_rThat)
     93    : m_fValue(a_rThat.m_fValue)
     94{
     95}
     96
     97
     98/** From value constructor. */
     99RTCRestBool::RTCRestBool(bool fValue)
     100    : m_fValue(fValue)
     101{
     102}
     103
     104
     105/** Destructor. */
     106RTCRestBool::~RTCRestBool()
     107{
     108    /* nothing to do */
     109}
     110
     111
     112/** Copy assignment operator. */
     113RTCRestBool &RTCRestBool::operator=(RTCRestBool const &a_rThat)
     114{
     115    m_fValue = a_rThat.m_fValue;
     116    return *this;
     117}
     118
     119
     120void RTCRestBool::resetToDefault()
     121{
     122    m_fValue = false;
     123}
     124
     125
     126RTCRestOutputBase &RTCRestBool::serializeAsJson(RTCRestOutputBase &a_rDst)
     127{
     128    a_rDst.printf(m_fValue ? "true" : "false");
     129    return a_rDst;
     130}
     131
     132
     133int RTCRestBool::deserializeFromJson(RTCRestJsonCursor const &a_rCursor)
    42134{
    43135    RTJSONVALTYPE enmType = RTJsonValueGetType(a_rCursor.m_hValue);
    44     if (enmType == RTJSONVALTYPE_STRING)
    45     {
    46         const char  *pszValue = RTJsonValueGetString(a_rCursor.m_hValue);
    47         const size_t cchValue = strlen(pszValue);
    48         int rc = a_pDst->reserveNoThrow(cchValue + 1);
    49         if (RT_SUCCESS(rc))
    50         {
    51             *a_pDst = pszValue;
    52             return VINF_SUCCESS;
    53         }
    54         return a_rCursor.m_pPrimary->addError(a_rCursor, rc, "no memory for %zu char long string", cchValue);
    55     }
    56 
    57     if (enmType == RTJSONVALTYPE_NULL) /** @todo RTJSONVALTYPE_NULL for strings??? */
    58     {
    59         a_pDst->setNull();
     136
     137    if (enmType == RTJSONVALTYPE_TRUE)
     138    {
     139        m_fValue = true;
    60140        return VINF_SUCCESS;
    61141    }
    62142
    63     return a_rCursor.m_pPrimary->addError(a_rCursor, VERR_WRONG_TYPE, "wrong JSON type %s for string",
     143    if (enmType == RTJSONVALTYPE_FALSE)
     144    {
     145        m_fValue = false;
     146        return VINF_SUCCESS;
     147    }
     148
     149    /* This is probably non-sense... */
     150    if (enmType == RTJSONVALTYPE_NULL)
     151        m_fValue = false;
     152
     153    return a_rCursor.m_pPrimary->addError(a_rCursor, VERR_WRONG_TYPE, "wrong JSON type %s for boolean",
    64154                                          RTJsonValueTypeName(RTJsonValueGetType(a_rCursor.m_hValue)));
    65155}
    66156
    67157
    68 /*static*/ int
    69 RTCRestObjectBase::deserialize_int64_t_FromJson(RTCRestJsonCursor const &a_rCursor, int64_t *a_piDst)
     158int RTCRestBool::toString(RTCString *a_pDst, uint32_t fFlags /*= 0*/)
     159{
     160    Assert(!fFlags);
     161
     162    /* Be a little careful here to avoid throwing anything. */
     163    int rc = a_pDst->reserveNoThrow(m_fValue ? sizeof("true") : sizeof("false"));
     164    if (RT_SUCCESS(rc))
     165    {
     166        if (m_fValue)
     167            a_pDst->assign(RT_STR_TUPLE("true"));
     168        else
     169            a_pDst->assign(RT_STR_TUPLE("false"));
     170    }
     171    return rc;
     172}
     173
     174
     175const char *RTCRestBool::getType()
     176{
     177    return "bool";
     178}
     179
     180
     181/*********************************************************************************************************************************
     182*   RTCRestInt64 implementation                                                                                                  *
     183*********************************************************************************************************************************/
     184
     185/** Default destructor. */
     186RTCRestInt64::RTCRestInt64()
     187    : m_iValue(0)
     188{
     189}
     190
     191
     192/** Copy constructor. */
     193RTCRestInt64::RTCRestInt64(RTCRestInt64 const &a_rThat)
     194    : m_iValue(a_rThat.m_iValue)
     195{
     196}
     197
     198
     199/** From value constructor. */
     200RTCRestInt64::RTCRestInt64(int64_t iValue)
     201    : m_iValue(iValue)
     202{
     203}
     204
     205
     206/** Destructor. */
     207RTCRestInt64::~RTCRestInt64()
     208{
     209    /* nothing to do */
     210}
     211
     212
     213/** Copy assignment operator. */
     214RTCRestInt64 &RTCRestInt64::operator=(RTCRestInt64 const &a_rThat)
     215{
     216    m_iValue = a_rThat.m_iValue;
     217    return *this;
     218}
     219
     220
     221void RTCRestInt64::resetToDefault()
     222{
     223    m_iValue = 0;
     224}
     225
     226
     227RTCRestOutputBase &RTCRestInt64::serializeAsJson(RTCRestOutputBase &a_rDst)
     228{
     229    a_rDst.printf("%RI64", m_iValue);
     230    return a_rDst;
     231}
     232
     233
     234int RTCRestInt64::deserializeFromJson(RTCRestJsonCursor const &a_rCursor)
    70235{
    71236    RTJSONVALTYPE enmType = RTJsonValueGetType(a_rCursor.m_hValue);
    72237    if (enmType == RTJSONVALTYPE_NUMBER)
    73238    {
    74         int rc = RTJsonValueQueryInteger(a_rCursor.m_hValue, a_piDst);
     239        int rc = RTJsonValueQueryInteger(a_rCursor.m_hValue, &m_iValue);
    75240        if (RT_SUCCESS(rc))
    76241            return rc;
     
    80245    /* This is probably non-sense... */
    81246    if (enmType == RTJSONVALTYPE_NULL || enmType == RTJSONVALTYPE_FALSE)
    82         *a_piDst = 0;
     247        m_iValue = 0;
    83248    else if (enmType == RTJSONVALTYPE_TRUE)
    84         *a_piDst = 1;
     249        m_iValue = 1;
    85250
    86251    return a_rCursor.m_pPrimary->addError(a_rCursor, VERR_WRONG_TYPE, "wrong JSON type %s for 64-bit integer",
     
    89254
    90255
    91 /*static*/ int
    92 RTCRestObjectBase::deserialize_int32_t_FromJson(RTCRestJsonCursor const &a_rCursor, int32_t *a_piDst)
     256int RTCRestInt64::toString(RTCString *a_pDst, uint32_t fFlags /*= 0*/)
     257{
     258    Assert(!fFlags);
     259
     260    /* Be a little careful here to avoid throwing anything. */
     261    char   szValue[64];
     262    size_t cchValue = RTStrPrintf(szValue, sizeof(szValue), "%RI64", m_iValue);
     263    int rc = a_pDst->reserveNoThrow(cchValue + 1);
     264    if (RT_SUCCESS(rc))
     265        a_pDst->assign(szValue, cchValue);
     266    return rc;
     267}
     268
     269
     270const char *RTCRestInt64::getType()
     271{
     272    return "int64_t";
     273}
     274
     275
     276
     277/*********************************************************************************************************************************
     278*   RTCRestInt32 implementation                                                                                                  *
     279*********************************************************************************************************************************/
     280
     281/** Default destructor. */
     282RTCRestInt32::RTCRestInt32()
     283    : m_iValue(0)
     284{
     285}
     286
     287
     288/** Copy constructor. */
     289RTCRestInt32::RTCRestInt32(RTCRestInt32 const &a_rThat)
     290    : m_iValue(a_rThat.m_iValue)
     291{
     292}
     293
     294
     295/** From value constructor. */
     296RTCRestInt32::RTCRestInt32(int32_t iValue)
     297    : m_iValue(iValue)
     298{
     299}
     300
     301
     302/** Destructor. */
     303RTCRestInt32::~RTCRestInt32()
     304{
     305    /* nothing to do */
     306}
     307
     308
     309/** Copy assignment operator. */
     310RTCRestInt32 &RTCRestInt32::operator=(RTCRestInt32 const &a_rThat)
     311{
     312    m_iValue = a_rThat.m_iValue;
     313    return *this;
     314}
     315
     316
     317void RTCRestInt32::resetToDefault()
     318{
     319    m_iValue = 0;
     320}
     321
     322
     323RTCRestOutputBase &RTCRestInt32::serializeAsJson(RTCRestOutputBase &a_rDst)
     324{
     325    a_rDst.printf("%RI32", m_iValue);
     326    return a_rDst;
     327}
     328
     329
     330int RTCRestInt32::deserializeFromJson(RTCRestJsonCursor const &a_rCursor)
    93331{
    94332    RTJSONVALTYPE enmType = RTJsonValueGetType(a_rCursor.m_hValue);
    95333    if (enmType == RTJSONVALTYPE_NUMBER)
    96334    {
    97         int64_t iTmp = *a_piDst;
     335        int64_t iTmp = m_iValue;
    98336        int rc = RTJsonValueQueryInteger(a_rCursor.m_hValue, &iTmp);
    99337        if (RT_SUCCESS(rc))
    100338        {
    101             *a_piDst = (int32_t)iTmp;
    102             if (*a_piDst == iTmp)
     339            m_iValue = (int32_t)iTmp;
     340            if (m_iValue == iTmp)
    103341                return rc;
    104342            return a_rCursor.m_pPrimary->addError(a_rCursor, VERR_OUT_OF_RANGE, "value %RI64 does not fit in 32 bits", iTmp);
     
    109347    /* This is probably non-sense... */
    110348    if (enmType == RTJSONVALTYPE_NULL || enmType == RTJSONVALTYPE_FALSE)
    111         *a_piDst = 0;
     349        m_iValue = 0;
    112350    else if (enmType == RTJSONVALTYPE_TRUE)
    113         *a_piDst = 1;
     351        m_iValue = 1;
    114352
    115353    return a_rCursor.m_pPrimary->addError(a_rCursor, VERR_WRONG_TYPE, "wrong JSON type %s for 32-bit integer",
     
    118356
    119357
    120 /*static*/ int
    121 RTCRestObjectBase::deserialize_int16_t_FromJson(RTCRestJsonCursor const &a_rCursor, int16_t *a_piDst)
     358int RTCRestInt32::toString(RTCString *a_pDst, uint32_t fFlags /*= 0*/)
     359{
     360    Assert(!fFlags);
     361
     362    /* Be a little careful here to avoid throwing anything. */
     363    char   szValue[16];
     364    size_t cchValue = RTStrPrintf(szValue, sizeof(szValue), "%RI32", m_iValue);
     365    int rc = a_pDst->reserveNoThrow(cchValue + 1);
     366    if (RT_SUCCESS(rc))
     367        a_pDst->assign(szValue, cchValue);
     368    return rc;
     369}
     370
     371
     372const char *RTCRestInt32::getType()
     373{
     374    return "int32_t";
     375}
     376
     377
     378
     379/*********************************************************************************************************************************
     380*   RTCRestInt16 implementation                                                                                                  *
     381*********************************************************************************************************************************/
     382
     383/** Default destructor. */
     384RTCRestInt16::RTCRestInt16()
     385    : m_iValue(0)
     386{
     387}
     388
     389
     390/** Copy constructor. */
     391RTCRestInt16::RTCRestInt16(RTCRestInt16 const &a_rThat)
     392    : m_iValue(a_rThat.m_iValue)
     393{
     394}
     395
     396
     397/** From value constructor. */
     398RTCRestInt16::RTCRestInt16(int16_t iValue)
     399    : m_iValue(iValue)
     400{
     401}
     402
     403
     404/** Destructor. */
     405RTCRestInt16::~RTCRestInt16()
     406{
     407    /* nothing to do */
     408}
     409
     410
     411/** Copy assignment operator. */
     412RTCRestInt16 &RTCRestInt16::operator=(RTCRestInt16 const &a_rThat)
     413{
     414    m_iValue = a_rThat.m_iValue;
     415    return *this;
     416}
     417
     418
     419void RTCRestInt16::resetToDefault()
     420{
     421    m_iValue = 0;
     422}
     423
     424
     425RTCRestOutputBase &RTCRestInt16::serializeAsJson(RTCRestOutputBase &a_rDst)
     426{
     427    a_rDst.printf("%RI16", m_iValue);
     428    return a_rDst;
     429}
     430
     431
     432int RTCRestInt16::deserializeFromJson(RTCRestJsonCursor const &a_rCursor)
    122433{
    123434    RTJSONVALTYPE enmType = RTJsonValueGetType(a_rCursor.m_hValue);
    124435    if (enmType == RTJSONVALTYPE_NUMBER)
    125436    {
    126         int64_t iTmp = *a_piDst;
     437        int64_t iTmp = m_iValue;
    127438        int rc = RTJsonValueQueryInteger(a_rCursor.m_hValue, &iTmp);
    128439        if (RT_SUCCESS(rc))
    129440        {
    130             *a_piDst = (int16_t)iTmp;
    131             if (*a_piDst == iTmp)
     441            m_iValue = (int16_t)iTmp;
     442            if (m_iValue == iTmp)
    132443                return rc;
    133444            return a_rCursor.m_pPrimary->addError(a_rCursor, VERR_OUT_OF_RANGE, "value %RI64 does not fit in 16 bits", iTmp);
     
    138449    /* This is probably non-sense... */
    139450    if (enmType == RTJSONVALTYPE_NULL || enmType == RTJSONVALTYPE_FALSE)
    140         *a_piDst = 0;
     451        m_iValue = 0;
    141452    else if (enmType == RTJSONVALTYPE_TRUE)
    142         *a_piDst = 1;
     453        m_iValue = 1;
    143454
    144455    return a_rCursor.m_pPrimary->addError(a_rCursor, VERR_WRONG_TYPE, "wrong JSON type %s for 16-bit integer",
     
    147458
    148459
    149 /*static*/ int
    150 RTCRestObjectBase::deserialize_bool_FromJson(RTCRestJsonCursor const &a_rCursor, bool *pfDst)
    151 {
    152     RTJSONVALTYPE enmType = RTJsonValueGetType(a_rCursor.m_hValue);
    153 
    154     if (enmType == RTJSONVALTYPE_TRUE)
    155     {
    156         *pfDst = true;
    157         return VINF_SUCCESS;
    158     }
    159 
    160     if (enmType == RTJSONVALTYPE_FALSE)
    161     {
    162         *pfDst = false;
    163         return VINF_SUCCESS;
    164     }
    165 
    166     /* This is probably non-sense... */
    167     if (enmType == RTJSONVALTYPE_NULL)
    168         *pfDst = false;
    169 
    170     return a_rCursor.m_pPrimary->addError(a_rCursor, VERR_WRONG_TYPE, "wrong JSON type %s for boolean",
    171                                           RTJsonValueTypeName(RTJsonValueGetType(a_rCursor.m_hValue)));
    172 }
    173 
    174 
    175 /*static*/ int
    176 RTCRestObjectBase::deserialize_double_FromJson(RTCRestJsonCursor const &a_rCursor, double *a_prdDst)
     460int RTCRestInt16::toString(RTCString *a_pDst, uint32_t fFlags /*= 0*/)
     461{
     462    Assert(!fFlags);
     463
     464    /* Be a little careful here to avoid throwing anything. */
     465    char   szValue[8];
     466    size_t cchValue = RTStrPrintf(szValue, sizeof(szValue), "%RI16", m_iValue);
     467    int rc = a_pDst->reserveNoThrow(cchValue + 1);
     468    if (RT_SUCCESS(rc))
     469        a_pDst->assign(szValue, cchValue);
     470    return rc;
     471}
     472
     473
     474const char *RTCRestInt16::getType()
     475{
     476    return "int16_t";
     477}
     478
     479
     480
     481/*********************************************************************************************************************************
     482*   RTCRestDouble implementation                                                                                                 *
     483*********************************************************************************************************************************/
     484
     485/** Default destructor. */
     486RTCRestDouble::RTCRestDouble()
     487    : m_rdValue(0.0)
     488{
     489}
     490
     491
     492/** Copy constructor. */
     493RTCRestDouble::RTCRestDouble(RTCRestDouble const &a_rThat)
     494    : m_rdValue(a_rThat.m_rdValue)
     495{
     496}
     497
     498
     499/** From value constructor. */
     500RTCRestDouble::RTCRestDouble(double rdValue)
     501    : m_rdValue(rdValue)
     502{
     503}
     504
     505
     506/** Destructor. */
     507RTCRestDouble::~RTCRestDouble()
     508{
     509    /* nothing to do */
     510}
     511
     512
     513void RTCRestDouble::resetToDefault()
     514{
     515    m_rdValue = 0.0;
     516}
     517
     518
     519RTCRestOutputBase &RTCRestDouble::serializeAsJson(RTCRestOutputBase &a_rDst)
     520{
     521    /* Just a simple approximation here. */
     522    /** @todo implement floating point values for json. */
     523    char szValue[128];
     524#ifdef _MSC_VER
     525    _snprintf(szValue, sizeof(szValue), "%g", m_rdValue);
     526#else
     527    snprintf(szValue, sizeof(szValue), "%g", m_rdValue);
     528#endif
     529    a_rDst.printf("%s", szValue);
     530    return a_rDst;
     531}
     532
     533
     534int RTCRestDouble::deserializeFromJson(RTCRestJsonCursor const &a_rCursor)
    177535{
    178536    AssertMsgFailed(("RTJson needs to be taught double values."));
    179     RT_NOREF(a_prdDst);
    180537    /** @todo implement floating point values for json. */
    181538    return a_rCursor.m_pPrimary->addError(a_rCursor, VERR_NOT_IMPLEMENTED, "double is not supported yet");
     
    183540
    184541
    185 /*static*/ RTCRestOutputBase &
    186 RTCRestObjectBase::serialize_double_AsJson(RTCRestOutputBase &a_rDst, double const *a_prdValue)
    187 {
     542int RTCRestDouble::toString(RTCString *a_pDst, uint32_t fFlags /*= 0*/)
     543{
     544    Assert(!fFlags);
     545
    188546    /* Just a simple approximation here. */
    189547    /** @todo implement floating point values for json. */
    190     double const rdValue = *a_prdValue;
    191     char szTmp[128];
     548    char szValue[128];
    192549#ifdef _MSC_VER
    193     _snprintf(szTmp, sizeof(szTmp), "%g", rdValue);
     550    _snprintf(szValue, sizeof(szValue), "%g", m_rdValue);
    194551#else
    195     snprintf(szTmp, sizeof(szTmp), "%g", rdValue);
     552    snprintf(szValue, sizeof(szValue), "%g", m_rdValue);
    196553#endif
    197     a_rDst.printf("%s", szTmp);
     554    size_t const cchValue = strlen(szValue);
     555
     556    int rc = a_pDst->reserveNoThrow(cchValue + 1);
     557    if (RT_SUCCESS(rc))
     558        a_pDst->assign(szValue, cchValue);
     559    return rc;
     560}
     561
     562
     563const char *RTCRestDouble::getType()
     564{
     565    return "double";
     566}
     567
     568
     569
     570/*********************************************************************************************************************************
     571*   RTCRestString implementation                                                                                                 *
     572*********************************************************************************************************************************/
     573
     574/** Default destructor. */
     575RTCRestString::RTCRestString()
     576    : RTCString()
     577{
     578}
     579
     580
     581/** Copy constructor. */
     582RTCRestString::RTCRestString(RTCRestString const &a_rThat)
     583    : RTCString(a_rThat)
     584{
     585}
     586
     587
     588/** From value constructor. */
     589RTCRestString::RTCRestString(RTCString const &a_rThat)
     590    : RTCString(a_rThat)
     591{
     592}
     593
     594
     595/** From value constructor. */
     596RTCRestString::RTCRestString(const char *a_pszSrc)
     597    : RTCString(a_pszSrc)
     598{
     599}
     600
     601
     602/** Destructor. */
     603RTCRestString::~RTCRestString()
     604{
     605    /* nothing to do */
     606}
     607
     608
     609void RTCRestString::resetToDefault()
     610{
     611    setNull();
     612}
     613
     614
     615RTCRestOutputBase &RTCRestString::serializeAsJson(RTCRestOutputBase &a_rDst)
     616{
     617    a_rDst.printf("%RJs", m_psz);
    198618    return a_rDst;
    199619}
    200620
     621
     622int RTCRestString::deserializeFromJson(RTCRestJsonCursor const &a_rCursor)
     623{
     624    RTJSONVALTYPE enmType = RTJsonValueGetType(a_rCursor.m_hValue);
     625    if (enmType == RTJSONVALTYPE_STRING)
     626    {
     627        const char  *pszValue = RTJsonValueGetString(a_rCursor.m_hValue);
     628        const size_t cchValue = strlen(pszValue);
     629        int rc = reserveNoThrow(cchValue + 1);
     630        if (RT_SUCCESS(rc))
     631        {
     632            assign(pszValue, cchValue);
     633            return VINF_SUCCESS;
     634        }
     635        return a_rCursor.m_pPrimary->addError(a_rCursor, rc, "no memory for %zu char long string", cchValue);
     636    }
     637
     638    if (enmType == RTJSONVALTYPE_NULL) /** @todo RTJSONVALTYPE_NULL for strings??? */
     639    {
     640        setNull();
     641        return VINF_SUCCESS;
     642    }
     643
     644    return a_rCursor.m_pPrimary->addError(a_rCursor, VERR_WRONG_TYPE, "wrong JSON type %s for string",
     645                                          RTJsonValueTypeName(RTJsonValueGetType(a_rCursor.m_hValue)));
     646}
     647
     648
     649int RTCRestString::toString(RTCString *a_pDst, uint32_t fFlags /*= 0*/)
     650{
     651    Assert(!fFlags);
     652
     653    /* Careful as always. */
     654    if (m_cch)
     655    {
     656        int rc = a_pDst->reserveNoThrow(m_cch + 1);
     657        if (RT_SUCCESS(rc))
     658        { /* likely */ }
     659        else
     660            return rc;
     661    }
     662    a_pDst->assign(*this);
     663    return VINF_SUCCESS;
     664}
     665
     666
     667const char *RTCRestString::getType()
     668{
     669    return "RTCString";
     670}
     671
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