02b2124a310f12adaeb34e21a5354e6ece26712a
2 * Copyright 2016 Mark Jansen
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #if !defined(SDBWRITE_HOSTTOOL)
20 #define WIN32_NO_STATUS
24 #else /* !defined(SDBWRITE_HOSTTOOL) */
29 #endif /* !defined(SDBWRITE_HOSTTOOL) */
31 #include "sdbstringtable.h"
33 #if !defined(offsetof)
35 #define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
37 #define offsetof(TYPE, MEMBER) ((size_t)&(((TYPE *)0)->MEMBER))
39 #endif // !defined(offsetof)
41 #define DEFAULT_TABLE_SIZE 0x100
43 typedef struct SdbHashEntry
45 struct SdbHashEntry
* Next
;
50 struct SdbStringHashTable
53 struct SdbHashEntry
** Entries
;
57 static struct SdbStringHashTable
* HashCreate(void)
59 struct SdbStringHashTable
* tab
= SdbAlloc(sizeof(*tab
));
62 SHIM_ERR("Failed to allocate 8 bytes.\r\n");
65 tab
->Size
= DEFAULT_TABLE_SIZE
;
66 tab
->Entries
= SdbAlloc(tab
->Size
* sizeof(*tab
->Entries
));
71 void SdbpTableDestroy(struct SdbStringHashTable
** pTable
)
73 struct SdbStringHashTable
* table
= *pTable
;
74 struct SdbHashEntry
* entry
, *next
;
75 DWORD n
, depth
= 0, once
= 1;
78 for (n
= 0; n
< table
->Size
; ++n
)
81 entry
= next
= table
->Entries
[n
];
89 if (once
&& depth
> 3)
95 SdbFree(table
->Entries
);
99 /* Based on RtlHashUnicodeString */
100 static DWORD
StringHash(const WCHAR
* str
)
105 hash
= ((65599 * hash
) + (ULONG
)(*str
));
110 int Sdbwcscmp(const WCHAR
* s1
, const WCHAR
* s2
)
123 // implementation taken from reactos/sdk/lib/crt/string/wcs.c
124 INT
Sdbwcscpy(WCHAR
* wcDest
, size_t numElement
, const WCHAR
*wcSrc
)
127 if(!wcDest
|| !numElement
)
128 return 22; /* EINVAL */
133 return 22; /* EINVAL */
135 size
= SdbpStrlen(wcSrc
) + 1;
137 if(size
> numElement
)
138 return 34; /* ERANGE */
140 memcpy(wcDest
, wcSrc
, size
* sizeof(WCHAR
));
145 static struct SdbHashEntry
** TableFindPtr(struct SdbStringHashTable
* table
, const WCHAR
* str
)
147 DWORD hash
= StringHash(str
);
148 struct SdbHashEntry
** entry
= &table
->Entries
[hash
% table
->Size
];
151 if (!Sdbwcscmp((*entry
)->Name
, str
))
153 entry
= &(*entry
)->Next
;
158 static BOOL
HashAddString(struct SdbStringHashTable
* table
, struct SdbHashEntry
** position
, const WCHAR
* str
, TAGID tagid
)
160 struct SdbHashEntry
* entry
;
164 position
= TableFindPtr(table
, str
);
166 len
= SdbpStrlen(str
) + 1;
167 size
= offsetof(struct SdbHashEntry
, Name
[len
]);
168 entry
= (*position
) = SdbAlloc(size
);
171 SHIM_ERR("Failed to allocate %u bytes.", size
);
174 entry
->Tagid
= tagid
;
175 Sdbwcscpy(entry
->Name
, len
, str
);
180 BOOL
SdbpAddStringToTable(struct SdbStringHashTable
** table
, const WCHAR
* str
, TAGID
* tagid
)
182 struct SdbHashEntry
** entry
;
186 *table
= HashCreate();
189 SHIM_ERR("Error creating hash table\n");
194 entry
= TableFindPtr(*table
, str
);
197 *tagid
= (*entry
)->Tagid
;
200 return HashAddString(*table
, entry
, str
, *tagid
);