diff options
Diffstat (limited to 'include/iprt/cpp/restbase.h')
-rw-r--r-- | include/iprt/cpp/restbase.h | 1106 |
1 files changed, 1106 insertions, 0 deletions
diff --git a/include/iprt/cpp/restbase.h b/include/iprt/cpp/restbase.h new file mode 100644 index 00000000..912610df --- /dev/null +++ b/include/iprt/cpp/restbase.h @@ -0,0 +1,1106 @@ +/** @file + * IPRT - C++ Representational State Transfer (REST) Base Classes. + */ + +/* + * Copyright (C) 2008-2022 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + +#ifndef IPRT_INCLUDED_cpp_restbase_h +#define IPRT_INCLUDED_cpp_restbase_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <iprt/cdefs.h> +#include <iprt/types.h> +#include <iprt/errcore.h> /* VERR_NO_MEMORY */ +#include <iprt/json.h> +#include <iprt/stdarg.h> +#include <iprt/time.h> +#include <iprt/cpp/ministring.h> + + +/** @defgroup grp_rt_cpp_restbase C++ Representational State Transfer (REST) Base Classes. + * @ingroup grp_rt_cpp + * @{ + */ + +/* forward decl: */ +class RTCRestOutputBase; +class RTCRestJsonPrimaryCursor; + +/** + * JSON cursor structure. + * + * This reduces the number of parameters passed around when deserializing JSON + * input and also helps constructing full object name for logging and error reporting. + */ +struct RT_DECL_CLASS RTCRestJsonCursor +{ + /** Handle to the value being parsed. */ + RTJSONVAL m_hValue; + /** Name of the value. */ + const char *m_pszName; + /** Pointer to the parent, NULL if primary. */ + struct RTCRestJsonCursor const *m_pParent; + /** Pointer to the primary cursor structure. */ + RTCRestJsonPrimaryCursor *m_pPrimary; + + RTCRestJsonCursor(struct RTCRestJsonCursor const &a_rParent) RT_NOEXCEPT + : m_hValue(NIL_RTJSONVAL), m_pszName(NULL), m_pParent(&a_rParent), m_pPrimary(a_rParent.m_pPrimary) + { } + + RTCRestJsonCursor(RTJSONVAL hValue, const char *pszName, struct RTCRestJsonCursor *pParent) RT_NOEXCEPT + : m_hValue(hValue), m_pszName(pszName), m_pParent(pParent), m_pPrimary(pParent->m_pPrimary) + { } + + RTCRestJsonCursor(RTJSONVAL hValue, const char *pszName) RT_NOEXCEPT + : m_hValue(hValue), m_pszName(pszName), m_pParent(NULL), m_pPrimary(NULL) + { } + + ~RTCRestJsonCursor() + { + if (m_hValue != NIL_RTJSONVAL) + { + RTJsonValueRelease(m_hValue); + m_hValue = NIL_RTJSONVAL; + } + } +}; + + +/** + * The primary JSON cursor class. + */ +class RT_DECL_CLASS RTCRestJsonPrimaryCursor +{ +public: + /** The cursor for the first level. */ + RTCRestJsonCursor m_Cursor; + /** Error info keeper. */ + PRTERRINFO m_pErrInfo; + + /** Creates a primary json cursor with optiona error info. */ + RTCRestJsonPrimaryCursor(RTJSONVAL hValue, const char *pszName, PRTERRINFO pErrInfo = NULL) RT_NOEXCEPT + : m_Cursor(hValue, pszName) + , m_pErrInfo(pErrInfo) + { + m_Cursor.m_pPrimary = this; + } + + virtual ~RTCRestJsonPrimaryCursor() + { } + + /** + * Add an error message. + * + * @returns a_rc + * @param a_rCursor The cursor reporting the error. + * @param a_rc The status code. + * @param a_pszFormat Format string. + * @param ... Format string arguments. + */ + virtual int addError(RTCRestJsonCursor const &a_rCursor, int a_rc, const char *a_pszFormat, ...) RT_NOEXCEPT; + + /** + * Reports that the current field is not known. + * + * @returns Status to propagate. + * @param a_rCursor The cursor for the field. + */ + virtual int unknownField(RTCRestJsonCursor const &a_rCursor) RT_NOEXCEPT; + + /** + * Copies the full path into pszDst. + * + * @returns pszDst + * @param a_rCursor The cursor to start walking at. + * @param a_pszDst Where to put the path. + * @param a_cbDst Size of the destination buffer. + */ + virtual char *getPath(RTCRestJsonCursor const &a_rCursor, char *a_pszDst, size_t a_cbDst) const RT_NOEXCEPT; +}; + + +/** + * Abstract base class for REST primitive types and data objects (via + * RTCRestDataObject). + * + * The only information this keeps is the null indicator. + */ +class RT_DECL_CLASS RTCRestObjectBase +{ +public: + RTCRestObjectBase() RT_NOEXCEPT; + RTCRestObjectBase(RTCRestObjectBase const &a_rThat) RT_NOEXCEPT; + virtual ~RTCRestObjectBase(); + + /** Copy assignment operator. */ + RTCRestObjectBase &operator=(RTCRestObjectBase const &a_rThat) RT_NOEXCEPT; + + /** + * Create a copy of this object. + * + * @returns Pointer to copy. + */ + virtual RTCRestObjectBase *baseClone() const RT_NOEXCEPT = 0; + + /** + * Tests if the object is @a null. + * @returns true if null, false if not. + */ + inline bool isNull(void) const RT_NOEXCEPT { return m_fNullIndicator; }; + + /** + * Sets the object to @a null and fills it with defaults. + * @returns IPRT status code (from resetToDefault). + */ + virtual int setNull(void) RT_NOEXCEPT; + + /** + * Sets the object to not-null state (i.e. undoes setNull()). + * @remarks Only really important for strings. + */ + virtual void setNotNull(void) RT_NOEXCEPT; + + /** + * Resets the object to all default values. + * @returns IPRT status code. + */ + virtual int resetToDefault() RT_NOEXCEPT = 0; + + /** + * Serialize the object as JSON. + * + * @returns a_rDst + * @param a_rDst The destination for the serialization. + */ + virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_NOEXCEPT = 0; + + /** + * Deserialize object from the given JSON iterator. + * + * @returns IPRT status code. + * @param a_rCursor The JSON cursor. + */ + virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_NOEXCEPT = 0; + + /** + * Polymorphic JSON deserialization helper that instantiate the matching class using + * the discriminator field. + * + * @returns IPRT status code. + * @param a_rCursor The JSON cursor. + * @param a_ppInstance Where to return the deserialized instance. + * May return an object on failure. + */ + typedef DECLCALLBACKTYPE(int, FNDESERIALIZEINSTANCEFROMJSON,(RTCRestJsonCursor const &a_rCursor, RTCRestObjectBase **a_ppInstance)); + /** Pointer to a FNDESERIALIZEINSTANCEFROMJSON function. */ + typedef FNDESERIALIZEINSTANCEFROMJSON *PFNDESERIALIZEINSTANCEFROMJSON; + + /** + * Flags for toString(). + * + * The kCollectionFormat_xxx bunch controls multiple values in arrays + * are formatted. They are ignored by everyone else. + * + * @note When adding collection format types, make sure to also + * update RTCRestArrayBase::toString(). + * @note Bit 24 is reserved (for kHdrField_MapCollection). + */ + enum + { + kCollectionFormat_Unspecified = 0, /**< Not specified. */ + kCollectionFormat_csv, /**< Comma-separated list. */ + kCollectionFormat_ssv, /**< Space-separated list. */ + kCollectionFormat_tsv, /**< Tab-separated list. */ + kCollectionFormat_pipes, /**< Pipe-separated list. */ + kCollectionFormat_multi, /**< Special collection type that must be handled by caller of toString. */ + kCollectionFormat_Mask = 7, /**< Collection type mask. */ + + kToString_Append = 8 /**< Append to the string/object (rather than assigning). */ + }; + + /** + * String conversion. + * + * The default implementation of is a wrapper around serializeAsJson(). + * + * @returns IPRT status code. + * @param a_pDst Pointer to the destionation string. + * @param a_fFlags kCollectionFormat_xxx. + */ + virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_NOEXCEPT; + + /** + * String convertsion, naive variant. + * + * @returns String represenation. + */ + RTCString toString() const; + + /** + * Convert from (header) string value. + * + * The default implementation of is a wrapper around deserializeFromJson(). + * + * @returns IPRT status code. + * @param a_rValue The string value string to parse. + * @param a_pszName Field name or similar. + * @param a_pErrInfo Where to return additional error info. Optional. + * @param a_fFlags kCollectionFormat_xxx. + */ + virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL, + uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_NOEXCEPT; + + /** Type classification */ + typedef enum kTypeClass + { + kTypeClass_Invalid = 0, + kTypeClass_Bool, /**< Primitive: bool. */ + kTypeClass_Int64, /**< Primitive: int64_t. */ + kTypeClass_Int32, /**< Primitive: int32_t. */ + kTypeClass_Int16, /**< Primitive: int16_t. */ + kTypeClass_Double, /**< Primitive: double. */ + kTypeClass_String, /**< Primitive: string. */ + kTypeClass_Date, /**< Date. */ + kTypeClass_Uuid, /**< UUID. */ + kTypeClass_Binary, /**< Binary blob. */ + kTypeClass_DataObject, /**< Data object child (RTCRestDataObject). */ + kTypeClass_AnyObject, /**< Any kind of object (RTCRestAnyObject). */ + kTypeClass_Array, /**< Array (containing any kind of object). */ + kTypeClass_StringMap, /**< String map (containing any kind of object). */ + kTypeClass_StringEnum /**< String enum. */ + } kTypeClass; + + /** + * Returns the object type class. + */ + virtual kTypeClass typeClass(void) const RT_NOEXCEPT = 0; + + /** + * Returns the object type name. + */ + virtual const char *typeName(void) const RT_NOEXCEPT = 0; + +protected: + /** Null indicator. + * @remarks The null values could be mapped onto C/C++ NULL pointer values, + * with the consequence that all data members in objects and such would + * have had to been allocated individually, even simple @a bool members. + * Given that we're overly paranoid about heap allocations (std::bad_alloc), + * it's more fitting to use a null indicator for us. + */ + bool m_fNullIndicator; +}; + + +/** + * Class wrapping 'bool'. + */ +class RT_DECL_CLASS RTCRestBool : public RTCRestObjectBase +{ +public: + /** Default constructor. */ + RTCRestBool() RT_NOEXCEPT; + /** Copy constructor. */ + RTCRestBool(RTCRestBool const &a_rThat) RT_NOEXCEPT; + /** From value constructor. */ + RTCRestBool(bool fValue) RT_NOEXCEPT; + /** Destructor. */ + virtual ~RTCRestBool(); + /** Copy assignment operator. */ + RTCRestBool &operator=(RTCRestBool const &a_rThat) RT_NOEXCEPT; + /** Safe copy assignment method. */ + int assignCopy(RTCRestBool const &a_rThat) RT_NOEXCEPT; + /** Assign value and clear null indicator. */ + void assignValue(bool a_fValue) RT_NOEXCEPT; + /** Make a clone of this object. */ + inline RTCRestBool *clone() const RT_NOEXCEPT { return (RTCRestBool *)baseClone(); } + + /* Overridden methods: */ + virtual RTCRestObjectBase *baseClone() const RT_NOEXCEPT RT_OVERRIDE; + virtual int resetToDefault() RT_NOEXCEPT RT_OVERRIDE; + virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_NOEXCEPT RT_OVERRIDE; + virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_NOEXCEPT RT_OVERRIDE; + virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_NOEXCEPT RT_OVERRIDE; + virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL, + uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_NOEXCEPT RT_OVERRIDE; + virtual kTypeClass typeClass(void) const RT_NOEXCEPT RT_OVERRIDE; + virtual const char *typeName(void) const RT_NOEXCEPT RT_OVERRIDE; + + /** Factory method. */ + static DECLCALLBACK(RTCRestObjectBase *) createInstance(void) RT_NOEXCEPT; + /** @copydoc RTCRestObjectBase::FNDESERIALIZEINSTANCEFROMJSON */ + static DECLCALLBACK(int) deserializeInstanceFromJson(RTCRestJsonCursor const &a_rCursor, RTCRestObjectBase **a_ppInstance) RT_NOEXCEPT; + +public: + /** The value. */ + bool m_fValue; +}; + + +/** + * Class wrapping 'int64_t'. + */ +class RT_DECL_CLASS RTCRestInt64 : public RTCRestObjectBase +{ +public: + /** Default constructor. */ + RTCRestInt64() RT_NOEXCEPT; + /** Copy constructor. */ + RTCRestInt64(RTCRestInt64 const &a_rThat) RT_NOEXCEPT; + /** From value constructor. */ + RTCRestInt64(int64_t a_iValue) RT_NOEXCEPT; + /** Destructor. */ + virtual ~RTCRestInt64(); + /** Copy assignment operator. */ + RTCRestInt64 &operator=(RTCRestInt64 const &a_rThat) RT_NOEXCEPT; + /** Safe copy assignment method. */ + int assignCopy(RTCRestInt64 const &a_rThat) RT_NOEXCEPT; + /** Assign value and clear null indicator. */ + void assignValue(int64_t a_iValue) RT_NOEXCEPT; + /** Make a clone of this object. */ + inline RTCRestInt64 *clone() const RT_NOEXCEPT { return (RTCRestInt64 *)baseClone(); } + + /* Overridden methods: */ + virtual RTCRestObjectBase *baseClone() const RT_NOEXCEPT RT_OVERRIDE; + virtual int resetToDefault() RT_NOEXCEPT RT_OVERRIDE; + virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_NOEXCEPT RT_OVERRIDE; + virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_NOEXCEPT RT_OVERRIDE; + virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_NOEXCEPT RT_OVERRIDE; + virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL, + uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_NOEXCEPT RT_OVERRIDE; + virtual kTypeClass typeClass(void) const RT_NOEXCEPT RT_OVERRIDE; + virtual const char *typeName(void) const RT_NOEXCEPT RT_OVERRIDE; + + /** Factory method. */ + static DECLCALLBACK(RTCRestObjectBase *) createInstance(void) RT_NOEXCEPT; + /** @copydoc RTCRestObjectBase::FNDESERIALIZEINSTANCEFROMJSON */ + static DECLCALLBACK(int) deserializeInstanceFromJson(RTCRestJsonCursor const &a_rCursor, RTCRestObjectBase **a_ppInstance) RT_NOEXCEPT; + +public: + /** The value. */ + int64_t m_iValue; +}; + + +/** + * Class wrapping 'int32_t'. + */ +class RT_DECL_CLASS RTCRestInt32 : public RTCRestObjectBase +{ +public: + /** Default constructor. */ + RTCRestInt32() RT_NOEXCEPT; + /** Copy constructor. */ + RTCRestInt32(RTCRestInt32 const &a_rThat) RT_NOEXCEPT; + /** From value constructor. */ + RTCRestInt32(int32_t iValue) RT_NOEXCEPT; + /** Destructor. */ + virtual ~RTCRestInt32() RT_NOEXCEPT; + /** Copy assignment operator. */ + RTCRestInt32 &operator=(RTCRestInt32 const &a_rThat) RT_NOEXCEPT; + /** Safe copy assignment method. */ + int assignCopy(RTCRestInt32 const &a_rThat) RT_NOEXCEPT; + /** Assign value and clear null indicator. */ + void assignValue(int32_t a_iValue) RT_NOEXCEPT; + /** Make a clone of this object. */ + inline RTCRestInt32 *clone() const { return (RTCRestInt32 *)baseClone(); } + + /* Overridden methods: */ + virtual RTCRestObjectBase *baseClone() const RT_NOEXCEPT RT_OVERRIDE; + virtual int resetToDefault() RT_NOEXCEPT RT_OVERRIDE; + virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_NOEXCEPT RT_OVERRIDE; + virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_NOEXCEPT RT_OVERRIDE; + virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_NOEXCEPT RT_OVERRIDE; + virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL, + uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_NOEXCEPT RT_OVERRIDE; + virtual kTypeClass typeClass(void) const RT_NOEXCEPT RT_OVERRIDE; + virtual const char *typeName(void) const RT_NOEXCEPT RT_OVERRIDE; + + /** Factory method. */ + static DECLCALLBACK(RTCRestObjectBase *) createInstance(void) RT_NOEXCEPT; + /** @copydoc RTCRestObjectBase::FNDESERIALIZEINSTANCEFROMJSON */ + static DECLCALLBACK(int) deserializeInstanceFromJson(RTCRestJsonCursor const &a_rCursor, RTCRestObjectBase **a_ppInstance) RT_NOEXCEPT; + +public: + /** The value. */ + int32_t m_iValue; +}; + + +/** + * Class wrapping 'int16_t'. + */ +class RT_DECL_CLASS RTCRestInt16 : public RTCRestObjectBase +{ +public: + /** Default constructor. */ + RTCRestInt16() RT_NOEXCEPT; + /** Copy constructor. */ + RTCRestInt16(RTCRestInt16 const &a_rThat) RT_NOEXCEPT; + /** From value constructor. */ + RTCRestInt16(int16_t iValue) RT_NOEXCEPT; + /** Destructor. */ + virtual ~RTCRestInt16(); + /** Copy assignment operator. */ + RTCRestInt16 &operator=(RTCRestInt16 const &a_rThat) RT_NOEXCEPT; + /** Safe copy assignment method. */ + int assignCopy(RTCRestInt16 const &a_rThat) RT_NOEXCEPT; + /** Assign value and clear null indicator. */ + void assignValue(int16_t a_iValue) RT_NOEXCEPT; + /** Make a clone of this object. */ + inline RTCRestInt16 *clone() const RT_NOEXCEPT { return (RTCRestInt16 *)baseClone(); } + + /* Overridden methods: */ + virtual RTCRestObjectBase *baseClone() const RT_NOEXCEPT RT_OVERRIDE; + virtual int resetToDefault() RT_NOEXCEPT RT_OVERRIDE; + virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_NOEXCEPT RT_OVERRIDE; + virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_NOEXCEPT RT_OVERRIDE; + virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_NOEXCEPT RT_OVERRIDE; + virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL, + uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_NOEXCEPT RT_OVERRIDE; + virtual kTypeClass typeClass(void) const RT_NOEXCEPT RT_OVERRIDE; + virtual const char *typeName(void) const RT_NOEXCEPT RT_OVERRIDE; + + /** Factory method. */ + static DECLCALLBACK(RTCRestObjectBase *) createInstance(void) RT_NOEXCEPT; + /** @copydoc RTCRestObjectBase::FNDESERIALIZEINSTANCEFROMJSON */ + static DECLCALLBACK(int) deserializeInstanceFromJson(RTCRestJsonCursor const &a_rCursor, RTCRestObjectBase **a_ppInstance) RT_NOEXCEPT; + +public: + /** The value. */ + int16_t m_iValue; +}; + + +/** + * Class wrapping 'double'. + */ +class RT_DECL_CLASS RTCRestDouble : public RTCRestObjectBase +{ +public: + /** Default constructor. */ + RTCRestDouble() RT_NOEXCEPT; + /** Copy constructor. */ + RTCRestDouble(RTCRestDouble const &a_rThat) RT_NOEXCEPT; + /** From value constructor. */ + RTCRestDouble(double rdValue) RT_NOEXCEPT; + /** Destructor. */ + virtual ~RTCRestDouble(); + /** Copy assignment operator. */ + RTCRestDouble &operator=(RTCRestDouble const &a_rThat) RT_NOEXCEPT; + /** Safe copy assignment method. */ + int assignCopy(RTCRestDouble const &a_rThat) RT_NOEXCEPT; + /** Assign value and clear null indicator. */ + void assignValue(double a_rdValue) RT_NOEXCEPT; + /** Make a clone of this object. */ + inline RTCRestDouble *clone() const RT_NOEXCEPT { return (RTCRestDouble *)baseClone(); } + + /* Overridden methods: */ + virtual RTCRestObjectBase *baseClone() const RT_NOEXCEPT RT_OVERRIDE; + virtual int resetToDefault() RT_NOEXCEPT RT_OVERRIDE; + virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_NOEXCEPT RT_OVERRIDE; + virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_NOEXCEPT RT_OVERRIDE; + virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_NOEXCEPT RT_OVERRIDE; + virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL, + uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_NOEXCEPT RT_OVERRIDE; + virtual kTypeClass typeClass(void) const RT_NOEXCEPT RT_OVERRIDE; + virtual const char *typeName(void) const RT_NOEXCEPT RT_OVERRIDE; + + /** Factory method. */ + static DECLCALLBACK(RTCRestObjectBase *) createInstance(void) RT_NOEXCEPT; + /** @copydoc RTCRestObjectBase::FNDESERIALIZEINSTANCEFROMJSON */ + static DECLCALLBACK(int) deserializeInstanceFromJson(RTCRestJsonCursor const &a_rCursor, RTCRestObjectBase **a_ppInstance) RT_NOEXCEPT; + +public: + /** The value. */ + double m_rdValue; +}; + + +/** + * Class wrapping 'RTCString'. + */ +class RT_DECL_CLASS RTCRestString : public RTCRestObjectBase, public RTCString +{ +public: + /** Default constructor. */ + RTCRestString() RT_NOEXCEPT; + /** Destructor. */ + virtual ~RTCRestString(); + + /** Copy constructor. */ + RTCRestString(RTCRestString const &a_rThat); + /** From value constructor. */ + RTCRestString(RTCString const &a_rThat); + /** From value constructor. */ + RTCRestString(const char *a_pszSrc); + /** Safe copy assignment method. */ + int assignCopy(RTCRestString const &a_rThat) RT_NOEXCEPT; + /** Safe copy assignment method. */ + int assignCopy(RTCString const &a_rThat) RT_NOEXCEPT; + /** Safe copy assignment method. */ + int assignCopy(const char *a_pszThat) RT_NOEXCEPT; + /** Make a clone of this object. */ + inline RTCRestString *clone() const RT_NOEXCEPT { return (RTCRestString *)baseClone(); } + + /* Overridden methods: */ + virtual RTCRestObjectBase *baseClone() const RT_NOEXCEPT RT_OVERRIDE; + virtual int setNull(void) RT_NOEXCEPT RT_OVERRIDE; /* (ambigious, so overrider it to make sure.) */ + virtual int resetToDefault() RT_NOEXCEPT RT_OVERRIDE; + virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_NOEXCEPT RT_OVERRIDE; + virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_NOEXCEPT RT_OVERRIDE; + virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_NOEXCEPT RT_OVERRIDE; + virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL, + uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_NOEXCEPT RT_OVERRIDE; + virtual kTypeClass typeClass(void) const RT_NOEXCEPT RT_OVERRIDE; + virtual const char *typeName(void) const RT_NOEXCEPT RT_OVERRIDE; + + /** Factory method. */ + static DECLCALLBACK(RTCRestObjectBase *) createInstance(void) RT_NOEXCEPT; + /** @copydoc RTCRestObjectBase::FNDESERIALIZEINSTANCEFROMJSON */ + static DECLCALLBACK(int) deserializeInstanceFromJson(RTCRestJsonCursor const &a_rCursor, RTCRestObjectBase **a_ppInstance) RT_NOEXCEPT; + + /** @name RTCString assignment methods we need to replace to manage the null indicator + * @{ */ + int assignNoThrow(const RTCString &a_rSrc) RT_NOEXCEPT; + int assignNoThrow(const char *a_pszSrc) RT_NOEXCEPT; + int assignNoThrow(const RTCString &a_rSrc, size_t a_offSrc, size_t a_cchSrc = npos) RT_NOEXCEPT; + int assignNoThrow(const char *a_pszSrc, size_t a_cchSrc) RT_NOEXCEPT; + int assignNoThrow(size_t a_cTimes, char a_ch) RT_NOEXCEPT; + int printfNoThrow(const char *pszFormat, ...) RT_NOEXCEPT RT_IPRT_FORMAT_ATTR(1, 2); + int printfVNoThrow(const char *pszFormat, va_list va) RT_NOEXCEPT RT_IPRT_FORMAT_ATTR(1, 0); + RTCRestString &operator=(const char *a_pcsz); + RTCRestString &operator=(const RTCString &a_rThat); + RTCRestString &operator=(const RTCRestString &a_rThat); + RTCRestString &assign(const RTCString &a_rSrc); + RTCRestString &assign(const char *a_pszSrc); + RTCRestString &assign(const RTCString &a_rSrc, size_t a_offSrc, size_t a_cchSrc = npos); + RTCRestString &assign(const char *a_pszSrc, size_t a_cchSrc); + RTCRestString &assign(size_t a_cTimes, char a_ch); + RTCRestString &printf(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2); + RTCRestString &printfV(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(1, 0); + /** @} */ +}; + + +/** + * Date class. + * + * There are numerous ways of formatting a timestamp and the specifications + * we're currently working with doesn't have a way of telling it seems. + * Thus, decoding need to have fail safes built in so the user can give hints. + * The formatting likewise needs to be told which format to use by the user. + * + * Two side-effects of the format stuff is that the default constructor creates + * an object that is null, and resetToDefault will do the same bug leave the + * format as a hint. + */ +class RT_DECL_CLASS RTCRestDate : public RTCRestObjectBase +{ +public: + /** Default constructor. + * @note The result is a null-object. */ + RTCRestDate() RT_NOEXCEPT; + /** Copy constructor. */ + RTCRestDate(RTCRestDate const &a_rThat); + /** Destructor. */ + virtual ~RTCRestDate(); + /** Copy assignment operator. */ + RTCRestDate &operator=(RTCRestDate const &a_rThat); + /** Safe copy assignment method. */ + int assignCopy(RTCRestDate const &a_rThat) RT_NOEXCEPT; + /** Make a clone of this object. */ + inline RTCRestDate *clone() const RT_NOEXCEPT{ return (RTCRestDate *)baseClone(); } + + /* Overridden methods: */ + virtual RTCRestObjectBase *baseClone() const RT_NOEXCEPT RT_OVERRIDE; + virtual int resetToDefault() RT_NOEXCEPT RT_OVERRIDE; + virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_NOEXCEPT RT_OVERRIDE; + virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_NOEXCEPT RT_OVERRIDE; + virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_NOEXCEPT RT_OVERRIDE; + virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL, + uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_NOEXCEPT RT_OVERRIDE; + virtual kTypeClass typeClass(void) const RT_NOEXCEPT RT_OVERRIDE; + virtual const char *typeName(void) const RT_NOEXCEPT RT_OVERRIDE; + + /** Factory method. */ + static DECLCALLBACK(RTCRestObjectBase *) createInstance(void) RT_NOEXCEPT; + /** @copydoc RTCRestObjectBase::FNDESERIALIZEINSTANCEFROMJSON */ + static DECLCALLBACK(int) deserializeInstanceFromJson(RTCRestJsonCursor const &a_rCursor, RTCRestObjectBase **a_ppInstance) RT_NOEXCEPT; + + /** Date formats. */ + typedef enum + { + kFormat_Invalid = 0, + kFormat_Rfc2822, /**< Format it according to RFC-2822. */ + kFormat_Rfc7131, /**< Format it according to RFC-7131 (HTTP). */ + kFormat_Rfc3339, /**< Format it according to RFC-3339 (ISO-8601) (no fraction). */ + kFormat_Rfc3339_Fraction_2, /**< Format it according to RFC-3339 (ISO-8601) with two digit fraction (hundreths). */ + kFormat_Rfc3339_Fraction_3, /**< Format it according to RFC-3339 (ISO-8601) with three digit fraction (milliseconds). */ + kFormat_Rfc3339_Fraction_6, /**< Format it according to RFC-3339 (ISO-8601) with six digit fraction (microseconds). */ + kFormat_Rfc3339_Fraction_9, /**< Format it according to RFC-3339 (ISO-8601) with nine digit fraction (nanoseconds). */ + kFormat_End + } kFormat; + + /** + * Assigns the value, formats it as a string and clears the null indicator. + * + * @returns VINF_SUCCESS, VERR_NO_STR_MEMORY or VERR_INVALID_PARAMETER. + * @param a_pTimeSpec The time spec to set. + * @param a_enmFormat The date format to use when formatting it. + */ + int assignValue(PCRTTIMESPEC a_pTimeSpec, kFormat a_enmFormat) RT_NOEXCEPT; + int assignValueRfc2822(PCRTTIMESPEC a_pTimeSpec) RT_NOEXCEPT; /**< Convenience method for email/whatnot. */ + int assignValueRfc7131(PCRTTIMESPEC a_pTimeSpec) RT_NOEXCEPT; /**< Convenience method for HTTP date. */ + int assignValueRfc3339(PCRTTIMESPEC a_pTimeSpec) RT_NOEXCEPT; /**< Convenience method for ISO-8601 timstamp. */ + + /** + * Assigns the current UTC time and clears the null indicator . + * + * @returns VINF_SUCCESS, VERR_NO_STR_MEMORY or VERR_INVALID_PARAMETER. + * @returns VINF_SUCCESS or VERR_NO_STR_MEMORY. + * @param a_enmFormat The date format to use when formatting it. + */ + int assignNow(kFormat a_enmFormat) RT_NOEXCEPT; + int assignNowRfc2822() RT_NOEXCEPT; /**< Convenience method for email/whatnot. */ + int assignNowRfc7131() RT_NOEXCEPT; /**< Convenience method for HTTP date. */ + int assignNowRfc3339() RT_NOEXCEPT; /**< Convenience method for ISO-8601 timstamp. */ + + /** + * Sets the format to help deal with decoding issues. + * + * This can also be used to change the date format for an okay timespec. + * @returns IPRT status code. + * @param a_enmFormat The date format to try/set. + */ + int setFormat(kFormat a_enmFormat) RT_NOEXCEPT; + + /** Check if the value is okay (m_TimeSpec & m_Exploded). */ + inline bool isOkay() const RT_NOEXCEPT { return m_fTimeSpecOkay; } + /** Get the timespec value. */ + inline RTTIMESPEC const &getTimeSpec() const RT_NOEXCEPT { return m_TimeSpec; } + /** Get the exploded time. */ + inline RTTIME const &getExploded() const RT_NOEXCEPT { return m_Exploded; } + /** Gets the format. */ + inline kFormat getFormat() const RT_NOEXCEPT { return m_enmFormat; } + /** Get the formatted/raw string value. */ + inline RTCString const &getString() const RT_NOEXCEPT { return m_strFormatted; } + + /** Get nanoseconds since unix epoch. */ + inline int64_t getEpochNano() const RT_NOEXCEPT { return RTTimeSpecGetNano(&m_TimeSpec); } + /** Get seconds since unix epoch. */ + inline int64_t getEpochSeconds() const RT_NOEXCEPT { return RTTimeSpecGetSeconds(&m_TimeSpec); } + /** Checks if UTC time. */ + inline bool isUtc() const RT_NOEXCEPT { return (m_Exploded.fFlags & RTTIME_FLAGS_TYPE_MASK) != RTTIME_FLAGS_TYPE_LOCAL; } + /** Checks if local time. */ + inline bool isLocal() const RT_NOEXCEPT { return (m_Exploded.fFlags & RTTIME_FLAGS_TYPE_MASK) == RTTIME_FLAGS_TYPE_LOCAL; } + +protected: + /** The value. */ + RTTIMESPEC m_TimeSpec; + /** The exploded time value. */ + RTTIME m_Exploded; + /** Set if m_TimeSpec is okay, consult m_strFormatted if not. */ + bool m_fTimeSpecOkay; + /** The format / format hint. */ + kFormat m_enmFormat; + /** The formatted date string. + * This will be the raw input string for a deserialized value, where as for + * a value set by the user it will be the formatted value. */ + RTCString m_strFormatted; + + /** + * Explodes and formats the m_TimeSpec value. + * + * Sets m_Exploded, m_strFormatted, m_fTimeSpecOkay, and m_enmFormat, clears m_fNullIndicator. + * + * @returns VINF_SUCCESS or VERR_NO_STR_MEMORY. + * @param a_enmFormat The format to use. + */ + int explodeAndFormat(kFormat a_enmFormat) RT_NOEXCEPT; + + /** + * Formats the m_Exploded value. + * + * Sets m_strFormatted, m_fTimeSpecOkay, and m_enmFormat, clears m_fNullIndicator. + * + * @returns VINF_SUCCESS or VERR_NO_STR_MEMORY. + * @param a_enmFormat The format to use. + */ + int format(kFormat a_enmFormat) RT_NOEXCEPT; + + /** + * Internal worker that attempts to decode m_strFormatted. + * + * Sets m_fTimeSpecOkay. + * + * @returns IPRT status code. + * @param enmFormat Specific format to try, kFormat_Invalid (default) to try guess it. + */ + int decodeFormattedString(kFormat enmFormat = kFormat_Invalid) RT_NOEXCEPT; +}; + + +/** We should provide a proper UUID class eventually. Currently it is not used. */ +typedef RTCRestString RTCRestUuid; + + +/** + * String enum base class. + */ +class RT_DECL_CLASS RTCRestStringEnumBase : public RTCRestObjectBase +{ +public: + /** Enum map entry. */ + typedef struct ENUMMAPENTRY + { + const char *pszName; + uint32_t cchName; + int32_t iValue; + } ENUMMAPENTRY; + + /** Default constructor. */ + RTCRestStringEnumBase() RT_NOEXCEPT; + /** Destructor. */ + virtual ~RTCRestStringEnumBase(); + + /** Copy constructor. */ + RTCRestStringEnumBase(RTCRestStringEnumBase const &a_rThat); + /** Copy assignment operator. */ + RTCRestStringEnumBase &operator=(RTCRestStringEnumBase const &a_rThat); + + /** Safe copy assignment method. */ + int assignCopy(RTCRestStringEnumBase const &a_rThat) RT_NOEXCEPT; + /** Safe copy assignment method. */ + inline int assignCopy(RTCString const &a_rThat) RT_NOEXCEPT { return setByString(a_rThat); } + /** Safe copy assignment method. */ + inline int assignCopy(const char *a_pszThat) RT_NOEXCEPT { return setByString(a_pszThat); } + + /* Overridden methods: */ + virtual int resetToDefault() RT_NOEXCEPT RT_OVERRIDE; + virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_NOEXCEPT RT_OVERRIDE; + virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_NOEXCEPT RT_OVERRIDE; + virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_NOEXCEPT RT_OVERRIDE; + virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL, + uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_NOEXCEPT RT_OVERRIDE; + virtual kTypeClass typeClass(void) const RT_NOEXCEPT RT_OVERRIDE; + + /** + * Sets the value given a C-string value. + * + * @retval VINF_SUCCESS on success. + * @retval VWRN_NOT_FOUND if not mappable to enum value. + * @retval VERR_NO_STR_MEMORY if not mappable and we're out of memory. + * @param a_pszValue The string value. + * @param a_cchValue The string value length. Optional. + */ + int setByString(const char *a_pszValue, size_t a_cchValue = RTSTR_MAX) RT_NOEXCEPT; + + /** + * Sets the value given a string value. + * + * @retval VINF_SUCCESS on success. + * @retval VWRN_NOT_FOUND if not mappable to enum value. + * @retval VERR_NO_STR_MEMORY if not mappable and we're out of memory. + * @param a_rValue The string value. + */ + int setByString(RTCString const &a_rValue) RT_NOEXCEPT; + + /** + * Gets the string value. + */ + const char *getString() const RT_NOEXCEPT; + + /** Maps the given string value to an enum. */ + int stringToEnum(const char *a_pszValue, size_t a_cchValue = RTSTR_MAX) RT_NOEXCEPT; + /** Maps the given string value to an enum. */ + int stringToEnum(RTCString const &a_rStrValue) RT_NOEXCEPT; + /** Maps the given string value to an enum. */ + const char *enumToString(int a_iEnumValue, size_t *a_pcchString) RT_NOEXCEPT; + + +protected: + /** The enum value. */ + int m_iEnumValue; + /** The string value if not a match. */ + RTCString m_strValue; + + /** + * Worker for setting the object to the given enum value. + * + * @retval true on success. + * @retval false if a_iEnumValue can't be translated. + * @param a_iEnumValue The enum value to set. + */ + bool setWorker(int a_iEnumValue) RT_NOEXCEPT; + + /** Helper for implementing RTCRestObjectBase::clone(). */ + RTCRestObjectBase *cloneWorker(RTCRestStringEnumBase *a_pDst) const RT_NOEXCEPT; + + /** + * Gets the mapping table. + * + * @returns Pointer to the translation table. + * @param pcEntries Where to return the translation table size. + */ + virtual ENUMMAPENTRY const *getMappingTable(size_t *pcEntries) const RT_NOEXCEPT = 0; +}; + + +/** + * String enum template class. + * + * Takes the enum type as argument. + */ +template <typename EnumType> +class RTCRestStringEnum : public RTCRestStringEnumBase +{ +public: + typedef EnumType Type; /**< The enum type. */ + + /** Default constructor */ + RTCRestStringEnum() RT_NOEXCEPT : RTCRestStringEnumBase() { } + /** Constructor with initial enum value. */ + RTCRestStringEnum(Type a_enmValue) RT_NOEXCEPT : RTCRestStringEnumBase() { set(a_enmValue); } + /** Constructor with string default. */ + RTCRestStringEnum(const char *a_pszDefault) : RTCRestStringEnumBase() { setByString(a_pszDefault); } + /** Copy constructor */ + RTCRestStringEnum(RTCRestStringEnum const &a_rThat) : RTCRestStringEnumBase(a_rThat) { } + /** Make a clone of this object. */ + inline RTCRestStringEnum *clone() const RT_NOEXCEPT { return (RTCRestStringEnum *)baseClone(); } + + virtual RTCRestObjectBase *baseClone() const RT_NOEXCEPT RT_OVERRIDE + { + return cloneWorker(new (std::nothrow) RTCRestStringEnum()); + } + + /** Copy assignment operator. */ + RTCRestStringEnum &operator=(RTCRestStringEnum const &a_rThat) RT_NOEXCEPT + { + RTCRestStringEnumBase::operator=(a_rThat); + return *this; + } + + /** + * Gets the enum value. + * @returns enum value. + * @retval kXxxxInvalid means there was no mapping for the string, or that + * no value has been assigned yet. + */ + Type get() const RT_NOEXCEPT { return (Type)m_iEnumValue; } + + /** + * Sets the object value to @a a_enmType + * + * @returns true if a_enmType is valid, false if not. + * @param a_enmType The new value. + */ + bool set(Type a_enmType) RT_NOEXCEPT { return setWorker((int)a_enmType); } + + virtual const char *typeName(void) const RT_NOEXCEPT RT_OVERRIDE { return "RTCRestStringEnum<EnumType>"; } + + /** Factory method. */ + static DECLCALLBACK(RTCRestObjectBase *) createInstance(void) RT_NOEXCEPT + { + return new (std::nothrow) RTCRestStringEnum(); + } + + /** @copydoc RTCRestObjectBase::FNDESERIALIZEINSTANCEFROMJSON */ + static DECLCALLBACK(int) deserializeInstanceFromJson(RTCRestJsonCursor const &a_rCursor, RTCRestObjectBase **a_ppInstance) RT_NOEXCEPT + { + *a_ppInstance = new (std::nothrow) RTCRestStringEnum(); + if (*a_ppInstance) + return (*a_ppInstance)->deserializeFromJson(a_rCursor); + return a_rCursor.m_pPrimary->addError(a_rCursor, VERR_NO_MEMORY, "Out of memory"); + } + +protected: + /** Enum mapping table. */ + static const ENUMMAPENTRY s_aMappingTable[]; + /** Enum mapping table size. */ + static const size_t s_cMappingTable; + + virtual ENUMMAPENTRY const *getMappingTable(size_t *pcEntries) const RT_NOEXCEPT RT_OVERRIDE + { + *pcEntries = s_cMappingTable; + return s_aMappingTable; + } +}; + + +/** + * Class for handling binary blobs (strings). + * + * There are specializations of this class for body parameters and responses, + * see RTCRestBinaryParameter and RTCRestBinaryResponse. + */ +class RT_DECL_CLASS RTCRestBinary : public RTCRestObjectBase +{ +public: + /** Default constructor. */ + RTCRestBinary() RT_NOEXCEPT; + /** Destructor. */ + virtual ~RTCRestBinary(); + + /** Safe copy assignment method. */ + virtual int assignCopy(RTCRestBinary const &a_rThat) RT_NOEXCEPT; + /** Safe buffer copy method. */ + virtual int assignCopy(void const *a_pvData, size_t a_cbData) RT_NOEXCEPT; + + /** Use the specified data buffer directly. */ + virtual int assignReadOnly(void const *a_pvData, size_t a_cbData) RT_NOEXCEPT; + /** Use the specified data buffer directly. */ + virtual int assignWriteable(void *a_pvBuf, size_t a_cbBuf) RT_NOEXCEPT; + /** Frees the data held by the object and resets it default state. */ + virtual void freeData() RT_NOEXCEPT; + + /** Returns a pointer to the data blob. */ + inline const uint8_t *getPtr() const RT_NOEXCEPT { return m_pbData; } + /** Gets the size of the data. */ + inline size_t getSize() const RT_NOEXCEPT { return m_cbData; } + + /** Make a clone of this object. */ + inline RTCRestBinary *clone() const RT_NOEXCEPT { return (RTCRestBinary *)baseClone(); } + + /* Overridden methods: */ + virtual RTCRestObjectBase *baseClone() const RT_NOEXCEPT RT_OVERRIDE; + virtual int setNull(void) RT_NOEXCEPT RT_OVERRIDE; + virtual int resetToDefault(void) RT_NOEXCEPT RT_OVERRIDE; + virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_NOEXCEPT RT_OVERRIDE; + virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_NOEXCEPT RT_OVERRIDE; + virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_NOEXCEPT RT_OVERRIDE; + virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL, + uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_NOEXCEPT RT_OVERRIDE; + virtual kTypeClass typeClass(void) const RT_NOEXCEPT RT_OVERRIDE; + virtual const char *typeName(void) const RT_NOEXCEPT RT_OVERRIDE; + + /** Factory method. */ + static DECLCALLBACK(RTCRestObjectBase *) createInstance(void) RT_NOEXCEPT; + /** @copydoc RTCRestObjectBase::FNDESERIALIZEINSTANCEFROMJSON */ + static DECLCALLBACK(int) deserializeInstanceFromJson(RTCRestJsonCursor const &a_rCursor, RTCRestObjectBase **a_ppInstance) RT_NOEXCEPT; + +protected: + /** Pointer to data blob. */ + uint8_t *m_pbData; + /** Amount of valid data in the blob. */ + size_t m_cbData; + /** Number of bytes allocated for the m_pbData buffer. */ + size_t m_cbAllocated; + /** Set if the data is freeable, only ever clear if user data. */ + bool m_fFreeable; + /** Set if the data blob is readonly user provided data. */ + bool m_fReadOnly; + +private: + /* No copy constructor or copy assignment: */ + RTCRestBinary(RTCRestBinary const &a_rThat); + RTCRestBinary &operator=(RTCRestBinary const &a_rThat); +}; + + +/** + * Abstract base class for REST data model classes. + */ +class RT_DECL_CLASS RTCRestDataObject : public RTCRestObjectBase +{ +public: + RTCRestDataObject() RT_NOEXCEPT; + RTCRestDataObject(RTCRestDataObject const &a_rThat) RT_NOEXCEPT; + virtual ~RTCRestDataObject(); + + /* Overridden methods:*/ + virtual int resetToDefault() RT_NOEXCEPT RT_OVERRIDE; + virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_NOEXCEPT RT_OVERRIDE; + virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_NOEXCEPT RT_OVERRIDE; + virtual kTypeClass typeClass(void) const RT_NOEXCEPT RT_OVERRIDE; + + /** + * Serialize the object members as JSON. + * + * @returns a_rDst + * @param a_rDst The destination for the serialization. + */ + virtual RTCRestOutputBase &serializeMembersAsJson(RTCRestOutputBase &a_rDst) const RT_NOEXCEPT; + + /** + * Deserialize object from the given JSON iterator. + * + * @returns IPRT status code. + * @retval VERR_NOT_FOUND if field is unknown. Top level caller will do + * invoke unknownField() on it. + * + * @param a_rCursor The JSON cursor with the current member. + * @param a_cchName The length of a_rCursor.m_pszName. + */ + virtual int deserializeMemberFromJson(RTCRestJsonCursor const &a_rCursor, size_t a_cchName) RT_NOEXCEPT; + +protected: + /** The is-set bits for all the fields. */ + uint64_t m_fIsSet; + + /** Copy assignment operator. */ + RTCRestDataObject &operator=(RTCRestDataObject const &a_rThat) RT_NOEXCEPT; + + /** Safe copy assignment method. */ + virtual int assignCopy(RTCRestDataObject const &a_rThat) RT_NOEXCEPT; +}; + + +/** + * Abstract base class for polymorphic REST data model classes. + */ +class RT_DECL_CLASS RTCRestPolyDataObject : public RTCRestDataObject +{ +public: + RTCRestPolyDataObject() RT_NOEXCEPT; + RTCRestPolyDataObject(RTCRestPolyDataObject const &a_rThat) RT_NOEXCEPT; + virtual ~RTCRestPolyDataObject(); + + /* Overridden methods:*/ + virtual int resetToDefault() RT_NOEXCEPT RT_OVERRIDE; + + /** Checks if the instance is of a child class (@c true) or of the parent (@c false). */ + virtual bool isChild() const RT_NOEXCEPT; + +protected: + + /** Copy assignment operator. */ + RTCRestPolyDataObject &operator=(RTCRestPolyDataObject const &a_rThat) RT_NOEXCEPT; +}; + + +/** @} */ + +#endif /* !IPRT_INCLUDED_cpp_restbase_h */ + |