VirtualBox

source: vbox/trunk/include/iprt/cpp/restbase.h@ 74231

Last change on this file since 74231 was 74181, checked in by vboxsync, 6 years ago

IPRT/rest: Wrote unit tests for RTCRestDate. Addressed some issues found. Marked methods implemented in headers with 'inline'. bugref:9167

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 35.5 KB
Line 
1/** @file
2 * IPRT - C++ Representational State Transfer (REST) Base Classes.
3 */
4
5/*
6 * Copyright (C) 2008-2018 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___iprt_cpp_restbase_h
27#define ___iprt_cpp_restbase_h
28
29#include <iprt/cdefs.h>
30#include <iprt/types.h>
31#include <iprt/json.h>
32#include <iprt/stdarg.h>
33#include <iprt/time.h>
34#include <iprt/cpp/ministring.h>
35
36
37/** @defgroup grp_rt_cpp_restbase C++ Representational State Transfer (REST) Base Classes.
38 * @ingroup grp_rt_cpp
39 * @{
40 */
41
42
43
44/**
45 * Abstract base class for serializing data objects.
46 */
47class RT_DECL_CLASS RTCRestOutputBase
48{
49public:
50 RTCRestOutputBase()
51 : m_uIndent(0)
52 { }
53 virtual ~RTCRestOutputBase()
54 { }
55
56 /**
57 * RTStrPrintf like function (see @ref pg_rt_str_format).
58 *
59 * @returns Number of bytes outputted.
60 * @param pszFormat The format string.
61 * @param ... Argument specfied in @a pszFormat.
62 */
63 size_t printf(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(2, 3)
64 {
65 va_list va;
66 va_start(va, pszFormat);
67 size_t cchWritten = this->vprintf(pszFormat, va);
68 va_end(va);
69 return cchWritten;
70 }
71
72 /**
73 * RTStrPrintfV like function (see @ref pg_rt_str_format).
74 *
75 * @returns Number of bytes outputted.
76 * @param pszFormat The format string.
77 * @param va Argument specfied in @a pszFormat.
78 */
79 virtual size_t vprintf(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(2, 0) = 0;
80
81 /**
82 * Sets the indentation level for use when pretty priting things.
83 *
84 * @returns Previous indentation level.
85 * @param uIndent The indentation level.
86 */
87 inline unsigned setIndent(unsigned uIndent)
88 {
89 unsigned const uRet = m_uIndent;
90 m_uIndent = uIndent;
91 return uRet;
92 }
93
94 /**
95 * Increases the indentation level.
96 *
97 * @returns Previous indentation level.
98 */
99 inline unsigned incrementIndent()
100 {
101 unsigned const uRet = m_uIndent;
102 m_uIndent = uRet + 1;
103 return uRet;
104 }
105
106protected:
107 /** The current indentation level. */
108 unsigned m_uIndent;
109};
110
111
112/**
113 * Serialize to a string object.
114 */
115class RT_DECL_CLASS RTCRestOutputToString : public RTCRestOutputBase
116{
117public:
118 /**
119 * Creates an instance that appends to @a a_pDst.
120 * @param a_pDst Pointer to the destination string object.
121 * NULL is not accepted and will assert.
122 * @param a_fAppend Whether to append to the current string value, or
123 * nuke the string content before starting the output.
124 */
125 RTCRestOutputToString(RTCString *a_pDst, bool a_fAppend = false);
126 virtual ~RTCRestOutputToString();
127
128 virtual size_t vprintf(const char *pszFormat, va_list va) RT_OVERRIDE;
129
130 /**
131 * Finalizes the output and releases the string object to the caller.
132 *
133 * @returns The released string object. NULL if we ran out of memory or if
134 * called already.
135 *
136 * @remark This sets m_pDst to NULL and the object cannot be use for any
137 * more output afterwards.
138 */
139 virtual RTCString *finalize();
140
141
142protected:
143 /** Pointer to the destination string. NULL after finalize(). */
144 RTCString *m_pDst;
145 /** Set if we ran out of memory and should ignore subsequent calls. */
146 bool m_fOutOfMemory;
147
148 /** @callback_method_impl{FNRTSTROUTPUT} */
149 static DECLCALLBACK(size_t) strOutput(void *pvArg, const char *pachChars, size_t cbChars);
150
151 /* Make non-copyable (RTCNonCopyable causes warnings): */
152 RTCRestOutputToString(RTCRestOutputToString const &);
153 RTCRestOutputToString *operator=(RTCRestOutputToString const &);
154};
155
156
157/* forward decl: */
158class RTCRestJsonPrimaryCursor;
159
160/**
161 * JSON cursor structure.
162 *
163 * This reduces the number of parameters passed around when deserializing JSON
164 * input and also helps constructing full object name for logging and error reporting.
165 */
166struct RT_DECL_CLASS RTCRestJsonCursor
167{
168 /** Handle to the value being parsed. */
169 RTJSONVAL m_hValue;
170 /** Name of the value. */
171 const char *m_pszName;
172 /** Pointer to the parent, NULL if primary. */
173 struct RTCRestJsonCursor const *m_pParent;
174 /** Pointer to the primary cursor structure. */
175 RTCRestJsonPrimaryCursor *m_pPrimary;
176
177 RTCRestJsonCursor(struct RTCRestJsonCursor const &a_rParent)
178 : m_hValue(NIL_RTJSONVAL), m_pszName(NULL), m_pParent(&a_rParent), m_pPrimary(a_rParent.m_pPrimary)
179 { }
180
181 RTCRestJsonCursor(RTJSONVAL hValue, const char *pszName, struct RTCRestJsonCursor *pParent)
182 : m_hValue(hValue), m_pszName(pszName), m_pParent(pParent), m_pPrimary(pParent->m_pPrimary)
183 { }
184
185 RTCRestJsonCursor(RTJSONVAL hValue, const char *pszName)
186 : m_hValue(hValue), m_pszName(pszName), m_pParent(NULL), m_pPrimary(NULL)
187 { }
188
189 ~RTCRestJsonCursor()
190 {
191 if (m_hValue != NIL_RTJSONVAL)
192 {
193 RTJsonValueRelease(m_hValue);
194 m_hValue = NIL_RTJSONVAL;
195 }
196 }
197};
198
199
200/**
201 * The primary JSON cursor class.
202 */
203class RT_DECL_CLASS RTCRestJsonPrimaryCursor
204{
205public:
206 /** The cursor for the first level. */
207 RTCRestJsonCursor m_Cursor;
208 /** Error info keeper. */
209 PRTERRINFO m_pErrInfo;
210
211 /** Creates a primary json cursor with optiona error info. */
212 RTCRestJsonPrimaryCursor(RTJSONVAL hValue, const char *pszName, PRTERRINFO pErrInfo = NULL)
213 : m_Cursor(hValue, pszName)
214 , m_pErrInfo(pErrInfo)
215 {
216 m_Cursor.m_pPrimary = this;
217 }
218
219 virtual ~RTCRestJsonPrimaryCursor()
220 { }
221
222 /**
223 * Add an error message.
224 *
225 * @returns a_rc
226 * @param a_rCursor The cursor reporting the error.
227 * @param a_rc The status code.
228 * @param a_pszFormat Format string.
229 * @param ... Format string arguments.
230 */
231 virtual int addError(RTCRestJsonCursor const &a_rCursor, int a_rc, const char *a_pszFormat, ...);
232
233 /**
234 * Reports that the current field is not known.
235 *
236 * @returns Status to propagate.
237 * @param a_rCursor The cursor for the field.
238 */
239 virtual int unknownField(RTCRestJsonCursor const &a_rCursor);
240
241 /**
242 * Copies the full path into pszDst.
243 *
244 * @returns pszDst
245 * @param a_rCursor The cursor to start walking at.
246 * @param a_pszDst Where to put the path.
247 * @param a_cbDst Size of the destination buffer.
248 */
249 virtual char *getPath(RTCRestJsonCursor const &a_rCursor, char *a_pszDst, size_t a_cbDst) const;
250};
251
252
253/**
254 * Abstract base class for REST data objects.
255 *
256 * The only information this keeps is the null indicator.
257 */
258class RT_DECL_CLASS RTCRestObjectBase
259{
260public:
261 RTCRestObjectBase();
262 RTCRestObjectBase(RTCRestObjectBase const &a_rThat);
263 virtual ~RTCRestObjectBase();
264
265 /**
266 * Tests if the object is @a null.
267 * @returns true if null, false if not.
268 */
269 inline bool isNull(void) const { return m_fNullIndicator; };
270
271 /**
272 * Sets the object to @a null and fills it with defaults.
273 * @returns IPRT status code (from resetToDefault).
274 */
275 virtual int setNull(void);
276
277 /**
278 * Sets the object to not-null state (i.e. undoes setNull()).
279 * @remarks Only really important for strings.
280 */
281 virtual void setNotNull(void);
282
283 /**
284 * Resets the object to all default values.
285 * @returns IPRT status code.
286 */
287 virtual int resetToDefault() = 0;
288
289 /**
290 * Serialize the object as JSON.
291 *
292 * @returns a_rDst
293 * @param a_rDst The destination for the serialization.
294 */
295 virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const = 0;
296
297 /**
298 * Deserialize object from the given JSON iterator.
299 *
300 * @returns IPRT status code.
301 * @param a_rCursor The JSON cursor.
302 */
303 virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) = 0;
304
305 /**
306 * Flags for toString().
307 *
308 * The kCollectionFormat_xxx bunch controls multiple values in arrays
309 * are formatted. They are ignored by everyone else.
310 *
311 * @note When adding collection format types, make sure to also
312 * update RTCRestArrayBase::toString().
313 * @note Bit 24 is reserved (for kHdrField_MapCollection).
314 */
315 enum
316 {
317 kCollectionFormat_Unspecified = 0, /**< Not specified. */
318 kCollectionFormat_csv, /**< Comma-separated list. */
319 kCollectionFormat_ssv, /**< Space-separated list. */
320 kCollectionFormat_tsv, /**< Tab-separated list. */
321 kCollectionFormat_pipes, /**< Pipe-separated list. */
322 kCollectionFormat_multi, /**< Special collection type that must be handled by caller of toString. */
323 kCollectionFormat_Mask = 7, /**< Collection type mask. */
324
325 kToString_Append = 8 /**< Append to the string (rather than assigning). */
326 };
327
328 /**
329 * String conversion.
330 *
331 * The default implementation of is a wrapper around serializeAsJson().
332 *
333 * @returns IPRT status code.
334 * @param a_pDst Pointer to the destionation string.
335 * @param a_fFlags kCollectionFormat_xxx.
336 */
337 virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const;
338
339 /**
340 * String convertsion, naive variant.
341 *
342 * @returns String represenation.
343 */
344 RTCString toString() const;
345
346 /**
347 * Convert from (header) string value.
348 *
349 * The default implementation of is a wrapper around deserializeFromJson().
350 *
351 * @returns IPRT status code.
352 * @param a_rValue The string value string to parse.
353 * @param a_pszName Field name or similar.
354 * @param a_pErrInfo Where to return additional error info. Optional.
355 * @param a_fFlags kCollectionFormat_xxx.
356 */
357 virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
358 uint32_t a_fFlags = kCollectionFormat_Unspecified);
359
360 /** Type classification */
361 typedef enum kTypeClass
362 {
363 kTypeClass_Invalid = 0,
364 kTypeClass_Bool, /**< Primitive: bool. */
365 kTypeClass_Int64, /**< Primitive: int64_t. */
366 kTypeClass_Int32, /**< Primitive: int32_t. */
367 kTypeClass_Int16, /**< Primitive: int16_t. */
368 kTypeClass_Double, /**< Primitive: double. */
369 kTypeClass_String, /**< Primitive: string. */
370 kTypeClass_Date, /**< Date. */
371 kTypeClass_Uuid, /**< UUID. */
372 kTypeClass_Binary, /**< Binary blob. */
373 kTypeClass_Object, /**< Object (any kind of data model object). */
374 kTypeClass_Array, /**< Array (containing any kind of object). */
375 kTypeClass_StringMap, /**< String map (containing any kind of object). */
376 kTypeClass_StringEnum /**< String enum. */
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
397protected:
398 /** Null indicator.
399 * @remarks The null values could be mapped onto C/C++ NULL pointer values,
400 * with the consequence that all data members in objects and such would
401 * have had to been allocated individually, even simple @a bool members.
402 * Given that we're overly paranoid about heap allocations (std::bad_alloc),
403 * it's more fitting to use a null indicator for us.
404 */
405 bool m_fNullIndicator;
406};
407
408
409/**
410 * Class wrapping 'bool'.
411 */
412class RT_DECL_CLASS RTCRestBool : public RTCRestObjectBase
413{
414public:
415 /** Default constructor. */
416 RTCRestBool();
417 /** Copy constructor. */
418 RTCRestBool(RTCRestBool const &a_rThat);
419 /** From value constructor. */
420 RTCRestBool(bool fValue);
421 /** Destructor. */
422 virtual ~RTCRestBool();
423 /** Copy assignment operator. */
424 RTCRestBool &operator=(RTCRestBool const &a_rThat);
425 /** Safe copy assignment method. */
426 int assignCopy(RTCRestBool const &a_rThat);
427 /** Assign value and clear null indicator. */
428 void assignValue(bool a_fValue);
429
430 /* Overridden methods: */
431 virtual int resetToDefault() RT_OVERRIDE;
432 virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
433 virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
434 virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_OVERRIDE;
435 virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
436 uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
437 virtual kTypeClass typeClass(void) const RT_OVERRIDE;
438 virtual const char *typeName(void) const RT_OVERRIDE;
439
440 /** Factory method. */
441 static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
442
443public:
444 /** The value. */
445 bool m_fValue;
446};
447
448
449/**
450 * Class wrapping 'int64_t'.
451 */
452class RT_DECL_CLASS RTCRestInt64 : public RTCRestObjectBase
453{
454public:
455 /** Default constructor. */
456 RTCRestInt64();
457 /** Copy constructor. */
458 RTCRestInt64(RTCRestInt64 const &a_rThat);
459 /** From value constructor. */
460 RTCRestInt64(int64_t a_iValue);
461 /** Destructor. */
462 virtual ~RTCRestInt64();
463 /** Copy assignment operator. */
464 RTCRestInt64 &operator=(RTCRestInt64 const &a_rThat);
465 /** Safe copy assignment method. */
466 int assignCopy(RTCRestInt64 const &a_rThat);
467 /** Assign value and clear null indicator. */
468 void assignValue(int64_t a_iValue);
469
470 /* Overridden methods: */
471 virtual int resetToDefault() RT_OVERRIDE;
472 virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
473 virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
474 virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_OVERRIDE;
475 virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
476 uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
477 virtual kTypeClass typeClass(void) const RT_OVERRIDE;
478 virtual const char *typeName(void) const RT_OVERRIDE;
479
480 /** Factory method. */
481 static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
482
483public:
484 /** The value. */
485 int64_t m_iValue;
486};
487
488
489/**
490 * Class wrapping 'int32_t'.
491 */
492class RT_DECL_CLASS RTCRestInt32 : public RTCRestObjectBase
493{
494public:
495 /** Default constructor. */
496 RTCRestInt32();
497 /** Copy constructor. */
498 RTCRestInt32(RTCRestInt32 const &a_rThat);
499 /** From value constructor. */
500 RTCRestInt32(int32_t iValue);
501 /** Destructor. */
502 virtual ~RTCRestInt32();
503 /** Copy assignment operator. */
504 RTCRestInt32 &operator=(RTCRestInt32 const &a_rThat);
505 /** Safe copy assignment method. */
506 int assignCopy(RTCRestInt32 const &a_rThat);
507 /** Assign value and clear null indicator. */
508 void assignValue(int32_t a_iValue);
509
510 /* Overridden methods: */
511 virtual int resetToDefault() RT_OVERRIDE;
512 virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
513 virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
514 virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_OVERRIDE;
515 virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
516 uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
517 virtual kTypeClass typeClass(void) const RT_OVERRIDE;
518 virtual const char *typeName(void) const RT_OVERRIDE;
519
520 /** Factory method. */
521 static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
522
523public:
524 /** The value. */
525 int32_t m_iValue;
526};
527
528
529/**
530 * Class wrapping 'int16_t'.
531 */
532class RT_DECL_CLASS RTCRestInt16 : public RTCRestObjectBase
533{
534public:
535 /** Default constructor. */
536 RTCRestInt16();
537 /** Copy constructor. */
538 RTCRestInt16(RTCRestInt16 const &a_rThat);
539 /** From value constructor. */
540 RTCRestInt16(int16_t iValue);
541 /** Destructor. */
542 virtual ~RTCRestInt16();
543 /** Copy assignment operator. */
544 RTCRestInt16 &operator=(RTCRestInt16 const &a_rThat);
545 /** Safe copy assignment method. */
546 int assignCopy(RTCRestInt16 const &a_rThat);
547 /** Assign value and clear null indicator. */
548 void assignValue(int16_t a_iValue);
549
550 /* Overridden methods: */
551 virtual int resetToDefault() RT_OVERRIDE;
552 virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
553 virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
554 virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_OVERRIDE;
555 virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
556 uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
557 virtual kTypeClass typeClass(void) const RT_OVERRIDE;
558 virtual const char *typeName(void) const RT_OVERRIDE;
559
560 /** Factory method. */
561 static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
562
563public:
564 /** The value. */
565 int16_t m_iValue;
566};
567
568
569/**
570 * Class wrapping 'double'.
571 */
572class RT_DECL_CLASS RTCRestDouble : public RTCRestObjectBase
573{
574public:
575 /** Default constructor. */
576 RTCRestDouble();
577 /** Copy constructor. */
578 RTCRestDouble(RTCRestDouble const &a_rThat);
579 /** From value constructor. */
580 RTCRestDouble(double rdValue);
581 /** Destructor. */
582 virtual ~RTCRestDouble();
583 /** Copy assignment operator. */
584 RTCRestDouble &operator=(RTCRestDouble const &a_rThat);
585 /** Safe copy assignment method. */
586 int assignCopy(RTCRestDouble const &a_rThat);
587 /** Assign value and clear null indicator. */
588 void assignValue(double a_rdValue);
589
590 /* Overridden methods: */
591 virtual int resetToDefault() RT_OVERRIDE;
592 virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
593 virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
594 virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_OVERRIDE;
595 virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
596 uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
597 virtual kTypeClass typeClass(void) const RT_OVERRIDE;
598 virtual const char *typeName(void) const RT_OVERRIDE;
599
600 /** Factory method. */
601 static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
602
603public:
604 /** The value. */
605 double m_rdValue;
606};
607
608
609/**
610 * Class wrapping 'RTCString'.
611 */
612class RT_DECL_CLASS RTCRestString : public RTCString, public RTCRestObjectBase
613{
614public:
615 /** Default constructor. */
616 RTCRestString();
617 /** Destructor. */
618 virtual ~RTCRestString();
619
620 /** Copy constructor. */
621 RTCRestString(RTCRestString const &a_rThat);
622 /** From value constructor. */
623 RTCRestString(RTCString const &a_rThat);
624 /** From value constructor. */
625 RTCRestString(const char *a_pszSrc);
626 /** Safe copy assignment method. */
627 int assignCopy(RTCRestString const &a_rThat);
628 /** Safe copy assignment method. */
629 int assignCopy(RTCString const &a_rThat);
630 /** Safe copy assignment method. */
631 int assignCopy(const char *a_pszThat);
632
633 /* Overridden methods: */
634 virtual int setNull(void) RT_OVERRIDE; /* (ambigious, so overrider it to make sure.) */
635 virtual int resetToDefault() RT_OVERRIDE;
636 virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
637 virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
638 virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_OVERRIDE;
639 virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
640 uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
641 virtual kTypeClass typeClass(void) const RT_OVERRIDE;
642 virtual const char *typeName(void) const RT_OVERRIDE;
643
644 /** Factory method. */
645 static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
646
647 /** @name RTCString assignment methods we need to replace to manage the null indicator
648 * @{ */
649 int assignNoThrow(const RTCString &a_rSrc) RT_NOEXCEPT;
650 int assignNoThrow(const char *a_pszSrc) RT_NOEXCEPT;
651 int assignNoThrow(const RTCString &a_rSrc, size_t a_offSrc, size_t a_cchSrc = npos) RT_NOEXCEPT;
652 int assignNoThrow(const char *a_pszSrc, size_t a_cchSrc) RT_NOEXCEPT;
653 int assignNoThrow(size_t a_cTimes, char a_ch) RT_NOEXCEPT;
654 int printfNoThrow(const char *pszFormat, ...) RT_NOEXCEPT RT_IPRT_FORMAT_ATTR(1, 2);
655 int printfVNoThrow(const char *pszFormat, va_list va) RT_NOEXCEPT RT_IPRT_FORMAT_ATTR(1, 0);
656 RTCRestString &operator=(const char *a_pcsz);
657 RTCRestString &operator=(const RTCString &a_rThat);
658 RTCRestString &operator=(const RTCRestString &a_rThat);
659 RTCRestString &assign(const RTCString &a_rSrc);
660 RTCRestString &assign(const char *a_pszSrc);
661 RTCRestString &assign(const RTCString &a_rSrc, size_t a_offSrc, size_t a_cchSrc = npos);
662 RTCRestString &assign(const char *a_pszSrc, size_t a_cchSrc);
663 RTCRestString &assign(size_t a_cTimes, char a_ch);
664 RTCRestString &printf(const char *pszFormat, ...) RT_IPRT_FORMAT_ATTR(1, 2);
665 RTCRestString &printfV(const char *pszFormat, va_list va) RT_IPRT_FORMAT_ATTR(1, 0);
666 /** @} */
667};
668
669
670/**
671 * Date class.
672 *
673 * There are numerous ways of formatting a timestamp and the specifications
674 * we're currently working with doesn't have a way of telling it seems.
675 * Thus, decoding need to have fail safes built in so the user can give hints.
676 * The formatting likewise needs to be told which format to use by the user.
677 *
678 * Two side-effects of the format stuff is that the default constructor creates
679 * an object that is null, and resetToDefault will do the same bug leave the
680 * format as a hint.
681 */
682class RT_DECL_CLASS RTCRestDate : public RTCRestObjectBase
683{
684public:
685 /** Default constructor.
686 * @note The result is a null-object. */
687 RTCRestDate();
688 /** Copy constructor. */
689 RTCRestDate(RTCRestDate const &a_rThat);
690 /** Destructor. */
691 virtual ~RTCRestDate();
692 /** Copy assignment operator. */
693 RTCRestDate &operator=(RTCRestDate const &a_rThat);
694 /** Safe copy assignment method. */
695 int assignCopy(RTCRestDate const &a_rThat);
696
697 /* Overridden methods: */
698 virtual int resetToDefault() RT_OVERRIDE;
699 virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
700 virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
701 virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = 0) const RT_OVERRIDE;
702 virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
703 uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
704 virtual kTypeClass typeClass(void) const RT_OVERRIDE;
705 virtual const char *typeName(void) const RT_OVERRIDE;
706
707 /** Factory method. */
708 static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
709
710 /** Date formats. */
711 typedef enum
712 {
713 kFormat_Invalid = 0,
714 kFormat_Rfc2822, /**< Format it according to RFC-2822. */
715 kFormat_Rfc7131, /**< Format it according to RFC-7131 (HTTP). */
716 kFormat_Rfc3339, /**< Format it according to RFC-3339 (ISO-8601) (no fraction). */
717 kFormat_Rfc3339_Fraction_2, /**< Format it according to RFC-3339 (ISO-8601) with two digit fraction (hundreths). */
718 kFormat_Rfc3339_Fraction_3, /**< Format it according to RFC-3339 (ISO-8601) with three digit fraction (milliseconds). */
719 kFormat_Rfc3339_Fraction_6, /**< Format it according to RFC-3339 (ISO-8601) with six digit fraction (microseconds). */
720 kFormat_Rfc3339_Fraction_9, /**< Format it according to RFC-3339 (ISO-8601) with nine digit fraction (nanoseconds). */
721 kFormat_End
722 } kFormat;
723
724 /**
725 * Assigns the value, formats it as a string and clears the null indicator.
726 *
727 * @returns VINF_SUCCESS, VERR_NO_STR_MEMORY or VERR_INVALID_PARAMETER.
728 * @param a_pTimeSpec The time spec to set.
729 * @param a_enmFormat The date format to use when formatting it.
730 */
731 int assignValue(PCRTTIMESPEC a_pTimeSpec, kFormat a_enmFormat);
732 int assignValueRfc2822(PCRTTIMESPEC a_pTimeSpec); /**< Convenience method for email/whatnot. */
733 int assignValueRfc7131(PCRTTIMESPEC a_pTimeSpec); /**< Convenience method for HTTP date. */
734 int assignValueRfc3339(PCRTTIMESPEC a_pTimeSpec); /**< Convenience method for ISO-8601 timstamp. */
735
736 /**
737 * Assigns the current UTC time and clears the null indicator .
738 *
739 * @returns VINF_SUCCESS, VERR_NO_STR_MEMORY or VERR_INVALID_PARAMETER.
740 * @returns VINF_SUCCESS or VERR_NO_STR_MEMORY.
741 * @param a_enmFormat The date format to use when formatting it.
742 */
743 int assignNow(kFormat a_enmFormat);
744 int assignNowRfc2822(); /**< Convenience method for email/whatnot. */
745 int assignNowRfc7131(); /**< Convenience method for HTTP date. */
746 int assignNowRfc3339(); /**< Convenience method for ISO-8601 timstamp. */
747
748 /**
749 * Sets the format to help deal with decoding issues.
750 *
751 * This can also be used to change the date format for an okay timespec.
752 * @returns IPRT status code.
753 * @param a_enmFormat The date format to try/set.
754 */
755 int setFormat(kFormat a_enmFormat);
756
757 /** Check if the value is okay (m_TimeSpec & m_Exploded). */
758 inline bool isOkay() const { return m_fTimeSpecOkay; }
759 /** Get the timespec value. */
760 inline RTTIMESPEC const &getTimeSpec() const { return m_TimeSpec; }
761 /** Get the exploded time. */
762 inline RTTIME const &getExploded() const { return m_Exploded; }
763 /** Gets the format. */
764 inline kFormat getFormat() const { return m_enmFormat; }
765 /** Get the formatted/raw string value. */
766 inline RTCString const &getString() const { return m_strFormatted; }
767
768 /** Get nanoseconds since unix epoch. */
769 inline int64_t getEpochNano() const { return RTTimeSpecGetNano(&m_TimeSpec); }
770 /** Get seconds since unix epoch. */
771 inline int64_t getEpochSeconds() const { return RTTimeSpecGetSeconds(&m_TimeSpec); }
772 /** Checks if UTC time. */
773 inline bool isUtc() const { return (m_Exploded.fFlags & RTTIME_FLAGS_TYPE_MASK) != RTTIME_FLAGS_TYPE_LOCAL; }
774 /** Checks if local time. */
775 inline bool isLocal() const { return (m_Exploded.fFlags & RTTIME_FLAGS_TYPE_MASK) == RTTIME_FLAGS_TYPE_LOCAL; }
776
777protected:
778 /** The value. */
779 RTTIMESPEC m_TimeSpec;
780 /** The exploded time value. */
781 RTTIME m_Exploded;
782 /** Set if m_TimeSpec is okay, consult m_strFormatted if not. */
783 bool m_fTimeSpecOkay;
784 /** The format / format hint. */
785 kFormat m_enmFormat;
786 /** The formatted date string.
787 * This will be the raw input string for a deserialized value, where as for
788 * a value set by the user it will be the formatted value. */
789 RTCString m_strFormatted;
790
791 /**
792 * Explodes and formats the m_TimeSpec value.
793 *
794 * Sets m_Exploded, m_strFormatted, m_fTimeSpecOkay, and m_enmFormat, clears m_fNullIndicator.
795 *
796 * @returns VINF_SUCCESS or VERR_NO_STR_MEMORY.
797 * @param a_enmFormat The format to use.
798 */
799 int explodeAndFormat(kFormat a_enmFormat);
800
801 /**
802 * Formats the m_Exploded value.
803 *
804 * Sets m_strFormatted, m_fTimeSpecOkay, and m_enmFormat, clears m_fNullIndicator.
805 *
806 * @returns VINF_SUCCESS or VERR_NO_STR_MEMORY.
807 * @param a_enmFormat The format to use.
808 */
809 int format(kFormat a_enmFormat);
810
811 /**
812 * Internal worker that attempts to decode m_strFormatted.
813 *
814 * Sets m_fTimeSpecOkay.
815 *
816 * @returns IPRT status code.
817 * @param enmFormat Specific format to try, kFormat_Invalid (default) to try guess it.
818 */
819 int decodeFormattedString(kFormat enmFormat = kFormat_Invalid);
820};
821
822
823/** We should provide a proper UUID class eventually. Currently it is not used. */
824typedef RTCRestString RTCRestUuid;
825
826
827/**
828 * String enum base class.
829 */
830class RT_DECL_CLASS RTCRestStringEnumBase : public RTCRestObjectBase
831{
832public:
833 /** Enum map entry. */
834 typedef struct ENUMMAPENTRY
835 {
836 const char *pszName;
837 uint32_t cchName;
838 int32_t iValue;
839 } ENUMMAPENTRY;
840
841 /** Default constructor. */
842 RTCRestStringEnumBase();
843 /** Destructor. */
844 virtual ~RTCRestStringEnumBase();
845
846 /** Copy constructor. */
847 RTCRestStringEnumBase(RTCRestStringEnumBase const &a_rThat);
848 /** Copy assignment operator. */
849 RTCRestStringEnumBase &operator=(RTCRestStringEnumBase const &a_rThat);
850
851 /** Safe copy assignment method. */
852 int assignCopy(RTCRestStringEnumBase const &a_rThat);
853 /** Safe copy assignment method. */
854 inline int assignCopy(RTCString const &a_rThat) { return setByString(a_rThat); }
855 /** Safe copy assignment method. */
856 inline int assignCopy(const char *a_pszThat) { return setByString(a_pszThat); }
857
858 /* Overridden methods: */
859 virtual int resetToDefault() RT_OVERRIDE;
860 virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
861 virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
862 virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_OVERRIDE;
863 virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
864 uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
865 virtual kTypeClass typeClass(void) const RT_OVERRIDE;
866
867 /**
868 * Sets the value given a C-string value.
869 *
870 * @retval VINF_SUCCESS on success.
871 * @retval VWRN_NOT_FOUND if not mappable to enum value.
872 * @retval VERR_NO_STR_MEMORY if not mappable and we're out of memory.
873 * @param a_pszValue The string value.
874 * @param a_cchValue The string value length. Optional.
875 */
876 int setByString(const char *a_pszValue, size_t a_cchValue = RTSTR_MAX);
877
878 /**
879 * Sets the value given a string value.
880 *
881 * @retval VINF_SUCCESS on success.
882 * @retval VWRN_NOT_FOUND if not mappable to enum value.
883 * @retval VERR_NO_STR_MEMORY if not mappable and we're out of memory.
884 * @param a_rValue The string value.
885 */
886 int setByString(RTCString const &a_rValue);
887
888 /**
889 * Gets the string value.
890 */
891 const char *getString() const;
892
893 /** Maps the given string value to an enum. */
894 int stringToEnum(const char *a_pszValue, size_t a_cchValue = RTSTR_MAX);
895 /** Maps the given string value to an enum. */
896 int stringToEnum(RTCString const &a_rStrValue);
897 /** Maps the given string value to an enum. */
898 const char *enumToString(int a_iEnumValue, size_t *a_pcchString);
899
900
901protected:
902 /** The enum value. */
903 int m_iEnumValue;
904 /** The string value if not a match. */
905 RTCString m_strValue;
906
907 /**
908 * Worker for setting the object to the given enum value.
909 *
910 * @retval true on success.
911 * @retval false if a_iEnumValue can't be translated.
912 * @param a_iEnumValue The enum value to set.
913 */
914 bool setWorker(int a_iEnumValue);
915
916 /**
917 * Gets the mapping table.
918 *
919 * @returns Pointer to the translation table.
920 * @param pcEntries Where to return the translation table size.
921 */
922 virtual ENUMMAPENTRY const *getMappingTable(size_t *pcEntries) const = 0;
923};
924
925
926/**
927 * Class for handling binary blobs (strings).
928 *
929 * There are specializations of this class for body parameters and responses,
930 * see RTCRestBinaryParameter and RTCRestBinaryResponse.
931 */
932class RT_DECL_CLASS RTCRestBinary : public RTCRestObjectBase
933{
934public:
935 /** Default constructor. */
936 RTCRestBinary();
937 /** Destructor. */
938 virtual ~RTCRestBinary();
939
940 /** Safe copy assignment method. */
941 virtual int assignCopy(RTCRestBinary const &a_rThat);
942 /** Safe buffer copy method. */
943 virtual int assignCopy(void const *a_pvData, size_t a_cbData);
944
945 /** Use the specified data buffer directly. */
946 virtual int assignReadOnly(void const *a_pvData, size_t a_cbData);
947 /** Use the specified data buffer directly. */
948 virtual int assignWriteable(void *a_pvBuf, size_t a_cbBuf);
949 /** Frees the data held by the object and resets it default state. */
950 virtual void freeData();
951
952 /** Returns a pointer to the data blob. */
953 inline const uint8_t *getPtr() const { return m_pbData; }
954 /** Gets the size of the data. */
955 inline size_t getSize() const { return m_cbData; }
956
957 /* Overridden methods: */
958 virtual int setNull(void) RT_OVERRIDE;
959 virtual int resetToDefault(void) RT_OVERRIDE;
960 virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
961 virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
962 virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_OVERRIDE;
963 virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
964 uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
965 virtual kTypeClass typeClass(void) const RT_OVERRIDE;
966 virtual const char *typeName(void) const RT_OVERRIDE;
967
968 /** Factory method. */
969 static DECLCALLBACK(RTCRestObjectBase *) createInstance(void);
970
971protected:
972 /** Pointer to data blob. */
973 uint8_t *m_pbData;
974 /** Amount of valid data in the blob. */
975 size_t m_cbData;
976 /** Number of bytes allocated for the m_pbData buffer. */
977 size_t m_cbAllocated;
978 /** Set if the data is freeable, only ever clear if user data. */
979 bool m_fFreeable;
980 /** Set if the data blob is readonly user provided data. */
981 bool m_fReadOnly;
982
983private:
984 /* No copy constructor or copy assignment: */
985 RTCRestBinary(RTCRestBinary const &a_rThat);
986 RTCRestBinary &operator=(RTCRestBinary const &a_rThat);
987};
988
989
990/** @} */
991
992#endif
993
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette