reshuffling of dlls
[reactos.git] / reactos / dll / win32 / user32 / misc / strpool.c
1 // strpool.c
2
3 #include <user32.h>
4
5 typedef struct tagHEAP_STRING_POOLA
6 {
7 char* data;
8 struct tagHEAP_STRING_POOLA* next;
9 } HEAP_STRING_POOLA, *PHEAP_STRING_POOLA;
10
11 typedef struct tagHEAP_STRING_POOLW
12 {
13 wchar_t* data;
14 struct tagHEAP_STRING_POOLW* next;
15 } HEAP_STRING_POOLW, *PHEAP_STRING_POOLW;
16
17 PHEAP_STRING_POOLA heap_string_Apool = NULL;
18
19 PHEAP_STRING_POOLW heap_string_Wpool = NULL;
20
21 HANDLE hProcessHeap = NULL;
22
23 PVOID
24 HEAP_alloc ( DWORD len )
25 {
26 return RtlAllocateHeap ( hProcessHeap, 0, len );
27 }
28
29 VOID
30 HEAP_free ( LPVOID memory )
31 {
32 RtlFreeHeap ( hProcessHeap, 0, memory );
33 }
34
35 LPWSTR
36 HEAP_strdupW ( LPCWSTR src, DWORD len )
37 {
38 LPWSTR dst;
39
40 if ( !src )
41 return NULL;
42
43 dst = HEAP_alloc ( (len+1) * sizeof(WCHAR) );
44 if ( !dst )
45 return NULL;
46 memcpy ( dst, src, (len+1)*sizeof(WCHAR) );
47 return dst;
48 }
49
50 NTSTATUS
51 HEAP_strcpyWtoA ( LPSTR lpszA, LPCWSTR lpszW, DWORD len )
52 {
53 NTSTATUS Status =
54 RtlUnicodeToMultiByteN ( lpszA, len, NULL, (LPWSTR)lpszW, len*sizeof(WCHAR) );
55 lpszA[len] = '\0';
56 return Status;
57 }
58
59 NTSTATUS
60 HEAP_strcpyAtoW ( LPWSTR lpszW, LPCSTR lpszA, DWORD len )
61 {
62 NTSTATUS Status =
63 RtlMultiByteToUnicodeN ( lpszW, len*sizeof(WCHAR), NULL, (LPSTR)lpszA, len );
64 lpszW[len] = L'\0';
65 return Status;
66 }
67
68 NTSTATUS
69 HEAP_strdupWtoA ( LPSTR* ppszA, LPCWSTR lpszW, DWORD len )
70 {
71 *ppszA = NULL;
72
73 if ( !lpszW )
74 return STATUS_SUCCESS;
75
76 *ppszA = HEAP_alloc ( len + 1 );
77
78 if ( !*ppszA )
79 return STATUS_NO_MEMORY;
80
81 return HEAP_strcpyWtoA ( *ppszA, lpszW, len );
82 }
83
84 NTSTATUS
85 HEAP_strdupAtoW ( LPWSTR* ppszW, LPCSTR lpszA, UINT* NewLen )
86 {
87 ULONG len;
88
89 *ppszW = NULL;
90
91 if ( !lpszA )
92 return STATUS_SUCCESS;
93
94 len = lstrlenA ( lpszA );
95
96 *ppszW = HEAP_alloc ( (len+1) * sizeof(WCHAR) );
97
98 if ( !*ppszW )
99 return STATUS_NO_MEMORY;
100
101 if ( NewLen ) *NewLen = (UINT)len;
102
103 return HEAP_strcpyAtoW ( *ppszW, lpszA, len );
104 }
105
106 char* heap_string_poolA ( const wchar_t* pstrW, DWORD length )
107 {
108 PHEAP_STRING_POOLA pPoolEntry = heap_string_Apool;
109 char* pstrA = NULL;
110 HEAP_strdupWtoA ( &pstrA, pstrW, length );
111 if ( !pstrA )
112 return NULL;
113 while ( pPoolEntry )
114 {
115 if ( !strcmp ( pPoolEntry->data, pstrA ) )
116 {
117 HEAP_free ( pstrA );
118 return pPoolEntry->data;
119 }
120 pPoolEntry = pPoolEntry->next;
121 }
122 pPoolEntry = (PHEAP_STRING_POOLA)HEAP_alloc ( sizeof(HEAP_STRING_POOLA) );
123 pPoolEntry->data = pstrA;
124
125 // IMHO, synchronization is *not* needed here. This data is process-
126 // local, so the only possible contention is among threads. If a
127 // conflict does occur, the only problem will be a small memory
128 // leak that gets cleared up when the heap is destroyed by the
129 // process exiting.
130 pPoolEntry->next = heap_string_Apool;
131 heap_string_Apool = pPoolEntry;
132 return pPoolEntry->data;
133 }
134
135 wchar_t* heap_string_poolW ( const wchar_t* pstrWSrc, DWORD length )
136 {
137 PHEAP_STRING_POOLW pPoolEntry = heap_string_Wpool;
138 wchar_t* pstrW = NULL;
139 pstrW = HEAP_strdupW ( (LPWSTR)pstrWSrc, length );
140 if ( !pstrW )
141 return NULL;
142 while ( pPoolEntry )
143 {
144 if ( !wcscmp (pPoolEntry->data, pstrW ) )
145 {
146 HEAP_free ( pstrW );
147 return pPoolEntry->data;
148 }
149 pPoolEntry = pPoolEntry->next;
150 }
151 pPoolEntry = (PHEAP_STRING_POOLW)HEAP_alloc ( sizeof(HEAP_STRING_POOLW) );
152 pPoolEntry->data = pstrW;
153
154 // IMHO, synchronization is *not* needed here. This data is process-
155 // local, so the only possible contention is among threads. If a
156 // conflict does occur, the only problem will be a small memory
157 // leak that gets cleared up when the heap is destroyed by the
158 // process exiting.
159 pPoolEntry->next = heap_string_Wpool;
160 heap_string_Wpool = pPoolEntry;
161 return pPoolEntry->data;
162 }