VirtualBox

source: vbox/trunk/include/iprt/cpp/reststringmap.h@ 74025

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

IPRT/rest: split up restbase.h into several files to make it more managable. bugref:9167

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.7 KB
Line 
1/** @file
2 * IPRT - C++ Representational State Transfer (REST) String Map Template.
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_reststringmap_h
27#define ___iprt_cpp_reststringmap_h
28
29#include <iprt/list.h>
30#include <iprt/string.h>
31#include <iprt/cpp/restbase.h>
32
33
34/** @defgroup grp_rt_cpp_reststingmap C++ Representational State Transfer (REST) String Map Template
35 * @ingroup grp_rt_cpp
36 * @{
37 */
38
39/**
40 * Abstract base class for the RTCRestStringMap template.
41 */
42class RT_DECL_CLASS RTCRestStringMapBase : public RTCRestObjectBase
43{
44public:
45 /** Default destructor. */
46 RTCRestStringMapBase();
47 /** Copy constructor. */
48 RTCRestStringMapBase(RTCRestStringMapBase const &a_rThat);
49 /** Destructor. */
50 virtual ~RTCRestStringMapBase();
51 /** Copy assignment operator. */
52 RTCRestStringMapBase &operator=(RTCRestStringMapBase const &a_rThat);
53
54 /* Overridden methods: */
55 virtual int resetToDefault() RT_OVERRIDE;
56 virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE;
57 virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE;
58 // later?
59 //virtual int toString(RTCString *a_pDst, uint32_t a_fFlags = kCollectionFormat_Unspecified) const RT_OVERRIDE;
60 //virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL,
61 // uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE;
62 virtual kTypeClass typeClass(void) const RT_OVERRIDE;
63 virtual const char *typeName(void) const RT_OVERRIDE;
64
65 /**
66 * Clear the content of the map.
67 */
68 void clear();
69
70 /**
71 * Gets the number of entries in the map.
72 */
73 size_t size() const;
74
75 /**
76 * Checks if the map contains the given key.
77 * @returns true if key found, false if not.
78 * @param a_pszKey The key to check fo.
79 */
80 bool constainsKey(const char *a_pszKey) const;
81
82 /**
83 * Checks if the map contains the given key.
84 * @returns true if key found, false if not.
85 * @param a_rStrKey The key to check fo.
86 */
87 bool constainsKey(RTCString const &a_rStrKey) const;
88
89 /**
90 * Remove any key-value pair with the given key.
91 * @returns true if anything was removed, false if not found.
92 * @param a_pszKey The key to remove.
93 */
94 bool remove(const char *a_pszKey);
95
96 /**
97 * Remove any key-value pair with the given key.
98 * @returns true if anything was removed, false if not found.
99 * @param a_rStrKey The key to remove.
100 */
101 bool remove(RTCString const &a_rStrKey);
102
103 /**
104 * Creates a new value and inserts it under the given key, returning the new value.
105 *
106 * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
107 * VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
108 * @param a_ppValue Where to return the pointer to the value.
109 * @param a_pszKey The key to put it under.
110 * @param a_cchKey The length of the key. Default is the entire string.
111 * @param a_fReplace Whether to replace or fail on key collision.
112 */
113 int putNewValue(RTCRestObjectBase **a_ppValue, const char *a_pszKey, size_t a_cchKey = RTSTR_MAX, bool a_fReplace = false);
114
115 /**
116 * Creates a new value and inserts it under the given key, returning the new value.
117 *
118 * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
119 * VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
120 * @param a_ppValue Where to return the pointer to the value.
121 * @param a_pszKey The key to put it under.
122 * @param a_fReplace Whether to replace or fail on key collision.
123 */
124 int putNewValue(RTCRestObjectBase **a_ppValue, RTCString const &a_rStrKey, bool a_fReplace = false);
125
126protected:
127 /** Map entry. */
128 typedef struct MapEntry
129 {
130 /** String space core. */
131 RTSTRSPACECORE Core;
132 /** List node for enumeration. */
133 RTLISTNODE ListEntry;
134 /** The key.
135 * @remarks Core.pszString points to the value of this object. So, consider it const. */
136 RTCString strKey;
137 /** The value. */
138 RTCRestObjectBase *pValue;
139 } MapEntry;
140 /** The map tree. */
141 RTSTRSPACE m_Map;
142 /** The enumeration list head (MapEntry). */
143 RTLISTANCHOR m_ListHead;
144 /** Number of map entries. */
145 size_t m_cEntries;
146
147public:
148 /** @name Map Iteration
149 * @{ */
150 /** Const iterator. */
151 class ConstIterator
152 {
153 private:
154 MapEntry *m_pCur;
155 ConstIterator();
156 protected:
157 ConstIterator(MapEntry *a_pEntry) : m_pCur(a_pEntry) { }
158 public:
159 ConstIterator(ConstIterator const &a_rThat) : m_pCur(a_rThat.m_pCur) { }
160
161 /** Gets the key string. */
162 RTCString const &getKey() { return m_pCur->strKey; }
163 /** Gets poitner to the value object. */
164 RTCRestObjectBase const *getValue() { return m_pCur->pValue; }
165
166 /** Advance to the next map entry. */
167 ConstIterator &operator++()
168 {
169 m_pCur = RTListNodeGetNextCpp(&m_pCur->ListEntry, MapEntry, ListEntry);
170 return *this;
171 }
172
173 /** Advance to the previous map entry. */
174 ConstIterator &operator--()
175 {
176 m_pCur = RTListNodeGetPrevCpp(&m_pCur->ListEntry, MapEntry, ListEntry);
177 return *this;
178 }
179
180 /** Compare equal. */
181 bool operator==(ConstIterator const &a_rThat) { return m_pCur == a_rThat.m_pCur; }
182 /** Compare not equal. */
183 bool operator!=(ConstIterator const &a_rThat) { return m_pCur != a_rThat.m_pCur; }
184
185 /* Map class must be friend so it can use the MapEntry constructor. */
186 friend class RTCRestStringMapBase;
187 };
188
189 /** Returns iterator for the first map entry (unless it's empty and it's also the end). */
190 ConstIterator begin() const { return ConstIterator(RTListGetFirstCpp(&m_ListHead, MapEntry, ListEntry)); }
191 /** Returns iterator for the last map entry (unless it's empty and it's also the end). */
192 ConstIterator last() const { return ConstIterator(RTListGetLastCpp(&m_ListHead, MapEntry, ListEntry)); }
193 /** Returns the end iterator. This does not ever refer to an actual map entry. */
194 ConstIterator end() const { return ConstIterator(RT_FROM_CPP_MEMBER(&m_ListHead, MapEntry, ListEntry)); }
195 /** @} */
196
197
198protected:
199 /**
200 * Wrapper around the value constructor.
201 *
202 * @returns Pointer to new value object on success, NULL if out of memory.
203 */
204 virtual RTCRestObjectBase *createValue(void) = 0;
205
206 /**
207 * Wrapper around the value copy constructor.
208 *
209 * @returns Pointer to copy on success, NULL if out of memory.
210 * @param a_pSrc The value to copy.
211 */
212 virtual RTCRestObjectBase *createValueCopy(RTCRestObjectBase const *a_pSrc) = 0;
213
214 /**
215 * Worker for the copy constructor and the assignment operator.
216 *
217 * This will use createEntryCopy to do the copying.
218 *
219 * @returns VINF_SUCCESS on success, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
220 * @param a_rThat The map to copy. Caller makes 100% sure the it has
221 * the same type as the destination.
222 * @param a_fThrow Whether to throw error.
223 */
224 int copyMapWorker(RTCRestStringMapBase const &a_rThat, bool a_fThrow);
225
226 /**
227 * Worker for performing inserts.
228 *
229 * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
230 * VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
231 * @param a_pszKey The key.
232 * @param a_pValue The value to insert. Ownership is transferred to the map on success.
233 * @param a_fReplace Whether to replace existing key-value pair with matching key.
234 * @param a_cchKey The key length, the whole string by default.
235 */
236 int putWorker(const char *a_pszKey, RTCRestObjectBase *a_pValue, bool a_fReplace, size_t a_cchKey = RTSTR_MAX);
237
238 /**
239 * Worker for performing inserts.
240 *
241 * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
242 * VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
243 * @param a_pszKey The key.
244 * @param a_rValue The value to copy into the map.
245 * @param a_fReplace Whether to replace existing key-value pair with matching key.
246 * @param a_cchKey The key length, the whole string by default.
247 */
248 int putCopyWorker(const char *a_pszKey, RTCRestObjectBase const &a_rValue, bool a_fReplace, size_t a_cchKey = RTSTR_MAX);
249
250 /**
251 * Worker for getting the value corresponding to the given key.
252 *
253 * @returns Pointer to the value object if found, NULL if key not in the map.
254 * @param a_pszKey The key which value to look up.
255 */
256 RTCRestObjectBase *getWorker(const char *a_pszKey);
257
258 /**
259 * Worker for getting the value corresponding to the given key, const variant.
260 *
261 * @returns Pointer to the value object if found, NULL if key not in the map.
262 * @param a_pszKey The key which value to look up.
263 */
264 RTCRestObjectBase const *getWorker(const char *a_pszKey) const;
265
266private:
267 static DECLCALLBACK(int) stringSpaceDestructorCallback(PRTSTRSPACECORE pStr, void *pvUser);
268};
269
270
271/**
272 * Limited map class.
273 */
274template<class ValueType> class RTCRestStringMap : public RTCRestStringMapBase
275{
276public:
277 /** Default constructor, creates emtpy map. */
278 RTCRestStringMap()
279 : RTCRestStringMapBase()
280 {}
281
282 /** Copy constructor. */
283 RTCRestStringMap(RTCRestStringMap const &a_rThat)
284 : RTCRestStringMapBase()
285 {
286 copyMapWorker(a_rThat, true /*a_fThrow*/);
287 }
288
289 /** Destructor. */
290 virtual ~RTCRestStringMap()
291 {
292 /* nothing to do here. */
293 }
294
295 /** Copy assignment operator. */
296 RTCRestStringMap &operator=(RTCRestStringMap const &a_rThat)
297 {
298 copyMapWorker(a_rThat, true /*a_fThrow*/);
299 return *this;
300 }
301
302 /** Safe copy assignment method. */
303 int assignCopy(RTCRestStringMap const &a_rThat)
304 {
305 return copyMapWorker(a_rThat, false /*a_fThrow*/);
306 }
307
308 /** Factory method. */
309 static DECLCALLBACK(RTCRestObjectBase *) createInstance(void)
310 {
311 return new (std::nothrow) RTCRestStringMap<ValueType>();
312 }
313
314 /** Factory method for values. */
315 static DECLCALLBACK(RTCRestObjectBase *) createValueInstance(void)
316 {
317 return new (std::nothrow) ValueType();
318 }
319
320 /**
321 * Inserts the given object into the map.
322 *
323 * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
324 * VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
325 * @param a_pszKey The key.
326 * @param a_pValue The value to insert. Ownership is transferred to the map on success.
327 * @param a_fReplace Whether to replace existing key-value pair with matching key.
328 */
329 int put(const char *a_pszKey, ValueType *a_pValue, bool a_fReplace = false)
330 {
331 return putWorker(a_pszKey, a_pValue, a_fReplace);
332 }
333
334 /**
335 * Inserts the given object into the map.
336 *
337 * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
338 * VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
339 * @param a_rStrKey The key.
340 * @param a_pValue The value to insert. Ownership is transferred to the map on success.
341 * @param a_fReplace Whether to replace existing key-value pair with matching key.
342 */
343 int put(RTCString const &a_rStrKey, ValueType *a_pValue, bool a_fReplace = false)
344 {
345 return putWorker(a_rStrKey.c_str(), a_pValue, a_fReplace, a_rStrKey.length());
346 }
347
348 /**
349 * Inserts a copy of the given object into the map.
350 *
351 * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
352 * VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
353 * @param a_pszKey The key.
354 * @param a_rValue The value to insert a copy of.
355 * @param a_fReplace Whether to replace existing key-value pair with matching key.
356 */
357 int putCopy(const char *a_pszKey, const ValueType &a_rValue, bool a_fReplace = false)
358 {
359 return putCopyWorker(a_pszKey, a_rValue, a_fReplace);
360 }
361
362 /**
363 * Inserts a copy of the given object into the map.
364 *
365 * @returns VINF_SUCCESS or VWRN_ALREADY_EXISTS on success.
366 * VERR_ALREADY_EXISTS, VERR_NO_MEMORY or VERR_NO_STR_MEMORY on failure.
367 * @param a_rStrKey The key.
368 * @param a_rValue The value to insert a copy of.
369 * @param a_fReplace Whether to replace existing key-value pair with matching key.
370 */
371 int putCopy(RTCString const &a_rStrKey, const ValueType &a_rValue, bool a_fReplace = false)
372 {
373 return putCopyWorker(a_rStrKey.c_str(), a_rValue, a_fReplace, a_rStrKey.length());
374 }
375
376 /**
377 * Gets the value corresponding to the given key.
378 *
379 * @returns Pointer to the value object if found, NULL if key not in the map.
380 * @param a_pszKey The key which value to look up.
381 */
382 ValueType *get(const char *a_pszKey)
383 {
384 return (ValueType *)getWorker(a_pszKey);
385 }
386
387 /**
388 * Gets the value corresponding to the given key.
389 *
390 * @returns Pointer to the value object if found, NULL if key not in the map.
391 * @param a_rStrKey The key which value to look up.
392 */
393 ValueType *get(RTCString const &a_rStrKey)
394 {
395 return (ValueType *)getWorker(a_rStrKey.c_str());
396 }
397
398 /**
399 * Gets the const value corresponding to the given key.
400 *
401 * @returns Pointer to the value object if found, NULL if key not in the map.
402 * @param a_pszKey The key which value to look up.
403 */
404 ValueType const *get(const char *a_pszKey) const
405 {
406 return (ValueType const *)getWorker(a_pszKey);
407 }
408
409 /**
410 * Gets the const value corresponding to the given key.
411 *
412 * @returns Pointer to the value object if found, NULL if key not in the map.
413 * @param a_rStrKey The key which value to look up.
414 */
415 ValueType const *get(RTCString const &a_rStrKey) const
416 {
417 return (ValueType const *)getWorker(a_rStrKey.c_str());
418 }
419
420 /** @todo enumerator*/
421
422protected:
423 virtual RTCRestObjectBase *createValue(void) RT_OVERRIDE
424 {
425 return new (std::nothrow) ValueType();
426 }
427
428 virtual RTCRestObjectBase *createValueCopy(RTCRestObjectBase const *a_pSrc) RT_OVERRIDE
429 {
430 ValueType *pCopy = new (std::nothrow) ValueType();
431 if (pCopy)
432 {
433 int rc = pCopy->assignCopy(*(ValueType const *)a_pSrc);
434 if (RT_SUCCESS(rc))
435 return pCopy;
436 delete pCopy;
437 }
438 return NULL;
439 }
440};
441
442
443/** @} */
444
445#endif
446
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