5 typedef struct tagHEAP_STRING_POOLA
8 struct tagHEAP_STRING_POOLA
* next
;
9 } HEAP_STRING_POOLA
, *PHEAP_STRING_POOLA
;
11 typedef struct tagHEAP_STRING_POOLW
14 struct tagHEAP_STRING_POOLW
* next
;
15 } HEAP_STRING_POOLW
, *PHEAP_STRING_POOLW
;
17 PHEAP_STRING_POOLA heap_string_Apool
= NULL
;
19 PHEAP_STRING_POOLW heap_string_Wpool
= NULL
;
21 HANDLE hProcessHeap
= NULL
;
24 HEAP_alloc ( DWORD len
)
26 return RtlAllocateHeap ( hProcessHeap
, 0, len
);
30 HEAP_free ( LPVOID memory
)
32 RtlFreeHeap ( hProcessHeap
, 0, memory
);
36 HEAP_strdupW ( LPCWSTR src
, DWORD len
)
43 dst
= HEAP_alloc ( (len
+1) * sizeof(WCHAR
) );
46 memcpy ( dst
, src
, (len
+1)*sizeof(WCHAR
) );
51 HEAP_strcpyWtoA ( LPSTR lpszA
, LPCWSTR lpszW
, DWORD len
)
54 RtlUnicodeToMultiByteN ( lpszA
, len
, NULL
, (LPWSTR
)lpszW
, len
*sizeof(WCHAR
) );
60 HEAP_strcpyAtoW ( LPWSTR lpszW
, LPCSTR lpszA
, DWORD len
)
63 RtlMultiByteToUnicodeN ( lpszW
, len
*sizeof(WCHAR
), NULL
, (LPSTR
)lpszA
, len
);
69 HEAP_strdupWtoA ( LPSTR
* ppszA
, LPCWSTR lpszW
, DWORD len
)
74 return STATUS_SUCCESS
;
76 *ppszA
= HEAP_alloc ( len
+ 1 );
79 return STATUS_NO_MEMORY
;
81 return HEAP_strcpyWtoA ( *ppszA
, lpszW
, len
);
85 HEAP_strdupAtoW ( LPWSTR
* ppszW
, LPCSTR lpszA
, UINT
* NewLen
)
92 return STATUS_SUCCESS
;
94 len
= lstrlenA ( lpszA
);
96 *ppszW
= HEAP_alloc ( (len
+1) * sizeof(WCHAR
) );
99 return STATUS_NO_MEMORY
;
101 if ( NewLen
) *NewLen
= (UINT
)len
;
103 return HEAP_strcpyAtoW ( *ppszW
, lpszA
, len
);
106 char* heap_string_poolA ( const wchar_t* pstrW
, DWORD length
)
108 PHEAP_STRING_POOLA pPoolEntry
= heap_string_Apool
;
110 HEAP_strdupWtoA ( &pstrA
, pstrW
, length
);
115 if ( !strcmp ( pPoolEntry
->data
, pstrA
) )
118 return pPoolEntry
->data
;
120 pPoolEntry
= pPoolEntry
->next
;
122 pPoolEntry
= (PHEAP_STRING_POOLA
)HEAP_alloc ( sizeof(HEAP_STRING_POOLA
) );
123 pPoolEntry
->data
= pstrA
;
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
130 pPoolEntry
->next
= heap_string_Apool
;
131 heap_string_Apool
= pPoolEntry
;
132 return pPoolEntry
->data
;
135 wchar_t* heap_string_poolW ( const wchar_t* pstrWSrc
, DWORD length
)
137 PHEAP_STRING_POOLW pPoolEntry
= heap_string_Wpool
;
138 wchar_t* pstrW
= NULL
;
139 pstrW
= HEAP_strdupW ( (LPWSTR
)pstrWSrc
, length
);
144 if ( !wcscmp (pPoolEntry
->data
, pstrW
) )
147 return pPoolEntry
->data
;
149 pPoolEntry
= pPoolEntry
->next
;
151 pPoolEntry
= (PHEAP_STRING_POOLW
)HEAP_alloc ( sizeof(HEAP_STRING_POOLW
) );
152 pPoolEntry
->data
= pstrW
;
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
159 pPoolEntry
->next
= heap_string_Wpool
;
160 heap_string_Wpool
= pPoolEntry
;
161 return pPoolEntry
->data
;