VirtualBox

Changeset 74025 in vbox


Ignore:
Timestamp:
Sep 2, 2018 2:14:43 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
124772
Message:

IPRT/rest: split up restbase.h into several files to make it more managable. bugref:9167

Location:
trunk
Files:
6 edited
3 copied

Legend:

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

    r74024 r74025  
    11/** @file
    2  * IPRT - C++ Representational State Transfer (REST) Base Classes.
     2 * IPRT - C++ Representational State Transfer (REST) Array Template Class.
    33 */
    44
     
    2424 */
    2525
    26 #ifndef ___iprt_cpp_restbase_h
    27 #define ___iprt_cpp_restbase_h
    28 
    29 #include <iprt/types.h>
    30 #include <iprt/assert.h>
    31 #include <iprt/err.h>
    32 #include <iprt/http.h>
    33 #include <iprt/json.h>
    34 #include <iprt/list.h>
    35 #include <iprt/string.h>
    36 #include <iprt/stdarg.h>
    37 #include <iprt/cpp/ministring.h>
    38 #include <iprt/cpp/utils.h>
    39 
    40 
    41 /** @defgroup grp_rt_cpp_restbase   C++ Representational State Transfer (REST) Base Classes.
     26#ifndef ___iprt_cpp_restarray_h
     27#define ___iprt_cpp_restarray_h
     28
     29#include <iprt/cpp/restbase.h>
     30
     31
     32/** @defgroup grp_rt_cpp_restarray  C++ Representational State Transfer (REST) Array Template Class.
    4233 * @ingroup grp_rt_cpp
    4334 * @{
    4435 */
    45 
    46 
    47 
    48 /**
    49  * Abstract base class for serializing data objects.
    50  */
    51 class RT_DECL_CLASS RTCRestOutputBase
    52 {
    53 public:
    54     RTCRestOutputBase()
    55         : m_uIndent(0)
    56     { }
    57     virtual ~RTCRestOutputBase()
    58     { }
    59 
    60     /**
    61      * RTStrPrintf like function (see @ref pg_rt_str_format).
    62      *
    63      * @returns Number of bytes outputted.
    64      * @param   pszFormat   The format string.
    65      * @param   ...         Argument specfied in @a pszFormat.
    66      */
    67     size_t         printf(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(2, 3)
    68     {
    69         va_list va;
    70         va_start(va, pszFormat);
    71         size_t cchWritten = this->vprintf(pszFormat, va);
    72         va_end(va);
    73         return cchWritten;
    74     }
    75 
    76     /**
    77      * RTStrPrintfV like function (see @ref pg_rt_str_format).
    78      *
    79      * @returns Number of bytes outputted.
    80      * @param   pszFormat   The format string.
    81      * @param   va          Argument specfied in @a pszFormat.
    82      */
    83     virtual size_t vprintf(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(2, 0) = 0;
    84 
    85     /**
    86      * Sets the indentation level for use when pretty priting things.
    87      *
    88      * @returns Previous indentation level.
    89      * @param   uIndent     The indentation level.
    90      */
    91     unsigned setIndent(unsigned uIndent)
    92     {
    93         unsigned const uRet = m_uIndent;
    94         m_uIndent = uIndent;
    95         return uRet;
    96     }
    97 
    98     /**
    99      * Increases the indentation level.
    100      *
    101      * @returns Previous indentation level.
    102      */
    103     unsigned incrementIndent()
    104     {
    105         unsigned const uRet = m_uIndent;
    106         m_uIndent = uRet + 1;
    107         return uRet;
    108     }
    109 
    110 protected:
    111     /** The current indentation level. */
    112     unsigned m_uIndent;
    113 };
    114 
    115 
    116 /**
    117  * Serialize to a string object.
    118  */
    119 class RT_DECL_CLASS RTCRestOutputToString : public RTCRestOutputBase
    120 {
    121 public:
    122     /**
    123      * Creates an instance that appends to @a a_pDst.
    124      * @param   a_pDst      Pointer to the destination string object.
    125      *                      NULL is not accepted and will assert.
    126      * @param   a_fAppend   Whether to append to the current string value, or
    127      *                      nuke the string content before starting the output.
    128      */
    129     RTCRestOutputToString(RTCString *a_pDst, bool a_fAppend = false);
    130     virtual ~RTCRestOutputToString();
    131 
    132     virtual size_t vprintf(const char *pszFormat, va_list va) RT_OVERRIDE;
    133 
    134     /**
    135      * Finalizes the output and releases the string object to the caller.
    136      *
    137      * @returns The released string object.  NULL if we ran out of memory or if
    138      *          called already.
    139      *
    140      * @remark  This sets m_pDst to NULL and the object cannot be use for any
    141      *          more output afterwards.
    142      */
    143     virtual RTCString *finalize();
    144 
    145 
    146 protected:
    147     /** Pointer to the destination string.  NULL after finalize().   */
    148     RTCString  *m_pDst;
    149     /** Set if we ran out of memory and should ignore subsequent calls. */
    150     bool        m_fOutOfMemory;
    151 
    152     /** @callback_method_impl{FNRTSTROUTPUT} */
    153     static DECLCALLBACK(size_t) strOutput(void *pvArg, const char *pachChars, size_t cbChars);
    154 
    155     /* Make non-copyable (RTCNonCopyable causes warnings): */
    156     RTCRestOutputToString(RTCRestOutputToString const &);
    157     RTCRestOutputToString *operator=(RTCRestOutputToString const &);
    158 };
    159 
    160 
    161 /* forward decl: */
    162 class RTCRestJsonPrimaryCursor;
    163 
    164 /**
    165  * JSON cursor structure.
    166  *
    167  * This reduces the number of parameters passed around when deserializing JSON
    168  * input and also helps constructing full object name for logging and error reporting.
    169  */
    170 struct RT_DECL_CLASS RTCRestJsonCursor
    171 {
    172     /** Handle to the value being parsed. */
    173     RTJSONVAL                           m_hValue;
    174     /** Name of the value. */
    175     const char                         *m_pszName;
    176     /** Pointer to the parent, NULL if primary. */
    177     struct RTCRestJsonCursor const     *m_pParent;
    178     /** Pointer to the primary cursor structure. */
    179     RTCRestJsonPrimaryCursor           *m_pPrimary;
    180 
    181     RTCRestJsonCursor(struct RTCRestJsonCursor const &a_rParent)
    182         : m_hValue(NIL_RTJSONVAL), m_pszName(NULL), m_pParent(&a_rParent), m_pPrimary(a_rParent.m_pPrimary)
    183     { }
    184 
    185     RTCRestJsonCursor(RTJSONVAL hValue, const char *pszName, struct RTCRestJsonCursor *pParent)
    186         : m_hValue(hValue), m_pszName(pszName), m_pParent(pParent), m_pPrimary(pParent->m_pPrimary)
    187     { }
    188 
    189     RTCRestJsonCursor(RTJSONVAL hValue, const char *pszName)
    190         : m_hValue(hValue), m_pszName(pszName), m_pParent(NULL), m_pPrimary(NULL)
    191     { }
    192 
    193     ~RTCRestJsonCursor()
    194     {
    195         if (m_hValue != NIL_RTJSONVAL)
    196         {
    197             RTJsonValueRelease(m_hValue);
    198             m_hValue = NIL_RTJSONVAL;
    199         }
    200     }
    201 };
    202 
    203 
    204 /**
    205  * The primary JSON cursor class.
    206  */
    207 class RT_DECL_CLASS RTCRestJsonPrimaryCursor
    208 {
    209 public:
    210     /** The cursor for the first level. */
    211     RTCRestJsonCursor   m_Cursor;
    212     /** Error info keeper. */
    213     PRTERRINFO          m_pErrInfo;
    214 
    215     /** Creates a primary json cursor with optiona error info. */
    216     RTCRestJsonPrimaryCursor(RTJSONVAL hValue, const char *pszName, PRTERRINFO pErrInfo = NULL)
    217         : m_Cursor(hValue, pszName)
    218         , m_pErrInfo(pErrInfo)
    219     {
    220         m_Cursor.m_pPrimary = this;
    221     }
    222 
    223     virtual ~RTCRestJsonPrimaryCursor()
    224     {  }
    225 
    226     /**
    227      * Add an error message.
    228      *
    229      * @returns a_rc
    230      * @param   a_rCursor       The cursor reporting the error.
    231      * @param   a_rc            The status code.
    232      * @param   a_pszFormat     Format string.
    233      * @param   ...             Format string arguments.
    234      */
    235     virtual int addError(RTCRestJsonCursor const &a_rCursor, int a_rc, const char *a_pszFormat, ...);
    236 
    237     /**
    238      * Reports that the current field is not known.
    239      *
    240      * @returns Status to propagate.
    241      * @param   a_rCursor       The cursor for the field.
    242      */
    243     virtual int unknownField(RTCRestJsonCursor const &a_rCursor);
    244 
    245     /**
    246      * Copies the full path into pszDst.
    247      *
    248      * @returns pszDst
    249      * @param   a_rCursor       The cursor to start walking at.
    250      * @param   a_pszDst        Where to put the path.
    251      * @param   a_cbDst         Size of the destination buffer.
    252      */
    253     virtual char *getPath(RTCRestJsonCursor const &a_rCursor, char *a_pszDst, size_t a_cbDst) const;
    254 };
    255 
    256 
    257 /**
    258  * Abstract base class for REST data objects.
    259  *
    260  * The only information this keeps is the null indicator.
    261  */
    262 class RT_DECL_CLASS RTCRestObjectBase
    263 {
    264 public:
    265     RTCRestObjectBase();
    266     RTCRestObjectBase(RTCRestObjectBase const &a_rThat);
    267     virtual ~RTCRestObjectBase();
    268 
    269     /**
    270      * Tests if the object is @a null.
    271      * @returns true if null, false if not.
    272      */
    273     bool isNull(void) const { return m_fNullIndicator; };
    274 
    275     /**
    276      * Sets the object to @a null and fills it with defaults.
    277      * @returns IPRT status code (from resetToDefault).
    278      */
    279     virtual int setNull(void);
    280 
    281     /**
    282      * Sets the object to not-null state (i.e. undoes setNull()).
    283      * @remarks Only really important for strings.
    284      */
    285     virtual void setNotNull(void);
    286 
    287     /**
    288      * Resets the object to all default values.
    289      * @returns IPRT status code.
    290      */
    291     virtual int resetToDefault() = 0;
    292 
    293     /**
    294      * Serialize the object as JSON.
    295      *
    296      * @returns a_rDst
    297      * @param   a_rDst      The destination for the serialization.
    298      */
    299     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const = 0;
    300 
    301     /**
    302      * Deserialize object from the given JSON iterator.
    303      *
    304      * @returns IPRT status code.
    305      * @param   a_rCursor    The JSON cursor.
    306      */
    307     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) = 0;
    308 
    309     /**
    310      * Flags for toString().
    311      *
    312      * The kCollectionFormat_xxx bunch controls multiple values in arrays
    313      * are formatted.  They are ignored by everyone else.
    314      *
    315      * @note When adding collection format types, make sure to also
    316      *       update RTCRestArrayBase::toString().
    317      * @note Bit 24 is reserved (for kHdrField_MapCollection).
    318      */
    319     enum
    320     {
    321         kCollectionFormat_Unspecified = 0,  /**< Not specified. */
    322         kCollectionFormat_csv,              /**< Comma-separated list. */
    323         kCollectionFormat_ssv,              /**< Space-separated list. */
    324         kCollectionFormat_tsv,              /**< Tab-separated list. */
    325         kCollectionFormat_pipes,            /**< Pipe-separated list. */
    326         kCollectionFormat_multi,            /**< Special collection type that must be handled by caller of toString. */
    327         kCollectionFormat_Mask = 7,         /**< Collection type mask. */
    328 
    329         kToString_Append = 8                /**< Append to the string (rather than assigning). */
    330     };
    331 
    332     /**
    333      * String conversion.
    334      *
    335      * The default implementation of is a wrapper around serializeAsJson().
    336      *
    337      * @returns IPRT status code.
    338      * @param   a_pDst      Pointer to the destionation string.
    339      * @param   a_fFlags    kCollectionFormat_xxx.
    340      */
    341     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const;
    342 
    343     /**
    344      * String convertsion, naive variant.
    345      *
    346      * @returns String represenation.
    347      */
    348     RTCString toString() const;
    349 
    350     /**
    351      * Convert from (header) string value.
    352      *
    353      * The default implementation of is a wrapper around deserializeFromJson().
    354      *
    355      * @returns IPRT status code.
    356      * @param   a_rValue    The string value string to parse.
    357      * @param   a_pszName   Field name or similar.
    358      * @param   a_pErrInfo  Where to return additional error info.  Optional.
    359      * @param   a_fFlags    kCollectionFormat_xxx.
    360      */
    361     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    362                            uint32_t a_fFlags = kCollectionFormat_Unspecified);
    363 
    364     /** Type classification */
    365     typedef enum kTypeClass
    366     {
    367         kTypeClass_Invalid = 0,
    368         kTypeClass_Bool,                /**< Primitive: bool. */
    369         kTypeClass_Int64,               /**< Primitive: bool. */
    370         kTypeClass_Int32,               /**< Primitive: bool. */
    371         kTypeClass_Int16,               /**< Primitive: bool. */
    372         kTypeClass_Double,              /**< Primitive: bool. */
    373         kTypeClass_String,              /**< Primitive: bool. */
    374         kTypeClass_Object,              /**< Object (any kind of data model object). */
    375         kTypeClass_Array,               /**< Array (containing any kind of object). */
    376         kTypeClass_StringMap            /**< String map (containing any kind of object). */
    377     } kTypeClass;
    378 
    379     /**
    380      * Returns the object type class.
    381      */
    382     virtual kTypeClass typeClass(void) const;
    383 
    384     /**
    385      * Returns the object type name.
    386      */
    387     virtual const char *typeName(void) const = 0;
    388 
    389     /**
    390      * Factory method.
    391      * @returns Pointer to new object on success, NULL if out of memory.
    392      */
    393     typedef DECLCALLBACK(RTCRestObjectBase *) FNCREATEINSTANCE(void);
    394     /** Pointer to factory method. */
    395     typedef FNCREATEINSTANCE *PFNCREATEINSTANCE;
    396 
    397 
    398 protected:
    399     /** Null indicator.
    400      * @remarks The null values could be mapped onto C/C++ NULL pointer values,
    401      *          with the consequence that all data members in objects and such would
    402      *          have had to been allocated individually, even simple @a bool members.
    403      *          Given that we're overly paranoid about heap allocations (std::bad_alloc),
    404      *          it's more fitting to use a null indicator for us.
    405      */
    406     bool    m_fNullIndicator;
    407 };
    408 
    409 
    410 /**
    411  * Class wrapping 'bool'.
    412  */
    413 class RT_DECL_CLASS RTCRestBool : public RTCRestObjectBase
    414 {
    415 public:
    416     /** Default destructor. */
    417     RTCRestBool();
    418     /** Copy constructor. */
    419     RTCRestBool(RTCRestBool const &a_rThat);
    420     /** From value constructor. */
    421     RTCRestBool(bool fValue);
    422     /** Destructor. */
    423     virtual ~RTCRestBool();
    424     /** Copy assignment operator. */
    425     RTCRestBool &operator=(RTCRestBool const &a_rThat);
    426     /** Safe copy assignment method. */
    427     int assignCopy(RTCRestBool const &a_rThat);
    428     /** Assign value and clear null indicator. */
    429     void assignValue(bool a_fValue);
    430 
    431     /* Overridden methods: */
    432     virtual int resetToDefault() RT_OVERRIDE;
    433     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    434     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    435     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_OVERRIDE;
    436     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    437                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    438     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    439     virtual const char *typeName(void) const RT_OVERRIDE;
    440 
    441     /** Factory method. */
    442     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
    443 
    444 public:
    445     /** The value. */
    446     bool    m_fValue;
    447 };
    448 
    449 
    450 /**
    451  * Class wrapping 'int64_t'.
    452  */
    453 class RT_DECL_CLASS RTCRestInt64 : public RTCRestObjectBase
    454 {
    455 public:
    456     /** Default destructor. */
    457     RTCRestInt64();
    458     /** Copy constructor. */
    459     RTCRestInt64(RTCRestInt64 const &a_rThat);
    460     /** From value constructor. */
    461     RTCRestInt64(int64_t a_iValue);
    462     /** Destructor. */
    463     virtual ~RTCRestInt64();
    464     /** Copy assignment operator. */
    465     RTCRestInt64 &operator=(RTCRestInt64 const &a_rThat);
    466     /** Safe copy assignment method. */
    467     int assignCopy(RTCRestInt64 const &a_rThat);
    468     /** Assign value and clear null indicator. */
    469     void assignValue(int64_t a_iValue);
    470 
    471     /* Overridden methods: */
    472     virtual int resetToDefault() RT_OVERRIDE;
    473     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    474     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    475     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_OVERRIDE;
    476     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    477                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    478     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    479     virtual const char *typeName(void) const RT_OVERRIDE;
    480 
    481     /** Factory method. */
    482     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
    483 
    484 public:
    485     /** The value. */
    486     int64_t m_iValue;
    487 };
    488 
    489 
    490 /**
    491  * Class wrapping 'int32_t'.
    492  */
    493 class RT_DECL_CLASS RTCRestInt32 : public RTCRestObjectBase
    494 {
    495 public:
    496     /** Default destructor. */
    497     RTCRestInt32();
    498     /** Copy constructor. */
    499     RTCRestInt32(RTCRestInt32 const &a_rThat);
    500     /** From value constructor. */
    501     RTCRestInt32(int32_t iValue);
    502     /** Destructor. */
    503     virtual ~RTCRestInt32();
    504     /** Copy assignment operator. */
    505     RTCRestInt32 &operator=(RTCRestInt32 const &a_rThat);
    506     /** Safe copy assignment method. */
    507     int assignCopy(RTCRestInt32 const &a_rThat);
    508     /** Assign value and clear null indicator. */
    509     void assignValue(int32_t a_iValue);
    510 
    511     /* Overridden methods: */
    512     virtual int resetToDefault() RT_OVERRIDE;
    513     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    514     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    515     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_OVERRIDE;
    516     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    517                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    518     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    519     virtual const char *typeName(void) const RT_OVERRIDE;
    520 
    521     /** Factory method. */
    522     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
    523 
    524 public:
    525     /** The value. */
    526     int32_t m_iValue;
    527 };
    528 
    529 
    530 /**
    531  * Class wrapping 'int16_t'.
    532  */
    533 class RT_DECL_CLASS RTCRestInt16 : public RTCRestObjectBase
    534 {
    535 public:
    536     /** Default destructor. */
    537     RTCRestInt16();
    538     /** Copy constructor. */
    539     RTCRestInt16(RTCRestInt16 const &a_rThat);
    540     /** From value constructor. */
    541     RTCRestInt16(int16_t iValue);
    542     /** Destructor. */
    543     virtual ~RTCRestInt16();
    544     /** Copy assignment operator. */
    545     RTCRestInt16 &operator=(RTCRestInt16 const &a_rThat);
    546     /** Safe copy assignment method. */
    547     int assignCopy(RTCRestInt16 const &a_rThat);
    548     /** Assign value and clear null indicator. */
    549     void assignValue(int16_t a_iValue);
    550 
    551     /* Overridden methods: */
    552     virtual int resetToDefault() RT_OVERRIDE;
    553     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    554     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    555     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_OVERRIDE;
    556     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    557                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    558     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    559     virtual const char *typeName(void) const RT_OVERRIDE;
    560 
    561     /** Factory method. */
    562     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
    563 
    564 public:
    565     /** The value. */
    566     int16_t m_iValue;
    567 };
    568 
    569 
    570 /**
    571  * Class wrapping 'double'.
    572  */
    573 class RT_DECL_CLASS RTCRestDouble : public RTCRestObjectBase
    574 {
    575 public:
    576     /** Default destructor. */
    577     RTCRestDouble();
    578     /** Copy constructor. */
    579     RTCRestDouble(RTCRestDouble const &a_rThat);
    580     /** From value constructor. */
    581     RTCRestDouble(double rdValue);
    582     /** Destructor. */
    583     virtual ~RTCRestDouble();
    584     /** Copy assignment operator. */
    585     RTCRestDouble &operator=(RTCRestDouble const &a_rThat);
    586     /** Safe copy assignment method. */
    587     int assignCopy(RTCRestDouble const &a_rThat);
    588     /** Assign value and clear null indicator. */
    589     void assignValue(double a_rdValue);
    590 
    591     /* Overridden methods: */
    592     virtual int resetToDefault() RT_OVERRIDE;
    593     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    594     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    595     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_OVERRIDE;
    596     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    597                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    598     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    599     virtual const char *typeName(void) const RT_OVERRIDE;
    600 
    601     /** Factory method. */
    602     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
    603 
    604 public:
    605     /** The value. */
    606     double m_rdValue;
    607 };
    608 
    609 
    610 /**
    611  * Class wrapping 'RTCString'.
    612  */
    613 class RT_DECL_CLASS RTCRestString : public RTCString, public RTCRestObjectBase
    614 {
    615 public:
    616     /** Default destructor. */
    617     RTCRestString();
    618     /** Destructor. */
    619     virtual ~RTCRestString();
    620 
    621     /** Copy constructor. */
    622     RTCRestString(RTCRestString const &a_rThat);
    623     /** From value constructor. */
    624     RTCRestString(RTCString const &a_rThat);
    625     /** From value constructor. */
    626     RTCRestString(const char *a_pszSrc);
    627     /** Safe copy assignment method. */
    628     int assignCopy(RTCRestString const &a_rThat);
    629     /** Safe copy assignment method. */
    630     int assignCopy(RTCString const &a_rThat);
    631     /** Safe copy assignment method. */
    632     int assignCopy(const char *a_pszThat);
    633 
    634     /* Overridden methods: */
    635     virtual int setNull(void) RT_OVERRIDE; /* (ambigious, so overrider it to make sure.) */
    636     virtual int resetToDefault() RT_OVERRIDE;
    637     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    638     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    639     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_OVERRIDE;
    640     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    641                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    642     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    643     virtual const char *typeName(void) const RT_OVERRIDE;
    644 
    645     /** Factory method. */
    646     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
    647 };
    648 
    64936
    65037/**
     
    1036423
    1037424
    1038 /**
    1039  * Abstract base class for the RTCRestStringMap template.
    1040  */
    1041 class RT_DECL_CLASS RTCRestStringMapBase : public RTCRestObjectBase
    1042 {
    1043 public:
    1044     /** Default destructor. */
    1045     RTCRestStringMapBase();
    1046     /** Copy constructor. */
    1047     RTCRestStringMapBase(RTCRestStringMapBase const &a_rThat);
    1048     /** Destructor. */
    1049     virtual ~RTCRestStringMapBase();
    1050     /** Copy assignment operator. */
    1051     RTCRestStringMapBase &operator=(RTCRestStringMapBase const &a_rThat);
    1052 
    1053     /* Overridden methods: */
    1054     virtual int resetToDefault() RT_OVERRIDE;
    1055     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    1056     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    1057     // later?
    1058     //virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_OVERRIDE;
    1059     //virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    1060     //                       uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    1061     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    1062     virtual const char *typeName(void) const RT_OVERRIDE;
    1063 
    1064     /**
    1065      * Clear the content of the map.
    1066      */
    1067     void clear();
    1068 
    1069     /**
    1070      * Gets the number of entries in the map.
    1071      */
    1072     size_t size() const;
    1073 
    1074     /**
    1075      * Checks if the map contains the given key.
    1076      * @returns true if key found, false if not.
    1077      * @param   a_pszKey   The key to check fo.
    1078      */
    1079     bool constainsKey(const char *a_pszKey) const;
    1080 
    1081     /**
    1082      * Checks if the map contains the given key.
    1083      * @returns true if key found, false if not.
    1084      * @param   a_rStrKey   The key to check fo.
    1085      */
    1086     bool constainsKey(RTCString const &a_rStrKey) const;
    1087 
    1088     /**
    1089      * Remove any key-value pair with the given key.
    1090      * @returns true if anything was removed, false if not found.
    1091      * @param   a_pszKey    The key to remove.
    1092      */
    1093     bool remove(const char *a_pszKey);
    1094 
    1095     /**
    1096      * Remove any key-value pair with the given key.
    1097      * @returns true if anything was removed, false if not found.
    1098      * @param   a_rStrKey   The key to remove.
    1099      */
    1100     bool remove(RTCString const &a_rStrKey);
    1101 
    1102     /**
    1103      * Creates a new value and inserts it under the given key, returning the new value.
    1104      *
    1105      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    1106      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1107      * @param   a_ppValue   Where to return the pointer to the value.
    1108      * @param   a_pszKey    The key to put it under.
    1109      * @param   a_cchKey    The length of the key.  Default is the entire string.
    1110      * @param   a_fReplace  Whether to replace or fail on key collision.
    1111      */
    1112     int putNewValue(RTCRestObjectBase **a_ppValue, const char *a_pszKey, size_t a_cchKey = RTSTR_MAX, bool a_fReplace = false);
    1113 
    1114     /**
    1115      * Creates a new value and inserts it under the given key, returning the new value.
    1116      *
    1117      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    1118      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1119      * @param   a_ppValue   Where to return the pointer to the value.
    1120      * @param   a_pszKey    The key to put it under.
    1121      * @param   a_fReplace  Whether to replace or fail on key collision.
    1122      */
    1123     int putNewValue(RTCRestObjectBase **a_ppValue, RTCString const &a_rStrKey, bool a_fReplace = false);
    1124 
    1125 protected:
    1126     /** Map entry. */
    1127     typedef struct MapEntry
    1128     {
    1129         /** String space core. */
    1130         RTSTRSPACECORE      Core;
    1131         /** List node for enumeration. */
    1132         RTLISTNODE          ListEntry;
    1133         /** The key.
    1134          * @remarks Core.pszString points to the value of this object.  So, consider it const. */
    1135         RTCString           strKey;
    1136         /** The value. */
    1137         RTCRestObjectBase  *pValue;
    1138     } MapEntry;
    1139     /** The map tree. */
    1140     RTSTRSPACE          m_Map;
    1141     /** The enumeration list head (MapEntry). */
    1142     RTLISTANCHOR        m_ListHead;
    1143     /** Number of map entries. */
    1144     size_t              m_cEntries;
    1145 
    1146 public:
    1147     /** @name Map Iteration
    1148      * @{  */
    1149     /** Const iterator. */
    1150     class ConstIterator
    1151     {
    1152     private:
    1153         MapEntry            *m_pCur;
    1154         ConstIterator();
    1155     protected:
    1156         ConstIterator(MapEntry *a_pEntry) : m_pCur(a_pEntry) { }
    1157     public:
    1158         ConstIterator(ConstIterator const &a_rThat) : m_pCur(a_rThat.m_pCur) { }
    1159 
    1160         /** Gets the key string. */
    1161         RTCString const         &getKey()   { return m_pCur->strKey; }
    1162         /** Gets poitner to the value object. */
    1163         RTCRestObjectBase const *getValue() { return m_pCur->pValue; }
    1164 
    1165         /** Advance to the next map entry. */
    1166         ConstIterator &operator++()
    1167         {
    1168             m_pCur = RTListNodeGetNextCpp(&m_pCur->ListEntry, MapEntry, ListEntry);
    1169             return *this;
    1170         }
    1171 
    1172         /** Advance to the previous map entry. */
    1173         ConstIterator &operator--()
    1174         {
    1175             m_pCur = RTListNodeGetPrevCpp(&m_pCur->ListEntry, MapEntry, ListEntry);
    1176             return *this;
    1177         }
    1178 
    1179         /** Compare equal. */
    1180         bool operator==(ConstIterator const &a_rThat) { return m_pCur == a_rThat.m_pCur; }
    1181         /** Compare not equal. */
    1182         bool operator!=(ConstIterator const &a_rThat) { return m_pCur != a_rThat.m_pCur; }
    1183 
    1184         /* Map class must be friend so it can use the MapEntry constructor. */
    1185         friend class RTCRestStringMapBase;
    1186     };
    1187 
    1188     /** Returns iterator for the first map entry (unless it's empty and it's also the end). */
    1189     ConstIterator begin() const { return ConstIterator(RTListGetFirstCpp(&m_ListHead, MapEntry, ListEntry)); }
    1190     /** Returns iterator for the last map entry (unless it's empty and it's also the end). */
    1191     ConstIterator last() const  { return ConstIterator(RTListGetLastCpp(&m_ListHead, MapEntry, ListEntry)); }
    1192     /** Returns the end iterator.  This does not ever refer to an actual map entry. */
    1193     ConstIterator end() const   { return ConstIterator(RT_FROM_CPP_MEMBER(&m_ListHead, MapEntry, ListEntry)); }
    1194     /** @} */
    1195 
    1196 
    1197 protected:
    1198     /**
    1199      * Wrapper around the value constructor.
    1200      *
    1201      * @returns Pointer to new value object on success, NULL if out of memory.
    1202      */
    1203     virtual RTCRestObjectBase *createValue(void) = 0;
    1204 
    1205     /**
    1206      * Wrapper around the value copy constructor.
    1207      *
    1208      * @returns Pointer to copy on success, NULL if out of memory.
    1209      * @param   a_pSrc      The value to copy.
    1210      */
    1211     virtual RTCRestObjectBase *createValueCopy(RTCRestObjectBase const *a_pSrc) = 0;
    1212 
    1213     /**
    1214      * Worker for the copy constructor and the assignment operator.
    1215      *
    1216      * This will use createEntryCopy to do the copying.
    1217      *
    1218      * @returns VINF_SUCCESS on success, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1219      * @param   a_rThat     The map to copy.  Caller makes 100% sure the it has
    1220      *                      the same type as the destination.
    1221      * @param   a_fThrow    Whether to throw error.
    1222      */
    1223     int copyMapWorker(RTCRestStringMapBase const &a_rThat, bool a_fThrow);
    1224 
    1225     /**
    1226      * Worker for performing inserts.
    1227      *
    1228      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    1229      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1230      * @param   a_pszKey        The key.
    1231      * @param   a_pValue        The value to insert.  Ownership is transferred to the map on success.
    1232      * @param   a_fReplace      Whether to replace existing key-value pair with matching key.
    1233      * @param   a_cchKey        The key length, the whole string by default.
    1234      */
    1235     int putWorker(const char *a_pszKey, RTCRestObjectBase *a_pValue, bool a_fReplace, size_t a_cchKey = RTSTR_MAX);
    1236 
    1237     /**
    1238      * Worker for performing inserts.
    1239      *
    1240      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    1241      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1242      * @param   a_pszKey        The key.
    1243      * @param   a_rValue        The value to copy into the map.
    1244      * @param   a_fReplace      Whether to replace existing key-value pair with matching key.
    1245      * @param   a_cchKey        The key length, the whole string by default.
    1246      */
    1247     int putCopyWorker(const char *a_pszKey, RTCRestObjectBase const &a_rValue, bool a_fReplace, size_t a_cchKey = RTSTR_MAX);
    1248 
    1249     /**
    1250      * Worker for getting the value corresponding to the given key.
    1251      *
    1252      * @returns Pointer to the value object if found, NULL if key not in the map.
    1253      * @param   a_pszKey        The key which value to look up.
    1254      */
    1255     RTCRestObjectBase *getWorker(const char *a_pszKey);
    1256 
    1257     /**
    1258      * Worker for getting the value corresponding to the given key, const variant.
    1259      *
    1260      * @returns Pointer to the value object if found, NULL if key not in the map.
    1261      * @param   a_pszKey        The key which value to look up.
    1262      */
    1263     RTCRestObjectBase const *getWorker(const char *a_pszKey) const;
    1264 
    1265 private:
    1266     static DECLCALLBACK(int) stringSpaceDestructorCallback(PRTSTRSPACECORE pStr, void *pvUser);
    1267 };
    1268 
    1269 
    1270 /**
    1271  * Limited map class.
    1272  */
    1273 template<class ValueType> class RTCRestStringMap : public RTCRestStringMapBase
    1274 {
    1275 public:
    1276     /** Default constructor, creates emtpy map. */
    1277     RTCRestStringMap()
    1278         : RTCRestStringMapBase()
    1279     {}
    1280 
    1281     /** Copy constructor. */
    1282     RTCRestStringMap(RTCRestStringMap const &a_rThat)
    1283         : RTCRestStringMapBase()
    1284     {
    1285         copyMapWorker(a_rThat, true /*a_fThrow*/);
    1286     }
    1287 
    1288     /** Destructor. */
    1289     virtual ~RTCRestStringMap()
    1290     {
    1291        /* nothing to do here. */
    1292     }
    1293 
    1294     /** Copy assignment operator. */
    1295     RTCRestStringMap &operator=(RTCRestStringMap const &a_rThat)
    1296     {
    1297         copyMapWorker(a_rThat, true /*a_fThrow*/);
    1298         return *this;
    1299     }
    1300 
    1301     /** Safe copy assignment method. */
    1302     int assignCopy(RTCRestStringMap const &a_rThat)
    1303     {
    1304         return copyMapWorker(a_rThat, false /*a_fThrow*/);
    1305     }
    1306 
    1307     /** Factory method. */
    1308     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void)
    1309     {
    1310         return new (std::nothrow) RTCRestStringMap<ValueType>();
    1311     }
    1312 
    1313     /** Factory method for values. */
    1314     static DECLCALLBACK(RTCRestObjectBase *) createValueInstance(void)
    1315     {
    1316         return new (std::nothrow) ValueType();
    1317     }
    1318 
    1319     /**
    1320      * Inserts the given object into the map.
    1321      *
    1322      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    1323      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1324      * @param   a_pszKey        The key.
    1325      * @param   a_pValue        The value to insert.  Ownership is transferred to the map on success.
    1326      * @param   a_fReplace      Whether to replace existing key-value pair with matching key.
    1327      */
    1328     int put(const char *a_pszKey, ValueType *a_pValue, bool a_fReplace = false)
    1329     {
    1330         return putWorker(a_pszKey, a_pValue, a_fReplace);
    1331     }
    1332 
    1333     /**
    1334      * Inserts the given object into the map.
    1335      *
    1336      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    1337      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1338      * @param   a_rStrKey       The key.
    1339      * @param   a_pValue        The value to insert.  Ownership is transferred to the map on success.
    1340      * @param   a_fReplace      Whether to replace existing key-value pair with matching key.
    1341      */
    1342     int put(RTCString const &a_rStrKey, ValueType *a_pValue, bool a_fReplace = false)
    1343     {
    1344         return putWorker(a_rStrKey.c_str(), a_pValue, a_fReplace, a_rStrKey.length());
    1345     }
    1346 
    1347     /**
    1348      * Inserts a copy of the given object into the map.
    1349      *
    1350      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    1351      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1352      * @param   a_pszKey        The key.
    1353      * @param   a_rValue        The value to insert a copy of.
    1354      * @param   a_fReplace      Whether to replace existing key-value pair with matching key.
    1355      */
    1356     int putCopy(const char *a_pszKey, const ValueType &a_rValue, bool a_fReplace = false)
    1357     {
    1358         return putCopyWorker(a_pszKey, a_rValue, a_fReplace);
    1359     }
    1360 
    1361     /**
    1362      * Inserts a copy of the given object into the map.
    1363      *
    1364      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    1365      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1366      * @param   a_rStrKey       The key.
    1367      * @param   a_rValue        The value to insert a copy of.
    1368      * @param   a_fReplace      Whether to replace existing key-value pair with matching key.
    1369      */
    1370     int putCopy(RTCString const &a_rStrKey, const ValueType &a_rValue, bool a_fReplace = false)
    1371     {
    1372         return putCopyWorker(a_rStrKey.c_str(), a_rValue, a_fReplace, a_rStrKey.length());
    1373     }
    1374 
    1375     /**
    1376      * Gets the value corresponding to the given key.
    1377      *
    1378      * @returns Pointer to the value object if found, NULL if key not in the map.
    1379      * @param   a_pszKey        The key which value to look up.
    1380      */
    1381     ValueType *get(const char *a_pszKey)
    1382     {
    1383         return (ValueType *)getWorker(a_pszKey);
    1384     }
    1385 
    1386     /**
    1387      * Gets the value corresponding to the given key.
    1388      *
    1389      * @returns Pointer to the value object if found, NULL if key not in the map.
    1390      * @param   a_rStrKey       The key which value to look up.
    1391      */
    1392     ValueType *get(RTCString const &a_rStrKey)
    1393     {
    1394         return (ValueType *)getWorker(a_rStrKey.c_str());
    1395     }
    1396 
    1397     /**
    1398      * Gets the const value corresponding to the given key.
    1399      *
    1400      * @returns Pointer to the value object if found, NULL if key not in the map.
    1401      * @param   a_pszKey        The key which value to look up.
    1402      */
    1403     ValueType const *get(const char *a_pszKey) const
    1404     {
    1405         return (ValueType const *)getWorker(a_pszKey);
    1406     }
    1407 
    1408     /**
    1409      * Gets the const value corresponding to the given key.
    1410      *
    1411      * @returns Pointer to the value object if found, NULL if key not in the map.
    1412      * @param   a_rStrKey       The key which value to look up.
    1413      */
    1414     ValueType const *get(RTCString const &a_rStrKey) const
    1415     {
    1416         return (ValueType const *)getWorker(a_rStrKey.c_str());
    1417     }
    1418 
    1419     /** @todo enumerator*/
    1420 
    1421 protected:
    1422     virtual RTCRestObjectBase *createValue(void) RT_OVERRIDE
    1423     {
    1424         return new (std::nothrow) ValueType();
    1425     }
    1426 
    1427     virtual RTCRestObjectBase *createValueCopy(RTCRestObjectBase const *a_pSrc) RT_OVERRIDE
    1428     {
    1429         ValueType *pCopy = new (std::nothrow) ValueType();
    1430         if (pCopy)
    1431         {
    1432             int rc = pCopy->assignCopy(*(ValueType const *)a_pSrc);
    1433             if (RT_SUCCESS(rc))
    1434                 return pCopy;
    1435             delete pCopy;
    1436         }
    1437         return NULL;
    1438     }
    1439 };
    1440 
    1441 
    1442 /**
    1443  * Dynamic REST object.
    1444  *
    1445  * @todo figure this one out. it's possible this is only used in maps and
    1446  *       could be a specialized map implementation.
    1447  */
    1448 class /*RT_DECL_CLASS*/ RTCRestObject : public RTCRestObjectBase
    1449 {
    1450 public:
    1451     /** Default destructor. */
    1452     RTCRestObject();
    1453     /** Destructor. */
    1454     virtual ~RTCRestObject();
    1455 
    1456     /** Copy constructor. */
    1457     RTCRestObject(RTCRestObject const &a_rThat);
    1458     /** Copy assignment operator. */
    1459     RTCRestObject &operator=(RTCRestObject const &a_rThat);
    1460     /** Safe Safe copy assignment method. */
    1461     int assignCopy(RTCRestObject const &a_rThat);
    1462 
    1463     /* Overridden methods: */
    1464     virtual int setNull(void) RT_OVERRIDE;
    1465     virtual int resetToDefault() RT_OVERRIDE;
    1466     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    1467     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    1468     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_OVERRIDE;
    1469     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    1470                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    1471     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    1472     virtual const char *typeName(void) const RT_OVERRIDE;
    1473 
    1474     /** Factory method. */
    1475     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
    1476 
    1477 protected:
    1478     /** @todo figure out the value stuff here later... */
    1479 };
    1480 
    1481 
    1482 /**
    1483  * Base class for REST client requests.
    1484  *
    1485  * This encapsulates parameters and helps transform them into a HTTP request.
    1486  *
    1487  * Parameters can be transfered in a number of places:
    1488  *      - Path part of the URL.
    1489  *      - Query part of the URL.
    1490  *      - HTTP header fields.
    1491  *      - FORM body.
    1492  *      - JSON body.
    1493  *      - XML body.
    1494  *      - ...
    1495  *
    1496  * They can be require or optional.  The latter may have default values.  In
    1497  * swagger 3 they can also be nullable, which means the null-indicator cannot
    1498  * be used for tracking optional parameters.
    1499  */
    1500 class RT_DECL_CLASS RTCRestClientRequestBase
    1501 {
    1502 public:
    1503     RTCRestClientRequestBase();
    1504     virtual ~RTCRestClientRequestBase();
    1505     RTCRestClientRequestBase(RTCRestClientRequestBase const &a_rThat);
    1506     RTCRestClientRequestBase &operator=(RTCRestClientRequestBase const &a_rThat);
    1507 
    1508     /**
    1509      * Reset all members to default values.
    1510      * @returns IPRT status code.
    1511      */
    1512     virtual int resetToDefault() = 0;
    1513 
    1514     /**
    1515      * Prepares the HTTP handle for transmitting this request.
    1516      *
    1517      * @returns IPRT status code.
    1518      * @param   a_pStrPath  Where to set path parameters.  Will be appended to the base path.
    1519      * @param   a_pStrQuery Where to set query parameters.
    1520      * @param   a_hHttp     Where to set header parameters and such.
    1521      * @param   a_pStrBody  Where to set body parameters.
    1522      */
    1523     virtual int xmitPrepare(RTCString *a_pStrPath, RTCString *a_pStrQuery, RTHTTP a_hHttp, RTCString *a_pStrBody) const = 0;
    1524 
    1525     /**
    1526      * Always called after the request has been transmitted.
    1527      *
    1528      * @param   a_rcStatus  Negative numbers are IPRT errors, positive are HTTP status codes.
    1529      * @param   a_hHttp     The HTTP handle the request was performed on.
    1530      */
    1531     virtual void xmitComplete(int a_rcStatus, RTHTTP a_hHttp) const = 0;
    1532 
    1533     /**
    1534      * Checks if there are were any assignment errors.
    1535      */
    1536     bool hasAssignmentErrors() const { return m_fErrorSet != 0; }
    1537 
    1538 protected:
    1539     /** Set of fields that have been explicitly assigned a value. */
    1540     uint64_t m_fIsSet;
    1541     /** Set of fields where value assigning failed. */
    1542     uint64_t m_fErrorSet;
    1543 
    1544     /** Path parameter descriptor. */
    1545     typedef struct
    1546     {
    1547         const char                 *pszName;    /**< The name string to replace (including {}). */
    1548         size_t                      cchName;    /**< Length of pszName. */
    1549         uint32_t                    fFlags;     /**< The toString flags. */
    1550         uint8_t                     iBitNo;     /**< The parameter bit number. */
    1551     } PATHPARAMDESC;
    1552 
    1553     /** Path parameter state. */
    1554     typedef struct
    1555     {
    1556         RTCRestObjectBase const    *pObj;       /**< Pointer to the parameter object. */
    1557         size_t                      offName;    /**< Maintained by worker. */
    1558     } PATHPARAMSTATE;
    1559 
    1560     /**
    1561      * Do path parameters.
    1562      *
    1563      * @returns IPRT status code
    1564      * @param   a_pStrPath          The destination path.
    1565      * @param   a_pszPathTemplate   The path template string.
    1566      * @param   a_cchPathTemplate   The length of the path template string.
    1567      * @param   a_paPathParams      The path parameter descriptors (static).
    1568      * @param   a_paPathParamStates The path parameter objects and states.
    1569      * @param   a_cPathParams       Number of path parameters.
    1570      */
    1571     int doPathParameters(RTCString *a_pStrPath, const char *a_pszPathTemplate, size_t a_cchPathTemplate,
    1572                          PATHPARAMDESC const *a_paPathParams, PATHPARAMSTATE *a_paPathParamStates, size_t a_cPathParams) const;
    1573 
    1574     /** Query parameter descriptor. */
    1575     typedef struct
    1576     {
    1577         const char *pszName;            /**< The parameter name. */
    1578         uint32_t    fFlags;             /**< The toString flags. */
    1579         bool        fRequired;          /**< Required or not. */
    1580         uint8_t     iBitNo;             /**< The parameter bit number. */
    1581     } QUERYPARAMDESC;
    1582 
    1583     /**
    1584      * Do query parameters.
    1585      *
    1586      * @returns IPRT status code
    1587      * @param   a_pStrQuery         The destination string.
    1588      * @param   a_paQueryParams     The query parameter descriptors.
    1589      * @param   a_papQueryParamObjs The query parameter objects, parallel to @a a_paQueryParams.
    1590      * @param   a_cQueryParams      Number of query parameters.
    1591      */
    1592     int doQueryParameters(RTCString *a_pStrQuery, QUERYPARAMDESC const *a_paQueryParams,
    1593                           RTCRestObjectBase const **a_papQueryParamObjs, size_t a_cQueryParams) const;
    1594 
    1595     /** Header parameter descriptor. */
    1596     typedef struct
    1597     {
    1598         const char *pszName;            /**< The parameter name. */
    1599         uint32_t    fFlags;             /**< The toString flags. */
    1600         bool        fRequired;          /**< Required or not. */
    1601         uint8_t     iBitNo;             /**< The parameter bit number. */
    1602         bool        fMapCollection;     /**< Collect headers starting with pszName into a map. */
    1603     } HEADERPARAMDESC;
    1604 
    1605     /**
    1606      * Do header parameters.
    1607      *
    1608      * @returns IPRT status code
    1609      * @param   a_hHttp                 Where to set header parameters.
    1610      * @param   a_paHeaderParams        The header parameter descriptors.
    1611      * @param   a_papHeaderParamObjs    The header parameter objects, parallel to @a a_paHeaderParams.
    1612      * @param   a_cHeaderParams         Number of header parameters.
    1613      */
    1614     int doHeaderParameters(RTHTTP a_hHttp, HEADERPARAMDESC const *a_paHeaderParams,
    1615                            RTCRestObjectBase const **a_papHeaderParamObjs, size_t a_cHeaderParams) const;
    1616 };
    1617 
    1618 
    1619 /**
    1620  * Base class for REST client responses.
    1621  */
    1622 class RT_DECL_CLASS RTCRestClientResponseBase
    1623 {
    1624 public:
    1625     /** Default constructor. */
    1626     RTCRestClientResponseBase();
    1627     /** Destructor. */
    1628     virtual ~RTCRestClientResponseBase();
    1629     /** Copy constructor. */
    1630     RTCRestClientResponseBase(RTCRestClientResponseBase const &a_rThat);
    1631     /** Copy assignment operator. */
    1632     RTCRestClientResponseBase &operator=(RTCRestClientResponseBase const &a_rThat);
    1633 
    1634     /**
    1635      * Resets the object state.
    1636      */
    1637     virtual void reset(void);
    1638 
    1639     /**
    1640      * Prepares the HTTP handle for receiving the response.
    1641      *
    1642      * This may install callbacks and such like.
    1643      *
    1644      * @returns IPRT status code.
    1645      * @param   a_hHttp     The HTTP handle to prepare for receiving.
    1646      * @param   a_pppvHdr   If a header callback handler is installed, set the value pointed to to NULL.
    1647      * @param   a_pppvBody  If a body callback handler is installed, set the value pointed to to NULL.
    1648      */
    1649     virtual int receivePrepare(RTHTTP a_hHttp, void ***a_pppvHdr, void ***a_pppvBody);
    1650 
    1651     /**
    1652      * Called when the HTTP request has been completely received.
    1653      *
    1654      * @param   a_rcStatus  Negative numbers are IPRT errors, positive are HTTP status codes.
    1655      * @param   a_hHttp     The HTTP handle the request was performed on.
    1656      *                      This can be NIL_RTHTTP should something fail early, in
    1657      *                      which case it is possible receivePrepare() wasn't called.
    1658      *
    1659      * @note    Called before consumeHeaders() and consumeBody().
    1660      */
    1661     virtual void receiveComplete(int a_rcStatus, RTHTTP a_hHttp);
    1662 
    1663     /**
    1664      * Callback that consumes HTTP header data from the server.
    1665      *
    1666      * @param   a_pchData  Body data.
    1667      * @param   a_cbData   Amount of body data.
    1668      *
    1669      * @note    Called after receiveComplete()..
    1670      */
    1671     virtual void consumeHeaders(const char *a_pchData, size_t a_cbData);
    1672 
    1673     /**
    1674      * Callback that consumes HTTP body data from the server.
    1675      *
    1676      * @param   a_pchData  Body data.
    1677      * @param   a_cbData   Amount of body data.
    1678      *
    1679      * @note    Called after consumeHeaders().
    1680      */
    1681     virtual void consumeBody(const char *a_pchData, size_t a_cbData);
    1682 
    1683     /**
    1684      * Called after status, headers and body all have been presented.
    1685      *
    1686      * @returns IPRT status code.
    1687      */
    1688     virtual void receiveFinal();
    1689 
    1690     /**
    1691      * Getter for m_rcStatus.
    1692      * @returns Negative numbers are IPRT errors, positive are HTTP status codes.
    1693      */
    1694     int getStatus() { return m_rcStatus; }
    1695 
    1696     /**
    1697      * Getter for m_rcHttp.
    1698      * @returns HTTP status code or VERR_NOT_AVAILABLE.
    1699      */
    1700     int getHttpStatus() { return m_rcHttp; }
    1701 
    1702     /**
    1703      * Getter for m_pErrInfo.
    1704      */
    1705     PCRTERRINFO getErrInfo(void) const { return m_pErrInfo; }
    1706 
    1707     /**
    1708      * Getter for m_strContentType.
    1709      */
    1710     RTCString const &getContentType(void) const { return m_strContentType; }
    1711 
    1712 
    1713 protected:
    1714     /** Negative numbers are IPRT errors, positive are HTTP status codes. */
    1715     int         m_rcStatus;
    1716     /** The HTTP status code, VERR_NOT_AVAILABLE if not set. */
    1717     int         m_rcHttp;
    1718     /** Error information. */
    1719     PRTERRINFO  m_pErrInfo;
    1720     /** The value of the Content-Type header field. */
    1721     RTCString   m_strContentType;
    1722 
    1723     PRTERRINFO  getErrInfoInternal(void);
    1724     void        deleteErrInfo(void);
    1725     void        copyErrInfo(PCRTERRINFO pErrInfo);
    1726 
    1727     /**
    1728      * Reports an error (or warning if a_rc non-negative).
    1729      *
    1730      * @returns a_rc
    1731      * @param   a_rc        The status code to report and return.  The first
    1732      *                      error status is assigned to m_rcStatus, subsequent
    1733      *                      ones as well as informational statuses are not
    1734      *                      recorded by m_rcStatus.
    1735      * @param   a_pszFormat The message format string.
    1736      * @param   ...         Message arguments.
    1737      */
    1738     int addError(int a_rc, const char *a_pszFormat, ...);
    1739 
    1740     /** Field flags. */
    1741     enum
    1742     {
    1743         /** Collection map, name is a prefix followed by '*'. */
    1744         kHdrField_MapCollection   = RT_BIT_32(24),
    1745     };
    1746 
    1747     /** Header field descriptor. */
    1748     typedef struct
    1749     {
    1750         /** The header field name. */
    1751         const char *pszName;
    1752         /** The length of the field name.*/
    1753         uint32_t    cchName;
    1754         /** Flags, TBD. */
    1755         uint32_t    fFlags;
    1756         /** Object factory. */
    1757         RTCRestObjectBase::PFNCREATEINSTANCE pfnCreateInstance;
    1758     } HEADERFIELDDESC;
    1759 
    1760     /**
    1761      * Helper that extracts fields from the HTTP headers.
    1762      *
    1763      * @param   a_paFieldDescs      Pointer to an array of field descriptors.
    1764      * @param   a_pappFieldValues   Pointer to a parallel array of value pointer pointers.
    1765      * @param   a_cFields           Number of field descriptors..
    1766      * @param   a_pchData           The header blob to search.
    1767      * @param   a_cbData            The size of the header blob to search.
    1768      */
    1769     void extracHeaderFieldsFromBlob(HEADERFIELDDESC const *a_paFieldDescs, RTCRestObjectBase ***a_pappFieldValues,
    1770                                     size_t a_cFields, const char *a_pchData, size_t a_cbData);
    1771 
    1772     /**
    1773      * Helper that extracts a header field.
    1774      *
    1775      * @retval  VINF_SUCCESS
    1776      * @retval  VERR_NOT_FOUND if not found.
    1777      * @retval  VERR_NO_STR_MEMORY
    1778      * @param   a_pszField  The header field header name.
    1779      * @param   a_cchField  The length of the header field name.
    1780      * @param   a_pchData   The header blob to search.
    1781      * @param   a_cbData    The size of the header blob to search.
    1782      * @param   a_pStrDst   Where to store the header value on successs.
    1783      */
    1784     int extractHeaderFromBlob(const char *a_pszField, size_t a_cchField, const char *a_pchData, size_t a_cbData,
    1785                               RTCString *a_pStrDst);
    1786 
    1787     /**
    1788      * Helper that does the deserializing of the response body.
    1789      *
    1790      * @param   a_pDst      The destination object for the body content.
    1791      * @param   a_pchData   The body blob.
    1792      * @param   a_cbData    The size of the body blob.
    1793      */
    1794     void deserializeBody(RTCRestObjectBase *a_pDst, const char *a_pchData, size_t a_cbData);
    1795 
    1796     /**
    1797      * Primary json cursor for parsing bodies.
    1798      */
    1799     class PrimaryJsonCursorForBody : public RTCRestJsonPrimaryCursor
    1800     {
    1801     public:
    1802         RTCRestClientResponseBase *m_pThat; /**< Pointer to response object. */
    1803         PrimaryJsonCursorForBody(RTJSONVAL hValue, const char *pszName, RTCRestClientResponseBase *a_pThat);
    1804         virtual int addError(RTCRestJsonCursor const &a_rCursor, int a_rc, const char *a_pszFormat, ...) RT_OVERRIDE;
    1805         virtual int unknownField(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    1806     };
    1807 };
    1808 
    1809 
    1810 /**
    1811  * Base class for REST client responses.
    1812  */
    1813 class RT_DECL_CLASS RTCRestClientApiBase
    1814 {
    1815 public:
    1816     RTCRestClientApiBase()
    1817         : m_hHttp(NIL_RTHTTP)
    1818     {}
    1819     virtual ~RTCRestClientApiBase();
    1820 
    1821     /** @name Base path (URL) handling.
    1822      * @{ */
    1823     /**
    1824      * Gets the base path we're using.
    1825      *
    1826      * @returns Base URL string.  If empty, we'll be using the default one.
    1827      */
    1828     RTCString const &getBasePath(void) const
    1829     {
    1830         return m_strBasePath;
    1831     }
    1832 
    1833     /**
    1834      * Sets the base path (URL) to use when talking to the server.
    1835      *
    1836      * Setting the base path is only required if there is a desire to use a
    1837      * different server from the one specified in the API specification, like
    1838      * for instance regional one.
    1839      *
    1840      * @param   a_pszPath   The base path to use.
    1841      */
    1842     virtual void setBasePath(const char *a_pszPath)
    1843     {
    1844         m_strBasePath = a_pszPath;
    1845     }
    1846 
    1847     /**
    1848      * Sets the base path (URL) to use when talking to the server.
    1849      *
    1850      * Setting the base path is only required if there is a desire to use a
    1851      * different server from the one specified in the API specification, like
    1852      * for instance regional one.
    1853      *
    1854      * @param   a_strPath   The base path to use.
    1855      * @note    Defers to the C-string variant.
    1856      */
    1857     void setBasePath(RTCString const &a_strPath) { setBasePath(a_strPath.c_str()); }
    1858 
    1859     /**
    1860      * Gets the default base path (URL) as specified in the specs.
    1861      *
    1862      * @returns Base path (URL) string.
    1863      */
    1864     virtual const char *getDefaultBasePath() = 0;
    1865     /** @} */
    1866 
    1867 protected:
    1868     /** Handle to the HTTP connection object. */
    1869     RTHTTP  m_hHttp;
    1870     /** The base path to use. */
    1871     RTCString m_strBasePath;
    1872 
    1873     /* Make non-copyable (RTCNonCopyable causes warnings): */
    1874     RTCRestClientApiBase(RTCRestOutputToString const &);
    1875     RTCRestClientApiBase *operator=(RTCRestOutputToString const &);
    1876 
    1877     /**
    1878      * Re-initializes the HTTP instance.
    1879      *
    1880      * @returns IPRT status code.
    1881      */
    1882     virtual int reinitHttpInstance();
    1883 
    1884     /**
    1885      * Implements stuff for making an API call.
    1886      *
    1887      * @returns a_pResponse->getStatus()
    1888      * @param   a_rRequest      Reference to the request object.
    1889      * @param   a_enmHttpMethod The HTTP request method.
    1890      * @param   a_pResponse     Pointer to the response object.
    1891      * @param   a_pszMethod     The method name, for logging purposes.
    1892      */
    1893     virtual int doCall(RTCRestClientRequestBase const &a_rRequest, RTHTTPMETHOD a_enmHttpMethod,
    1894                        RTCRestClientResponseBase *a_pResponse, const char *a_pszMethod);
    1895 
    1896 };
    1897 
    1898425/** @} */
    1899426
  • trunk/include/iprt/cpp/restbase.h

    r74024 r74025  
    2727#define ___iprt_cpp_restbase_h
    2828
     29#include <iprt/cdefs.h>
    2930#include <iprt/types.h>
    30 #include <iprt/assert.h>
    31 #include <iprt/err.h>
    32 #include <iprt/http.h>
    3331#include <iprt/json.h>
    34 #include <iprt/list.h>
    35 #include <iprt/string.h>
    3632#include <iprt/stdarg.h>
    3733#include <iprt/cpp/ministring.h>
    38 #include <iprt/cpp/utils.h>
    3934
    4035
     
    649644
    650645/**
    651  * Abstract base class for the RTCRestArray template.
    652  */
    653 class RT_DECL_CLASS RTCRestArrayBase : public RTCRestObjectBase
    654 {
    655 public:
    656     /** Default destructor. */
    657     RTCRestArrayBase();
    658     /** Destructor. */
    659     virtual ~RTCRestArrayBase();
    660 
    661     /* Overridden methods: */
    662     virtual int resetToDefault() RT_OVERRIDE;
    663     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    664     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    665     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_OVERRIDE;
    666     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    667                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    668     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    669     virtual const char *typeName(void) const RT_OVERRIDE;
    670 
    671     /**
    672      * Clear the content of the map.
    673      */
    674     void clear();
    675 
    676     /**
    677      * Check if an list contains any items.
    678      *
    679      * @return   True if there is more than zero items, false otherwise.
    680      */
    681     bool isEmpty() const
    682     {
    683         return m_cElements == 0;
    684     }
    685 
    686     /**
    687      * Gets the number of entries in the map.
    688      */
    689     size_t size() const
    690     {
    691         return m_cElements;
    692     }
    693 
    694     /**
    695      * Returns the base object pointer at a given index.
    696      *
    697      * @returns The base object at @a a_idx, NULL if out of range.
    698      * @param   a_idx           The array index.
    699      */
    700     RTCRestObjectBase *atBase(size_t a_idx)
    701     {
    702         if (a_idx < m_cElements)
    703             return m_papElements[a_idx];
    704         return NULL;
    705     }
    706 
    707     /**
    708      * Returns the const base object pointer at a given index.
    709      *
    710      * @returns The base object at @a a_idx, NULL if out of range.
    711      * @param   a_idx           The array index.
    712      */
    713     RTCRestObjectBase const *atBase(size_t a_idx) const
    714     {
    715         if (a_idx < m_cElements)
    716             return m_papElements[a_idx];
    717         return NULL;
    718     }
    719 
    720     /**
    721      * Removes the element at @a a_idx.
    722      * @returns true if @a a_idx is valid, false if out of range.
    723      * @param   a_idx       The index of the element to remove.
    724      *                      The value ~(size_t)0 is an alias for the final element.
    725      */
    726     bool removeAt(size_t a_idx);
    727 
    728     /**
    729      * Makes sure the array can hold at the given number of entries.
    730      *
    731      * @returns VINF_SUCCESS or VERR_NO_MEMORY.
    732      * @param   a_cEnsureCapacity   The number of elements to ensure capacity to hold.
    733      */
    734     int ensureCapacity(size_t a_cEnsureCapacity);
    735 
    736 
    737 protected:
    738     /** The array. */
    739     RTCRestObjectBase **m_papElements;
    740     /** Number of elements in the array. */
    741     size_t              m_cElements;
    742     /** The number of elements m_papElements can hold.
    743      * The difference between m_cCapacity and m_cElements are all NULLs. */
    744     size_t              m_cCapacity;
    745 
    746     /**
    747      * Wrapper around the value constructor.
    748      *
    749      * @returns Pointer to new value object on success, NULL if out of memory.
    750      */
    751     virtual RTCRestObjectBase *createValue(void) = 0;
    752 
    753     /**
    754      * Wrapper around the value copy constructor.
    755      *
    756      * @returns Pointer to copy on success, NULL if out of memory.
    757      * @param   a_pSrc      The value to copy.
    758      */
    759     virtual RTCRestObjectBase *createValueCopy(RTCRestObjectBase const *a_pSrc) = 0;
    760 
    761     /**
    762      * Worker for the copy constructor and the assignment operator.
    763      *
    764      * This will use createEntryCopy to do the copying.
    765      *
    766      * @returns VINF_SUCCESS on success, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    767      * @param   a_rThat     The array to copy.  Caller makes 100% sure the it has
    768      *                      the same type as the destination.
    769      * @param   a_fThrow    Whether to throw error.
    770      */
    771     int copyArrayWorker(RTCRestArrayBase const &a_rThat, bool a_fThrow);
    772 
    773     /**
    774      * Worker for performing inserts.
    775      *
    776      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    777      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    778      * @param   a_idx           Where to insert it.  The value ~(size_t)0 is an alias for m_cElements.
    779      * @param   a_pValue        The value to insert.  Ownership is transferred to the map on success.
    780      * @param   a_fReplace      Whether to replace existing entry rather than insert.
    781      */
    782     int insertWorker(size_t a_idx, RTCRestObjectBase *a_pValue, bool a_fReplace);
    783 
    784     /**
    785      * Worker for performing inserts.
    786      *
    787      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    788      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    789      * @param   a_idx           Where to insert it.  The value ~(size_t)0 is an alias for m_cElements.
    790      * @param   a_rValue        The value to copy into the map.
    791      * @param   a_fReplace      Whether to replace existing key-value pair with matching key.
    792      */
    793     int insertCopyWorker(size_t a_idx, RTCRestObjectBase const &a_rValue, bool a_fReplace);
    794 
    795 private:
    796     /** Copy constructor on this class should never be used. */
    797     RTCRestArrayBase(RTCRestArrayBase const &a_rThat);
    798     /** Copy assignment operator on this class should never be used. */
    799     RTCRestArrayBase &operator=(RTCRestArrayBase const &a_rThat);
    800 };
    801 
    802 
    803 
    804 /**
    805  * Limited array class.
    806  */
    807 template<class ElementType> class RTCRestArray : public RTCRestArrayBase
    808 {
    809 public:
    810     /** Default constructor - empty array. */
    811     RTCRestArray()
    812         : RTCRestArrayBase()
    813     {
    814     }
    815 
    816     /** Destructor. */
    817     ~RTCRestArray()
    818     {
    819     }
    820 
    821     /** Copy constructor. */
    822     RTCRestArray(RTCRestArray const &a_rThat)
    823         : RTCRestArrayBase()
    824     {
    825         copyArrayWorker(a_rThat, true /*fThrow*/);
    826     }
    827 
    828     /** Copy assignment operator. */
    829     RTCRestArray &operator=(RTCRestArray const &a_rThat)
    830     {
    831         copyArrayWorker(a_rThat, true /*fThrow*/);
    832         return *this;
    833     }
    834 
    835     /** Safe copy assignment method. */
    836     int assignCopy(RTCRestArray const &a_rThat)
    837     {
    838         return copyArrayWorker(a_rThat, false /*fThrow*/);
    839     }
    840 
    841     /** Factory method. */
    842     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void)
    843     {
    844         return new (std::nothrow) RTCRestArray<ElementType>();
    845     }
    846 
    847     /** Factory method for elements. */
    848     static DECLCALLBACK(RTCRestObjectBase *) createElementInstance(void)
    849     {
    850         return new (std::nothrow) ElementType();
    851     }
    852 
    853 
    854     /**
    855      * Insert the given object at the specified index.
    856      *
    857      * @returns VINF_SUCCESS on success.
    858      *          VERR_INVALID_POINTER, VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
    859      * @param   a_idx           The insertion index.  ~(size_t)0 is an alias for the end.
    860      * @param   a_pThat         The object to insert.  The array takes ownership of the object on success.
    861      */
    862     int insert(size_t a_idx, ElementType *a_pThat)
    863     {
    864         return insertWorker(a_idx, a_pThat, false /*a_fReplace*/);
    865     }
    866 
    867     /**
    868      * Insert a copy of the object at the specified index.
    869      *
    870      * @returns VINF_SUCCESS on success.
    871      *          VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
    872      * @param   a_idx           The insertion index.  ~(size_t)0 is an alias for the end.
    873      * @param   a_rThat         The object to insert a copy of.
    874      */
    875     int insertCopy(size_t a_idx, ElementType const &a_rThat)
    876     {
    877         return insertCopyWorker(a_idx, a_rThat, false /*a_fReplace*/);
    878     }
    879 
    880     /**
    881      * Appends the given object to the array.
    882      *
    883      * @returns VINF_SUCCESS on success.
    884      *          VERR_INVALID_POINTER, VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
    885      * @param   a_pThat         The object to insert.  The array takes ownership of the object on success.
    886      */
    887     int append(ElementType *a_pThat)
    888     {
    889         return insertWorker(~(size_t)0, a_pThat, false /*a_fReplace*/);
    890     }
    891 
    892     /**
    893      * Appends a copy of the object at the specified index.
    894      *
    895      * @returns VINF_SUCCESS on success.
    896      *          VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
    897      * @param   a_rThat         The object to insert a copy of.
    898      */
    899     int appendCopy(ElementType const &a_rThat)
    900     {
    901         return insertCopyWorker(~(size_t)0, a_rThat, false /*a_fReplace*/);
    902     }
    903 
    904     /**
    905      * Prepends the given object to the array.
    906      *
    907      * @returns VINF_SUCCESS on success.
    908      *          VERR_INVALID_POINTER, VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
    909      * @param   a_pThat         The object to insert.  The array takes ownership of the object on success.
    910      */
    911     int prepend(ElementType *a_pThat)
    912     {
    913         return insertWorker(0, a_pThat, false /*a_fReplace*/);
    914     }
    915 
    916     /**
    917      * Prepends a copy of the object at the specified index.
    918      *
    919      * @returns VINF_SUCCESS on success.
    920      *          VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
    921      * @param   a_rThat         The object to insert a copy of.
    922      */
    923     int prependCopy(ElementType const &a_rThat)
    924     {
    925         return insertCopyWorker(0, a_rThat, false /*a_fReplace*/);
    926     }
    927 
    928     /**
    929      * Insert the given object at the specified index.
    930      *
    931      * @returns VINF_SUCCESS on success.
    932      *          VERR_INVALID_POINTER, VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
    933      * @param   a_idx           The index of the existing object to replace.
    934      * @param   a_pThat         The replacement object.  The array takes ownership of the object on success.
    935      */
    936     int replace(size_t a_idx, ElementType *a_pThat)
    937     {
    938         return insertWorker(a_idx, a_pThat, true /*a_fReplace*/);
    939     }
    940 
    941     /**
    942      * Insert a copy of the object at the specified index.
    943      *
    944      * @returns VINF_SUCCESS on success.
    945      *          VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
    946      * @param   a_idx           The index of the existing object to replace.
    947      * @param   a_rThat         The object to insert a copy of.
    948      */
    949     int replaceCopy(size_t a_idx, ElementType const &a_rThat)
    950     {
    951         return insertCopyWorker(a_idx, a_rThat, true /*a_fReplace*/);
    952     }
    953 
    954     /**
    955      * Returns the object at a given index.
    956      *
    957      * @returns The object at @a a_idx, NULL if out of range.
    958      * @param   a_idx           The array index.
    959      */
    960     ElementType *at(size_t a_idx)
    961     {
    962         if (a_idx < m_cElements)
    963             return (ElementType *)m_papElements[a_idx];
    964         return NULL;
    965     }
    966 
    967     /**
    968      * Returns the object at a given index, const variant.
    969      *
    970      * @returns The object at @a a_idx, NULL if out of range.
    971      * @param   a_idx           The array index.
    972      */
    973     ElementType const *at(size_t a_idx) const
    974     {
    975         if (a_idx < m_cElements)
    976             return (ElementType const *)m_papElements[a_idx];
    977         return NULL;
    978     }
    979 
    980     /**
    981      * Returns the first object in the array.
    982      * @returns The first object, NULL if empty.
    983      */
    984     ElementType *first()
    985     {
    986         return at(0);
    987     }
    988 
    989     /**
    990      * Returns the first object in the array, const variant.
    991      * @returns The first object, NULL if empty.
    992      */
    993     ElementType const *first() const
    994     {
    995         return at(0);
    996     }
    997 
    998     /**
    999      * Returns the last object in the array.
    1000      * @returns The last object, NULL if empty.
    1001      */
    1002     ElementType *last()
    1003     {
    1004         return at(m_cElements - 1);
    1005     }
    1006 
    1007     /**
    1008      * Returns the last object in the array, const variant.
    1009      * @returns The last object, NULL if empty.
    1010      */
    1011     ElementType const *last() const
    1012     {
    1013         return at(m_cElements - 1);
    1014     }
    1015 
    1016 
    1017 protected:
    1018     virtual RTCRestObjectBase *createValue(void) RT_OVERRIDE
    1019     {
    1020         return new (std::nothrow) ElementType();
    1021     }
    1022 
    1023     virtual RTCRestObjectBase *createValueCopy(RTCRestObjectBase const *a_pSrc) RT_OVERRIDE
    1024     {
    1025         ElementType *pCopy = new (std::nothrow) ElementType();
    1026         if (pCopy)
    1027         {
    1028             int rc = pCopy->assignCopy(*(ElementType const *)a_pSrc);
    1029             if (RT_SUCCESS(rc))
    1030                 return pCopy;
    1031             delete pCopy;
    1032         }
    1033         return NULL;
    1034     }
    1035 };
    1036 
    1037 
    1038 /**
    1039  * Abstract base class for the RTCRestStringMap template.
    1040  */
    1041 class RT_DECL_CLASS RTCRestStringMapBase : public RTCRestObjectBase
    1042 {
    1043 public:
    1044     /** Default destructor. */
    1045     RTCRestStringMapBase();
    1046     /** Copy constructor. */
    1047     RTCRestStringMapBase(RTCRestStringMapBase const &a_rThat);
    1048     /** Destructor. */
    1049     virtual ~RTCRestStringMapBase();
    1050     /** Copy assignment operator. */
    1051     RTCRestStringMapBase &operator=(RTCRestStringMapBase const &a_rThat);
    1052 
    1053     /* Overridden methods: */
    1054     virtual int resetToDefault() RT_OVERRIDE;
    1055     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    1056     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    1057     // later?
    1058     //virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_OVERRIDE;
    1059     //virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    1060     //                       uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    1061     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    1062     virtual const char *typeName(void) const RT_OVERRIDE;
    1063 
    1064     /**
    1065      * Clear the content of the map.
    1066      */
    1067     void clear();
    1068 
    1069     /**
    1070      * Gets the number of entries in the map.
    1071      */
    1072     size_t size() const;
    1073 
    1074     /**
    1075      * Checks if the map contains the given key.
    1076      * @returns true if key found, false if not.
    1077      * @param   a_pszKey   The key to check fo.
    1078      */
    1079     bool constainsKey(const char *a_pszKey) const;
    1080 
    1081     /**
    1082      * Checks if the map contains the given key.
    1083      * @returns true if key found, false if not.
    1084      * @param   a_rStrKey   The key to check fo.
    1085      */
    1086     bool constainsKey(RTCString const &a_rStrKey) const;
    1087 
    1088     /**
    1089      * Remove any key-value pair with the given key.
    1090      * @returns true if anything was removed, false if not found.
    1091      * @param   a_pszKey    The key to remove.
    1092      */
    1093     bool remove(const char *a_pszKey);
    1094 
    1095     /**
    1096      * Remove any key-value pair with the given key.
    1097      * @returns true if anything was removed, false if not found.
    1098      * @param   a_rStrKey   The key to remove.
    1099      */
    1100     bool remove(RTCString const &a_rStrKey);
    1101 
    1102     /**
    1103      * Creates a new value and inserts it under the given key, returning the new value.
    1104      *
    1105      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    1106      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1107      * @param   a_ppValue   Where to return the pointer to the value.
    1108      * @param   a_pszKey    The key to put it under.
    1109      * @param   a_cchKey    The length of the key.  Default is the entire string.
    1110      * @param   a_fReplace  Whether to replace or fail on key collision.
    1111      */
    1112     int putNewValue(RTCRestObjectBase **a_ppValue, const char *a_pszKey, size_t a_cchKey = RTSTR_MAX, bool a_fReplace = false);
    1113 
    1114     /**
    1115      * Creates a new value and inserts it under the given key, returning the new value.
    1116      *
    1117      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    1118      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1119      * @param   a_ppValue   Where to return the pointer to the value.
    1120      * @param   a_pszKey    The key to put it under.
    1121      * @param   a_fReplace  Whether to replace or fail on key collision.
    1122      */
    1123     int putNewValue(RTCRestObjectBase **a_ppValue, RTCString const &a_rStrKey, bool a_fReplace = false);
    1124 
    1125 protected:
    1126     /** Map entry. */
    1127     typedef struct MapEntry
    1128     {
    1129         /** String space core. */
    1130         RTSTRSPACECORE      Core;
    1131         /** List node for enumeration. */
    1132         RTLISTNODE          ListEntry;
    1133         /** The key.
    1134          * @remarks Core.pszString points to the value of this object.  So, consider it const. */
    1135         RTCString           strKey;
    1136         /** The value. */
    1137         RTCRestObjectBase  *pValue;
    1138     } MapEntry;
    1139     /** The map tree. */
    1140     RTSTRSPACE          m_Map;
    1141     /** The enumeration list head (MapEntry). */
    1142     RTLISTANCHOR        m_ListHead;
    1143     /** Number of map entries. */
    1144     size_t              m_cEntries;
    1145 
    1146 public:
    1147     /** @name Map Iteration
    1148      * @{  */
    1149     /** Const iterator. */
    1150     class ConstIterator
    1151     {
    1152     private:
    1153         MapEntry            *m_pCur;
    1154         ConstIterator();
    1155     protected:
    1156         ConstIterator(MapEntry *a_pEntry) : m_pCur(a_pEntry) { }
    1157     public:
    1158         ConstIterator(ConstIterator const &a_rThat) : m_pCur(a_rThat.m_pCur) { }
    1159 
    1160         /** Gets the key string. */
    1161         RTCString const         &getKey()   { return m_pCur->strKey; }
    1162         /** Gets poitner to the value object. */
    1163         RTCRestObjectBase const *getValue() { return m_pCur->pValue; }
    1164 
    1165         /** Advance to the next map entry. */
    1166         ConstIterator &operator++()
    1167         {
    1168             m_pCur = RTListNodeGetNextCpp(&m_pCur->ListEntry, MapEntry, ListEntry);
    1169             return *this;
    1170         }
    1171 
    1172         /** Advance to the previous map entry. */
    1173         ConstIterator &operator--()
    1174         {
    1175             m_pCur = RTListNodeGetPrevCpp(&m_pCur->ListEntry, MapEntry, ListEntry);
    1176             return *this;
    1177         }
    1178 
    1179         /** Compare equal. */
    1180         bool operator==(ConstIterator const &a_rThat) { return m_pCur == a_rThat.m_pCur; }
    1181         /** Compare not equal. */
    1182         bool operator!=(ConstIterator const &a_rThat) { return m_pCur != a_rThat.m_pCur; }
    1183 
    1184         /* Map class must be friend so it can use the MapEntry constructor. */
    1185         friend class RTCRestStringMapBase;
    1186     };
    1187 
    1188     /** Returns iterator for the first map entry (unless it's empty and it's also the end). */
    1189     ConstIterator begin() const { return ConstIterator(RTListGetFirstCpp(&m_ListHead, MapEntry, ListEntry)); }
    1190     /** Returns iterator for the last map entry (unless it's empty and it's also the end). */
    1191     ConstIterator last() const  { return ConstIterator(RTListGetLastCpp(&m_ListHead, MapEntry, ListEntry)); }
    1192     /** Returns the end iterator.  This does not ever refer to an actual map entry. */
    1193     ConstIterator end() const   { return ConstIterator(RT_FROM_CPP_MEMBER(&m_ListHead, MapEntry, ListEntry)); }
    1194     /** @} */
    1195 
    1196 
    1197 protected:
    1198     /**
    1199      * Wrapper around the value constructor.
    1200      *
    1201      * @returns Pointer to new value object on success, NULL if out of memory.
    1202      */
    1203     virtual RTCRestObjectBase *createValue(void) = 0;
    1204 
    1205     /**
    1206      * Wrapper around the value copy constructor.
    1207      *
    1208      * @returns Pointer to copy on success, NULL if out of memory.
    1209      * @param   a_pSrc      The value to copy.
    1210      */
    1211     virtual RTCRestObjectBase *createValueCopy(RTCRestObjectBase const *a_pSrc) = 0;
    1212 
    1213     /**
    1214      * Worker for the copy constructor and the assignment operator.
    1215      *
    1216      * This will use createEntryCopy to do the copying.
    1217      *
    1218      * @returns VINF_SUCCESS on success, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1219      * @param   a_rThat     The map to copy.  Caller makes 100% sure the it has
    1220      *                      the same type as the destination.
    1221      * @param   a_fThrow    Whether to throw error.
    1222      */
    1223     int copyMapWorker(RTCRestStringMapBase const &a_rThat, bool a_fThrow);
    1224 
    1225     /**
    1226      * Worker for performing inserts.
    1227      *
    1228      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    1229      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1230      * @param   a_pszKey        The key.
    1231      * @param   a_pValue        The value to insert.  Ownership is transferred to the map on success.
    1232      * @param   a_fReplace      Whether to replace existing key-value pair with matching key.
    1233      * @param   a_cchKey        The key length, the whole string by default.
    1234      */
    1235     int putWorker(const char *a_pszKey, RTCRestObjectBase *a_pValue, bool a_fReplace, size_t a_cchKey = RTSTR_MAX);
    1236 
    1237     /**
    1238      * Worker for performing inserts.
    1239      *
    1240      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    1241      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1242      * @param   a_pszKey        The key.
    1243      * @param   a_rValue        The value to copy into the map.
    1244      * @param   a_fReplace      Whether to replace existing key-value pair with matching key.
    1245      * @param   a_cchKey        The key length, the whole string by default.
    1246      */
    1247     int putCopyWorker(const char *a_pszKey, RTCRestObjectBase const &a_rValue, bool a_fReplace, size_t a_cchKey = RTSTR_MAX);
    1248 
    1249     /**
    1250      * Worker for getting the value corresponding to the given key.
    1251      *
    1252      * @returns Pointer to the value object if found, NULL if key not in the map.
    1253      * @param   a_pszKey        The key which value to look up.
    1254      */
    1255     RTCRestObjectBase *getWorker(const char *a_pszKey);
    1256 
    1257     /**
    1258      * Worker for getting the value corresponding to the given key, const variant.
    1259      *
    1260      * @returns Pointer to the value object if found, NULL if key not in the map.
    1261      * @param   a_pszKey        The key which value to look up.
    1262      */
    1263     RTCRestObjectBase const *getWorker(const char *a_pszKey) const;
    1264 
    1265 private:
    1266     static DECLCALLBACK(int) stringSpaceDestructorCallback(PRTSTRSPACECORE pStr, void *pvUser);
    1267 };
    1268 
    1269 
    1270 /**
    1271  * Limited map class.
    1272  */
    1273 template<class ValueType> class RTCRestStringMap : public RTCRestStringMapBase
    1274 {
    1275 public:
    1276     /** Default constructor, creates emtpy map. */
    1277     RTCRestStringMap()
    1278         : RTCRestStringMapBase()
    1279     {}
    1280 
    1281     /** Copy constructor. */
    1282     RTCRestStringMap(RTCRestStringMap const &a_rThat)
    1283         : RTCRestStringMapBase()
    1284     {
    1285         copyMapWorker(a_rThat, true /*a_fThrow*/);
    1286     }
    1287 
    1288     /** Destructor. */
    1289     virtual ~RTCRestStringMap()
    1290     {
    1291        /* nothing to do here. */
    1292     }
    1293 
    1294     /** Copy assignment operator. */
    1295     RTCRestStringMap &operator=(RTCRestStringMap const &a_rThat)
    1296     {
    1297         copyMapWorker(a_rThat, true /*a_fThrow*/);
    1298         return *this;
    1299     }
    1300 
    1301     /** Safe copy assignment method. */
    1302     int assignCopy(RTCRestStringMap const &a_rThat)
    1303     {
    1304         return copyMapWorker(a_rThat, false /*a_fThrow*/);
    1305     }
    1306 
    1307     /** Factory method. */
    1308     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void)
    1309     {
    1310         return new (std::nothrow) RTCRestStringMap<ValueType>();
    1311     }
    1312 
    1313     /** Factory method for values. */
    1314     static DECLCALLBACK(RTCRestObjectBase *) createValueInstance(void)
    1315     {
    1316         return new (std::nothrow) ValueType();
    1317     }
    1318 
    1319     /**
    1320      * Inserts the given object into the map.
    1321      *
    1322      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    1323      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1324      * @param   a_pszKey        The key.
    1325      * @param   a_pValue        The value to insert.  Ownership is transferred to the map on success.
    1326      * @param   a_fReplace      Whether to replace existing key-value pair with matching key.
    1327      */
    1328     int put(const char *a_pszKey, ValueType *a_pValue, bool a_fReplace = false)
    1329     {
    1330         return putWorker(a_pszKey, a_pValue, a_fReplace);
    1331     }
    1332 
    1333     /**
    1334      * Inserts the given object into the map.
    1335      *
    1336      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    1337      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1338      * @param   a_rStrKey       The key.
    1339      * @param   a_pValue        The value to insert.  Ownership is transferred to the map on success.
    1340      * @param   a_fReplace      Whether to replace existing key-value pair with matching key.
    1341      */
    1342     int put(RTCString const &a_rStrKey, ValueType *a_pValue, bool a_fReplace = false)
    1343     {
    1344         return putWorker(a_rStrKey.c_str(), a_pValue, a_fReplace, a_rStrKey.length());
    1345     }
    1346 
    1347     /**
    1348      * Inserts a copy of the given object into the map.
    1349      *
    1350      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    1351      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1352      * @param   a_pszKey        The key.
    1353      * @param   a_rValue        The value to insert a copy of.
    1354      * @param   a_fReplace      Whether to replace existing key-value pair with matching key.
    1355      */
    1356     int putCopy(const char *a_pszKey, const ValueType &a_rValue, bool a_fReplace = false)
    1357     {
    1358         return putCopyWorker(a_pszKey, a_rValue, a_fReplace);
    1359     }
    1360 
    1361     /**
    1362      * Inserts a copy of the given object into the map.
    1363      *
    1364      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    1365      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1366      * @param   a_rStrKey       The key.
    1367      * @param   a_rValue        The value to insert a copy of.
    1368      * @param   a_fReplace      Whether to replace existing key-value pair with matching key.
    1369      */
    1370     int putCopy(RTCString const &a_rStrKey, const ValueType &a_rValue, bool a_fReplace = false)
    1371     {
    1372         return putCopyWorker(a_rStrKey.c_str(), a_rValue, a_fReplace, a_rStrKey.length());
    1373     }
    1374 
    1375     /**
    1376      * Gets the value corresponding to the given key.
    1377      *
    1378      * @returns Pointer to the value object if found, NULL if key not in the map.
    1379      * @param   a_pszKey        The key which value to look up.
    1380      */
    1381     ValueType *get(const char *a_pszKey)
    1382     {
    1383         return (ValueType *)getWorker(a_pszKey);
    1384     }
    1385 
    1386     /**
    1387      * Gets the value corresponding to the given key.
    1388      *
    1389      * @returns Pointer to the value object if found, NULL if key not in the map.
    1390      * @param   a_rStrKey       The key which value to look up.
    1391      */
    1392     ValueType *get(RTCString const &a_rStrKey)
    1393     {
    1394         return (ValueType *)getWorker(a_rStrKey.c_str());
    1395     }
    1396 
    1397     /**
    1398      * Gets the const value corresponding to the given key.
    1399      *
    1400      * @returns Pointer to the value object if found, NULL if key not in the map.
    1401      * @param   a_pszKey        The key which value to look up.
    1402      */
    1403     ValueType const *get(const char *a_pszKey) const
    1404     {
    1405         return (ValueType const *)getWorker(a_pszKey);
    1406     }
    1407 
    1408     /**
    1409      * Gets the const value corresponding to the given key.
    1410      *
    1411      * @returns Pointer to the value object if found, NULL if key not in the map.
    1412      * @param   a_rStrKey       The key which value to look up.
    1413      */
    1414     ValueType const *get(RTCString const &a_rStrKey) const
    1415     {
    1416         return (ValueType const *)getWorker(a_rStrKey.c_str());
    1417     }
    1418 
    1419     /** @todo enumerator*/
    1420 
    1421 protected:
    1422     virtual RTCRestObjectBase *createValue(void) RT_OVERRIDE
    1423     {
    1424         return new (std::nothrow) ValueType();
    1425     }
    1426 
    1427     virtual RTCRestObjectBase *createValueCopy(RTCRestObjectBase const *a_pSrc) RT_OVERRIDE
    1428     {
    1429         ValueType *pCopy = new (std::nothrow) ValueType();
    1430         if (pCopy)
    1431         {
    1432             int rc = pCopy->assignCopy(*(ValueType const *)a_pSrc);
    1433             if (RT_SUCCESS(rc))
    1434                 return pCopy;
    1435             delete pCopy;
    1436         }
    1437         return NULL;
    1438     }
    1439 };
    1440 
    1441 
    1442 /**
    1443646 * Dynamic REST object.
    1444647 *
     
    1480683
    1481684
    1482 /**
    1483  * Base class for REST client requests.
    1484  *
    1485  * This encapsulates parameters and helps transform them into a HTTP request.
    1486  *
    1487  * Parameters can be transfered in a number of places:
    1488  *      - Path part of the URL.
    1489  *      - Query part of the URL.
    1490  *      - HTTP header fields.
    1491  *      - FORM body.
    1492  *      - JSON body.
    1493  *      - XML body.
    1494  *      - ...
    1495  *
    1496  * They can be require or optional.  The latter may have default values.  In
    1497  * swagger 3 they can also be nullable, which means the null-indicator cannot
    1498  * be used for tracking optional parameters.
    1499  */
    1500 class RT_DECL_CLASS RTCRestClientRequestBase
    1501 {
    1502 public:
    1503     RTCRestClientRequestBase();
    1504     virtual ~RTCRestClientRequestBase();
    1505     RTCRestClientRequestBase(RTCRestClientRequestBase const &a_rThat);
    1506     RTCRestClientRequestBase &operator=(RTCRestClientRequestBase const &a_rThat);
    1507 
    1508     /**
    1509      * Reset all members to default values.
    1510      * @returns IPRT status code.
    1511      */
    1512     virtual int resetToDefault() = 0;
    1513 
    1514     /**
    1515      * Prepares the HTTP handle for transmitting this request.
    1516      *
    1517      * @returns IPRT status code.
    1518      * @param   a_pStrPath  Where to set path parameters.  Will be appended to the base path.
    1519      * @param   a_pStrQuery Where to set query parameters.
    1520      * @param   a_hHttp     Where to set header parameters and such.
    1521      * @param   a_pStrBody  Where to set body parameters.
    1522      */
    1523     virtual int xmitPrepare(RTCString *a_pStrPath, RTCString *a_pStrQuery, RTHTTP a_hHttp, RTCString *a_pStrBody) const = 0;
    1524 
    1525     /**
    1526      * Always called after the request has been transmitted.
    1527      *
    1528      * @param   a_rcStatus  Negative numbers are IPRT errors, positive are HTTP status codes.
    1529      * @param   a_hHttp     The HTTP handle the request was performed on.
    1530      */
    1531     virtual void xmitComplete(int a_rcStatus, RTHTTP a_hHttp) const = 0;
    1532 
    1533     /**
    1534      * Checks if there are were any assignment errors.
    1535      */
    1536     bool hasAssignmentErrors() const { return m_fErrorSet != 0; }
    1537 
    1538 protected:
    1539     /** Set of fields that have been explicitly assigned a value. */
    1540     uint64_t m_fIsSet;
    1541     /** Set of fields where value assigning failed. */
    1542     uint64_t m_fErrorSet;
    1543 
    1544     /** Path parameter descriptor. */
    1545     typedef struct
    1546     {
    1547         const char                 *pszName;    /**< The name string to replace (including {}). */
    1548         size_t                      cchName;    /**< Length of pszName. */
    1549         uint32_t                    fFlags;     /**< The toString flags. */
    1550         uint8_t                     iBitNo;     /**< The parameter bit number. */
    1551     } PATHPARAMDESC;
    1552 
    1553     /** Path parameter state. */
    1554     typedef struct
    1555     {
    1556         RTCRestObjectBase const    *pObj;       /**< Pointer to the parameter object. */
    1557         size_t                      offName;    /**< Maintained by worker. */
    1558     } PATHPARAMSTATE;
    1559 
    1560     /**
    1561      * Do path parameters.
    1562      *
    1563      * @returns IPRT status code
    1564      * @param   a_pStrPath          The destination path.
    1565      * @param   a_pszPathTemplate   The path template string.
    1566      * @param   a_cchPathTemplate   The length of the path template string.
    1567      * @param   a_paPathParams      The path parameter descriptors (static).
    1568      * @param   a_paPathParamStates The path parameter objects and states.
    1569      * @param   a_cPathParams       Number of path parameters.
    1570      */
    1571     int doPathParameters(RTCString *a_pStrPath, const char *a_pszPathTemplate, size_t a_cchPathTemplate,
    1572                          PATHPARAMDESC const *a_paPathParams, PATHPARAMSTATE *a_paPathParamStates, size_t a_cPathParams) const;
    1573 
    1574     /** Query parameter descriptor. */
    1575     typedef struct
    1576     {
    1577         const char *pszName;            /**< The parameter name. */
    1578         uint32_t    fFlags;             /**< The toString flags. */
    1579         bool        fRequired;          /**< Required or not. */
    1580         uint8_t     iBitNo;             /**< The parameter bit number. */
    1581     } QUERYPARAMDESC;
    1582 
    1583     /**
    1584      * Do query parameters.
    1585      *
    1586      * @returns IPRT status code
    1587      * @param   a_pStrQuery         The destination string.
    1588      * @param   a_paQueryParams     The query parameter descriptors.
    1589      * @param   a_papQueryParamObjs The query parameter objects, parallel to @a a_paQueryParams.
    1590      * @param   a_cQueryParams      Number of query parameters.
    1591      */
    1592     int doQueryParameters(RTCString *a_pStrQuery, QUERYPARAMDESC const *a_paQueryParams,
    1593                           RTCRestObjectBase const **a_papQueryParamObjs, size_t a_cQueryParams) const;
    1594 
    1595     /** Header parameter descriptor. */
    1596     typedef struct
    1597     {
    1598         const char *pszName;            /**< The parameter name. */
    1599         uint32_t    fFlags;             /**< The toString flags. */
    1600         bool        fRequired;          /**< Required or not. */
    1601         uint8_t     iBitNo;             /**< The parameter bit number. */
    1602         bool        fMapCollection;     /**< Collect headers starting with pszName into a map. */
    1603     } HEADERPARAMDESC;
    1604 
    1605     /**
    1606      * Do header parameters.
    1607      *
    1608      * @returns IPRT status code
    1609      * @param   a_hHttp                 Where to set header parameters.
    1610      * @param   a_paHeaderParams        The header parameter descriptors.
    1611      * @param   a_papHeaderParamObjs    The header parameter objects, parallel to @a a_paHeaderParams.
    1612      * @param   a_cHeaderParams         Number of header parameters.
    1613      */
    1614     int doHeaderParameters(RTHTTP a_hHttp, HEADERPARAMDESC const *a_paHeaderParams,
    1615                            RTCRestObjectBase const **a_papHeaderParamObjs, size_t a_cHeaderParams) const;
    1616 };
    1617 
    1618 
    1619 /**
    1620  * Base class for REST client responses.
    1621  */
    1622 class RT_DECL_CLASS RTCRestClientResponseBase
    1623 {
    1624 public:
    1625     /** Default constructor. */
    1626     RTCRestClientResponseBase();
    1627     /** Destructor. */
    1628     virtual ~RTCRestClientResponseBase();
    1629     /** Copy constructor. */
    1630     RTCRestClientResponseBase(RTCRestClientResponseBase const &a_rThat);
    1631     /** Copy assignment operator. */
    1632     RTCRestClientResponseBase &operator=(RTCRestClientResponseBase const &a_rThat);
    1633 
    1634     /**
    1635      * Resets the object state.
    1636      */
    1637     virtual void reset(void);
    1638 
    1639     /**
    1640      * Prepares the HTTP handle for receiving the response.
    1641      *
    1642      * This may install callbacks and such like.
    1643      *
    1644      * @returns IPRT status code.
    1645      * @param   a_hHttp     The HTTP handle to prepare for receiving.
    1646      * @param   a_pppvHdr   If a header callback handler is installed, set the value pointed to to NULL.
    1647      * @param   a_pppvBody  If a body callback handler is installed, set the value pointed to to NULL.
    1648      */
    1649     virtual int receivePrepare(RTHTTP a_hHttp, void ***a_pppvHdr, void ***a_pppvBody);
    1650 
    1651     /**
    1652      * Called when the HTTP request has been completely received.
    1653      *
    1654      * @param   a_rcStatus  Negative numbers are IPRT errors, positive are HTTP status codes.
    1655      * @param   a_hHttp     The HTTP handle the request was performed on.
    1656      *                      This can be NIL_RTHTTP should something fail early, in
    1657      *                      which case it is possible receivePrepare() wasn't called.
    1658      *
    1659      * @note    Called before consumeHeaders() and consumeBody().
    1660      */
    1661     virtual void receiveComplete(int a_rcStatus, RTHTTP a_hHttp);
    1662 
    1663     /**
    1664      * Callback that consumes HTTP header data from the server.
    1665      *
    1666      * @param   a_pchData  Body data.
    1667      * @param   a_cbData   Amount of body data.
    1668      *
    1669      * @note    Called after receiveComplete()..
    1670      */
    1671     virtual void consumeHeaders(const char *a_pchData, size_t a_cbData);
    1672 
    1673     /**
    1674      * Callback that consumes HTTP body data from the server.
    1675      *
    1676      * @param   a_pchData  Body data.
    1677      * @param   a_cbData   Amount of body data.
    1678      *
    1679      * @note    Called after consumeHeaders().
    1680      */
    1681     virtual void consumeBody(const char *a_pchData, size_t a_cbData);
    1682 
    1683     /**
    1684      * Called after status, headers and body all have been presented.
    1685      *
    1686      * @returns IPRT status code.
    1687      */
    1688     virtual void receiveFinal();
    1689 
    1690     /**
    1691      * Getter for m_rcStatus.
    1692      * @returns Negative numbers are IPRT errors, positive are HTTP status codes.
    1693      */
    1694     int getStatus() { return m_rcStatus; }
    1695 
    1696     /**
    1697      * Getter for m_rcHttp.
    1698      * @returns HTTP status code or VERR_NOT_AVAILABLE.
    1699      */
    1700     int getHttpStatus() { return m_rcHttp; }
    1701 
    1702     /**
    1703      * Getter for m_pErrInfo.
    1704      */
    1705     PCRTERRINFO getErrInfo(void) const { return m_pErrInfo; }
    1706 
    1707     /**
    1708      * Getter for m_strContentType.
    1709      */
    1710     RTCString const &getContentType(void) const { return m_strContentType; }
    1711 
    1712 
    1713 protected:
    1714     /** Negative numbers are IPRT errors, positive are HTTP status codes. */
    1715     int         m_rcStatus;
    1716     /** The HTTP status code, VERR_NOT_AVAILABLE if not set. */
    1717     int         m_rcHttp;
    1718     /** Error information. */
    1719     PRTERRINFO  m_pErrInfo;
    1720     /** The value of the Content-Type header field. */
    1721     RTCString   m_strContentType;
    1722 
    1723     PRTERRINFO  getErrInfoInternal(void);
    1724     void        deleteErrInfo(void);
    1725     void        copyErrInfo(PCRTERRINFO pErrInfo);
    1726 
    1727     /**
    1728      * Reports an error (or warning if a_rc non-negative).
    1729      *
    1730      * @returns a_rc
    1731      * @param   a_rc        The status code to report and return.  The first
    1732      *                      error status is assigned to m_rcStatus, subsequent
    1733      *                      ones as well as informational statuses are not
    1734      *                      recorded by m_rcStatus.
    1735      * @param   a_pszFormat The message format string.
    1736      * @param   ...         Message arguments.
    1737      */
    1738     int addError(int a_rc, const char *a_pszFormat, ...);
    1739 
    1740     /** Field flags. */
    1741     enum
    1742     {
    1743         /** Collection map, name is a prefix followed by '*'. */
    1744         kHdrField_MapCollection   = RT_BIT_32(24),
    1745     };
    1746 
    1747     /** Header field descriptor. */
    1748     typedef struct
    1749     {
    1750         /** The header field name. */
    1751         const char *pszName;
    1752         /** The length of the field name.*/
    1753         uint32_t    cchName;
    1754         /** Flags, TBD. */
    1755         uint32_t    fFlags;
    1756         /** Object factory. */
    1757         RTCRestObjectBase::PFNCREATEINSTANCE pfnCreateInstance;
    1758     } HEADERFIELDDESC;
    1759 
    1760     /**
    1761      * Helper that extracts fields from the HTTP headers.
    1762      *
    1763      * @param   a_paFieldDescs      Pointer to an array of field descriptors.
    1764      * @param   a_pappFieldValues   Pointer to a parallel array of value pointer pointers.
    1765      * @param   a_cFields           Number of field descriptors..
    1766      * @param   a_pchData           The header blob to search.
    1767      * @param   a_cbData            The size of the header blob to search.
    1768      */
    1769     void extracHeaderFieldsFromBlob(HEADERFIELDDESC const *a_paFieldDescs, RTCRestObjectBase ***a_pappFieldValues,
    1770                                     size_t a_cFields, const char *a_pchData, size_t a_cbData);
    1771 
    1772     /**
    1773      * Helper that extracts a header field.
    1774      *
    1775      * @retval  VINF_SUCCESS
    1776      * @retval  VERR_NOT_FOUND if not found.
    1777      * @retval  VERR_NO_STR_MEMORY
    1778      * @param   a_pszField  The header field header name.
    1779      * @param   a_cchField  The length of the header field name.
    1780      * @param   a_pchData   The header blob to search.
    1781      * @param   a_cbData    The size of the header blob to search.
    1782      * @param   a_pStrDst   Where to store the header value on successs.
    1783      */
    1784     int extractHeaderFromBlob(const char *a_pszField, size_t a_cchField, const char *a_pchData, size_t a_cbData,
    1785                               RTCString *a_pStrDst);
    1786 
    1787     /**
    1788      * Helper that does the deserializing of the response body.
    1789      *
    1790      * @param   a_pDst      The destination object for the body content.
    1791      * @param   a_pchData   The body blob.
    1792      * @param   a_cbData    The size of the body blob.
    1793      */
    1794     void deserializeBody(RTCRestObjectBase *a_pDst, const char *a_pchData, size_t a_cbData);
    1795 
    1796     /**
    1797      * Primary json cursor for parsing bodies.
    1798      */
    1799     class PrimaryJsonCursorForBody : public RTCRestJsonPrimaryCursor
    1800     {
    1801     public:
    1802         RTCRestClientResponseBase *m_pThat; /**< Pointer to response object. */
    1803         PrimaryJsonCursorForBody(RTJSONVAL hValue, const char *pszName, RTCRestClientResponseBase *a_pThat);
    1804         virtual int addError(RTCRestJsonCursor const &a_rCursor, int a_rc, const char *a_pszFormat, ...) RT_OVERRIDE;
    1805         virtual int unknownField(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    1806     };
    1807 };
    1808 
    1809 
    1810 /**
    1811  * Base class for REST client responses.
    1812  */
    1813 class RT_DECL_CLASS RTCRestClientApiBase
    1814 {
    1815 public:
    1816     RTCRestClientApiBase()
    1817         : m_hHttp(NIL_RTHTTP)
    1818     {}
    1819     virtual ~RTCRestClientApiBase();
    1820 
    1821     /** @name Base path (URL) handling.
    1822      * @{ */
    1823     /**
    1824      * Gets the base path we're using.
    1825      *
    1826      * @returns Base URL string.  If empty, we'll be using the default one.
    1827      */
    1828     RTCString const &getBasePath(void) const
    1829     {
    1830         return m_strBasePath;
    1831     }
    1832 
    1833     /**
    1834      * Sets the base path (URL) to use when talking to the server.
    1835      *
    1836      * Setting the base path is only required if there is a desire to use a
    1837      * different server from the one specified in the API specification, like
    1838      * for instance regional one.
    1839      *
    1840      * @param   a_pszPath   The base path to use.
    1841      */
    1842     virtual void setBasePath(const char *a_pszPath)
    1843     {
    1844         m_strBasePath = a_pszPath;
    1845     }
    1846 
    1847     /**
    1848      * Sets the base path (URL) to use when talking to the server.
    1849      *
    1850      * Setting the base path is only required if there is a desire to use a
    1851      * different server from the one specified in the API specification, like
    1852      * for instance regional one.
    1853      *
    1854      * @param   a_strPath   The base path to use.
    1855      * @note    Defers to the C-string variant.
    1856      */
    1857     void setBasePath(RTCString const &a_strPath) { setBasePath(a_strPath.c_str()); }
    1858 
    1859     /**
    1860      * Gets the default base path (URL) as specified in the specs.
    1861      *
    1862      * @returns Base path (URL) string.
    1863      */
    1864     virtual const char *getDefaultBasePath() = 0;
    1865     /** @} */
    1866 
    1867 protected:
    1868     /** Handle to the HTTP connection object. */
    1869     RTHTTP  m_hHttp;
    1870     /** The base path to use. */
    1871     RTCString m_strBasePath;
    1872 
    1873     /* Make non-copyable (RTCNonCopyable causes warnings): */
    1874     RTCRestClientApiBase(RTCRestOutputToString const &);
    1875     RTCRestClientApiBase *operator=(RTCRestOutputToString const &);
    1876 
    1877     /**
    1878      * Re-initializes the HTTP instance.
    1879      *
    1880      * @returns IPRT status code.
    1881      */
    1882     virtual int reinitHttpInstance();
    1883 
    1884     /**
    1885      * Implements stuff for making an API call.
    1886      *
    1887      * @returns a_pResponse->getStatus()
    1888      * @param   a_rRequest      Reference to the request object.
    1889      * @param   a_enmHttpMethod The HTTP request method.
    1890      * @param   a_pResponse     Pointer to the response object.
    1891      * @param   a_pszMethod     The method name, for logging purposes.
    1892      */
    1893     virtual int doCall(RTCRestClientRequestBase const &a_rRequest, RTHTTPMETHOD a_enmHttpMethod,
    1894                        RTCRestClientResponseBase *a_pResponse, const char *a_pszMethod);
    1895 
    1896 };
    1897 
    1898685/** @} */
    1899686
  • trunk/include/iprt/cpp/restclient.h

    r74024 r74025  
    11/** @file
    2  * IPRT - C++ Representational State Transfer (REST) Base Classes.
     2 * IPRT - C++ Representational State Transfer (REST) Client Classes.
    33 */
    44
     
    2424 */
    2525
    26 #ifndef ___iprt_cpp_restbase_h
    27 #define ___iprt_cpp_restbase_h
    28 
    29 #include <iprt/types.h>
    30 #include <iprt/assert.h>
    31 #include <iprt/err.h>
     26#ifndef ___iprt_cpp_restclient_h
     27#define ___iprt_cpp_restclient_h
     28
    3229#include <iprt/http.h>
    33 #include <iprt/json.h>
    34 #include <iprt/list.h>
    35 #include <iprt/string.h>
    36 #include <iprt/stdarg.h>
    37 #include <iprt/cpp/ministring.h>
    38 #include <iprt/cpp/utils.h>
    39 
    40 
    41 /** @defgroup grp_rt_cpp_restbase   C++ Representational State Transfer (REST) Base Classes.
     30#include <iprt/cpp/restbase.h>
     31
     32
     33/** @defgroup grp_rt_cpp_restclient     C++ Representational State Transfer (REST) Client Classes.
    4234 * @ingroup grp_rt_cpp
    4335 * @{
    4436 */
    45 
    46 
    47 
    48 /**
    49  * Abstract base class for serializing data objects.
    50  */
    51 class RT_DECL_CLASS RTCRestOutputBase
    52 {
    53 public:
    54     RTCRestOutputBase()
    55         : m_uIndent(0)
    56     { }
    57     virtual ~RTCRestOutputBase()
    58     { }
    59 
    60     /**
    61      * RTStrPrintf like function (see @ref pg_rt_str_format).
    62      *
    63      * @returns Number of bytes outputted.
    64      * @param   pszFormat   The format string.
    65      * @param   ...         Argument specfied in @a pszFormat.
    66      */
    67     size_t         printf(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(2, 3)
    68     {
    69         va_list va;
    70         va_start(va, pszFormat);
    71         size_t cchWritten = this->vprintf(pszFormat, va);
    72         va_end(va);
    73         return cchWritten;
    74     }
    75 
    76     /**
    77      * RTStrPrintfV like function (see @ref pg_rt_str_format).
    78      *
    79      * @returns Number of bytes outputted.
    80      * @param   pszFormat   The format string.
    81      * @param   va          Argument specfied in @a pszFormat.
    82      */
    83     virtual size_t vprintf(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(2, 0) = 0;
    84 
    85     /**
    86      * Sets the indentation level for use when pretty priting things.
    87      *
    88      * @returns Previous indentation level.
    89      * @param   uIndent     The indentation level.
    90      */
    91     unsigned setIndent(unsigned uIndent)
    92     {
    93         unsigned const uRet = m_uIndent;
    94         m_uIndent = uIndent;
    95         return uRet;
    96     }
    97 
    98     /**
    99      * Increases the indentation level.
    100      *
    101      * @returns Previous indentation level.
    102      */
    103     unsigned incrementIndent()
    104     {
    105         unsigned const uRet = m_uIndent;
    106         m_uIndent = uRet + 1;
    107         return uRet;
    108     }
    109 
    110 protected:
    111     /** The current indentation level. */
    112     unsigned m_uIndent;
    113 };
    114 
    115 
    116 /**
    117  * Serialize to a string object.
    118  */
    119 class RT_DECL_CLASS RTCRestOutputToString : public RTCRestOutputBase
    120 {
    121 public:
    122     /**
    123      * Creates an instance that appends to @a a_pDst.
    124      * @param   a_pDst      Pointer to the destination string object.
    125      *                      NULL is not accepted and will assert.
    126      * @param   a_fAppend   Whether to append to the current string value, or
    127      *                      nuke the string content before starting the output.
    128      */
    129     RTCRestOutputToString(RTCString *a_pDst, bool a_fAppend = false);
    130     virtual ~RTCRestOutputToString();
    131 
    132     virtual size_t vprintf(const char *pszFormat, va_list va) RT_OVERRIDE;
    133 
    134     /**
    135      * Finalizes the output and releases the string object to the caller.
    136      *
    137      * @returns The released string object.  NULL if we ran out of memory or if
    138      *          called already.
    139      *
    140      * @remark  This sets m_pDst to NULL and the object cannot be use for any
    141      *          more output afterwards.
    142      */
    143     virtual RTCString *finalize();
    144 
    145 
    146 protected:
    147     /** Pointer to the destination string.  NULL after finalize().   */
    148     RTCString  *m_pDst;
    149     /** Set if we ran out of memory and should ignore subsequent calls. */
    150     bool        m_fOutOfMemory;
    151 
    152     /** @callback_method_impl{FNRTSTROUTPUT} */
    153     static DECLCALLBACK(size_t) strOutput(void *pvArg, const char *pachChars, size_t cbChars);
    154 
    155     /* Make non-copyable (RTCNonCopyable causes warnings): */
    156     RTCRestOutputToString(RTCRestOutputToString const &);
    157     RTCRestOutputToString *operator=(RTCRestOutputToString const &);
    158 };
    159 
    160 
    161 /* forward decl: */
    162 class RTCRestJsonPrimaryCursor;
    163 
    164 /**
    165  * JSON cursor structure.
    166  *
    167  * This reduces the number of parameters passed around when deserializing JSON
    168  * input and also helps constructing full object name for logging and error reporting.
    169  */
    170 struct RT_DECL_CLASS RTCRestJsonCursor
    171 {
    172     /** Handle to the value being parsed. */
    173     RTJSONVAL                           m_hValue;
    174     /** Name of the value. */
    175     const char                         *m_pszName;
    176     /** Pointer to the parent, NULL if primary. */
    177     struct RTCRestJsonCursor const     *m_pParent;
    178     /** Pointer to the primary cursor structure. */
    179     RTCRestJsonPrimaryCursor           *m_pPrimary;
    180 
    181     RTCRestJsonCursor(struct RTCRestJsonCursor const &a_rParent)
    182         : m_hValue(NIL_RTJSONVAL), m_pszName(NULL), m_pParent(&a_rParent), m_pPrimary(a_rParent.m_pPrimary)
    183     { }
    184 
    185     RTCRestJsonCursor(RTJSONVAL hValue, const char *pszName, struct RTCRestJsonCursor *pParent)
    186         : m_hValue(hValue), m_pszName(pszName), m_pParent(pParent), m_pPrimary(pParent->m_pPrimary)
    187     { }
    188 
    189     RTCRestJsonCursor(RTJSONVAL hValue, const char *pszName)
    190         : m_hValue(hValue), m_pszName(pszName), m_pParent(NULL), m_pPrimary(NULL)
    191     { }
    192 
    193     ~RTCRestJsonCursor()
    194     {
    195         if (m_hValue != NIL_RTJSONVAL)
    196         {
    197             RTJsonValueRelease(m_hValue);
    198             m_hValue = NIL_RTJSONVAL;
    199         }
    200     }
    201 };
    202 
    203 
    204 /**
    205  * The primary JSON cursor class.
    206  */
    207 class RT_DECL_CLASS RTCRestJsonPrimaryCursor
    208 {
    209 public:
    210     /** The cursor for the first level. */
    211     RTCRestJsonCursor   m_Cursor;
    212     /** Error info keeper. */
    213     PRTERRINFO          m_pErrInfo;
    214 
    215     /** Creates a primary json cursor with optiona error info. */
    216     RTCRestJsonPrimaryCursor(RTJSONVAL hValue, const char *pszName, PRTERRINFO pErrInfo = NULL)
    217         : m_Cursor(hValue, pszName)
    218         , m_pErrInfo(pErrInfo)
    219     {
    220         m_Cursor.m_pPrimary = this;
    221     }
    222 
    223     virtual ~RTCRestJsonPrimaryCursor()
    224     {  }
    225 
    226     /**
    227      * Add an error message.
    228      *
    229      * @returns a_rc
    230      * @param   a_rCursor       The cursor reporting the error.
    231      * @param   a_rc            The status code.
    232      * @param   a_pszFormat     Format string.
    233      * @param   ...             Format string arguments.
    234      */
    235     virtual int addError(RTCRestJsonCursor const &a_rCursor, int a_rc, const char *a_pszFormat, ...);
    236 
    237     /**
    238      * Reports that the current field is not known.
    239      *
    240      * @returns Status to propagate.
    241      * @param   a_rCursor       The cursor for the field.
    242      */
    243     virtual int unknownField(RTCRestJsonCursor const &a_rCursor);
    244 
    245     /**
    246      * Copies the full path into pszDst.
    247      *
    248      * @returns pszDst
    249      * @param   a_rCursor       The cursor to start walking at.
    250      * @param   a_pszDst        Where to put the path.
    251      * @param   a_cbDst         Size of the destination buffer.
    252      */
    253     virtual char *getPath(RTCRestJsonCursor const &a_rCursor, char *a_pszDst, size_t a_cbDst) const;
    254 };
    255 
    256 
    257 /**
    258  * Abstract base class for REST data objects.
    259  *
    260  * The only information this keeps is the null indicator.
    261  */
    262 class RT_DECL_CLASS RTCRestObjectBase
    263 {
    264 public:
    265     RTCRestObjectBase();
    266     RTCRestObjectBase(RTCRestObjectBase const &a_rThat);
    267     virtual ~RTCRestObjectBase();
    268 
    269     /**
    270      * Tests if the object is @a null.
    271      * @returns true if null, false if not.
    272      */
    273     bool isNull(void) const { return m_fNullIndicator; };
    274 
    275     /**
    276      * Sets the object to @a null and fills it with defaults.
    277      * @returns IPRT status code (from resetToDefault).
    278      */
    279     virtual int setNull(void);
    280 
    281     /**
    282      * Sets the object to not-null state (i.e. undoes setNull()).
    283      * @remarks Only really important for strings.
    284      */
    285     virtual void setNotNull(void);
    286 
    287     /**
    288      * Resets the object to all default values.
    289      * @returns IPRT status code.
    290      */
    291     virtual int resetToDefault() = 0;
    292 
    293     /**
    294      * Serialize the object as JSON.
    295      *
    296      * @returns a_rDst
    297      * @param   a_rDst      The destination for the serialization.
    298      */
    299     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const = 0;
    300 
    301     /**
    302      * Deserialize object from the given JSON iterator.
    303      *
    304      * @returns IPRT status code.
    305      * @param   a_rCursor    The JSON cursor.
    306      */
    307     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) = 0;
    308 
    309     /**
    310      * Flags for toString().
    311      *
    312      * The kCollectionFormat_xxx bunch controls multiple values in arrays
    313      * are formatted.  They are ignored by everyone else.
    314      *
    315      * @note When adding collection format types, make sure to also
    316      *       update RTCRestArrayBase::toString().
    317      * @note Bit 24 is reserved (for kHdrField_MapCollection).
    318      */
    319     enum
    320     {
    321         kCollectionFormat_Unspecified = 0,  /**< Not specified. */
    322         kCollectionFormat_csv,              /**< Comma-separated list. */
    323         kCollectionFormat_ssv,              /**< Space-separated list. */
    324         kCollectionFormat_tsv,              /**< Tab-separated list. */
    325         kCollectionFormat_pipes,            /**< Pipe-separated list. */
    326         kCollectionFormat_multi,            /**< Special collection type that must be handled by caller of toString. */
    327         kCollectionFormat_Mask = 7,         /**< Collection type mask. */
    328 
    329         kToString_Append = 8                /**< Append to the string (rather than assigning). */
    330     };
    331 
    332     /**
    333      * String conversion.
    334      *
    335      * The default implementation of is a wrapper around serializeAsJson().
    336      *
    337      * @returns IPRT status code.
    338      * @param   a_pDst      Pointer to the destionation string.
    339      * @param   a_fFlags    kCollectionFormat_xxx.
    340      */
    341     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const;
    342 
    343     /**
    344      * String convertsion, naive variant.
    345      *
    346      * @returns String represenation.
    347      */
    348     RTCString toString() const;
    349 
    350     /**
    351      * Convert from (header) string value.
    352      *
    353      * The default implementation of is a wrapper around deserializeFromJson().
    354      *
    355      * @returns IPRT status code.
    356      * @param   a_rValue    The string value string to parse.
    357      * @param   a_pszName   Field name or similar.
    358      * @param   a_pErrInfo  Where to return additional error info.  Optional.
    359      * @param   a_fFlags    kCollectionFormat_xxx.
    360      */
    361     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    362                            uint32_t a_fFlags = kCollectionFormat_Unspecified);
    363 
    364     /** Type classification */
    365     typedef enum kTypeClass
    366     {
    367         kTypeClass_Invalid = 0,
    368         kTypeClass_Bool,                /**< Primitive: bool. */
    369         kTypeClass_Int64,               /**< Primitive: bool. */
    370         kTypeClass_Int32,               /**< Primitive: bool. */
    371         kTypeClass_Int16,               /**< Primitive: bool. */
    372         kTypeClass_Double,              /**< Primitive: bool. */
    373         kTypeClass_String,              /**< Primitive: bool. */
    374         kTypeClass_Object,              /**< Object (any kind of data model object). */
    375         kTypeClass_Array,               /**< Array (containing any kind of object). */
    376         kTypeClass_StringMap            /**< String map (containing any kind of object). */
    377     } kTypeClass;
    378 
    379     /**
    380      * Returns the object type class.
    381      */
    382     virtual kTypeClass typeClass(void) const;
    383 
    384     /**
    385      * Returns the object type name.
    386      */
    387     virtual const char *typeName(void) const = 0;
    388 
    389     /**
    390      * Factory method.
    391      * @returns Pointer to new object on success, NULL if out of memory.
    392      */
    393     typedef DECLCALLBACK(RTCRestObjectBase *) FNCREATEINSTANCE(void);
    394     /** Pointer to factory method. */
    395     typedef FNCREATEINSTANCE *PFNCREATEINSTANCE;
    396 
    397 
    398 protected:
    399     /** Null indicator.
    400      * @remarks The null values could be mapped onto C/C++ NULL pointer values,
    401      *          with the consequence that all data members in objects and such would
    402      *          have had to been allocated individually, even simple @a bool members.
    403      *          Given that we're overly paranoid about heap allocations (std::bad_alloc),
    404      *          it's more fitting to use a null indicator for us.
    405      */
    406     bool    m_fNullIndicator;
    407 };
    408 
    409 
    410 /**
    411  * Class wrapping 'bool'.
    412  */
    413 class RT_DECL_CLASS RTCRestBool : public RTCRestObjectBase
    414 {
    415 public:
    416     /** Default destructor. */
    417     RTCRestBool();
    418     /** Copy constructor. */
    419     RTCRestBool(RTCRestBool const &a_rThat);
    420     /** From value constructor. */
    421     RTCRestBool(bool fValue);
    422     /** Destructor. */
    423     virtual ~RTCRestBool();
    424     /** Copy assignment operator. */
    425     RTCRestBool &operator=(RTCRestBool const &a_rThat);
    426     /** Safe copy assignment method. */
    427     int assignCopy(RTCRestBool const &a_rThat);
    428     /** Assign value and clear null indicator. */
    429     void assignValue(bool a_fValue);
    430 
    431     /* Overridden methods: */
    432     virtual int resetToDefault() RT_OVERRIDE;
    433     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    434     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    435     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_OVERRIDE;
    436     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    437                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    438     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    439     virtual const char *typeName(void) const RT_OVERRIDE;
    440 
    441     /** Factory method. */
    442     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
    443 
    444 public:
    445     /** The value. */
    446     bool    m_fValue;
    447 };
    448 
    449 
    450 /**
    451  * Class wrapping 'int64_t'.
    452  */
    453 class RT_DECL_CLASS RTCRestInt64 : public RTCRestObjectBase
    454 {
    455 public:
    456     /** Default destructor. */
    457     RTCRestInt64();
    458     /** Copy constructor. */
    459     RTCRestInt64(RTCRestInt64 const &a_rThat);
    460     /** From value constructor. */
    461     RTCRestInt64(int64_t a_iValue);
    462     /** Destructor. */
    463     virtual ~RTCRestInt64();
    464     /** Copy assignment operator. */
    465     RTCRestInt64 &operator=(RTCRestInt64 const &a_rThat);
    466     /** Safe copy assignment method. */
    467     int assignCopy(RTCRestInt64 const &a_rThat);
    468     /** Assign value and clear null indicator. */
    469     void assignValue(int64_t a_iValue);
    470 
    471     /* Overridden methods: */
    472     virtual int resetToDefault() RT_OVERRIDE;
    473     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    474     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    475     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_OVERRIDE;
    476     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    477                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    478     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    479     virtual const char *typeName(void) const RT_OVERRIDE;
    480 
    481     /** Factory method. */
    482     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
    483 
    484 public:
    485     /** The value. */
    486     int64_t m_iValue;
    487 };
    488 
    489 
    490 /**
    491  * Class wrapping 'int32_t'.
    492  */
    493 class RT_DECL_CLASS RTCRestInt32 : public RTCRestObjectBase
    494 {
    495 public:
    496     /** Default destructor. */
    497     RTCRestInt32();
    498     /** Copy constructor. */
    499     RTCRestInt32(RTCRestInt32 const &a_rThat);
    500     /** From value constructor. */
    501     RTCRestInt32(int32_t iValue);
    502     /** Destructor. */
    503     virtual ~RTCRestInt32();
    504     /** Copy assignment operator. */
    505     RTCRestInt32 &operator=(RTCRestInt32 const &a_rThat);
    506     /** Safe copy assignment method. */
    507     int assignCopy(RTCRestInt32 const &a_rThat);
    508     /** Assign value and clear null indicator. */
    509     void assignValue(int32_t a_iValue);
    510 
    511     /* Overridden methods: */
    512     virtual int resetToDefault() RT_OVERRIDE;
    513     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    514     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    515     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_OVERRIDE;
    516     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    517                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    518     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    519     virtual const char *typeName(void) const RT_OVERRIDE;
    520 
    521     /** Factory method. */
    522     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
    523 
    524 public:
    525     /** The value. */
    526     int32_t m_iValue;
    527 };
    528 
    529 
    530 /**
    531  * Class wrapping 'int16_t'.
    532  */
    533 class RT_DECL_CLASS RTCRestInt16 : public RTCRestObjectBase
    534 {
    535 public:
    536     /** Default destructor. */
    537     RTCRestInt16();
    538     /** Copy constructor. */
    539     RTCRestInt16(RTCRestInt16 const &a_rThat);
    540     /** From value constructor. */
    541     RTCRestInt16(int16_t iValue);
    542     /** Destructor. */
    543     virtual ~RTCRestInt16();
    544     /** Copy assignment operator. */
    545     RTCRestInt16 &operator=(RTCRestInt16 const &a_rThat);
    546     /** Safe copy assignment method. */
    547     int assignCopy(RTCRestInt16 const &a_rThat);
    548     /** Assign value and clear null indicator. */
    549     void assignValue(int16_t a_iValue);
    550 
    551     /* Overridden methods: */
    552     virtual int resetToDefault() RT_OVERRIDE;
    553     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    554     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    555     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_OVERRIDE;
    556     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    557                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    558     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    559     virtual const char *typeName(void) const RT_OVERRIDE;
    560 
    561     /** Factory method. */
    562     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
    563 
    564 public:
    565     /** The value. */
    566     int16_t m_iValue;
    567 };
    568 
    569 
    570 /**
    571  * Class wrapping 'double'.
    572  */
    573 class RT_DECL_CLASS RTCRestDouble : public RTCRestObjectBase
    574 {
    575 public:
    576     /** Default destructor. */
    577     RTCRestDouble();
    578     /** Copy constructor. */
    579     RTCRestDouble(RTCRestDouble const &a_rThat);
    580     /** From value constructor. */
    581     RTCRestDouble(double rdValue);
    582     /** Destructor. */
    583     virtual ~RTCRestDouble();
    584     /** Copy assignment operator. */
    585     RTCRestDouble &operator=(RTCRestDouble const &a_rThat);
    586     /** Safe copy assignment method. */
    587     int assignCopy(RTCRestDouble const &a_rThat);
    588     /** Assign value and clear null indicator. */
    589     void assignValue(double a_rdValue);
    590 
    591     /* Overridden methods: */
    592     virtual int resetToDefault() RT_OVERRIDE;
    593     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    594     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    595     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_OVERRIDE;
    596     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    597                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    598     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    599     virtual const char *typeName(void) const RT_OVERRIDE;
    600 
    601     /** Factory method. */
    602     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
    603 
    604 public:
    605     /** The value. */
    606     double m_rdValue;
    607 };
    608 
    609 
    610 /**
    611  * Class wrapping 'RTCString'.
    612  */
    613 class RT_DECL_CLASS RTCRestString : public RTCString, public RTCRestObjectBase
    614 {
    615 public:
    616     /** Default destructor. */
    617     RTCRestString();
    618     /** Destructor. */
    619     virtual ~RTCRestString();
    620 
    621     /** Copy constructor. */
    622     RTCRestString(RTCRestString const &a_rThat);
    623     /** From value constructor. */
    624     RTCRestString(RTCString const &a_rThat);
    625     /** From value constructor. */
    626     RTCRestString(const char *a_pszSrc);
    627     /** Safe copy assignment method. */
    628     int assignCopy(RTCRestString const &a_rThat);
    629     /** Safe copy assignment method. */
    630     int assignCopy(RTCString const &a_rThat);
    631     /** Safe copy assignment method. */
    632     int assignCopy(const char *a_pszThat);
    633 
    634     /* Overridden methods: */
    635     virtual int setNull(void) RT_OVERRIDE; /* (ambigious, so overrider it to make sure.) */
    636     virtual int resetToDefault() RT_OVERRIDE;
    637     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    638     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    639     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_OVERRIDE;
    640     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    641                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    642     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    643     virtual const char *typeName(void) const RT_OVERRIDE;
    644 
    645     /** Factory method. */
    646     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
    647 };
    648 
    649 
    650 /**
    651  * Abstract base class for the RTCRestArray template.
    652  */
    653 class RT_DECL_CLASS RTCRestArrayBase : public RTCRestObjectBase
    654 {
    655 public:
    656     /** Default destructor. */
    657     RTCRestArrayBase();
    658     /** Destructor. */
    659     virtual ~RTCRestArrayBase();
    660 
    661     /* Overridden methods: */
    662     virtual int resetToDefault() RT_OVERRIDE;
    663     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    664     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    665     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_OVERRIDE;
    666     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    667                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    668     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    669     virtual const char *typeName(void) const RT_OVERRIDE;
    670 
    671     /**
    672      * Clear the content of the map.
    673      */
    674     void clear();
    675 
    676     /**
    677      * Check if an list contains any items.
    678      *
    679      * @return   True if there is more than zero items, false otherwise.
    680      */
    681     bool isEmpty() const
    682     {
    683         return m_cElements == 0;
    684     }
    685 
    686     /**
    687      * Gets the number of entries in the map.
    688      */
    689     size_t size() const
    690     {
    691         return m_cElements;
    692     }
    693 
    694     /**
    695      * Returns the base object pointer at a given index.
    696      *
    697      * @returns The base object at @a a_idx, NULL if out of range.
    698      * @param   a_idx           The array index.
    699      */
    700     RTCRestObjectBase *atBase(size_t a_idx)
    701     {
    702         if (a_idx < m_cElements)
    703             return m_papElements[a_idx];
    704         return NULL;
    705     }
    706 
    707     /**
    708      * Returns the const base object pointer at a given index.
    709      *
    710      * @returns The base object at @a a_idx, NULL if out of range.
    711      * @param   a_idx           The array index.
    712      */
    713     RTCRestObjectBase const *atBase(size_t a_idx) const
    714     {
    715         if (a_idx < m_cElements)
    716             return m_papElements[a_idx];
    717         return NULL;
    718     }
    719 
    720     /**
    721      * Removes the element at @a a_idx.
    722      * @returns true if @a a_idx is valid, false if out of range.
    723      * @param   a_idx       The index of the element to remove.
    724      *                      The value ~(size_t)0 is an alias for the final element.
    725      */
    726     bool removeAt(size_t a_idx);
    727 
    728     /**
    729      * Makes sure the array can hold at the given number of entries.
    730      *
    731      * @returns VINF_SUCCESS or VERR_NO_MEMORY.
    732      * @param   a_cEnsureCapacity   The number of elements to ensure capacity to hold.
    733      */
    734     int ensureCapacity(size_t a_cEnsureCapacity);
    735 
    736 
    737 protected:
    738     /** The array. */
    739     RTCRestObjectBase **m_papElements;
    740     /** Number of elements in the array. */
    741     size_t              m_cElements;
    742     /** The number of elements m_papElements can hold.
    743      * The difference between m_cCapacity and m_cElements are all NULLs. */
    744     size_t              m_cCapacity;
    745 
    746     /**
    747      * Wrapper around the value constructor.
    748      *
    749      * @returns Pointer to new value object on success, NULL if out of memory.
    750      */
    751     virtual RTCRestObjectBase *createValue(void) = 0;
    752 
    753     /**
    754      * Wrapper around the value copy constructor.
    755      *
    756      * @returns Pointer to copy on success, NULL if out of memory.
    757      * @param   a_pSrc      The value to copy.
    758      */
    759     virtual RTCRestObjectBase *createValueCopy(RTCRestObjectBase const *a_pSrc) = 0;
    760 
    761     /**
    762      * Worker for the copy constructor and the assignment operator.
    763      *
    764      * This will use createEntryCopy to do the copying.
    765      *
    766      * @returns VINF_SUCCESS on success, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    767      * @param   a_rThat     The array to copy.  Caller makes 100% sure the it has
    768      *                      the same type as the destination.
    769      * @param   a_fThrow    Whether to throw error.
    770      */
    771     int copyArrayWorker(RTCRestArrayBase const &a_rThat, bool a_fThrow);
    772 
    773     /**
    774      * Worker for performing inserts.
    775      *
    776      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    777      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    778      * @param   a_idx           Where to insert it.  The value ~(size_t)0 is an alias for m_cElements.
    779      * @param   a_pValue        The value to insert.  Ownership is transferred to the map on success.
    780      * @param   a_fReplace      Whether to replace existing entry rather than insert.
    781      */
    782     int insertWorker(size_t a_idx, RTCRestObjectBase *a_pValue, bool a_fReplace);
    783 
    784     /**
    785      * Worker for performing inserts.
    786      *
    787      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    788      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    789      * @param   a_idx           Where to insert it.  The value ~(size_t)0 is an alias for m_cElements.
    790      * @param   a_rValue        The value to copy into the map.
    791      * @param   a_fReplace      Whether to replace existing key-value pair with matching key.
    792      */
    793     int insertCopyWorker(size_t a_idx, RTCRestObjectBase const &a_rValue, bool a_fReplace);
    794 
    795 private:
    796     /** Copy constructor on this class should never be used. */
    797     RTCRestArrayBase(RTCRestArrayBase const &a_rThat);
    798     /** Copy assignment operator on this class should never be used. */
    799     RTCRestArrayBase &operator=(RTCRestArrayBase const &a_rThat);
    800 };
    801 
    802 
    803 
    804 /**
    805  * Limited array class.
    806  */
    807 template<class ElementType> class RTCRestArray : public RTCRestArrayBase
    808 {
    809 public:
    810     /** Default constructor - empty array. */
    811     RTCRestArray()
    812         : RTCRestArrayBase()
    813     {
    814     }
    815 
    816     /** Destructor. */
    817     ~RTCRestArray()
    818     {
    819     }
    820 
    821     /** Copy constructor. */
    822     RTCRestArray(RTCRestArray const &a_rThat)
    823         : RTCRestArrayBase()
    824     {
    825         copyArrayWorker(a_rThat, true /*fThrow*/);
    826     }
    827 
    828     /** Copy assignment operator. */
    829     RTCRestArray &operator=(RTCRestArray const &a_rThat)
    830     {
    831         copyArrayWorker(a_rThat, true /*fThrow*/);
    832         return *this;
    833     }
    834 
    835     /** Safe copy assignment method. */
    836     int assignCopy(RTCRestArray const &a_rThat)
    837     {
    838         return copyArrayWorker(a_rThat, false /*fThrow*/);
    839     }
    840 
    841     /** Factory method. */
    842     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void)
    843     {
    844         return new (std::nothrow) RTCRestArray<ElementType>();
    845     }
    846 
    847     /** Factory method for elements. */
    848     static DECLCALLBACK(RTCRestObjectBase *) createElementInstance(void)
    849     {
    850         return new (std::nothrow) ElementType();
    851     }
    852 
    853 
    854     /**
    855      * Insert the given object at the specified index.
    856      *
    857      * @returns VINF_SUCCESS on success.
    858      *          VERR_INVALID_POINTER, VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
    859      * @param   a_idx           The insertion index.  ~(size_t)0 is an alias for the end.
    860      * @param   a_pThat         The object to insert.  The array takes ownership of the object on success.
    861      */
    862     int insert(size_t a_idx, ElementType *a_pThat)
    863     {
    864         return insertWorker(a_idx, a_pThat, false /*a_fReplace*/);
    865     }
    866 
    867     /**
    868      * Insert a copy of the object at the specified index.
    869      *
    870      * @returns VINF_SUCCESS on success.
    871      *          VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
    872      * @param   a_idx           The insertion index.  ~(size_t)0 is an alias for the end.
    873      * @param   a_rThat         The object to insert a copy of.
    874      */
    875     int insertCopy(size_t a_idx, ElementType const &a_rThat)
    876     {
    877         return insertCopyWorker(a_idx, a_rThat, false /*a_fReplace*/);
    878     }
    879 
    880     /**
    881      * Appends the given object to the array.
    882      *
    883      * @returns VINF_SUCCESS on success.
    884      *          VERR_INVALID_POINTER, VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
    885      * @param   a_pThat         The object to insert.  The array takes ownership of the object on success.
    886      */
    887     int append(ElementType *a_pThat)
    888     {
    889         return insertWorker(~(size_t)0, a_pThat, false /*a_fReplace*/);
    890     }
    891 
    892     /**
    893      * Appends a copy of the object at the specified index.
    894      *
    895      * @returns VINF_SUCCESS on success.
    896      *          VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
    897      * @param   a_rThat         The object to insert a copy of.
    898      */
    899     int appendCopy(ElementType const &a_rThat)
    900     {
    901         return insertCopyWorker(~(size_t)0, a_rThat, false /*a_fReplace*/);
    902     }
    903 
    904     /**
    905      * Prepends the given object to the array.
    906      *
    907      * @returns VINF_SUCCESS on success.
    908      *          VERR_INVALID_POINTER, VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
    909      * @param   a_pThat         The object to insert.  The array takes ownership of the object on success.
    910      */
    911     int prepend(ElementType *a_pThat)
    912     {
    913         return insertWorker(0, a_pThat, false /*a_fReplace*/);
    914     }
    915 
    916     /**
    917      * Prepends a copy of the object at the specified index.
    918      *
    919      * @returns VINF_SUCCESS on success.
    920      *          VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
    921      * @param   a_rThat         The object to insert a copy of.
    922      */
    923     int prependCopy(ElementType const &a_rThat)
    924     {
    925         return insertCopyWorker(0, a_rThat, false /*a_fReplace*/);
    926     }
    927 
    928     /**
    929      * Insert the given object at the specified index.
    930      *
    931      * @returns VINF_SUCCESS on success.
    932      *          VERR_INVALID_POINTER, VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
    933      * @param   a_idx           The index of the existing object to replace.
    934      * @param   a_pThat         The replacement object.  The array takes ownership of the object on success.
    935      */
    936     int replace(size_t a_idx, ElementType *a_pThat)
    937     {
    938         return insertWorker(a_idx, a_pThat, true /*a_fReplace*/);
    939     }
    940 
    941     /**
    942      * Insert a copy of the object at the specified index.
    943      *
    944      * @returns VINF_SUCCESS on success.
    945      *          VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
    946      * @param   a_idx           The index of the existing object to replace.
    947      * @param   a_rThat         The object to insert a copy of.
    948      */
    949     int replaceCopy(size_t a_idx, ElementType const &a_rThat)
    950     {
    951         return insertCopyWorker(a_idx, a_rThat, true /*a_fReplace*/);
    952     }
    953 
    954     /**
    955      * Returns the object at a given index.
    956      *
    957      * @returns The object at @a a_idx, NULL if out of range.
    958      * @param   a_idx           The array index.
    959      */
    960     ElementType *at(size_t a_idx)
    961     {
    962         if (a_idx < m_cElements)
    963             return (ElementType *)m_papElements[a_idx];
    964         return NULL;
    965     }
    966 
    967     /**
    968      * Returns the object at a given index, const variant.
    969      *
    970      * @returns The object at @a a_idx, NULL if out of range.
    971      * @param   a_idx           The array index.
    972      */
    973     ElementType const *at(size_t a_idx) const
    974     {
    975         if (a_idx < m_cElements)
    976             return (ElementType const *)m_papElements[a_idx];
    977         return NULL;
    978     }
    979 
    980     /**
    981      * Returns the first object in the array.
    982      * @returns The first object, NULL if empty.
    983      */
    984     ElementType *first()
    985     {
    986         return at(0);
    987     }
    988 
    989     /**
    990      * Returns the first object in the array, const variant.
    991      * @returns The first object, NULL if empty.
    992      */
    993     ElementType const *first() const
    994     {
    995         return at(0);
    996     }
    997 
    998     /**
    999      * Returns the last object in the array.
    1000      * @returns The last object, NULL if empty.
    1001      */
    1002     ElementType *last()
    1003     {
    1004         return at(m_cElements - 1);
    1005     }
    1006 
    1007     /**
    1008      * Returns the last object in the array, const variant.
    1009      * @returns The last object, NULL if empty.
    1010      */
    1011     ElementType const *last() const
    1012     {
    1013         return at(m_cElements - 1);
    1014     }
    1015 
    1016 
    1017 protected:
    1018     virtual RTCRestObjectBase *createValue(void) RT_OVERRIDE
    1019     {
    1020         return new (std::nothrow) ElementType();
    1021     }
    1022 
    1023     virtual RTCRestObjectBase *createValueCopy(RTCRestObjectBase const *a_pSrc) RT_OVERRIDE
    1024     {
    1025         ElementType *pCopy = new (std::nothrow) ElementType();
    1026         if (pCopy)
    1027         {
    1028             int rc = pCopy->assignCopy(*(ElementType const *)a_pSrc);
    1029             if (RT_SUCCESS(rc))
    1030                 return pCopy;
    1031             delete pCopy;
    1032         }
    1033         return NULL;
    1034     }
    1035 };
    1036 
    1037 
    1038 /**
    1039  * Abstract base class for the RTCRestStringMap template.
    1040  */
    1041 class RT_DECL_CLASS RTCRestStringMapBase : public RTCRestObjectBase
    1042 {
    1043 public:
    1044     /** Default destructor. */
    1045     RTCRestStringMapBase();
    1046     /** Copy constructor. */
    1047     RTCRestStringMapBase(RTCRestStringMapBase const &a_rThat);
    1048     /** Destructor. */
    1049     virtual ~RTCRestStringMapBase();
    1050     /** Copy assignment operator. */
    1051     RTCRestStringMapBase &operator=(RTCRestStringMapBase const &a_rThat);
    1052 
    1053     /* Overridden methods: */
    1054     virtual int resetToDefault() RT_OVERRIDE;
    1055     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    1056     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    1057     // later?
    1058     //virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_OVERRIDE;
    1059     //virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    1060     //                       uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    1061     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    1062     virtual const char *typeName(void) const RT_OVERRIDE;
    1063 
    1064     /**
    1065      * Clear the content of the map.
    1066      */
    1067     void clear();
    1068 
    1069     /**
    1070      * Gets the number of entries in the map.
    1071      */
    1072     size_t size() const;
    1073 
    1074     /**
    1075      * Checks if the map contains the given key.
    1076      * @returns true if key found, false if not.
    1077      * @param   a_pszKey   The key to check fo.
    1078      */
    1079     bool constainsKey(const char *a_pszKey) const;
    1080 
    1081     /**
    1082      * Checks if the map contains the given key.
    1083      * @returns true if key found, false if not.
    1084      * @param   a_rStrKey   The key to check fo.
    1085      */
    1086     bool constainsKey(RTCString const &a_rStrKey) const;
    1087 
    1088     /**
    1089      * Remove any key-value pair with the given key.
    1090      * @returns true if anything was removed, false if not found.
    1091      * @param   a_pszKey    The key to remove.
    1092      */
    1093     bool remove(const char *a_pszKey);
    1094 
    1095     /**
    1096      * Remove any key-value pair with the given key.
    1097      * @returns true if anything was removed, false if not found.
    1098      * @param   a_rStrKey   The key to remove.
    1099      */
    1100     bool remove(RTCString const &a_rStrKey);
    1101 
    1102     /**
    1103      * Creates a new value and inserts it under the given key, returning the new value.
    1104      *
    1105      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    1106      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1107      * @param   a_ppValue   Where to return the pointer to the value.
    1108      * @param   a_pszKey    The key to put it under.
    1109      * @param   a_cchKey    The length of the key.  Default is the entire string.
    1110      * @param   a_fReplace  Whether to replace or fail on key collision.
    1111      */
    1112     int putNewValue(RTCRestObjectBase **a_ppValue, const char *a_pszKey, size_t a_cchKey = RTSTR_MAX, bool a_fReplace = false);
    1113 
    1114     /**
    1115      * Creates a new value and inserts it under the given key, returning the new value.
    1116      *
    1117      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    1118      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1119      * @param   a_ppValue   Where to return the pointer to the value.
    1120      * @param   a_pszKey    The key to put it under.
    1121      * @param   a_fReplace  Whether to replace or fail on key collision.
    1122      */
    1123     int putNewValue(RTCRestObjectBase **a_ppValue, RTCString const &a_rStrKey, bool a_fReplace = false);
    1124 
    1125 protected:
    1126     /** Map entry. */
    1127     typedef struct MapEntry
    1128     {
    1129         /** String space core. */
    1130         RTSTRSPACECORE      Core;
    1131         /** List node for enumeration. */
    1132         RTLISTNODE          ListEntry;
    1133         /** The key.
    1134          * @remarks Core.pszString points to the value of this object.  So, consider it const. */
    1135         RTCString           strKey;
    1136         /** The value. */
    1137         RTCRestObjectBase  *pValue;
    1138     } MapEntry;
    1139     /** The map tree. */
    1140     RTSTRSPACE          m_Map;
    1141     /** The enumeration list head (MapEntry). */
    1142     RTLISTANCHOR        m_ListHead;
    1143     /** Number of map entries. */
    1144     size_t              m_cEntries;
    1145 
    1146 public:
    1147     /** @name Map Iteration
    1148      * @{  */
    1149     /** Const iterator. */
    1150     class ConstIterator
    1151     {
    1152     private:
    1153         MapEntry            *m_pCur;
    1154         ConstIterator();
    1155     protected:
    1156         ConstIterator(MapEntry *a_pEntry) : m_pCur(a_pEntry) { }
    1157     public:
    1158         ConstIterator(ConstIterator const &a_rThat) : m_pCur(a_rThat.m_pCur) { }
    1159 
    1160         /** Gets the key string. */
    1161         RTCString const         &getKey()   { return m_pCur->strKey; }
    1162         /** Gets poitner to the value object. */
    1163         RTCRestObjectBase const *getValue() { return m_pCur->pValue; }
    1164 
    1165         /** Advance to the next map entry. */
    1166         ConstIterator &operator++()
    1167         {
    1168             m_pCur = RTListNodeGetNextCpp(&m_pCur->ListEntry, MapEntry, ListEntry);
    1169             return *this;
    1170         }
    1171 
    1172         /** Advance to the previous map entry. */
    1173         ConstIterator &operator--()
    1174         {
    1175             m_pCur = RTListNodeGetPrevCpp(&m_pCur->ListEntry, MapEntry, ListEntry);
    1176             return *this;
    1177         }
    1178 
    1179         /** Compare equal. */
    1180         bool operator==(ConstIterator const &a_rThat) { return m_pCur == a_rThat.m_pCur; }
    1181         /** Compare not equal. */
    1182         bool operator!=(ConstIterator const &a_rThat) { return m_pCur != a_rThat.m_pCur; }
    1183 
    1184         /* Map class must be friend so it can use the MapEntry constructor. */
    1185         friend class RTCRestStringMapBase;
    1186     };
    1187 
    1188     /** Returns iterator for the first map entry (unless it's empty and it's also the end). */
    1189     ConstIterator begin() const { return ConstIterator(RTListGetFirstCpp(&m_ListHead, MapEntry, ListEntry)); }
    1190     /** Returns iterator for the last map entry (unless it's empty and it's also the end). */
    1191     ConstIterator last() const  { return ConstIterator(RTListGetLastCpp(&m_ListHead, MapEntry, ListEntry)); }
    1192     /** Returns the end iterator.  This does not ever refer to an actual map entry. */
    1193     ConstIterator end() const   { return ConstIterator(RT_FROM_CPP_MEMBER(&m_ListHead, MapEntry, ListEntry)); }
    1194     /** @} */
    1195 
    1196 
    1197 protected:
    1198     /**
    1199      * Wrapper around the value constructor.
    1200      *
    1201      * @returns Pointer to new value object on success, NULL if out of memory.
    1202      */
    1203     virtual RTCRestObjectBase *createValue(void) = 0;
    1204 
    1205     /**
    1206      * Wrapper around the value copy constructor.
    1207      *
    1208      * @returns Pointer to copy on success, NULL if out of memory.
    1209      * @param   a_pSrc      The value to copy.
    1210      */
    1211     virtual RTCRestObjectBase *createValueCopy(RTCRestObjectBase const *a_pSrc) = 0;
    1212 
    1213     /**
    1214      * Worker for the copy constructor and the assignment operator.
    1215      *
    1216      * This will use createEntryCopy to do the copying.
    1217      *
    1218      * @returns VINF_SUCCESS on success, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1219      * @param   a_rThat     The map to copy.  Caller makes 100% sure the it has
    1220      *                      the same type as the destination.
    1221      * @param   a_fThrow    Whether to throw error.
    1222      */
    1223     int copyMapWorker(RTCRestStringMapBase const &a_rThat, bool a_fThrow);
    1224 
    1225     /**
    1226      * Worker for performing inserts.
    1227      *
    1228      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    1229      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1230      * @param   a_pszKey        The key.
    1231      * @param   a_pValue        The value to insert.  Ownership is transferred to the map on success.
    1232      * @param   a_fReplace      Whether to replace existing key-value pair with matching key.
    1233      * @param   a_cchKey        The key length, the whole string by default.
    1234      */
    1235     int putWorker(const char *a_pszKey, RTCRestObjectBase *a_pValue, bool a_fReplace, size_t a_cchKey = RTSTR_MAX);
    1236 
    1237     /**
    1238      * Worker for performing inserts.
    1239      *
    1240      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    1241      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1242      * @param   a_pszKey        The key.
    1243      * @param   a_rValue        The value to copy into the map.
    1244      * @param   a_fReplace      Whether to replace existing key-value pair with matching key.
    1245      * @param   a_cchKey        The key length, the whole string by default.
    1246      */
    1247     int putCopyWorker(const char *a_pszKey, RTCRestObjectBase const &a_rValue, bool a_fReplace, size_t a_cchKey = RTSTR_MAX);
    1248 
    1249     /**
    1250      * Worker for getting the value corresponding to the given key.
    1251      *
    1252      * @returns Pointer to the value object if found, NULL if key not in the map.
    1253      * @param   a_pszKey        The key which value to look up.
    1254      */
    1255     RTCRestObjectBase *getWorker(const char *a_pszKey);
    1256 
    1257     /**
    1258      * Worker for getting the value corresponding to the given key, const variant.
    1259      *
    1260      * @returns Pointer to the value object if found, NULL if key not in the map.
    1261      * @param   a_pszKey        The key which value to look up.
    1262      */
    1263     RTCRestObjectBase const *getWorker(const char *a_pszKey) const;
    1264 
    1265 private:
    1266     static DECLCALLBACK(int) stringSpaceDestructorCallback(PRTSTRSPACECORE pStr, void *pvUser);
    1267 };
    1268 
    1269 
    1270 /**
    1271  * Limited map class.
    1272  */
    1273 template<class ValueType> class RTCRestStringMap : public RTCRestStringMapBase
    1274 {
    1275 public:
    1276     /** Default constructor, creates emtpy map. */
    1277     RTCRestStringMap()
    1278         : RTCRestStringMapBase()
    1279     {}
    1280 
    1281     /** Copy constructor. */
    1282     RTCRestStringMap(RTCRestStringMap const &a_rThat)
    1283         : RTCRestStringMapBase()
    1284     {
    1285         copyMapWorker(a_rThat, true /*a_fThrow*/);
    1286     }
    1287 
    1288     /** Destructor. */
    1289     virtual ~RTCRestStringMap()
    1290     {
    1291        /* nothing to do here. */
    1292     }
    1293 
    1294     /** Copy assignment operator. */
    1295     RTCRestStringMap &operator=(RTCRestStringMap const &a_rThat)
    1296     {
    1297         copyMapWorker(a_rThat, true /*a_fThrow*/);
    1298         return *this;
    1299     }
    1300 
    1301     /** Safe copy assignment method. */
    1302     int assignCopy(RTCRestStringMap const &a_rThat)
    1303     {
    1304         return copyMapWorker(a_rThat, false /*a_fThrow*/);
    1305     }
    1306 
    1307     /** Factory method. */
    1308     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void)
    1309     {
    1310         return new (std::nothrow) RTCRestStringMap<ValueType>();
    1311     }
    1312 
    1313     /** Factory method for values. */
    1314     static DECLCALLBACK(RTCRestObjectBase *) createValueInstance(void)
    1315     {
    1316         return new (std::nothrow) ValueType();
    1317     }
    1318 
    1319     /**
    1320      * Inserts the given object into the map.
    1321      *
    1322      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    1323      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1324      * @param   a_pszKey        The key.
    1325      * @param   a_pValue        The value to insert.  Ownership is transferred to the map on success.
    1326      * @param   a_fReplace      Whether to replace existing key-value pair with matching key.
    1327      */
    1328     int put(const char *a_pszKey, ValueType *a_pValue, bool a_fReplace = false)
    1329     {
    1330         return putWorker(a_pszKey, a_pValue, a_fReplace);
    1331     }
    1332 
    1333     /**
    1334      * Inserts the given object into the map.
    1335      *
    1336      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    1337      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1338      * @param   a_rStrKey       The key.
    1339      * @param   a_pValue        The value to insert.  Ownership is transferred to the map on success.
    1340      * @param   a_fReplace      Whether to replace existing key-value pair with matching key.
    1341      */
    1342     int put(RTCString const &a_rStrKey, ValueType *a_pValue, bool a_fReplace = false)
    1343     {
    1344         return putWorker(a_rStrKey.c_str(), a_pValue, a_fReplace, a_rStrKey.length());
    1345     }
    1346 
    1347     /**
    1348      * Inserts a copy of the given object into the map.
    1349      *
    1350      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    1351      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1352      * @param   a_pszKey        The key.
    1353      * @param   a_rValue        The value to insert a copy of.
    1354      * @param   a_fReplace      Whether to replace existing key-value pair with matching key.
    1355      */
    1356     int putCopy(const char *a_pszKey, const ValueType &a_rValue, bool a_fReplace = false)
    1357     {
    1358         return putCopyWorker(a_pszKey, a_rValue, a_fReplace);
    1359     }
    1360 
    1361     /**
    1362      * Inserts a copy of the given object into the map.
    1363      *
    1364      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    1365      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    1366      * @param   a_rStrKey       The key.
    1367      * @param   a_rValue        The value to insert a copy of.
    1368      * @param   a_fReplace      Whether to replace existing key-value pair with matching key.
    1369      */
    1370     int putCopy(RTCString const &a_rStrKey, const ValueType &a_rValue, bool a_fReplace = false)
    1371     {
    1372         return putCopyWorker(a_rStrKey.c_str(), a_rValue, a_fReplace, a_rStrKey.length());
    1373     }
    1374 
    1375     /**
    1376      * Gets the value corresponding to the given key.
    1377      *
    1378      * @returns Pointer to the value object if found, NULL if key not in the map.
    1379      * @param   a_pszKey        The key which value to look up.
    1380      */
    1381     ValueType *get(const char *a_pszKey)
    1382     {
    1383         return (ValueType *)getWorker(a_pszKey);
    1384     }
    1385 
    1386     /**
    1387      * Gets the value corresponding to the given key.
    1388      *
    1389      * @returns Pointer to the value object if found, NULL if key not in the map.
    1390      * @param   a_rStrKey       The key which value to look up.
    1391      */
    1392     ValueType *get(RTCString const &a_rStrKey)
    1393     {
    1394         return (ValueType *)getWorker(a_rStrKey.c_str());
    1395     }
    1396 
    1397     /**
    1398      * Gets the const value corresponding to the given key.
    1399      *
    1400      * @returns Pointer to the value object if found, NULL if key not in the map.
    1401      * @param   a_pszKey        The key which value to look up.
    1402      */
    1403     ValueType const *get(const char *a_pszKey) const
    1404     {
    1405         return (ValueType const *)getWorker(a_pszKey);
    1406     }
    1407 
    1408     /**
    1409      * Gets the const value corresponding to the given key.
    1410      *
    1411      * @returns Pointer to the value object if found, NULL if key not in the map.
    1412      * @param   a_rStrKey       The key which value to look up.
    1413      */
    1414     ValueType const *get(RTCString const &a_rStrKey) const
    1415     {
    1416         return (ValueType const *)getWorker(a_rStrKey.c_str());
    1417     }
    1418 
    1419     /** @todo enumerator*/
    1420 
    1421 protected:
    1422     virtual RTCRestObjectBase *createValue(void) RT_OVERRIDE
    1423     {
    1424         return new (std::nothrow) ValueType();
    1425     }
    1426 
    1427     virtual RTCRestObjectBase *createValueCopy(RTCRestObjectBase const *a_pSrc) RT_OVERRIDE
    1428     {
    1429         ValueType *pCopy = new (std::nothrow) ValueType();
    1430         if (pCopy)
    1431         {
    1432             int rc = pCopy->assignCopy(*(ValueType const *)a_pSrc);
    1433             if (RT_SUCCESS(rc))
    1434                 return pCopy;
    1435             delete pCopy;
    1436         }
    1437         return NULL;
    1438     }
    1439 };
    1440 
    1441 
    1442 /**
    1443  * Dynamic REST object.
    1444  *
    1445  * @todo figure this one out. it's possible this is only used in maps and
    1446  *       could be a specialized map implementation.
    1447  */
    1448 class /*RT_DECL_CLASS*/ RTCRestObject : public RTCRestObjectBase
    1449 {
    1450 public:
    1451     /** Default destructor. */
    1452     RTCRestObject();
    1453     /** Destructor. */
    1454     virtual ~RTCRestObject();
    1455 
    1456     /** Copy constructor. */
    1457     RTCRestObject(RTCRestObject const &a_rThat);
    1458     /** Copy assignment operator. */
    1459     RTCRestObject &operator=(RTCRestObject const &a_rThat);
    1460     /** Safe Safe copy assignment method. */
    1461     int assignCopy(RTCRestObject const &a_rThat);
    1462 
    1463     /* Overridden methods: */
    1464     virtual int setNull(void) RT_OVERRIDE;
    1465     virtual int resetToDefault() RT_OVERRIDE;
    1466     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    1467     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    1468     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_OVERRIDE;
    1469     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    1470                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    1471     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    1472     virtual const char *typeName(void) const RT_OVERRIDE;
    1473 
    1474     /** Factory method. */
    1475     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
    1476 
    1477 protected:
    1478     /** @todo figure out the value stuff here later... */
    1479 };
    1480 
    148137
    148238/**
  • trunk/include/iprt/cpp/reststringmap.h

    r74024 r74025  
    11/** @file
    2  * IPRT - C++ Representational State Transfer (REST) Base Classes.
     2 * IPRT - C++ Representational State Transfer (REST) String Map Template.
    33 */
    44
     
    2424 */
    2525
    26 #ifndef ___iprt_cpp_restbase_h
    27 #define ___iprt_cpp_restbase_h
    28 
    29 #include <iprt/types.h>
    30 #include <iprt/assert.h>
    31 #include <iprt/err.h>
    32 #include <iprt/http.h>
    33 #include <iprt/json.h>
     26#ifndef ___iprt_cpp_reststringmap_h
     27#define ___iprt_cpp_reststringmap_h
     28
    3429#include <iprt/list.h>
    3530#include <iprt/string.h>
    36 #include <iprt/stdarg.h>
    37 #include <iprt/cpp/ministring.h>
    38 #include <iprt/cpp/utils.h>
    39 
    40 
    41 /** @defgroup grp_rt_cpp_restbase   C++ Representational State Transfer (REST) Base Classes.
     31#include <iprt/cpp/restbase.h>
     32
     33
     34/** @defgroup grp_rt_cpp_reststingmap   C++ Representational State Transfer (REST) String Map Template
    4235 * @ingroup grp_rt_cpp
    4336 * @{
    4437 */
    45 
    46 
    47 
    48 /**
    49  * Abstract base class for serializing data objects.
    50  */
    51 class RT_DECL_CLASS RTCRestOutputBase
    52 {
    53 public:
    54     RTCRestOutputBase()
    55         : m_uIndent(0)
    56     { }
    57     virtual ~RTCRestOutputBase()
    58     { }
    59 
    60     /**
    61      * RTStrPrintf like function (see @ref pg_rt_str_format).
    62      *
    63      * @returns Number of bytes outputted.
    64      * @param   pszFormat   The format string.
    65      * @param   ...         Argument specfied in @a pszFormat.
    66      */
    67     size_t         printf(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(2, 3)
    68     {
    69         va_list va;
    70         va_start(va, pszFormat);
    71         size_t cchWritten = this->vprintf(pszFormat, va);
    72         va_end(va);
    73         return cchWritten;
    74     }
    75 
    76     /**
    77      * RTStrPrintfV like function (see @ref pg_rt_str_format).
    78      *
    79      * @returns Number of bytes outputted.
    80      * @param   pszFormat   The format string.
    81      * @param   va          Argument specfied in @a pszFormat.
    82      */
    83     virtual size_t vprintf(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(2, 0) = 0;
    84 
    85     /**
    86      * Sets the indentation level for use when pretty priting things.
    87      *
    88      * @returns Previous indentation level.
    89      * @param   uIndent     The indentation level.
    90      */
    91     unsigned setIndent(unsigned uIndent)
    92     {
    93         unsigned const uRet = m_uIndent;
    94         m_uIndent = uIndent;
    95         return uRet;
    96     }
    97 
    98     /**
    99      * Increases the indentation level.
    100      *
    101      * @returns Previous indentation level.
    102      */
    103     unsigned incrementIndent()
    104     {
    105         unsigned const uRet = m_uIndent;
    106         m_uIndent = uRet + 1;
    107         return uRet;
    108     }
    109 
    110 protected:
    111     /** The current indentation level. */
    112     unsigned m_uIndent;
    113 };
    114 
    115 
    116 /**
    117  * Serialize to a string object.
    118  */
    119 class RT_DECL_CLASS RTCRestOutputToString : public RTCRestOutputBase
    120 {
    121 public:
    122     /**
    123      * Creates an instance that appends to @a a_pDst.
    124      * @param   a_pDst      Pointer to the destination string object.
    125      *                      NULL is not accepted and will assert.
    126      * @param   a_fAppend   Whether to append to the current string value, or
    127      *                      nuke the string content before starting the output.
    128      */
    129     RTCRestOutputToString(RTCString *a_pDst, bool a_fAppend = false);
    130     virtual ~RTCRestOutputToString();
    131 
    132     virtual size_t vprintf(const char *pszFormat, va_list va) RT_OVERRIDE;
    133 
    134     /**
    135      * Finalizes the output and releases the string object to the caller.
    136      *
    137      * @returns The released string object.  NULL if we ran out of memory or if
    138      *          called already.
    139      *
    140      * @remark  This sets m_pDst to NULL and the object cannot be use for any
    141      *          more output afterwards.
    142      */
    143     virtual RTCString *finalize();
    144 
    145 
    146 protected:
    147     /** Pointer to the destination string.  NULL after finalize().   */
    148     RTCString  *m_pDst;
    149     /** Set if we ran out of memory and should ignore subsequent calls. */
    150     bool        m_fOutOfMemory;
    151 
    152     /** @callback_method_impl{FNRTSTROUTPUT} */
    153     static DECLCALLBACK(size_t) strOutput(void *pvArg, const char *pachChars, size_t cbChars);
    154 
    155     /* Make non-copyable (RTCNonCopyable causes warnings): */
    156     RTCRestOutputToString(RTCRestOutputToString const &);
    157     RTCRestOutputToString *operator=(RTCRestOutputToString const &);
    158 };
    159 
    160 
    161 /* forward decl: */
    162 class RTCRestJsonPrimaryCursor;
    163 
    164 /**
    165  * JSON cursor structure.
    166  *
    167  * This reduces the number of parameters passed around when deserializing JSON
    168  * input and also helps constructing full object name for logging and error reporting.
    169  */
    170 struct RT_DECL_CLASS RTCRestJsonCursor
    171 {
    172     /** Handle to the value being parsed. */
    173     RTJSONVAL                           m_hValue;
    174     /** Name of the value. */
    175     const char                         *m_pszName;
    176     /** Pointer to the parent, NULL if primary. */
    177     struct RTCRestJsonCursor const     *m_pParent;
    178     /** Pointer to the primary cursor structure. */
    179     RTCRestJsonPrimaryCursor           *m_pPrimary;
    180 
    181     RTCRestJsonCursor(struct RTCRestJsonCursor const &a_rParent)
    182         : m_hValue(NIL_RTJSONVAL), m_pszName(NULL), m_pParent(&a_rParent), m_pPrimary(a_rParent.m_pPrimary)
    183     { }
    184 
    185     RTCRestJsonCursor(RTJSONVAL hValue, const char *pszName, struct RTCRestJsonCursor *pParent)
    186         : m_hValue(hValue), m_pszName(pszName), m_pParent(pParent), m_pPrimary(pParent->m_pPrimary)
    187     { }
    188 
    189     RTCRestJsonCursor(RTJSONVAL hValue, const char *pszName)
    190         : m_hValue(hValue), m_pszName(pszName), m_pParent(NULL), m_pPrimary(NULL)
    191     { }
    192 
    193     ~RTCRestJsonCursor()
    194     {
    195         if (m_hValue != NIL_RTJSONVAL)
    196         {
    197             RTJsonValueRelease(m_hValue);
    198             m_hValue = NIL_RTJSONVAL;
    199         }
    200     }
    201 };
    202 
    203 
    204 /**
    205  * The primary JSON cursor class.
    206  */
    207 class RT_DECL_CLASS RTCRestJsonPrimaryCursor
    208 {
    209 public:
    210     /** The cursor for the first level. */
    211     RTCRestJsonCursor   m_Cursor;
    212     /** Error info keeper. */
    213     PRTERRINFO          m_pErrInfo;
    214 
    215     /** Creates a primary json cursor with optiona error info. */
    216     RTCRestJsonPrimaryCursor(RTJSONVAL hValue, const char *pszName, PRTERRINFO pErrInfo = NULL)
    217         : m_Cursor(hValue, pszName)
    218         , m_pErrInfo(pErrInfo)
    219     {
    220         m_Cursor.m_pPrimary = this;
    221     }
    222 
    223     virtual ~RTCRestJsonPrimaryCursor()
    224     {  }
    225 
    226     /**
    227      * Add an error message.
    228      *
    229      * @returns a_rc
    230      * @param   a_rCursor       The cursor reporting the error.
    231      * @param   a_rc            The status code.
    232      * @param   a_pszFormat     Format string.
    233      * @param   ...             Format string arguments.
    234      */
    235     virtual int addError(RTCRestJsonCursor const &a_rCursor, int a_rc, const char *a_pszFormat, ...);
    236 
    237     /**
    238      * Reports that the current field is not known.
    239      *
    240      * @returns Status to propagate.
    241      * @param   a_rCursor       The cursor for the field.
    242      */
    243     virtual int unknownField(RTCRestJsonCursor const &a_rCursor);
    244 
    245     /**
    246      * Copies the full path into pszDst.
    247      *
    248      * @returns pszDst
    249      * @param   a_rCursor       The cursor to start walking at.
    250      * @param   a_pszDst        Where to put the path.
    251      * @param   a_cbDst         Size of the destination buffer.
    252      */
    253     virtual char *getPath(RTCRestJsonCursor const &a_rCursor, char *a_pszDst, size_t a_cbDst) const;
    254 };
    255 
    256 
    257 /**
    258  * Abstract base class for REST data objects.
    259  *
    260  * The only information this keeps is the null indicator.
    261  */
    262 class RT_DECL_CLASS RTCRestObjectBase
    263 {
    264 public:
    265     RTCRestObjectBase();
    266     RTCRestObjectBase(RTCRestObjectBase const &a_rThat);
    267     virtual ~RTCRestObjectBase();
    268 
    269     /**
    270      * Tests if the object is @a null.
    271      * @returns true if null, false if not.
    272      */
    273     bool isNull(void) const { return m_fNullIndicator; };
    274 
    275     /**
    276      * Sets the object to @a null and fills it with defaults.
    277      * @returns IPRT status code (from resetToDefault).
    278      */
    279     virtual int setNull(void);
    280 
    281     /**
    282      * Sets the object to not-null state (i.e. undoes setNull()).
    283      * @remarks Only really important for strings.
    284      */
    285     virtual void setNotNull(void);
    286 
    287     /**
    288      * Resets the object to all default values.
    289      * @returns IPRT status code.
    290      */
    291     virtual int resetToDefault() = 0;
    292 
    293     /**
    294      * Serialize the object as JSON.
    295      *
    296      * @returns a_rDst
    297      * @param   a_rDst      The destination for the serialization.
    298      */
    299     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const = 0;
    300 
    301     /**
    302      * Deserialize object from the given JSON iterator.
    303      *
    304      * @returns IPRT status code.
    305      * @param   a_rCursor    The JSON cursor.
    306      */
    307     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) = 0;
    308 
    309     /**
    310      * Flags for toString().
    311      *
    312      * The kCollectionFormat_xxx bunch controls multiple values in arrays
    313      * are formatted.  They are ignored by everyone else.
    314      *
    315      * @note When adding collection format types, make sure to also
    316      *       update RTCRestArrayBase::toString().
    317      * @note Bit 24 is reserved (for kHdrField_MapCollection).
    318      */
    319     enum
    320     {
    321         kCollectionFormat_Unspecified = 0,  /**< Not specified. */
    322         kCollectionFormat_csv,              /**< Comma-separated list. */
    323         kCollectionFormat_ssv,              /**< Space-separated list. */
    324         kCollectionFormat_tsv,              /**< Tab-separated list. */
    325         kCollectionFormat_pipes,            /**< Pipe-separated list. */
    326         kCollectionFormat_multi,            /**< Special collection type that must be handled by caller of toString. */
    327         kCollectionFormat_Mask = 7,         /**< Collection type mask. */
    328 
    329         kToString_Append = 8                /**< Append to the string (rather than assigning). */
    330     };
    331 
    332     /**
    333      * String conversion.
    334      *
    335      * The default implementation of is a wrapper around serializeAsJson().
    336      *
    337      * @returns IPRT status code.
    338      * @param   a_pDst      Pointer to the destionation string.
    339      * @param   a_fFlags    kCollectionFormat_xxx.
    340      */
    341     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const;
    342 
    343     /**
    344      * String convertsion, naive variant.
    345      *
    346      * @returns String represenation.
    347      */
    348     RTCString toString() const;
    349 
    350     /**
    351      * Convert from (header) string value.
    352      *
    353      * The default implementation of is a wrapper around deserializeFromJson().
    354      *
    355      * @returns IPRT status code.
    356      * @param   a_rValue    The string value string to parse.
    357      * @param   a_pszName   Field name or similar.
    358      * @param   a_pErrInfo  Where to return additional error info.  Optional.
    359      * @param   a_fFlags    kCollectionFormat_xxx.
    360      */
    361     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    362                            uint32_t a_fFlags = kCollectionFormat_Unspecified);
    363 
    364     /** Type classification */
    365     typedef enum kTypeClass
    366     {
    367         kTypeClass_Invalid = 0,
    368         kTypeClass_Bool,                /**< Primitive: bool. */
    369         kTypeClass_Int64,               /**< Primitive: bool. */
    370         kTypeClass_Int32,               /**< Primitive: bool. */
    371         kTypeClass_Int16,               /**< Primitive: bool. */
    372         kTypeClass_Double,              /**< Primitive: bool. */
    373         kTypeClass_String,              /**< Primitive: bool. */
    374         kTypeClass_Object,              /**< Object (any kind of data model object). */
    375         kTypeClass_Array,               /**< Array (containing any kind of object). */
    376         kTypeClass_StringMap            /**< String map (containing any kind of object). */
    377     } kTypeClass;
    378 
    379     /**
    380      * Returns the object type class.
    381      */
    382     virtual kTypeClass typeClass(void) const;
    383 
    384     /**
    385      * Returns the object type name.
    386      */
    387     virtual const char *typeName(void) const = 0;
    388 
    389     /**
    390      * Factory method.
    391      * @returns Pointer to new object on success, NULL if out of memory.
    392      */
    393     typedef DECLCALLBACK(RTCRestObjectBase *) FNCREATEINSTANCE(void);
    394     /** Pointer to factory method. */
    395     typedef FNCREATEINSTANCE *PFNCREATEINSTANCE;
    396 
    397 
    398 protected:
    399     /** Null indicator.
    400      * @remarks The null values could be mapped onto C/C++ NULL pointer values,
    401      *          with the consequence that all data members in objects and such would
    402      *          have had to been allocated individually, even simple @a bool members.
    403      *          Given that we're overly paranoid about heap allocations (std::bad_alloc),
    404      *          it's more fitting to use a null indicator for us.
    405      */
    406     bool    m_fNullIndicator;
    407 };
    408 
    409 
    410 /**
    411  * Class wrapping 'bool'.
    412  */
    413 class RT_DECL_CLASS RTCRestBool : public RTCRestObjectBase
    414 {
    415 public:
    416     /** Default destructor. */
    417     RTCRestBool();
    418     /** Copy constructor. */
    419     RTCRestBool(RTCRestBool const &a_rThat);
    420     /** From value constructor. */
    421     RTCRestBool(bool fValue);
    422     /** Destructor. */
    423     virtual ~RTCRestBool();
    424     /** Copy assignment operator. */
    425     RTCRestBool &operator=(RTCRestBool const &a_rThat);
    426     /** Safe copy assignment method. */
    427     int assignCopy(RTCRestBool const &a_rThat);
    428     /** Assign value and clear null indicator. */
    429     void assignValue(bool a_fValue);
    430 
    431     /* Overridden methods: */
    432     virtual int resetToDefault() RT_OVERRIDE;
    433     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    434     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    435     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_OVERRIDE;
    436     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    437                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    438     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    439     virtual const char *typeName(void) const RT_OVERRIDE;
    440 
    441     /** Factory method. */
    442     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
    443 
    444 public:
    445     /** The value. */
    446     bool    m_fValue;
    447 };
    448 
    449 
    450 /**
    451  * Class wrapping 'int64_t'.
    452  */
    453 class RT_DECL_CLASS RTCRestInt64 : public RTCRestObjectBase
    454 {
    455 public:
    456     /** Default destructor. */
    457     RTCRestInt64();
    458     /** Copy constructor. */
    459     RTCRestInt64(RTCRestInt64 const &a_rThat);
    460     /** From value constructor. */
    461     RTCRestInt64(int64_t a_iValue);
    462     /** Destructor. */
    463     virtual ~RTCRestInt64();
    464     /** Copy assignment operator. */
    465     RTCRestInt64 &operator=(RTCRestInt64 const &a_rThat);
    466     /** Safe copy assignment method. */
    467     int assignCopy(RTCRestInt64 const &a_rThat);
    468     /** Assign value and clear null indicator. */
    469     void assignValue(int64_t a_iValue);
    470 
    471     /* Overridden methods: */
    472     virtual int resetToDefault() RT_OVERRIDE;
    473     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    474     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    475     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_OVERRIDE;
    476     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    477                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    478     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    479     virtual const char *typeName(void) const RT_OVERRIDE;
    480 
    481     /** Factory method. */
    482     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
    483 
    484 public:
    485     /** The value. */
    486     int64_t m_iValue;
    487 };
    488 
    489 
    490 /**
    491  * Class wrapping 'int32_t'.
    492  */
    493 class RT_DECL_CLASS RTCRestInt32 : public RTCRestObjectBase
    494 {
    495 public:
    496     /** Default destructor. */
    497     RTCRestInt32();
    498     /** Copy constructor. */
    499     RTCRestInt32(RTCRestInt32 const &a_rThat);
    500     /** From value constructor. */
    501     RTCRestInt32(int32_t iValue);
    502     /** Destructor. */
    503     virtual ~RTCRestInt32();
    504     /** Copy assignment operator. */
    505     RTCRestInt32 &operator=(RTCRestInt32 const &a_rThat);
    506     /** Safe copy assignment method. */
    507     int assignCopy(RTCRestInt32 const &a_rThat);
    508     /** Assign value and clear null indicator. */
    509     void assignValue(int32_t a_iValue);
    510 
    511     /* Overridden methods: */
    512     virtual int resetToDefault() RT_OVERRIDE;
    513     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    514     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    515     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_OVERRIDE;
    516     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    517                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    518     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    519     virtual const char *typeName(void) const RT_OVERRIDE;
    520 
    521     /** Factory method. */
    522     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
    523 
    524 public:
    525     /** The value. */
    526     int32_t m_iValue;
    527 };
    528 
    529 
    530 /**
    531  * Class wrapping 'int16_t'.
    532  */
    533 class RT_DECL_CLASS RTCRestInt16 : public RTCRestObjectBase
    534 {
    535 public:
    536     /** Default destructor. */
    537     RTCRestInt16();
    538     /** Copy constructor. */
    539     RTCRestInt16(RTCRestInt16 const &a_rThat);
    540     /** From value constructor. */
    541     RTCRestInt16(int16_t iValue);
    542     /** Destructor. */
    543     virtual ~RTCRestInt16();
    544     /** Copy assignment operator. */
    545     RTCRestInt16 &operator=(RTCRestInt16 const &a_rThat);
    546     /** Safe copy assignment method. */
    547     int assignCopy(RTCRestInt16 const &a_rThat);
    548     /** Assign value and clear null indicator. */
    549     void assignValue(int16_t a_iValue);
    550 
    551     /* Overridden methods: */
    552     virtual int resetToDefault() RT_OVERRIDE;
    553     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    554     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    555     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_OVERRIDE;
    556     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    557                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    558     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    559     virtual const char *typeName(void) const RT_OVERRIDE;
    560 
    561     /** Factory method. */
    562     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
    563 
    564 public:
    565     /** The value. */
    566     int16_t m_iValue;
    567 };
    568 
    569 
    570 /**
    571  * Class wrapping 'double'.
    572  */
    573 class RT_DECL_CLASS RTCRestDouble : public RTCRestObjectBase
    574 {
    575 public:
    576     /** Default destructor. */
    577     RTCRestDouble();
    578     /** Copy constructor. */
    579     RTCRestDouble(RTCRestDouble const &a_rThat);
    580     /** From value constructor. */
    581     RTCRestDouble(double rdValue);
    582     /** Destructor. */
    583     virtual ~RTCRestDouble();
    584     /** Copy assignment operator. */
    585     RTCRestDouble &operator=(RTCRestDouble const &a_rThat);
    586     /** Safe copy assignment method. */
    587     int assignCopy(RTCRestDouble const &a_rThat);
    588     /** Assign value and clear null indicator. */
    589     void assignValue(double a_rdValue);
    590 
    591     /* Overridden methods: */
    592     virtual int resetToDefault() RT_OVERRIDE;
    593     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    594     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    595     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_OVERRIDE;
    596     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    597                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    598     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    599     virtual const char *typeName(void) const RT_OVERRIDE;
    600 
    601     /** Factory method. */
    602     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
    603 
    604 public:
    605     /** The value. */
    606     double m_rdValue;
    607 };
    608 
    609 
    610 /**
    611  * Class wrapping 'RTCString'.
    612  */
    613 class RT_DECL_CLASS RTCRestString : public RTCString, public RTCRestObjectBase
    614 {
    615 public:
    616     /** Default destructor. */
    617     RTCRestString();
    618     /** Destructor. */
    619     virtual ~RTCRestString();
    620 
    621     /** Copy constructor. */
    622     RTCRestString(RTCRestString const &a_rThat);
    623     /** From value constructor. */
    624     RTCRestString(RTCString const &a_rThat);
    625     /** From value constructor. */
    626     RTCRestString(const char *a_pszSrc);
    627     /** Safe copy assignment method. */
    628     int assignCopy(RTCRestString const &a_rThat);
    629     /** Safe copy assignment method. */
    630     int assignCopy(RTCString const &a_rThat);
    631     /** Safe copy assignment method. */
    632     int assignCopy(const char *a_pszThat);
    633 
    634     /* Overridden methods: */
    635     virtual int setNull(void) RT_OVERRIDE; /* (ambigious, so overrider it to make sure.) */
    636     virtual int resetToDefault() RT_OVERRIDE;
    637     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    638     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    639     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_OVERRIDE;
    640     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    641                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    642     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    643     virtual const char *typeName(void) const RT_OVERRIDE;
    644 
    645     /** Factory method. */
    646     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
    647 };
    648 
    649 
    650 /**
    651  * Abstract base class for the RTCRestArray template.
    652  */
    653 class RT_DECL_CLASS RTCRestArrayBase : public RTCRestObjectBase
    654 {
    655 public:
    656     /** Default destructor. */
    657     RTCRestArrayBase();
    658     /** Destructor. */
    659     virtual ~RTCRestArrayBase();
    660 
    661     /* Overridden methods: */
    662     virtual int resetToDefault() RT_OVERRIDE;
    663     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    664     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    665     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_OVERRIDE;
    666     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    667                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    668     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    669     virtual const char *typeName(void) const RT_OVERRIDE;
    670 
    671     /**
    672      * Clear the content of the map.
    673      */
    674     void clear();
    675 
    676     /**
    677      * Check if an list contains any items.
    678      *
    679      * @return   True if there is more than zero items, false otherwise.
    680      */
    681     bool isEmpty() const
    682     {
    683         return m_cElements == 0;
    684     }
    685 
    686     /**
    687      * Gets the number of entries in the map.
    688      */
    689     size_t size() const
    690     {
    691         return m_cElements;
    692     }
    693 
    694     /**
    695      * Returns the base object pointer at a given index.
    696      *
    697      * @returns The base object at @a a_idx, NULL if out of range.
    698      * @param   a_idx           The array index.
    699      */
    700     RTCRestObjectBase *atBase(size_t a_idx)
    701     {
    702         if (a_idx < m_cElements)
    703             return m_papElements[a_idx];
    704         return NULL;
    705     }
    706 
    707     /**
    708      * Returns the const base object pointer at a given index.
    709      *
    710      * @returns The base object at @a a_idx, NULL if out of range.
    711      * @param   a_idx           The array index.
    712      */
    713     RTCRestObjectBase const *atBase(size_t a_idx) const
    714     {
    715         if (a_idx < m_cElements)
    716             return m_papElements[a_idx];
    717         return NULL;
    718     }
    719 
    720     /**
    721      * Removes the element at @a a_idx.
    722      * @returns true if @a a_idx is valid, false if out of range.
    723      * @param   a_idx       The index of the element to remove.
    724      *                      The value ~(size_t)0 is an alias for the final element.
    725      */
    726     bool removeAt(size_t a_idx);
    727 
    728     /**
    729      * Makes sure the array can hold at the given number of entries.
    730      *
    731      * @returns VINF_SUCCESS or VERR_NO_MEMORY.
    732      * @param   a_cEnsureCapacity   The number of elements to ensure capacity to hold.
    733      */
    734     int ensureCapacity(size_t a_cEnsureCapacity);
    735 
    736 
    737 protected:
    738     /** The array. */
    739     RTCRestObjectBase **m_papElements;
    740     /** Number of elements in the array. */
    741     size_t              m_cElements;
    742     /** The number of elements m_papElements can hold.
    743      * The difference between m_cCapacity and m_cElements are all NULLs. */
    744     size_t              m_cCapacity;
    745 
    746     /**
    747      * Wrapper around the value constructor.
    748      *
    749      * @returns Pointer to new value object on success, NULL if out of memory.
    750      */
    751     virtual RTCRestObjectBase *createValue(void) = 0;
    752 
    753     /**
    754      * Wrapper around the value copy constructor.
    755      *
    756      * @returns Pointer to copy on success, NULL if out of memory.
    757      * @param   a_pSrc      The value to copy.
    758      */
    759     virtual RTCRestObjectBase *createValueCopy(RTCRestObjectBase const *a_pSrc) = 0;
    760 
    761     /**
    762      * Worker for the copy constructor and the assignment operator.
    763      *
    764      * This will use createEntryCopy to do the copying.
    765      *
    766      * @returns VINF_SUCCESS on success, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    767      * @param   a_rThat     The array to copy.  Caller makes 100% sure the it has
    768      *                      the same type as the destination.
    769      * @param   a_fThrow    Whether to throw error.
    770      */
    771     int copyArrayWorker(RTCRestArrayBase const &a_rThat, bool a_fThrow);
    772 
    773     /**
    774      * Worker for performing inserts.
    775      *
    776      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    777      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    778      * @param   a_idx           Where to insert it.  The value ~(size_t)0 is an alias for m_cElements.
    779      * @param   a_pValue        The value to insert.  Ownership is transferred to the map on success.
    780      * @param   a_fReplace      Whether to replace existing entry rather than insert.
    781      */
    782     int insertWorker(size_t a_idx, RTCRestObjectBase *a_pValue, bool a_fReplace);
    783 
    784     /**
    785      * Worker for performing inserts.
    786      *
    787      * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
    788      *          VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
    789      * @param   a_idx           Where to insert it.  The value ~(size_t)0 is an alias for m_cElements.
    790      * @param   a_rValue        The value to copy into the map.
    791      * @param   a_fReplace      Whether to replace existing key-value pair with matching key.
    792      */
    793     int insertCopyWorker(size_t a_idx, RTCRestObjectBase const &a_rValue, bool a_fReplace);
    794 
    795 private:
    796     /** Copy constructor on this class should never be used. */
    797     RTCRestArrayBase(RTCRestArrayBase const &a_rThat);
    798     /** Copy assignment operator on this class should never be used. */
    799     RTCRestArrayBase &operator=(RTCRestArrayBase const &a_rThat);
    800 };
    801 
    802 
    803 
    804 /**
    805  * Limited array class.
    806  */
    807 template<class ElementType> class RTCRestArray : public RTCRestArrayBase
    808 {
    809 public:
    810     /** Default constructor - empty array. */
    811     RTCRestArray()
    812         : RTCRestArrayBase()
    813     {
    814     }
    815 
    816     /** Destructor. */
    817     ~RTCRestArray()
    818     {
    819     }
    820 
    821     /** Copy constructor. */
    822     RTCRestArray(RTCRestArray const &a_rThat)
    823         : RTCRestArrayBase()
    824     {
    825         copyArrayWorker(a_rThat, true /*fThrow*/);
    826     }
    827 
    828     /** Copy assignment operator. */
    829     RTCRestArray &operator=(RTCRestArray const &a_rThat)
    830     {
    831         copyArrayWorker(a_rThat, true /*fThrow*/);
    832         return *this;
    833     }
    834 
    835     /** Safe copy assignment method. */
    836     int assignCopy(RTCRestArray const &a_rThat)
    837     {
    838         return copyArrayWorker(a_rThat, false /*fThrow*/);
    839     }
    840 
    841     /** Factory method. */
    842     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void)
    843     {
    844         return new (std::nothrow) RTCRestArray<ElementType>();
    845     }
    846 
    847     /** Factory method for elements. */
    848     static DECLCALLBACK(RTCRestObjectBase *) createElementInstance(void)
    849     {
    850         return new (std::nothrow) ElementType();
    851     }
    852 
    853 
    854     /**
    855      * Insert the given object at the specified index.
    856      *
    857      * @returns VINF_SUCCESS on success.
    858      *          VERR_INVALID_POINTER, VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
    859      * @param   a_idx           The insertion index.  ~(size_t)0 is an alias for the end.
    860      * @param   a_pThat         The object to insert.  The array takes ownership of the object on success.
    861      */
    862     int insert(size_t a_idx, ElementType *a_pThat)
    863     {
    864         return insertWorker(a_idx, a_pThat, false /*a_fReplace*/);
    865     }
    866 
    867     /**
    868      * Insert a copy of the object at the specified index.
    869      *
    870      * @returns VINF_SUCCESS on success.
    871      *          VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
    872      * @param   a_idx           The insertion index.  ~(size_t)0 is an alias for the end.
    873      * @param   a_rThat         The object to insert a copy of.
    874      */
    875     int insertCopy(size_t a_idx, ElementType const &a_rThat)
    876     {
    877         return insertCopyWorker(a_idx, a_rThat, false /*a_fReplace*/);
    878     }
    879 
    880     /**
    881      * Appends the given object to the array.
    882      *
    883      * @returns VINF_SUCCESS on success.
    884      *          VERR_INVALID_POINTER, VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
    885      * @param   a_pThat         The object to insert.  The array takes ownership of the object on success.
    886      */
    887     int append(ElementType *a_pThat)
    888     {
    889         return insertWorker(~(size_t)0, a_pThat, false /*a_fReplace*/);
    890     }
    891 
    892     /**
    893      * Appends a copy of the object at the specified index.
    894      *
    895      * @returns VINF_SUCCESS on success.
    896      *          VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
    897      * @param   a_rThat         The object to insert a copy of.
    898      */
    899     int appendCopy(ElementType const &a_rThat)
    900     {
    901         return insertCopyWorker(~(size_t)0, a_rThat, false /*a_fReplace*/);
    902     }
    903 
    904     /**
    905      * Prepends the given object to the array.
    906      *
    907      * @returns VINF_SUCCESS on success.
    908      *          VERR_INVALID_POINTER, VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
    909      * @param   a_pThat         The object to insert.  The array takes ownership of the object on success.
    910      */
    911     int prepend(ElementType *a_pThat)
    912     {
    913         return insertWorker(0, a_pThat, false /*a_fReplace*/);
    914     }
    915 
    916     /**
    917      * Prepends a copy of the object at the specified index.
    918      *
    919      * @returns VINF_SUCCESS on success.
    920      *          VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
    921      * @param   a_rThat         The object to insert a copy of.
    922      */
    923     int prependCopy(ElementType const &a_rThat)
    924     {
    925         return insertCopyWorker(0, a_rThat, false /*a_fReplace*/);
    926     }
    927 
    928     /**
    929      * Insert the given object at the specified index.
    930      *
    931      * @returns VINF_SUCCESS on success.
    932      *          VERR_INVALID_POINTER, VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
    933      * @param   a_idx           The index of the existing object to replace.
    934      * @param   a_pThat         The replacement object.  The array takes ownership of the object on success.
    935      */
    936     int replace(size_t a_idx, ElementType *a_pThat)
    937     {
    938         return insertWorker(a_idx, a_pThat, true /*a_fReplace*/);
    939     }
    940 
    941     /**
    942      * Insert a copy of the object at the specified index.
    943      *
    944      * @returns VINF_SUCCESS on success.
    945      *          VERR_NO_MEMORY, VERR_NO_STR_MEMORY or VERR_OUT_OF_RANGE on failure.
    946      * @param   a_idx           The index of the existing object to replace.
    947      * @param   a_rThat         The object to insert a copy of.
    948      */
    949     int replaceCopy(size_t a_idx, ElementType const &a_rThat)
    950     {
    951         return insertCopyWorker(a_idx, a_rThat, true /*a_fReplace*/);
    952     }
    953 
    954     /**
    955      * Returns the object at a given index.
    956      *
    957      * @returns The object at @a a_idx, NULL if out of range.
    958      * @param   a_idx           The array index.
    959      */
    960     ElementType *at(size_t a_idx)
    961     {
    962         if (a_idx < m_cElements)
    963             return (ElementType *)m_papElements[a_idx];
    964         return NULL;
    965     }
    966 
    967     /**
    968      * Returns the object at a given index, const variant.
    969      *
    970      * @returns The object at @a a_idx, NULL if out of range.
    971      * @param   a_idx           The array index.
    972      */
    973     ElementType const *at(size_t a_idx) const
    974     {
    975         if (a_idx < m_cElements)
    976             return (ElementType const *)m_papElements[a_idx];
    977         return NULL;
    978     }
    979 
    980     /**
    981      * Returns the first object in the array.
    982      * @returns The first object, NULL if empty.
    983      */
    984     ElementType *first()
    985     {
    986         return at(0);
    987     }
    988 
    989     /**
    990      * Returns the first object in the array, const variant.
    991      * @returns The first object, NULL if empty.
    992      */
    993     ElementType const *first() const
    994     {
    995         return at(0);
    996     }
    997 
    998     /**
    999      * Returns the last object in the array.
    1000      * @returns The last object, NULL if empty.
    1001      */
    1002     ElementType *last()
    1003     {
    1004         return at(m_cElements - 1);
    1005     }
    1006 
    1007     /**
    1008      * Returns the last object in the array, const variant.
    1009      * @returns The last object, NULL if empty.
    1010      */
    1011     ElementType const *last() const
    1012     {
    1013         return at(m_cElements - 1);
    1014     }
    1015 
    1016 
    1017 protected:
    1018     virtual RTCRestObjectBase *createValue(void) RT_OVERRIDE
    1019     {
    1020         return new (std::nothrow) ElementType();
    1021     }
    1022 
    1023     virtual RTCRestObjectBase *createValueCopy(RTCRestObjectBase const *a_pSrc) RT_OVERRIDE
    1024     {
    1025         ElementType *pCopy = new (std::nothrow) ElementType();
    1026         if (pCopy)
    1027         {
    1028             int rc = pCopy->assignCopy(*(ElementType const *)a_pSrc);
    1029             if (RT_SUCCESS(rc))
    1030                 return pCopy;
    1031             delete pCopy;
    1032         }
    1033         return NULL;
    1034     }
    1035 };
    1036 
    103738
    103839/**
     
    1440441
    1441442
    1442 /**
    1443  * Dynamic REST object.
    1444  *
    1445  * @todo figure this one out. it's possible this is only used in maps and
    1446  *       could be a specialized map implementation.
    1447  */
    1448 class /*RT_DECL_CLASS*/ RTCRestObject : public RTCRestObjectBase
    1449 {
    1450 public:
    1451     /** Default destructor. */
    1452     RTCRestObject();
    1453     /** Destructor. */
    1454     virtual ~RTCRestObject();
    1455 
    1456     /** Copy constructor. */
    1457     RTCRestObject(RTCRestObject const &a_rThat);
    1458     /** Copy assignment operator. */
    1459     RTCRestObject &operator=(RTCRestObject const &a_rThat);
    1460     /** Safe Safe copy assignment method. */
    1461     int assignCopy(RTCRestObject const &a_rThat);
    1462 
    1463     /* Overridden methods: */
    1464     virtual int setNull(void) RT_OVERRIDE;
    1465     virtual int resetToDefault() RT_OVERRIDE;
    1466     virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
    1467     virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    1468     virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_OVERRIDE;
    1469     virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
    1470                            uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
    1471     virtual kTypeClass typeClass(void) const RT_OVERRIDE;
    1472     virtual const char *typeName(void) const RT_OVERRIDE;
    1473 
    1474     /** Factory method. */
    1475     static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
    1476 
    1477 protected:
    1478     /** @todo figure out the value stuff here later... */
    1479 };
    1480 
    1481 
    1482 /**
    1483  * Base class for REST client requests.
    1484  *
    1485  * This encapsulates parameters and helps transform them into a HTTP request.
    1486  *
    1487  * Parameters can be transfered in a number of places:
    1488  *      - Path part of the URL.
    1489  *      - Query part of the URL.
    1490  *      - HTTP header fields.
    1491  *      - FORM body.
    1492  *      - JSON body.
    1493  *      - XML body.
    1494  *      - ...
    1495  *
    1496  * They can be require or optional.  The latter may have default values.  In
    1497  * swagger 3 they can also be nullable, which means the null-indicator cannot
    1498  * be used for tracking optional parameters.
    1499  */
    1500 class RT_DECL_CLASS RTCRestClientRequestBase
    1501 {
    1502 public:
    1503     RTCRestClientRequestBase();
    1504     virtual ~RTCRestClientRequestBase();
    1505     RTCRestClientRequestBase(RTCRestClientRequestBase const &a_rThat);
    1506     RTCRestClientRequestBase &operator=(RTCRestClientRequestBase const &a_rThat);
    1507 
    1508     /**
    1509      * Reset all members to default values.
    1510      * @returns IPRT status code.
    1511      */
    1512     virtual int resetToDefault() = 0;
    1513 
    1514     /**
    1515      * Prepares the HTTP handle for transmitting this request.
    1516      *
    1517      * @returns IPRT status code.
    1518      * @param   a_pStrPath  Where to set path parameters.  Will be appended to the base path.
    1519      * @param   a_pStrQuery Where to set query parameters.
    1520      * @param   a_hHttp     Where to set header parameters and such.
    1521      * @param   a_pStrBody  Where to set body parameters.
    1522      */
    1523     virtual int xmitPrepare(RTCString *a_pStrPath, RTCString *a_pStrQuery, RTHTTP a_hHttp, RTCString *a_pStrBody) const = 0;
    1524 
    1525     /**
    1526      * Always called after the request has been transmitted.
    1527      *
    1528      * @param   a_rcStatus  Negative numbers are IPRT errors, positive are HTTP status codes.
    1529      * @param   a_hHttp     The HTTP handle the request was performed on.
    1530      */
    1531     virtual void xmitComplete(int a_rcStatus, RTHTTP a_hHttp) const = 0;
    1532 
    1533     /**
    1534      * Checks if there are were any assignment errors.
    1535      */
    1536     bool hasAssignmentErrors() const { return m_fErrorSet != 0; }
    1537 
    1538 protected:
    1539     /** Set of fields that have been explicitly assigned a value. */
    1540     uint64_t m_fIsSet;
    1541     /** Set of fields where value assigning failed. */
    1542     uint64_t m_fErrorSet;
    1543 
    1544     /** Path parameter descriptor. */
    1545     typedef struct
    1546     {
    1547         const char                 *pszName;    /**< The name string to replace (including {}). */
    1548         size_t                      cchName;    /**< Length of pszName. */
    1549         uint32_t                    fFlags;     /**< The toString flags. */
    1550         uint8_t                     iBitNo;     /**< The parameter bit number. */
    1551     } PATHPARAMDESC;
    1552 
    1553     /** Path parameter state. */
    1554     typedef struct
    1555     {
    1556         RTCRestObjectBase const    *pObj;       /**< Pointer to the parameter object. */
    1557         size_t                      offName;    /**< Maintained by worker. */
    1558     } PATHPARAMSTATE;
    1559 
    1560     /**
    1561      * Do path parameters.
    1562      *
    1563      * @returns IPRT status code
    1564      * @param   a_pStrPath          The destination path.
    1565      * @param   a_pszPathTemplate   The path template string.
    1566      * @param   a_cchPathTemplate   The length of the path template string.
    1567      * @param   a_paPathParams      The path parameter descriptors (static).
    1568      * @param   a_paPathParamStates The path parameter objects and states.
    1569      * @param   a_cPathParams       Number of path parameters.
    1570      */
    1571     int doPathParameters(RTCString *a_pStrPath, const char *a_pszPathTemplate, size_t a_cchPathTemplate,
    1572                          PATHPARAMDESC const *a_paPathParams, PATHPARAMSTATE *a_paPathParamStates, size_t a_cPathParams) const;
    1573 
    1574     /** Query parameter descriptor. */
    1575     typedef struct
    1576     {
    1577         const char *pszName;            /**< The parameter name. */
    1578         uint32_t    fFlags;             /**< The toString flags. */
    1579         bool        fRequired;          /**< Required or not. */
    1580         uint8_t     iBitNo;             /**< The parameter bit number. */
    1581     } QUERYPARAMDESC;
    1582 
    1583     /**
    1584      * Do query parameters.
    1585      *
    1586      * @returns IPRT status code
    1587      * @param   a_pStrQuery         The destination string.
    1588      * @param   a_paQueryParams     The query parameter descriptors.
    1589      * @param   a_papQueryParamObjs The query parameter objects, parallel to @a a_paQueryParams.
    1590      * @param   a_cQueryParams      Number of query parameters.
    1591      */
    1592     int doQueryParameters(RTCString *a_pStrQuery, QUERYPARAMDESC const *a_paQueryParams,
    1593                           RTCRestObjectBase const **a_papQueryParamObjs, size_t a_cQueryParams) const;
    1594 
    1595     /** Header parameter descriptor. */
    1596     typedef struct
    1597     {
    1598         const char *pszName;            /**< The parameter name. */
    1599         uint32_t    fFlags;             /**< The toString flags. */
    1600         bool        fRequired;          /**< Required or not. */
    1601         uint8_t     iBitNo;             /**< The parameter bit number. */
    1602         bool        fMapCollection;     /**< Collect headers starting with pszName into a map. */
    1603     } HEADERPARAMDESC;
    1604 
    1605     /**
    1606      * Do header parameters.
    1607      *
    1608      * @returns IPRT status code
    1609      * @param   a_hHttp                 Where to set header parameters.
    1610      * @param   a_paHeaderParams        The header parameter descriptors.
    1611      * @param   a_papHeaderParamObjs    The header parameter objects, parallel to @a a_paHeaderParams.
    1612      * @param   a_cHeaderParams         Number of header parameters.
    1613      */
    1614     int doHeaderParameters(RTHTTP a_hHttp, HEADERPARAMDESC const *a_paHeaderParams,
    1615                            RTCRestObjectBase const **a_papHeaderParamObjs, size_t a_cHeaderParams) const;
    1616 };
    1617 
    1618 
    1619 /**
    1620  * Base class for REST client responses.
    1621  */
    1622 class RT_DECL_CLASS RTCRestClientResponseBase
    1623 {
    1624 public:
    1625     /** Default constructor. */
    1626     RTCRestClientResponseBase();
    1627     /** Destructor. */
    1628     virtual ~RTCRestClientResponseBase();
    1629     /** Copy constructor. */
    1630     RTCRestClientResponseBase(RTCRestClientResponseBase const &a_rThat);
    1631     /** Copy assignment operator. */
    1632     RTCRestClientResponseBase &operator=(RTCRestClientResponseBase const &a_rThat);
    1633 
    1634     /**
    1635      * Resets the object state.
    1636      */
    1637     virtual void reset(void);
    1638 
    1639     /**
    1640      * Prepares the HTTP handle for receiving the response.
    1641      *
    1642      * This may install callbacks and such like.
    1643      *
    1644      * @returns IPRT status code.
    1645      * @param   a_hHttp     The HTTP handle to prepare for receiving.
    1646      * @param   a_pppvHdr   If a header callback handler is installed, set the value pointed to to NULL.
    1647      * @param   a_pppvBody  If a body callback handler is installed, set the value pointed to to NULL.
    1648      */
    1649     virtual int receivePrepare(RTHTTP a_hHttp, void ***a_pppvHdr, void ***a_pppvBody);
    1650 
    1651     /**
    1652      * Called when the HTTP request has been completely received.
    1653      *
    1654      * @param   a_rcStatus  Negative numbers are IPRT errors, positive are HTTP status codes.
    1655      * @param   a_hHttp     The HTTP handle the request was performed on.
    1656      *                      This can be NIL_RTHTTP should something fail early, in
    1657      *                      which case it is possible receivePrepare() wasn't called.
    1658      *
    1659      * @note    Called before consumeHeaders() and consumeBody().
    1660      */
    1661     virtual void receiveComplete(int a_rcStatus, RTHTTP a_hHttp);
    1662 
    1663     /**
    1664      * Callback that consumes HTTP header data from the server.
    1665      *
    1666      * @param   a_pchData  Body data.
    1667      * @param   a_cbData   Amount of body data.
    1668      *
    1669      * @note    Called after receiveComplete()..
    1670      */
    1671     virtual void consumeHeaders(const char *a_pchData, size_t a_cbData);
    1672 
    1673     /**
    1674      * Callback that consumes HTTP body data from the server.
    1675      *
    1676      * @param   a_pchData  Body data.
    1677      * @param   a_cbData   Amount of body data.
    1678      *
    1679      * @note    Called after consumeHeaders().
    1680      */
    1681     virtual void consumeBody(const char *a_pchData, size_t a_cbData);
    1682 
    1683     /**
    1684      * Called after status, headers and body all have been presented.
    1685      *
    1686      * @returns IPRT status code.
    1687      */
    1688     virtual void receiveFinal();
    1689 
    1690     /**
    1691      * Getter for m_rcStatus.
    1692      * @returns Negative numbers are IPRT errors, positive are HTTP status codes.
    1693      */
    1694     int getStatus() { return m_rcStatus; }
    1695 
    1696     /**
    1697      * Getter for m_rcHttp.
    1698      * @returns HTTP status code or VERR_NOT_AVAILABLE.
    1699      */
    1700     int getHttpStatus() { return m_rcHttp; }
    1701 
    1702     /**
    1703      * Getter for m_pErrInfo.
    1704      */
    1705     PCRTERRINFO getErrInfo(void) const { return m_pErrInfo; }
    1706 
    1707     /**
    1708      * Getter for m_strContentType.
    1709      */
    1710     RTCString const &getContentType(void) const { return m_strContentType; }
    1711 
    1712 
    1713 protected:
    1714     /** Negative numbers are IPRT errors, positive are HTTP status codes. */
    1715     int         m_rcStatus;
    1716     /** The HTTP status code, VERR_NOT_AVAILABLE if not set. */
    1717     int         m_rcHttp;
    1718     /** Error information. */
    1719     PRTERRINFO  m_pErrInfo;
    1720     /** The value of the Content-Type header field. */
    1721     RTCString   m_strContentType;
    1722 
    1723     PRTERRINFO  getErrInfoInternal(void);
    1724     void        deleteErrInfo(void);
    1725     void        copyErrInfo(PCRTERRINFO pErrInfo);
    1726 
    1727     /**
    1728      * Reports an error (or warning if a_rc non-negative).
    1729      *
    1730      * @returns a_rc
    1731      * @param   a_rc        The status code to report and return.  The first
    1732      *                      error status is assigned to m_rcStatus, subsequent
    1733      *                      ones as well as informational statuses are not
    1734      *                      recorded by m_rcStatus.
    1735      * @param   a_pszFormat The message format string.
    1736      * @param   ...         Message arguments.
    1737      */
    1738     int addError(int a_rc, const char *a_pszFormat, ...);
    1739 
    1740     /** Field flags. */
    1741     enum
    1742     {
    1743         /** Collection map, name is a prefix followed by '*'. */
    1744         kHdrField_MapCollection   = RT_BIT_32(24),
    1745     };
    1746 
    1747     /** Header field descriptor. */
    1748     typedef struct
    1749     {
    1750         /** The header field name. */
    1751         const char *pszName;
    1752         /** The length of the field name.*/
    1753         uint32_t    cchName;
    1754         /** Flags, TBD. */
    1755         uint32_t    fFlags;
    1756         /** Object factory. */
    1757         RTCRestObjectBase::PFNCREATEINSTANCE pfnCreateInstance;
    1758     } HEADERFIELDDESC;
    1759 
    1760     /**
    1761      * Helper that extracts fields from the HTTP headers.
    1762      *
    1763      * @param   a_paFieldDescs      Pointer to an array of field descriptors.
    1764      * @param   a_pappFieldValues   Pointer to a parallel array of value pointer pointers.
    1765      * @param   a_cFields           Number of field descriptors..
    1766      * @param   a_pchData           The header blob to search.
    1767      * @param   a_cbData            The size of the header blob to search.
    1768      */
    1769     void extracHeaderFieldsFromBlob(HEADERFIELDDESC const *a_paFieldDescs, RTCRestObjectBase ***a_pappFieldValues,
    1770                                     size_t a_cFields, const char *a_pchData, size_t a_cbData);
    1771 
    1772     /**
    1773      * Helper that extracts a header field.
    1774      *
    1775      * @retval  VINF_SUCCESS
    1776      * @retval  VERR_NOT_FOUND if not found.
    1777      * @retval  VERR_NO_STR_MEMORY
    1778      * @param   a_pszField  The header field header name.
    1779      * @param   a_cchField  The length of the header field name.
    1780      * @param   a_pchData   The header blob to search.
    1781      * @param   a_cbData    The size of the header blob to search.
    1782      * @param   a_pStrDst   Where to store the header value on successs.
    1783      */
    1784     int extractHeaderFromBlob(const char *a_pszField, size_t a_cchField, const char *a_pchData, size_t a_cbData,
    1785                               RTCString *a_pStrDst);
    1786 
    1787     /**
    1788      * Helper that does the deserializing of the response body.
    1789      *
    1790      * @param   a_pDst      The destination object for the body content.
    1791      * @param   a_pchData   The body blob.
    1792      * @param   a_cbData    The size of the body blob.
    1793      */
    1794     void deserializeBody(RTCRestObjectBase *a_pDst, const char *a_pchData, size_t a_cbData);
    1795 
    1796     /**
    1797      * Primary json cursor for parsing bodies.
    1798      */
    1799     class PrimaryJsonCursorForBody : public RTCRestJsonPrimaryCursor
    1800     {
    1801     public:
    1802         RTCRestClientResponseBase *m_pThat; /**< Pointer to response object. */
    1803         PrimaryJsonCursorForBody(RTJSONVAL hValue, const char *pszName, RTCRestClientResponseBase *a_pThat);
    1804         virtual int addError(RTCRestJsonCursor const &a_rCursor, int a_rc, const char *a_pszFormat, ...) RT_OVERRIDE;
    1805         virtual int unknownField(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
    1806     };
    1807 };
    1808 
    1809 
    1810 /**
    1811  * Base class for REST client responses.
    1812  */
    1813 class RT_DECL_CLASS RTCRestClientApiBase
    1814 {
    1815 public:
    1816     RTCRestClientApiBase()
    1817         : m_hHttp(NIL_RTHTTP)
    1818     {}
    1819     virtual ~RTCRestClientApiBase();
    1820 
    1821     /** @name Base path (URL) handling.
    1822      * @{ */
    1823     /**
    1824      * Gets the base path we're using.
    1825      *
    1826      * @returns Base URL string.  If empty, we'll be using the default one.
    1827      */
    1828     RTCString const &getBasePath(void) const
    1829     {
    1830         return m_strBasePath;
    1831     }
    1832 
    1833     /**
    1834      * Sets the base path (URL) to use when talking to the server.
    1835      *
    1836      * Setting the base path is only required if there is a desire to use a
    1837      * different server from the one specified in the API specification, like
    1838      * for instance regional one.
    1839      *
    1840      * @param   a_pszPath   The base path to use.
    1841      */
    1842     virtual void setBasePath(const char *a_pszPath)
    1843     {
    1844         m_strBasePath = a_pszPath;
    1845     }
    1846 
    1847     /**
    1848      * Sets the base path (URL) to use when talking to the server.
    1849      *
    1850      * Setting the base path is only required if there is a desire to use a
    1851      * different server from the one specified in the API specification, like
    1852      * for instance regional one.
    1853      *
    1854      * @param   a_strPath   The base path to use.
    1855      * @note    Defers to the C-string variant.
    1856      */
    1857     void setBasePath(RTCString const &a_strPath) { setBasePath(a_strPath.c_str()); }
    1858 
    1859     /**
    1860      * Gets the default base path (URL) as specified in the specs.
    1861      *
    1862      * @returns Base path (URL) string.
    1863      */
    1864     virtual const char *getDefaultBasePath() = 0;
    1865     /** @} */
    1866 
    1867 protected:
    1868     /** Handle to the HTTP connection object. */
    1869     RTHTTP  m_hHttp;
    1870     /** The base path to use. */
    1871     RTCString m_strBasePath;
    1872 
    1873     /* Make non-copyable (RTCNonCopyable causes warnings): */
    1874     RTCRestClientApiBase(RTCRestOutputToString const &);
    1875     RTCRestClientApiBase *operator=(RTCRestOutputToString const &);
    1876 
    1877     /**
    1878      * Re-initializes the HTTP instance.
    1879      *
    1880      * @returns IPRT status code.
    1881      */
    1882     virtual int reinitHttpInstance();
    1883 
    1884     /**
    1885      * Implements stuff for making an API call.
    1886      *
    1887      * @returns a_pResponse->getStatus()
    1888      * @param   a_rRequest      Reference to the request object.
    1889      * @param   a_enmHttpMethod The HTTP request method.
    1890      * @param   a_pResponse     Pointer to the response object.
    1891      * @param   a_pszMethod     The method name, for logging purposes.
    1892      */
    1893     virtual int doCall(RTCRestClientRequestBase const &a_rRequest, RTHTTPMETHOD a_enmHttpMethod,
    1894                        RTCRestClientResponseBase *a_pResponse, const char *a_pszMethod);
    1895 
    1896 };
    1897 
    1898443/** @} */
    1899444
  • trunk/src/VBox/Runtime/common/rest/RTCRestArrayBase.cpp

    r74023 r74025  
    3030*********************************************************************************************************************************/
    3131#define LOG_GROUP RTLOGGROUP_REST
    32 #include <iprt/cpp/restbase.h>
     32#include <iprt/cpp/restarray.h>
    3333
    3434#include <iprt/err.h>
  • trunk/src/VBox/Runtime/common/rest/RTCRestClientApiBase.cpp

    r74013 r74025  
    3030*********************************************************************************************************************************/
    3131#define LOG_GROUP RTLOGGROUP_REST
    32 #include <iprt/cpp/restbase.h>
     32#include <iprt/cpp/restclient.h>
    3333
    3434#include <iprt/err.h>
  • trunk/src/VBox/Runtime/common/rest/RTCRestClientRequestBase.cpp

    r74024 r74025  
    3030*********************************************************************************************************************************/
    3131#define LOG_GROUP RTLOGGROUP_REST
    32 #include <iprt/cpp/restbase.h>
     32#include <iprt/cpp/restclient.h>
    3333
    3434#include <iprt/assert.h>
    3535#include <iprt/err.h>
     36#include <iprt/cpp/restarray.h>
     37#include <iprt/cpp/reststringmap.h>
    3638
    3739
  • trunk/src/VBox/Runtime/common/rest/RTCRestClientResponseBase.cpp

    r74023 r74025  
    3030*********************************************************************************************************************************/
    3131#define LOG_GROUP RTLOGGROUP_REST
    32 #include <iprt/cpp/restbase.h>
     32#include <iprt/cpp/restclient.h>
    3333
    3434#include <iprt/ctype.h>
    3535#include <iprt/err.h>
     36#include <iprt/cpp/reststringmap.h>
    3637
    3738
  • trunk/src/VBox/Runtime/common/rest/RTCRestStringMapBase.cpp

    r74023 r74025  
    3030*********************************************************************************************************************************/
    3131#define LOG_GROUP RTLOGGROUP_REST
    32 #include <iprt/cpp/restbase.h>
     32#include <iprt/cpp/reststringmap.h>
    3333
    3434#include <iprt/err.h>
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