VirtualBox

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

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

IPRT/rest: Bug fixes. Pet listing works. bugref:9167

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