VirtualBox

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

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

IPRT/rest: Build fix for array tests. Started testing the string map. Added isEmpty method to the string map. bugref:9167

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