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) */
28 #endif /* !defined(SDBWRITE_HOSTTOOL) */
30 #include "sdbstringtable.h"
32 #define DEFAULT_TABLE_SIZE 0x100
34 typedef struct SdbHashEntry
36 struct SdbHashEntry
* Next
;
41 struct SdbStringHashTable
44 struct SdbHashEntry
** Entries
;
48 static struct SdbStringHashTable
* HashCreate(void)
50 struct SdbStringHashTable
* tab
= SdbAlloc(sizeof(*tab
));
53 SHIM_ERR("Failed to allocate 8 bytes.\r\n");
56 tab
->Size
= DEFAULT_TABLE_SIZE
;
57 tab
->Entries
= SdbAlloc(tab
->Size
* sizeof(*tab
->Entries
));
62 void SdbpTableDestroy(struct SdbStringHashTable
** pTable
)
64 struct SdbStringHashTable
* table
= *pTable
;
65 struct SdbHashEntry
* entry
, *next
;
66 DWORD n
, depth
= 0, once
= 1;
69 for (n
= 0; n
< table
->Size
; ++n
)
72 entry
= next
= table
->Entries
[n
];
80 if (once
&& depth
> 3)
86 SdbFree(table
->Entries
);
90 /* Based on RtlHashUnicodeString */
91 static DWORD
StringHash(const WCHAR
* str
)
96 hash
= ((65599 * hash
) + (ULONG
)(*str
));
101 static struct SdbHashEntry
** TableFindPtr(struct SdbStringHashTable
* table
, const WCHAR
* str
)
103 DWORD hash
= StringHash(str
);
104 struct SdbHashEntry
** entry
= &table
->Entries
[hash
% table
->Size
];
107 if (!wcscmp((*entry
)->Name
, str
))
109 entry
= &(*entry
)->Next
;
114 static BOOL
HashAddString(struct SdbStringHashTable
* table
, struct SdbHashEntry
** position
, const WCHAR
* str
, TAGID tagid
)
116 struct SdbHashEntry
* entry
;
120 position
= TableFindPtr(table
, str
);
122 size
= offsetof(struct SdbHashEntry
, Name
[SdbpStrlen(str
) + 2]);
123 entry
= (*position
) = SdbAlloc(size
);
126 SHIM_ERR("Failed to allocate %u bytes.", size
);
129 entry
->Tagid
= tagid
;
130 wcscpy(entry
->Name
, str
);
135 BOOL
SdbpAddStringToTable(struct SdbStringHashTable
** table
, const WCHAR
* str
, TAGID
* tagid
)
137 struct SdbHashEntry
** entry
;
141 *table
= HashCreate();
144 SHIM_ERR("Error creating hash table\n");
149 entry
= TableFindPtr(*table
, str
);
152 *tagid
= (*entry
)->Tagid
;
155 return HashAddString(*table
, entry
, str
, *tagid
);