VirtualBox

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

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

IPRT/rest: Early support for polymorphic data objects in the data model. bugref:9167 ..\..\ e:\vbox\svn\trunk\include\iprt\

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.7 KB
Line 
1/* $Id: RTCRestAnyObject.cpp 74386 2018-09-20 15:46:38Z 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_Date:
111 case kTypeClass_Uuid:
112 case kTypeClass_Binary:
113 case kTypeClass_StringEnum:
114 case kTypeClass_AnyObject:
115 case kTypeClass_DataObject:
116 case kTypeClass_Invalid:
117 AssertFailedReturn(VERR_REST_INTERNAL_ERROR_7);
118 }
119 }
120 return VINF_SUCCESS;
121}
122
123
124/**
125 * Safe copy assignment method, boolean variant.
126 */
127int RTCRestAnyObject::assignCopy(RTCRestBool const &a_rThat)
128{
129 setNull();
130 RTCRestBool *pData = new (std::nothrow) RTCRestBool();
131 if (pData)
132 {
133 m_pData = pData;
134 m_fNullIndicator = false;
135 return pData->assignCopy(a_rThat);
136 }
137 return VERR_NO_MEMORY;
138}
139
140
141/**
142 * Safe copy assignment method, int64_t variant.
143 */
144int RTCRestAnyObject::assignCopy(RTCRestInt64 const &a_rThat)
145{
146 setNull();
147 RTCRestInt64 *pData = new (std::nothrow) RTCRestInt64();
148 if (pData)
149 {
150 m_pData = pData;
151 m_fNullIndicator = false;
152 return pData->assignCopy(a_rThat);
153 }
154 return VERR_NO_MEMORY;
155}
156
157
158/**
159 * Safe copy assignment method, int32_t variant.
160 */
161int RTCRestAnyObject::assignCopy(RTCRestInt32 const &a_rThat)
162{
163 setNull();
164 RTCRestInt32 *pData = new (std::nothrow) RTCRestInt32();
165 if (pData)
166 {
167 m_pData = pData;
168 m_fNullIndicator = false;
169 return pData->assignCopy(a_rThat);
170 }
171 return VERR_NO_MEMORY;
172}
173
174
175/**
176 * Safe copy assignment method, int16_t variant.
177 */
178int RTCRestAnyObject::assignCopy(RTCRestInt16 const &a_rThat)
179{
180 setNull();
181 RTCRestInt16 *pData = new (std::nothrow) RTCRestInt16();
182 if (pData)
183 {
184 m_pData = pData;
185 m_fNullIndicator = false;
186 return pData->assignCopy(a_rThat);
187 }
188 return VERR_NO_MEMORY;
189}
190
191
192/**
193 * Safe copy assignment method, double variant.
194 */
195int RTCRestAnyObject::assignCopy(RTCRestDouble const &a_rThat)
196{
197 setNull();
198 RTCRestDouble *pData = new (std::nothrow) RTCRestDouble();
199 if (pData)
200 {
201 m_pData = pData;
202 m_fNullIndicator = false;
203 return pData->assignCopy(a_rThat);
204 }
205 return VERR_NO_MEMORY;
206}
207
208
209/**
210 * Safe copy assignment method, string variant.
211 */
212int RTCRestAnyObject::assignCopy(RTCRestString const &a_rThat)
213{
214 setNull();
215 RTCRestString *pData = new (std::nothrow) RTCRestString();
216 if (pData)
217 {
218 m_pData = pData;
219 m_fNullIndicator = false;
220 return pData->assignCopy(a_rThat);
221 }
222 return VERR_NO_MEMORY;
223}
224
225
226/**
227 * Safe copy assignment method, array variant.
228 */
229int RTCRestAnyObject::assignCopy(RTCRestArray<RTCRestAnyObject> const &a_rThat)
230{
231 setNull();
232 RTCRestArray<RTCRestAnyObject> *pData = new (std::nothrow) RTCRestArray<RTCRestAnyObject>();
233 if (pData)
234 {
235 m_pData = pData;
236 m_fNullIndicator = false;
237 return pData->assignCopy(a_rThat);
238 }
239 return VERR_NO_MEMORY;
240}
241
242
243/**
244 * Safe copy assignment method, string map variant.
245 */
246int RTCRestAnyObject::assignCopy(RTCRestStringMap<RTCRestAnyObject> const &a_rThat)
247{
248 setNull();
249 RTCRestStringMap<RTCRestAnyObject> *pData = new (std::nothrow) RTCRestStringMap<RTCRestAnyObject>();
250 if (pData)
251 {
252 m_pData = pData;
253 m_fNullIndicator = false;
254 return pData->assignCopy(a_rThat);
255 }
256 return VERR_NO_MEMORY;
257}
258
259
260/**
261 * Safe value assignment method, boolean variant.
262 */
263int RTCRestAnyObject::assignValue(bool a_fValue)
264{
265 setNull();
266 RTCRestBool *pData = new (std::nothrow) RTCRestBool();
267 if (pData)
268 {
269 m_pData = pData;
270 pData->assignValue(a_fValue);
271 m_fNullIndicator = false;
272 return VINF_SUCCESS;
273 }
274 return VERR_NO_MEMORY;
275}
276
277
278/**
279 * Safe value assignment method, int64_t variant.
280 */
281int RTCRestAnyObject::assignValue(int64_t a_iValue)
282{
283 setNull();
284 RTCRestInt64 *pData = new (std::nothrow) RTCRestInt64();
285 if (pData)
286 {
287 m_pData = pData;
288 pData->assignValue(a_iValue);
289 m_fNullIndicator = false;
290 return VINF_SUCCESS;
291 }
292 return VERR_NO_MEMORY;
293}
294
295
296/**
297 * Safe value assignment method, int32_t variant.
298 */
299int RTCRestAnyObject::assignValue(int32_t a_iValue)
300{
301 setNull();
302 RTCRestInt32 *pData = new (std::nothrow) RTCRestInt32();
303 if (pData)
304 {
305 m_pData = pData;
306 pData->assignValue(a_iValue);
307 m_fNullIndicator = false;
308 return VINF_SUCCESS;
309 }
310 return VERR_NO_MEMORY;
311}
312
313
314/**
315 * Safe value assignment method, int16_t variant.
316 */
317int RTCRestAnyObject::assignValue(int16_t a_iValue)
318{
319 setNull();
320 RTCRestInt16 *pData = new (std::nothrow) RTCRestInt16();
321 if (pData)
322 {
323 m_pData = pData;
324 pData->assignValue(a_iValue);
325 m_fNullIndicator = false;
326 return VINF_SUCCESS;
327 }
328 return VERR_NO_MEMORY;
329}
330
331
332/**
333 * Safe value assignment method, double variant.
334 */
335int RTCRestAnyObject::assignValue(double a_iValue)
336{
337 setNull();
338 RTCRestDouble *pData = new (std::nothrow) RTCRestDouble();
339 if (pData)
340 {
341 m_pData = pData;
342 pData->assignValue(a_iValue);
343 m_fNullIndicator = false;
344 return VINF_SUCCESS;
345 }
346 return VERR_NO_MEMORY;
347}
348
349
350/**
351 * Safe value assignment method, string variant.
352 */
353int RTCRestAnyObject::assignValue(RTCString const &a_rValue)
354{
355 setNull();
356 RTCRestString *pData = new (std::nothrow) RTCRestString();
357 if (pData)
358 {
359 m_pData = pData;
360 m_fNullIndicator = false;
361 return pData->assignNoThrow(a_rValue);
362 }
363 return VERR_NO_MEMORY;
364}
365
366
367/**
368 * Safe value assignment method, C-string variant.
369 */
370int RTCRestAnyObject::assignValue(const char *a_pszValue)
371{
372 setNull();
373 RTCRestString *pData = new (std::nothrow) RTCRestString();
374 if (pData)
375 {
376 m_pData = pData;
377 m_fNullIndicator = false;
378 return pData->assignNoThrow(a_pszValue);
379 }
380 return VERR_NO_MEMORY;
381}
382
383
384RTCRestObjectBase *RTCRestAnyObject::baseClone() const
385{
386 RTCRestAnyObject *pClone = new (std::nothrow) RTCRestAnyObject();
387 if (pClone)
388 {
389 int rc = pClone->assignCopy(*this);
390 if (RT_SUCCESS(rc))
391 return pClone;
392 delete pClone;
393 }
394 return NULL;
395}
396
397
398int RTCRestAnyObject::setNull(void)
399{
400 if (m_pData)
401 {
402 delete m_pData;
403 m_pData = NULL;
404 }
405 return RTCRestObjectBase::setNull();
406}
407
408
409int RTCRestAnyObject::resetToDefault()
410{
411 if (m_pData)
412 return m_pData->resetToDefault();
413 return VINF_SUCCESS;
414}
415
416
417RTCRestOutputBase &RTCRestAnyObject::serializeAsJson(RTCRestOutputBase &a_rDst) const
418{
419 if (m_pData)
420 return m_pData->serializeAsJson(a_rDst);
421 a_rDst.printf("null");
422 return a_rDst;
423}
424
425
426int RTCRestAnyObject::deserializeFromJson(RTCRestJsonCursor const &a_rCursor)
427{
428 setNull();
429
430 RTJSONVALTYPE enmType = RTJsonValueGetType(a_rCursor.m_hValue);
431 switch (enmType)
432 {
433 case RTJSONVALTYPE_OBJECT:
434 {
435 RTCRestStringMap<RTCRestAnyObject> *pMap = new (std::nothrow) RTCRestStringMap<RTCRestAnyObject>();
436 if (pMap)
437 {
438 m_pData = pMap;
439 m_fNullIndicator = false;
440 return pMap->deserializeFromJson(a_rCursor);
441 }
442 break;
443 }
444
445 case RTJSONVALTYPE_ARRAY:
446 {
447 RTCRestArray<RTCRestAnyObject> *pArray = new (std::nothrow) RTCRestArray<RTCRestAnyObject>();
448 if (pArray)
449 {
450 m_pData = pArray;
451 m_fNullIndicator = false;
452 return pArray->deserializeFromJson(a_rCursor);
453 }
454 break;
455 }
456
457 case RTJSONVALTYPE_STRING:
458 {
459 RTCRestString *pString = new (std::nothrow) RTCRestString();
460 if (pString)
461 {
462 m_pData = pString;
463 m_fNullIndicator = false;
464 return pString->deserializeFromJson(a_rCursor);
465 }
466 break;
467 }
468
469 case RTJSONVALTYPE_INTEGER:
470 {
471 RTCRestInt64 *pInt64 = new (std::nothrow) RTCRestInt64();
472 if (pInt64)
473 {
474 m_pData = pInt64;
475 m_fNullIndicator = false;
476 return pInt64->deserializeFromJson(a_rCursor);
477 }
478 break;
479 }
480
481 case RTJSONVALTYPE_NUMBER:
482 {
483 RTCRestDouble *pDouble = new (std::nothrow) RTCRestDouble();
484 if (pDouble)
485 {
486 m_pData = pDouble;
487 m_fNullIndicator = false;
488 return pDouble->deserializeFromJson(a_rCursor);
489 }
490 break;
491 }
492
493 case RTJSONVALTYPE_NULL:
494 return VINF_SUCCESS;
495
496 case RTJSONVALTYPE_TRUE:
497 case RTJSONVALTYPE_FALSE:
498 {
499 RTCRestBool *pBool = new (std::nothrow) RTCRestBool();
500 if (pBool)
501 {
502 m_pData = pBool;
503 m_fNullIndicator = false;
504 pBool->assignValue(enmType == RTJSONVALTYPE_TRUE);
505 return VINF_SUCCESS;
506 }
507 break;
508 }
509
510 /* no break. */
511 case RTJSONVALTYPE_INVALID:
512 case RTJSONVALTYPE_32BIT_HACK:
513 break;
514 }
515 return a_rCursor.m_pPrimary->addError(a_rCursor, VERR_WRONG_TYPE, "RTCRestAnyObject found %d (%s)",
516 enmType, RTJsonValueTypeName(enmType));
517}
518
519
520int RTCRestAnyObject::toString(RTCString *a_pDst, uint32_t a_fFlags /*= kCollectionFormat_Unspecified*/) const
521{
522 if (m_pData)
523 return m_pData->toString(a_pDst, a_fFlags);
524 if (a_fFlags & kToString_Append)
525 return a_pDst->appendNoThrow(RT_STR_TUPLE("null"));
526 return a_pDst->assignNoThrow(RT_STR_TUPLE("null"));
527}
528
529
530int RTCRestAnyObject::fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo /*= NULL*/,
531 uint32_t a_fFlags /*= kCollectionFormat_Unspecified*/)
532{
533 return RTCRestObjectBase::fromString(a_rValue, a_pszName, a_pErrInfo, a_fFlags);
534}
535
536
537RTCRestObjectBase::kTypeClass RTCRestAnyObject::typeClass(void) const
538{
539 return kTypeClass_AnyObject;
540}
541
542
543const char *RTCRestAnyObject::typeName(void) const
544{
545 if (m_pData)
546 {
547 kTypeClass enmType = m_pData->typeClass();
548 switch (enmType)
549 {
550 case kTypeClass_Bool: return "RTCRestAnyObject[Bool]";
551 case kTypeClass_Int64: return "RTCRestAnyObject[Int64]";
552 case kTypeClass_Int32: return "RTCRestAnyObject[Int32]";
553 case kTypeClass_Int16: return "RTCRestAnyObject[Int16]";
554 case kTypeClass_Double: return "RTCRestAnyObject[Double]";
555 case kTypeClass_String: return "RTCRestAnyObject[String]";
556 case kTypeClass_Array: return "RTCRestAnyObject[Array]";
557 case kTypeClass_StringMap: return "RTCRestAnyObject[StringMap]";
558
559 /* Currently unused of invalid: */
560 case kTypeClass_Date:
561 case kTypeClass_Uuid:
562 case kTypeClass_Binary:
563 case kTypeClass_StringEnum:
564 case kTypeClass_DataObject:
565 case kTypeClass_AnyObject:
566 case kTypeClass_Invalid:
567 AssertFailed();
568 }
569 }
570 return "RTCRestAnyObject";
571}
572
573
574/**
575 * Factory method.
576 */
577/*static*/ DECLCALLBACK(RTCRestObjectBase *) RTCRestAnyObject::createInstance(void)
578{
579 return new (std::nothrow) RTCRestAnyObject();
580}
581
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