VirtualBox

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

Last change on this file since 96563 was 96407, checked in by vboxsync, 2 years ago

scm copyright and license note update

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 8.4 KB
Line 
1/* $Id: strspace.cpp 96407 2022-08-22 17:43:14Z vboxsync $ */
2/** @file
3 * IPRT - Unique String Spaces.
4 */
5
6/*
7 * Copyright (C) 2006-2022 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37
38/*********************************************************************************************************************************
39* Header Files *
40*********************************************************************************************************************************/
41#include <iprt/string.h>
42#include "internal/iprt.h"
43
44#include <iprt/assert.h>
45#include "internal/strhash.h"
46
47
48/*********************************************************************************************************************************
49* Defined Constants And Macros *
50*********************************************************************************************************************************/
51/*
52 * AVL configuration.
53 */
54#define KAVL_DECL(a_Type) static a_Type
55#define KAVL_FN(a) rtstrspace##a
56#define KAVL_MAX_STACK 27 /* Up to 2^24 nodes. */
57#define KAVL_EQUAL_ALLOWED 1
58#define KAVLNODECORE RTSTRSPACECORE
59#define PKAVLNODECORE PRTSTRSPACECORE
60#define PPKAVLNODECORE PPRTSTRSPACECORE
61#define KAVLKEY uint32_t
62#define PKAVLKEY uint32_t *
63
64#define PKAVLCALLBACK PFNRTSTRSPACECALLBACK
65
66/*
67 * AVL Compare macros
68 */
69#define KAVL_G(key1, key2) (key1 > key2)
70#define KAVL_E(key1, key2) (key1 == key2)
71#define KAVL_NE(key1, key2) (key1 != key2)
72
73
74/*
75 * Include the code.
76 */
77#define SSToDS(ptr) ptr
78#define KMAX RT_MAX
79#define kASSERT Assert
80#include "../table/avl_Base.cpp.h"
81#include "../table/avl_Get.cpp.h"
82#include "../table/avl_DoWithAll.cpp.h"
83#include "../table/avl_Destroy.cpp.h"
84
85
86
87/**
88 * Inserts a string into a unique string space.
89 *
90 * @returns true on success.
91 * @returns false if the string collided with an existing string.
92 * @param pStrSpace The space to insert it into.
93 * @param pStr The string node.
94 */
95RTDECL(bool) RTStrSpaceInsert(PRTSTRSPACE pStrSpace, PRTSTRSPACECORE pStr)
96{
97 pStr->Key = sdbm(pStr->pszString, &pStr->cchString);
98 PRTSTRSPACECORE pMatch = KAVL_FN(Get)(pStrSpace, pStr->Key);
99 if (!pMatch)
100 return KAVL_FN(Insert)(pStrSpace, pStr);
101
102 /* Check for clashes. */
103 for (PRTSTRSPACECORE pCur = pMatch; pCur; pCur = pCur->pList)
104 if ( pCur->cchString == pStr->cchString
105 && !memcmp(pCur->pszString, pStr->pszString, pStr->cchString))
106 return false;
107 pStr->pList = pMatch->pList;
108 pMatch->pList = pStr;
109 return true;
110}
111RT_EXPORT_SYMBOL(RTStrSpaceInsert);
112
113
114/**
115 * Removes a string from a unique string space.
116 *
117 * @returns Pointer to the removed string node.
118 * @returns NULL if the string was not found in the string space.
119 * @param pStrSpace The space to insert it into.
120 * @param pszString The string to remove.
121 */
122RTDECL(PRTSTRSPACECORE) RTStrSpaceRemove(PRTSTRSPACE pStrSpace, const char *pszString)
123{
124 size_t cchString;
125 KAVLKEY Key = sdbm(pszString, &cchString);
126 PRTSTRSPACECORE pCur = KAVL_FN(Get)(pStrSpace, Key);
127 if (!pCur)
128 return NULL;
129
130 /* find the right one. */
131 PRTSTRSPACECORE pPrev = NULL;
132 for (; pCur; pPrev = pCur, pCur = pCur->pList)
133 if ( pCur->cchString == cchString
134 && !memcmp(pCur->pszString, pszString, cchString))
135 break;
136 if (pCur)
137 {
138 if (pPrev)
139 /* simple, it's in the linked list. */
140 pPrev->pList = pCur->pList;
141 else
142 {
143 /* in the tree. remove and reinsert list head. */
144 PRTSTRSPACECORE pInsert = pCur->pList;
145 pCur->pList = NULL;
146 pCur = KAVL_FN(Remove)(pStrSpace, Key);
147 Assert(pCur);
148 if (pInsert)
149 {
150 PRTSTRSPACECORE pList = pInsert->pList;
151 bool fRc = KAVL_FN(Insert)(pStrSpace, pInsert);
152 Assert(fRc); NOREF(fRc);
153 pInsert->pList = pList;
154 }
155 }
156 }
157
158 return pCur;
159}
160RT_EXPORT_SYMBOL(RTStrSpaceRemove);
161
162
163/**
164 * Gets a string from a unique string space.
165 *
166 * @returns Pointer to the string node.
167 * @returns NULL if the string was not found in the string space.
168 * @param pStrSpace The space to insert it into.
169 * @param pszString The string to get.
170 */
171RTDECL(PRTSTRSPACECORE) RTStrSpaceGet(PRTSTRSPACE pStrSpace, const char *pszString)
172{
173 size_t cchString;
174 KAVLKEY Key = sdbm(pszString, &cchString);
175 PRTSTRSPACECORE pCur = KAVL_FN(Get)(pStrSpace, Key);
176 if (!pCur)
177 return NULL;
178
179 /* Linear search. */
180 for (; pCur; pCur = pCur->pList)
181 if ( pCur->cchString == cchString
182 && !memcmp(pCur->pszString, pszString, cchString))
183 return pCur;
184 return NULL;
185}
186RT_EXPORT_SYMBOL(RTStrSpaceGet);
187
188
189/**
190 * Gets a string from a unique string space.
191 *
192 * @returns Pointer to the string node.
193 * @returns NULL if the string was not found in the string space.
194 * @param pStrSpace The space to insert it into.
195 * @param pszString The string to get.
196 * @param cchMax The max string length to evaluate. Passing
197 * RTSTR_MAX is ok and makes it behave just like
198 * RTStrSpaceGet.
199 */
200RTDECL(PRTSTRSPACECORE) RTStrSpaceGetN(PRTSTRSPACE pStrSpace, const char *pszString, size_t cchMax)
201{
202 size_t cchString;
203 KAVLKEY Key = sdbmN(pszString, cchMax, &cchString);
204 PRTSTRSPACECORE pCur = KAVL_FN(Get)(pStrSpace, Key);
205 if (!pCur)
206 return NULL;
207
208 /* Linear search. */
209 for (; pCur; pCur = pCur->pList)
210 if ( pCur->cchString == cchString
211 && !memcmp(pCur->pszString, pszString, cchString))
212 return pCur;
213 return NULL;
214}
215RT_EXPORT_SYMBOL(RTStrSpaceGetN);
216
217
218/**
219 * Enumerates the string space.
220 * The caller supplies a callback which will be called for each of
221 * the string nodes.
222 *
223 * @returns 0 or what ever non-zero return value pfnCallback returned
224 * when aborting the destruction.
225 * @param pStrSpace The space to insert it into.
226 * @param pfnCallback The callback.
227 * @param pvUser The user argument.
228 */
229RTDECL(int) RTStrSpaceEnumerate(PRTSTRSPACE pStrSpace, PFNRTSTRSPACECALLBACK pfnCallback, void *pvUser)
230{
231 return KAVL_FN(DoWithAll)(pStrSpace, true, pfnCallback, pvUser);
232}
233RT_EXPORT_SYMBOL(RTStrSpaceEnumerate);
234
235
236/**
237 * Destroys the string space.
238 * The caller supplies a callback which will be called for each of
239 * the string nodes in for freeing their memory and other resources.
240 *
241 * @returns 0 or what ever non-zero return value pfnCallback returned
242 * when aborting the destruction.
243 * @param pStrSpace The space to insert it into.
244 * @param pfnCallback The callback.
245 * @param pvUser The user argument.
246 */
247RTDECL(int) RTStrSpaceDestroy(PRTSTRSPACE pStrSpace, PFNRTSTRSPACECALLBACK pfnCallback, void *pvUser)
248{
249 return KAVL_FN(Destroy)(pStrSpace, pfnCallback, pvUser);
250}
251RT_EXPORT_SYMBOL(RTStrSpaceDestroy);
252
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