ReactOS 0.4.16-dev-2320-ge1853c6
string.c
Go to the documentation of this file.
1/*
2 * Copyright 2014 Martin Storsjo
3 *
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.
8 *
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.
13 *
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
17 */
18
19#include <string.h>
20#include <wchar.h>
21
22#include "windows.h"
23#include "winerror.h"
24#include "hstring.h"
25#include "wine/debug.h"
26
28
29#define HSTRING_REFERENCE_FLAG 1
30
32{
37 const WCHAR *str;
38};
39
41{
45};
46
47static const WCHAR empty[1];
48
49C_ASSERT(sizeof(struct hstring_header) <= sizeof(HSTRING_HEADER));
50
51static inline struct hstring_private *impl_from_HSTRING(HSTRING string)
52{
53 return (struct hstring_private *)string;
54}
55
57{
59}
60
61static inline struct hstring_private *impl_from_HSTRING_BUFFER(HSTRING_BUFFER buffer)
62{
64}
65
67{
68 struct hstring_private *priv;
69 priv = malloc(offsetof(struct hstring_private, buffer[len+1]));
70 if (!priv)
71 return FALSE;
72
73 priv->header.flags = 0;
74 priv->header.length = len;
75 priv->header.str = priv->buffer;
76
77 priv->refcount = 1;
78 priv->buffer[len] = '\0';
79
80 *out = (HSTRING)priv;
81 return TRUE;
82}
83
84/***********************************************************************
85 * WindowsCreateString (combase.@)
86 */
88 HSTRING *out)
89{
90 struct hstring_private *priv;
91
92 TRACE("(%s, %u, %p)\n", debugstr_wn(ptr, len), len, out);
93
94 if (out == NULL)
95 return E_INVALIDARG;
96 if (len == 0)
97 {
98 *out = NULL;
99 return S_OK;
100 }
101 if (ptr == NULL)
102 return E_POINTER;
103 if (!alloc_string(len, out))
104 return E_OUTOFMEMORY;
105 priv = impl_from_HSTRING(*out);
106 memcpy(priv->buffer, ptr, len * sizeof(*priv->buffer));
107 return S_OK;
108}
109
110/***********************************************************************
111 * WindowsCreateStringReference (combase.@)
112 */
115{
117
118 TRACE("(%s, %u, %p, %p)\n", debugstr_wn(ptr, len), len, header, out);
119
120 if (out == NULL || header == NULL)
121 return E_INVALIDARG;
122 if (ptr != NULL && ptr[len] != '\0')
123 return E_INVALIDARG;
124 if (len == 0)
125 {
126 *out = NULL;
127 return S_OK;
128 }
129 if (ptr == NULL)
130 return E_POINTER;
131
132 priv->header.str = ptr;
133 priv->header.length = len;
134 priv->header.flags = HSTRING_REFERENCE_FLAG;
135
136 *out = (HSTRING)priv;
137 return S_OK;
138}
139
140/***********************************************************************
141 * WindowsDeleteString (combase.@)
142 */
144{
145 struct hstring_private *priv = impl_from_HSTRING(str);
146
147 TRACE("(%p)\n", str);
148
149 if (str == NULL)
150 return S_OK;
151 if (priv->header.flags & HSTRING_REFERENCE_FLAG)
152 return S_OK;
153 if (InterlockedDecrement(&priv->refcount) == 0)
154 free(priv);
155 return S_OK;
156}
157
158/***********************************************************************
159 * WindowsDuplicateString (combase.@)
160 */
162{
163 struct hstring_private *priv = impl_from_HSTRING(str);
164
165 TRACE("(%p, %p)\n", str, out);
166
167 if (out == NULL)
168 return E_INVALIDARG;
169 if (str == NULL)
170 {
171 *out = NULL;
172 return S_OK;
173 }
174 if (priv->header.flags & HSTRING_REFERENCE_FLAG)
175 return WindowsCreateString(priv->header.str, priv->header.length, out);
177 *out = str;
178 return S_OK;
179}
180
181/***********************************************************************
182 * WindowsPreallocateStringBuffer (combase.@)
183 */
185 HSTRING_BUFFER *out)
186{
187 struct hstring_private *priv;
188 HSTRING str;
189
190 TRACE("(%u, %p, %p)\n", len, outptr, out);
191
192 if (outptr == NULL || out == NULL)
193 return E_POINTER;
194 if (len == 0)
195 {
196 *outptr = (LPWSTR)empty;
197 *out = NULL;
198 return S_OK;
199 }
200
201 if (!alloc_string(len, &str))
202 return E_OUTOFMEMORY;
203 priv = impl_from_HSTRING(str);
204 *outptr = priv->buffer;
205 *out = (HSTRING_BUFFER)&priv->buffer;
206 return S_OK;
207}
208
209/***********************************************************************
210 * WindowsDeleteStringBuffer (combase.@)
211 */
213{
214 struct hstring_private *priv = NULL;
215
216 TRACE("(%p)\n", buf);
217
218 if(buf)
220
221 return WindowsDeleteString((HSTRING)priv);
222}
223
224/***********************************************************************
225 * WindowsPromoteStringBuffer (combase.@)
226 */
228{
230
231 TRACE("(%p, %p)\n", buf, out);
232
233 if (out == NULL)
234 return E_POINTER;
235 if (buf == NULL)
236 {
237 *out = NULL;
238 return S_OK;
239 }
240 if (priv->buffer[priv->header.length] != 0 || priv->header.flags & HSTRING_REFERENCE_FLAG || priv->refcount != 1)
241 return E_INVALIDARG;
242 *out = (HSTRING)priv;
243 return S_OK;
244}
245
246/***********************************************************************
247 * WindowsGetStringLen (combase.@)
248 */
250{
251 struct hstring_private *priv = impl_from_HSTRING(str);
252
253 TRACE("(%p)\n", str);
254
255 if (str == NULL)
256 return 0;
257 return priv->header.length;
258}
259
260/***********************************************************************
261 * WindowsGetStringRawBuffer (combase.@)
262 */
264{
265 struct hstring_private *priv = impl_from_HSTRING(str);
266
267 TRACE("(%p, %p)\n", str, len);
268
269 if (str == NULL)
270 {
271 if (len)
272 *len = 0;
273 return empty;
274 }
275 if (len)
276 *len = priv->header.length;
277 return priv->header.str;
278}
279
280/***********************************************************************
281 * WindowsStringHasEmbeddedNull (combase.@)
282 */
284{
285 UINT32 i;
286 struct hstring_private *priv = impl_from_HSTRING(str);
287
288 TRACE("(%p, %p)\n", str, out);
289
290 if (out == NULL)
291 return E_INVALIDARG;
292 if (str == NULL)
293 {
294 *out = FALSE;
295 return S_OK;
296 }
297 for (i = 0; i < priv->header.length; i++)
298 {
299 if (priv->header.str[i] == '\0')
300 {
301 *out = TRUE;
302 return S_OK;
303 }
304 }
305 *out = FALSE;
306 return S_OK;
307}
308
309/***********************************************************************
310 * WindowsSubstring (combase.@)
311 */
313{
314 struct hstring_private *priv = impl_from_HSTRING(str);
316
317 TRACE("(%p, %u, %p)\n", str, start, out);
318
319 if (out == NULL)
320 return E_INVALIDARG;
321 if (start > len)
322 return E_BOUNDS;
323 if (start == len)
324 {
325 *out = NULL;
326 return S_OK;
327 }
328 return WindowsCreateString(&priv->header.str[start], len - start, out);
329}
330
331/***********************************************************************
332 * WindowsSubstringWithSpecifiedLength (combase.@)
333 */
335{
336 struct hstring_private *priv = impl_from_HSTRING(str);
337
338 TRACE("(%p, %u, %u, %p)\n", str, start, len, out);
339
340 if (out == NULL)
341 return E_INVALIDARG;
342 if (start + len < start ||
344 return E_BOUNDS;
345 if (len == 0)
346 {
347 *out = NULL;
348 return S_OK;
349 }
350 return WindowsCreateString(&priv->header.str[start], len, out);
351}
352
353/***********************************************************************
354 * WindowsConcatString (combase.@)
355 */
357{
358 struct hstring_private *priv1 = impl_from_HSTRING(str1);
359 struct hstring_private *priv2 = impl_from_HSTRING(str2);
360 struct hstring_private *priv;
361
362 TRACE("(%p, %p, %p)\n", str1, str2, out);
363
364 if (out == NULL)
365 return E_INVALIDARG;
366 if (str1 == NULL)
368 if (str2 == NULL)
370 if (!priv1->header.length && !priv2->header.length)
371 {
372 *out = NULL;
373 return S_OK;
374 }
375 if (!alloc_string(priv1->header.length + priv2->header.length, out))
376 return E_OUTOFMEMORY;
377 priv = impl_from_HSTRING(*out);
378 memcpy(priv->buffer, priv1->header.str, priv1->header.length * sizeof(*priv1->buffer));
379 memcpy(priv->buffer + priv1->header.length, priv2->header.str, priv2->header.length * sizeof(*priv2->buffer));
380 return S_OK;
381}
382
383/***********************************************************************
384 * WindowsIsStringEmpty (combase.@)
385 */
387{
388 struct hstring_private *priv = impl_from_HSTRING(str);
389
390 TRACE("(%p)\n", str);
391
392 if (str == NULL)
393 return TRUE;
394 return priv->header.length == 0;
395}
396
397/***********************************************************************
398 * WindowsCompareStringOrdinal (combase.@)
399 */
401{
402 struct hstring_private *priv1 = impl_from_HSTRING(str1);
403 struct hstring_private *priv2 = impl_from_HSTRING(str2);
404 const WCHAR *buf1 = empty, *buf2 = empty;
405 UINT32 len1 = 0, len2 = 0;
406
407 TRACE("(%p, %p, %p)\n", str1, str2, res);
408
409 if (res == NULL)
410 return E_INVALIDARG;
411 if (str1 == str2)
412 {
413 *res = 0;
414 return S_OK;
415 }
416 if (str1)
417 {
418 buf1 = priv1->header.str;
419 len1 = priv1->header.length;
420 }
421 if (str2)
422 {
423 buf2 = priv2->header.str;
424 len2 = priv2->header.length;
425 }
426 *res = CompareStringOrdinal(buf1, len1, buf2, len2, FALSE) - CSTR_EQUAL;
427 return S_OK;
428}
429
430/***********************************************************************
431 * WindowsTrimStringStart (combase.@)
432 */
434{
435 struct hstring_private *priv1 = impl_from_HSTRING(str1);
436 struct hstring_private *priv2 = impl_from_HSTRING(str2);
438
439 TRACE("(%p, %p, %p)\n", str1, str2, out);
440
441 if (!out || !str2 || !priv2->header.length)
442 return E_INVALIDARG;
443 if (!str1)
444 {
445 *out = NULL;
446 return S_OK;
447 }
448 for (start = 0; start < priv1->header.length; start++)
449 {
450 if (!wmemchr(priv2->header.str, priv1->header.str[start], priv2->header.length))
451 break;
452 }
453 return start ? WindowsCreateString(&priv1->header.str[start], priv1->header.length - start, out) :
455}
456
457/***********************************************************************
458 * WindowsTrimStringEnd (combase.@)
459 */
461{
462 struct hstring_private *priv1 = impl_from_HSTRING(str1);
463 struct hstring_private *priv2 = impl_from_HSTRING(str2);
464 UINT32 len;
465
466 TRACE("(%p, %p, %p)\n", str1, str2, out);
467
468 if (!out || !str2 || !priv2->header.length)
469 return E_INVALIDARG;
470 if (!str1)
471 {
472 *out = NULL;
473 return S_OK;
474 }
475 for (len = priv1->header.length; len > 0; len--)
476 {
477 if (!wmemchr(priv2->header.str, priv1->header.str[len - 1], priv2->header.length))
478 break;
479 }
480 return (len < priv1->header.length) ? WindowsCreateString(priv1->header.str, len, out) :
482}
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
HRESULT WINAPI WindowsDeleteStringBuffer(HSTRING_BUFFER buf)
Definition: string.c:212
UINT32 WINAPI WindowsGetStringLen(HSTRING str)
Definition: string.c:249
HRESULT WINAPI WindowsCreateString(LPCWSTR ptr, UINT32 len, HSTRING *out)
Definition: string.c:87
static struct hstring_private * impl_from_HSTRING_HEADER(HSTRING_HEADER *header)
Definition: string.c:56
LPCWSTR WINAPI WindowsGetStringRawBuffer(HSTRING str, UINT32 *len)
Definition: string.c:263
HRESULT WINAPI WindowsConcatString(HSTRING str1, HSTRING str2, HSTRING *out)
Definition: string.c:356
HRESULT WINAPI WindowsCompareStringOrdinal(HSTRING str1, HSTRING str2, INT32 *res)
Definition: string.c:400
HRESULT WINAPI WindowsSubstringWithSpecifiedLength(HSTRING str, UINT32 start, UINT32 len, HSTRING *out)
Definition: string.c:334
static struct hstring_private * impl_from_HSTRING(HSTRING string)
Definition: string.c:51
HRESULT WINAPI WindowsDeleteString(HSTRING str)
Definition: string.c:143
HRESULT WINAPI WindowsTrimStringStart(HSTRING str1, HSTRING str2, HSTRING *out)
Definition: string.c:433
HRESULT WINAPI WindowsSubstring(HSTRING str, UINT32 start, HSTRING *out)
Definition: string.c:312
static const WCHAR empty[1]
Definition: string.c:47
HRESULT WINAPI WindowsDuplicateString(HSTRING str, HSTRING *out)
Definition: string.c:161
HRESULT WINAPI WindowsTrimStringEnd(HSTRING str1, HSTRING str2, HSTRING *out)
Definition: string.c:460
HRESULT WINAPI WindowsPromoteStringBuffer(HSTRING_BUFFER buf, HSTRING *out)
Definition: string.c:227
HRESULT WINAPI WindowsStringHasEmbeddedNull(HSTRING str, BOOL *out)
Definition: string.c:283
HRESULT WINAPI WindowsPreallocateStringBuffer(UINT32 len, WCHAR **outptr, HSTRING_BUFFER *out)
Definition: string.c:184
HRESULT WINAPI WindowsCreateStringReference(LPCWSTR ptr, UINT32 len, HSTRING_HEADER *header, HSTRING *out)
Definition: string.c:113
#define HSTRING_REFERENCE_FLAG
Definition: string.c:29
static struct hstring_private * impl_from_HSTRING_BUFFER(HSTRING_BUFFER buffer)
Definition: string.c:61
BOOL WINAPI WindowsIsStringEmpty(HSTRING str)
Definition: string.c:386
static BOOL alloc_string(UINT32 len, HSTRING *out)
Definition: string.c:66
static wchar_t * wmemchr(const wchar_t *s, wchar_t c, size_t n)
Definition: wchar.h:48
unsigned int BOOL
Definition: ntddk_ex.h:94
GLuint start
Definition: gl.h:1545
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
HSTRING__ * HSTRING
Definition: hstring.idl:26
#define S_OK
Definition: intsafe.h:52
#define C_ASSERT(e)
Definition: intsafe.h:73
INT WINAPI CompareStringOrdinal(const WCHAR *str1, INT len1, const WCHAR *str2, INT len2, BOOL ignore_case)
Definition: vista.c:749
#define debugstr_wn
Definition: kernel32.h:33
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
char string[160]
Definition: util.h:11
static PVOID ptr
Definition: dispmode.c:27
long LONG
Definition: pedump.c:60
const WCHAR * str
#define offsetof(TYPE, MEMBER)
XML_HIDDEN void xmlParserErrors const char const xmlChar const xmlChar * str2
Definition: parser.h:35
XML_HIDDEN void xmlParserErrors const char const xmlChar * str1
Definition: parser.h:35
#define TRACE(s)
Definition: solgame.cpp:4
UINT32 padding1
Definition: string.c:35
const WCHAR * str
Definition: string.c:37
UINT32 padding2
Definition: string.c:36
UINT32 length
Definition: string.c:34
UINT32 flags
Definition: string.c:33
WCHAR buffer[1]
Definition: string.c:44
struct hstring_header header
Definition: string.c:42
LONG refcount
Definition: string.c:43
int32_t INT32
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t UINT32
Definition: typedefs.h:59
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
#define WINAPI
Definition: msvc.h:6
#define E_BOUNDS
Definition: winerror.h:3454
#define E_POINTER
Definition: winerror.h:3480
#define CSTR_EQUAL
Definition: winnls.h:500
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184