VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/string/strspace.cpp@ 45221

Last change on this file since 45221 was 44528, checked in by vboxsync, 12 years ago

header (C) fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.8 KB
Line 
1/* $Id: strspace.cpp 44528 2013-02-04 14:27:54Z vboxsync $ */
2/** @file
3 * IPRT - Unique String Spaces.
4 */
5
6/*
7 * Copyright (C) 2006-2011 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#include <iprt/string.h>
32#include "internal/iprt.h"
33
34#include <iprt/assert.h>
35#include "internal/strhash.h"
36
37
38/*******************************************************************************
39* Defined Constants And Macros *
40*******************************************************************************/
41/*
42 * AVL configuration.
43 */
44#define KAVL_DECL(a_Type) static a_Type
45#define KAVL_FN(a) rtstrspace##a
46#define KAVL_MAX_STACK 27 /* Up to 2^24 nodes. */
47#define KAVL_EQUAL_ALLOWED 1
48#define KAVLNODECORE RTSTRSPACECORE
49#define PKAVLNODECORE PRTSTRSPACECORE
50#define PPKAVLNODECORE PPRTSTRSPACECORE
51#define KAVLKEY uint32_t
52#define PKAVLKEY uint32_t *
53
54#define PKAVLCALLBACK PFNRTSTRSPACECALLBACK
55
56/*
57 * AVL Compare macros
58 */
59#define KAVL_G(key1, key2) (key1 > key2)
60#define KAVL_E(key1, key2) (key1 == key2)
61#define KAVL_NE(key1, key2) (key1 != key2)
62
63
64/*
65 * Include the code.
66 */
67#define SSToDS(ptr) ptr
68#define KMAX RT_MAX
69#define kASSERT Assert
70#include "../table/avl_Base.cpp.h"
71#include "../table/avl_Get.cpp.h"
72#include "../table/avl_DoWithAll.cpp.h"
73#include "../table/avl_Destroy.cpp.h"
74
75
76
77/**
78 * Inserts a string into a unique string space.
79 *
80 * @returns true on success.
81 * @returns false if the string collided with an existing string.
82 * @param pStrSpace The space to insert it into.
83 * @param pStr The string node.
84 */
85RTDECL(bool) RTStrSpaceInsert(PRTSTRSPACE pStrSpace, PRTSTRSPACECORE pStr)
86{
87 pStr->Key = sdbm(pStr->pszString, &pStr->cchString);
88 PRTSTRSPACECORE pMatch = KAVL_FN(Get)(pStrSpace, pStr->Key);
89 if (!pMatch)
90 return KAVL_FN(Insert)(pStrSpace, pStr);
91
92 /* Check for clashes. */
93 for (PRTSTRSPACECORE pCur = pMatch; pCur; pCur = pCur->pList)
94 if ( pCur->cchString == pStr->cchString
95 && !memcmp(pCur->pszString, pStr->pszString, pStr->cchString))
96 return false;
97 pStr->pList = pMatch->pList;
98 pMatch->pList = pStr;
99 return true;
100}
101RT_EXPORT_SYMBOL(RTStrSpaceInsert);
102
103
104/**
105 * Removes a string from a unique string space.
106 *
107 * @returns Pointer to the removed string node.
108 * @returns NULL if the string was not found in the string space.
109 * @param pStrSpace The space to insert it into.
110 * @param pszString The string to remove.
111 */
112RTDECL(PRTSTRSPACECORE) RTStrSpaceRemove(PRTSTRSPACE pStrSpace, const char *pszString)
113{
114 size_t cchString;
115 KAVLKEY Key = sdbm(pszString, &cchString);
116 PRTSTRSPACECORE pCur = KAVL_FN(Get)(pStrSpace, Key);
117 if (!pCur)
118 return NULL;
119
120 /* find the right one. */
121 PRTSTRSPACECORE pPrev = NULL;
122 for (; pCur; pPrev = pCur, pCur = pCur->pList)
123 if ( pCur->cchString == cchString
124 && !memcmp(pCur->pszString, pszString, cchString))
125 break;
126 if (pCur)
127 {
128 if (pPrev)
129 /* simple, it's in the linked list. */
130 pPrev->pList = pCur->pList;
131 else
132 {
133 /* in the tree. remove and reinsert list head. */
134 PRTSTRSPACECORE pInsert = pCur->pList;
135 pCur->pList = NULL;
136 pCur = KAVL_FN(Remove)(pStrSpace, Key);
137 Assert(pCur);
138 if (pInsert)
139 {
140 PRTSTRSPACECORE pList = pInsert->pList;
141 bool fRc = KAVL_FN(Insert)(pStrSpace, pInsert);
142 Assert(fRc); NOREF(fRc);
143 pInsert->pList = pList;
144 }
145 }
146 }
147
148 return pCur;
149}
150RT_EXPORT_SYMBOL(RTStrSpaceRemove);
151
152
153/**
154 * Gets a string from a unique string space.
155 *
156 * @returns Pointer to the string node.
157 * @returns NULL if the string was not found in the string space.
158 * @param pStrSpace The space to insert it into.
159 * @param pszString The string to get.
160 */
161RTDECL(PRTSTRSPACECORE) RTStrSpaceGet(PRTSTRSPACE pStrSpace, const char *pszString)
162{
163 size_t cchString;
164 KAVLKEY Key = sdbm(pszString, &cchString);
165 PRTSTRSPACECORE pCur = KAVL_FN(Get)(pStrSpace, Key);
166 if (!pCur)
167 return NULL;
168
169 /* Linear search. */
170 for (; pCur; pCur = pCur->pList)
171 if ( pCur->cchString == cchString
172 && !memcmp(pCur->pszString, pszString, cchString))
173 return pCur;
174 return NULL;
175}
176RT_EXPORT_SYMBOL(RTStrSpaceGet);
177
178
179/**
180 * Gets a string from a unique string space.
181 *
182 * @returns Pointer to the string node.
183 * @returns NULL if the string was not found in the string space.
184 * @param pStrSpace The space to insert it into.
185 * @param pszString The string to get.
186 * @param cchMax The max string length to evaluate. Passing
187 * RTSTR_MAX is ok and makes it behave just like
188 * RTStrSpaceGet.
189 */
190RTDECL(PRTSTRSPACECORE) RTStrSpaceGetN(PRTSTRSPACE pStrSpace, const char *pszString, size_t cchMax)
191{
192 size_t cchString;
193 KAVLKEY Key = sdbmN(pszString, cchMax, &cchString);
194 PRTSTRSPACECORE pCur = KAVL_FN(Get)(pStrSpace, Key);
195 if (!pCur)
196 return NULL;
197
198 /* Linear search. */
199 for (; pCur; pCur = pCur->pList)
200 if ( pCur->cchString == cchString
201 && !memcmp(pCur->pszString, pszString, cchString))
202 return pCur;
203 return NULL;
204}
205RT_EXPORT_SYMBOL(RTStrSpaceGetN);
206
207
208/**
209 * Enumerates the string space.
210 * The caller supplies a callback which will be called for each of
211 * the string nodes.
212 *
213 * @returns 0 or what ever non-zero return value pfnCallback returned
214 * when aborting the destruction.
215 * @param pStrSpace The space to insert it into.
216 * @param pfnCallback The callback.
217 * @param pvUser The user argument.
218 */
219RTDECL(int) RTStrSpaceEnumerate(PRTSTRSPACE pStrSpace, PFNRTSTRSPACECALLBACK pfnCallback, void *pvUser)
220{
221 return KAVL_FN(DoWithAll)(pStrSpace, true, pfnCallback, pvUser);
222}
223RT_EXPORT_SYMBOL(RTStrSpaceEnumerate);
224
225
226/**
227 * Destroys the string space.
228 * The caller supplies a callback which will be called for each of
229 * the string nodes in for freeing their memory and other resources.
230 *
231 * @returns 0 or what ever non-zero return value pfnCallback returned
232 * when aborting the destruction.
233 * @param pStrSpace The space to insert it into.
234 * @param pfnCallback The callback.
235 * @param pvUser The user argument.
236 */
237RTDECL(int) RTStrSpaceDestroy(PRTSTRSPACE pStrSpace, PFNRTSTRSPACECALLBACK pfnCallback, void *pvUser)
238{
239 return KAVL_FN(Destroy)(pStrSpace, pfnCallback, pvUser);
240}
241RT_EXPORT_SYMBOL(RTStrSpaceDestroy);
242
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