VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/rest/RTCRestAnyObject.cpp@ 74093

Last change on this file since 74093 was 74093, checked in by vboxsync, 7 years ago

IPRT/rest: Implemented the hybrid RTCRestAnyObject chameleon. bugref:9167

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.1 KB
Line 
1/* $Id: RTCRestAnyObject.cpp 74093 2018-09-05 19:30:01Z vboxsync $ */
2/** @file
3 * IPRT - C++ REST, RTCRestAnyObject implementation.
4 */
5
6/*
7 * Copyright (C) 2018 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.215389.xyz. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#define LOG_GROUP RTLOGGROUP_REST
32#include <iprt/cpp/restanyobject.h>
33
34#include <iprt/assert.h>
35#include <iprt/err.h>
36
37
38
39/**
40 * Default constructor.
41 */
42RTCRestAnyObject::RTCRestAnyObject()
43 : RTCRestObjectBase()
44 , m_pData(NULL)
45{
46 m_fNullIndicator = true;
47}
48
49
50/**
51 * Destructor.
52 */
53RTCRestAnyObject::~RTCRestAnyObject()
54{
55 if (m_pData)
56 {
57 delete m_pData;
58 m_pData = NULL;
59 }
60}
61
62
63/**
64 * Copy constructor.
65 */
66RTCRestAnyObject::RTCRestAnyObject(RTCRestAnyObject const &a_rThat)
67 : RTCRestObjectBase()
68 , m_pData(NULL)
69{
70 int rc = assignCopy(a_rThat);
71 if (RT_FAILURE(rc))
72 throw std::bad_alloc();
73}
74
75
76/**
77 * Copy assignment operator.
78 */
79RTCRestAnyObject &RTCRestAnyObject::operator=(RTCRestAnyObject const &a_rThat)
80{
81 int rc = assignCopy(a_rThat);
82 if (RT_FAILURE(rc))
83 throw std::bad_alloc();
84 return *this;
85}
86
87
88/**
89 * Safe copy assignment method.
90 */
91int RTCRestAnyObject::assignCopy(RTCRestAnyObject const &a_rThat)
92{
93 setNull();
94 if ( !a_rThat.m_fNullIndicator
95 && a_rThat.m_pData != NULL)
96 {
97 kTypeClass enmType = a_rThat.m_pData->typeClass();
98 switch (enmType)
99 {
100 case kTypeClass_Bool: return assignCopy(*(RTCRestBool const *)a_rThat.m_pData);
101 case kTypeClass_Int64: return assignCopy(*(RTCRestInt64 const *)a_rThat.m_pData);
102 case kTypeClass_Int32: return assignCopy(*(RTCRestInt32 const *)a_rThat.m_pData);
103 case kTypeClass_Int16: return assignCopy(*(RTCRestInt16 const *)a_rThat.m_pData);
104 case kTypeClass_Double: return assignCopy(*(RTCRestDouble const *)a_rThat.m_pData);
105 case kTypeClass_String: return assignCopy(*(RTCRestString const *)a_rThat.m_pData);
106 case kTypeClass_Array: return assignCopy(*(RTCRestArray<RTCRestAnyObject> const *)a_rThat.m_pData);
107 case kTypeClass_StringMap: return assignCopy(*(RTCRestStringMap<RTCRestAnyObject> const *)a_rThat.m_pData);
108
109 /* Currently unused of invalid: */
110 case kTypeClass_StringEnum:
111 case kTypeClass_Object:
112 case kTypeClass_Invalid:
113 AssertFailedReturn(VERR_REST_INTERNAL_ERROR_7);
114 }
115 }
116 return VINF_SUCCESS;
117}
118
119
120/**
121 * Safe copy assignment method, boolean variant.
122 */
123int RTCRestAnyObject::assignCopy(RTCRestBool const &a_rThat)
124{
125 setNull();
126 RTCRestBool *pData = new (std::nothrow) RTCRestBool();
127 if (pData)
128 {
129 m_pData = pData;
130 m_fNullIndicator = false;
131 return pData->assignCopy(a_rThat);
132 }
133 return VERR_NO_MEMORY;
134}
135
136
137/**
138 * Safe copy assignment method, int64_t variant.
139 */
140int RTCRestAnyObject::assignCopy(RTCRestInt64 const &a_rThat)
141{
142 setNull();
143 RTCRestInt64 *pData = new (std::nothrow) RTCRestInt64();
144 if (pData)
145 {
146 m_pData = pData;
147 m_fNullIndicator = false;
148 return pData->assignCopy(a_rThat);
149 }
150 return VERR_NO_MEMORY;
151}
152
153
154/**
155 * Safe copy assignment method, int32_t variant.
156 */
157int RTCRestAnyObject::assignCopy(RTCRestInt32 const &a_rThat)
158{
159 setNull();
160 RTCRestInt32 *pData = new (std::nothrow) RTCRestInt32();
161 if (pData)
162 {
163 m_pData = pData;
164 m_fNullIndicator = false;
165 return pData->assignCopy(a_rThat);
166 }
167 return VERR_NO_MEMORY;
168}
169
170
171/**
172 * Safe copy assignment method, int16_t variant.
173 */
174int RTCRestAnyObject::assignCopy(RTCRestInt16 const &a_rThat)
175{
176 setNull();
177 RTCRestInt16 *pData = new (std::nothrow) RTCRestInt16();
178 if (pData)
179 {
180 m_pData = pData;
181 m_fNullIndicator = false;
182 return pData->assignCopy(a_rThat);
183 }
184 return VERR_NO_MEMORY;
185}
186
187
188/**
189 * Safe copy assignment method, double variant.
190 */
191int RTCRestAnyObject::assignCopy(RTCRestDouble const &a_rThat)
192{
193 setNull();
194 RTCRestDouble *pData = new (std::nothrow) RTCRestDouble();
195 if (pData)
196 {
197 m_pData = pData;
198 m_fNullIndicator = false;
199 return pData->assignCopy(a_rThat);
200 }
201 return VERR_NO_MEMORY;
202}
203
204
205/**
206 * Safe copy assignment method, string variant.
207 */
208int RTCRestAnyObject::assignCopy(RTCRestString const &a_rThat)
209{
210 setNull();
211 RTCRestString *pData = new (std::nothrow) RTCRestString();
212 if (pData)
213 {
214 m_pData = pData;
215 m_fNullIndicator = false;
216 return pData->assignCopy(a_rThat);
217 }
218 return VERR_NO_MEMORY;
219}
220
221
222/**
223 * Safe copy assignment method, array variant.
224 */
225int RTCRestAnyObject::assignCopy(RTCRestArray<RTCRestAnyObject> const &a_rThat)
226{
227 setNull();
228 RTCRestArray<RTCRestAnyObject> *pData = new (std::nothrow) RTCRestArray<RTCRestAnyObject>();
229 if (pData)
230 {
231 m_pData = pData;
232 m_fNullIndicator = false;
233 return pData->assignCopy(a_rThat);
234 }
235 return VERR_NO_MEMORY;
236}
237
238
239/**
240 * Safe copy assignment method, string map variant.
241 */
242int RTCRestAnyObject::assignCopy(RTCRestStringMap<RTCRestAnyObject> const &a_rThat)
243{
244 setNull();
245 RTCRestStringMap<RTCRestAnyObject> *pData = new (std::nothrow) RTCRestStringMap<RTCRestAnyObject>();
246 if (pData)
247 {
248 m_pData = pData;
249 m_fNullIndicator = false;
250 return pData->assignCopy(a_rThat);
251 }
252 return VERR_NO_MEMORY;
253}
254
255
256/**
257 * Safe value assignment method, boolean variant.
258 */
259int RTCRestAnyObject::assignValue(bool a_fValue)
260{
261 setNull();
262 RTCRestBool *pData = new (std::nothrow) RTCRestBool();
263 if (pData)
264 {
265 m_pData = pData;
266 pData->assignValue(a_fValue);
267 m_fNullIndicator = false;
268 return VINF_SUCCESS;
269 }
270 return VERR_NO_MEMORY;
271}
272
273
274/**
275 * Safe value assignment method, int64_t variant.
276 */
277int RTCRestAnyObject::assignValue(int64_t a_iValue)
278{
279 setNull();
280 RTCRestInt64 *pData = new (std::nothrow) RTCRestInt64();
281 if (pData)
282 {
283 m_pData = pData;
284 pData->assignValue(a_iValue);
285 m_fNullIndicator = false;
286 return VINF_SUCCESS;
287 }
288 return VERR_NO_MEMORY;
289}
290
291
292/**
293 * Safe value assignment method, int32_t variant.
294 */
295int RTCRestAnyObject::assignValue(int32_t a_iValue)
296{
297 setNull();
298 RTCRestInt32 *pData = new (std::nothrow) RTCRestInt32();
299 if (pData)
300 {
301 m_pData = pData;
302 pData->assignValue(a_iValue);
303 m_fNullIndicator = false;
304 return VINF_SUCCESS;
305 }
306 return VERR_NO_MEMORY;
307}
308
309
310/**
311 * Safe value assignment method, int16_t variant.
312 */
313int RTCRestAnyObject::assignValue(int16_t a_iValue)
314{
315 setNull();
316 RTCRestInt16 *pData = new (std::nothrow) RTCRestInt16();
317 if (pData)
318 {
319 m_pData = pData;
320 pData->assignValue(a_iValue);
321 m_fNullIndicator = false;
322 return VINF_SUCCESS;
323 }
324 return VERR_NO_MEMORY;
325}
326
327
328/**
329 * Safe value assignment method, double variant.
330 */
331int RTCRestAnyObject::assignValue(double a_iValue)
332{
333 setNull();
334 RTCRestDouble *pData = new (std::nothrow) RTCRestDouble();
335 if (pData)
336 {
337 m_pData = pData;
338 pData->assignValue(a_iValue);
339 m_fNullIndicator = false;
340 return VINF_SUCCESS;
341 }
342 return VERR_NO_MEMORY;
343}
344
345
346/**
347 * Safe value assignment method, string variant.
348 */
349int RTCRestAnyObject::assignValue(RTCString const &a_rValue)
350{
351 setNull();
352 RTCRestString *pData = new (std::nothrow) RTCRestString();
353 if (pData)
354 {
355 m_pData = pData;
356 m_fNullIndicator = false;
357 return pData->assignNoThrow(a_rValue);
358 }
359 return VERR_NO_MEMORY;
360}
361
362
363/**
364 * Safe value assignment method, C-string variant.
365 */
366int RTCRestAnyObject::assignValue(const char *a_pszValue)
367{
368 setNull();
369 RTCRestString *pData = new (std::nothrow) RTCRestString();
370 if (pData)
371 {
372 m_pData = pData;
373 m_fNullIndicator = false;
374 return pData->assignNoThrow(a_pszValue);
375 }
376 return VERR_NO_MEMORY;
377}
378
379
380int RTCRestAnyObject::setNull(void)
381{
382 if (m_pData)
383 {
384 delete m_pData;
385 m_pData = NULL;
386 }
387 return RTCRestObjectBase::setNull();
388}
389
390
391int RTCRestAnyObject::resetToDefault()
392{
393 if (m_pData)
394 return m_pData->resetToDefault();
395 return VINF_SUCCESS;
396}
397
398
399RTCRestOutputBase &RTCRestAnyObject::serializeAsJson(RTCRestOutputBase &a_rDst) const
400{
401 if (m_pData)
402 return m_pData->serializeAsJson(a_rDst);
403 a_rDst.printf("null");
404 return a_rDst;
405}
406
407
408int RTCRestAnyObject::deserializeFromJson(RTCRestJsonCursor const &a_rCursor)
409{
410 setNull();
411
412 RTJSONVALTYPE enmType = RTJsonValueGetType(a_rCursor.m_hValue);
413 switch (enmType)
414 {
415 case RTJSONVALTYPE_OBJECT:
416 {
417 RTCRestStringMap<RTCRestAnyObject> *pMap = new (std::nothrow) RTCRestStringMap<RTCRestAnyObject>();
418 if (pMap)
419 {
420 m_pData = pMap;
421 m_fNullIndicator = false;
422 return pMap->deserializeFromJson(a_rCursor);
423 }
424 break;
425 }
426
427 case RTJSONVALTYPE_ARRAY:
428 {
429 RTCRestArray<RTCRestAnyObject> *pArray = new (std::nothrow) RTCRestArray<RTCRestAnyObject>();
430 if (pArray)
431 {
432 m_pData = pArray;
433 m_fNullIndicator = false;
434 return pArray->deserializeFromJson(a_rCursor);
435 }
436 break;
437 }
438
439 case RTJSONVALTYPE_STRING:
440 {
441 RTCRestString *pString = new (std::nothrow) RTCRestString();
442 if (pString)
443 {
444 m_pData = pString;
445 m_fNullIndicator = false;
446 return pString->deserializeFromJson(a_rCursor);
447 }
448 break;
449 }
450
451 case RTJSONVALTYPE_INTEGER:
452 {
453 RTCRestInt64 *pInt64 = new (std::nothrow) RTCRestInt64();
454 if (pInt64)
455 {
456 m_pData = pInt64;
457 m_fNullIndicator = false;
458 return pInt64->deserializeFromJson(a_rCursor);
459 }
460 break;
461 }
462
463 case RTJSONVALTYPE_NUMBER:
464 {
465 RTCRestDouble *pDouble = new (std::nothrow) RTCRestDouble();
466 if (pDouble)
467 {
468 m_pData = pDouble;
469 m_fNullIndicator = false;
470 return pDouble->deserializeFromJson(a_rCursor);
471 }
472 break;
473 }
474
475 case RTJSONVALTYPE_NULL:
476 return VINF_SUCCESS;
477
478 case RTJSONVALTYPE_TRUE:
479 case RTJSONVALTYPE_FALSE:
480 {
481 RTCRestBool *pBool = new (std::nothrow) RTCRestBool();
482 if (pBool)
483 {
484 m_pData = pBool;
485 m_fNullIndicator = false;
486 pBool->assignValue(enmType == RTJSONVALTYPE_TRUE);
487 return VINF_SUCCESS;
488 }
489 break;
490 }
491
492 /* no break. */
493 case RTJSONVALTYPE_INVALID:
494 case RTJSONVALTYPE_32BIT_HACK:
495 break;
496 }
497 return a_rCursor.m_pPrimary->addError(a_rCursor, VERR_WRONG_TYPE, "RTCRestAnyObject found %d (%s)",
498 enmType, RTJsonValueTypeName(enmType));
499}
500
501
502int RTCRestAnyObject::toString(RTCString *a_pDst, uint32_t a_fFlags /*= kCollectionFormat_Unspecified*/) const
503{
504 if (m_pData)
505 return m_pData->toString(a_pDst, a_fFlags);
506 if (a_fFlags & kToString_Append)
507 return a_pDst->appendNoThrow(RT_STR_TUPLE("null"));
508 return a_pDst->assignNoThrow(RT_STR_TUPLE("null"));
509}
510
511
512int RTCRestAnyObject::fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo /*= NULL*/,
513 uint32_t a_fFlags /*= kCollectionFormat_Unspecified*/)
514{
515 return RTCRestObjectBase::fromString(a_rValue, a_pszName, a_pErrInfo, a_fFlags);
516}
517
518
519RTCRestObjectBase::kTypeClass RTCRestAnyObject::typeClass(void) const
520{
521 return kTypeClass_Object;
522}
523
524
525const char *RTCRestAnyObject::typeName(void) const
526{
527 if (m_pData)
528 {
529 kTypeClass enmType = m_pData->typeClass();
530 switch (enmType)
531 {
532 case kTypeClass_Bool: return "RTCRestAnyObject[Bool]";
533 case kTypeClass_Int64: return "RTCRestAnyObject[Int64]";
534 case kTypeClass_Int32: return "RTCRestAnyObject[Int32]";
535 case kTypeClass_Int16: return "RTCRestAnyObject[Int16]";
536 case kTypeClass_Double: return "RTCRestAnyObject[Double]";
537 case kTypeClass_String: return "RTCRestAnyObject[String]";
538 case kTypeClass_Array: return "RTCRestAnyObject[Array]";
539 case kTypeClass_StringMap: return "RTCRestAnyObject[StringMap]";
540
541 /* Currently unused of invalid: */
542 case kTypeClass_StringEnum:
543 case kTypeClass_Object:
544 case kTypeClass_Invalid:
545 AssertFailed();
546 }
547 }
548 return "RTCRestAnyObject";
549}
550
551
552/**
553 * Factory method.
554 */
555/*static*/ DECLCALLBACK(RTCRestObjectBase *) RTCRestAnyObject::createInstance(void)
556{
557 return new (std::nothrow) RTCRestAnyObject();
558}
559
Note: See TracBrowser for help on using the repository browser.

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