VirtualBox

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

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

IPRT/rest: Started implemented more flexible handling of binary uploads and downloads. bugref:9167

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