2 * Copyright 2014 Martin Storsjo
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
24 #include "wine/debug.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(combase
);
28 struct hstring_private
36 static const WCHAR empty
[1];
38 C_ASSERT(sizeof(struct hstring_private
) <= sizeof(HSTRING_HEADER
));
40 static inline struct hstring_private
*impl_from_HSTRING(HSTRING string
)
42 return (struct hstring_private
*)string
;
45 static inline struct hstring_private
*impl_from_HSTRING_HEADER(HSTRING_HEADER
*header
)
47 return (struct hstring_private
*)header
;
50 static inline struct hstring_private
*impl_from_HSTRING_BUFFER(HSTRING_BUFFER buffer
)
52 return (struct hstring_private
*)buffer
;
55 static BOOL
alloc_string(UINT32 len
, HSTRING
*out
)
57 struct hstring_private
*priv
;
58 priv
= HeapAlloc(GetProcessHeap(), 0, sizeof(*priv
) + (len
+ 1) * sizeof(*priv
->buffer
));
61 priv
->buffer
= (LPWSTR
)(priv
+ 1);
63 priv
->reference
= FALSE
;
65 priv
->buffer
[len
] = '\0';
70 /***********************************************************************
71 * WindowsCreateString (combase.@)
73 HRESULT WINAPI
WindowsCreateString(LPCWSTR ptr
, UINT32 len
,
76 struct hstring_private
*priv
;
79 if (ptr
== NULL
&& len
> 0)
86 if (!alloc_string(len
, out
))
88 priv
= impl_from_HSTRING(*out
);
89 memcpy(priv
->buffer
, ptr
, len
* sizeof(*priv
->buffer
));
93 /***********************************************************************
94 * WindowsCreateStringReference (combase.@)
96 HRESULT WINAPI
WindowsCreateStringReference(LPCWSTR ptr
, UINT32 len
,
97 HSTRING_HEADER
*header
, HSTRING
*out
)
99 struct hstring_private
*priv
= impl_from_HSTRING_HEADER(header
);
100 if (out
== NULL
|| header
== NULL
)
102 if (ptr
== NULL
&& len
> 0)
104 if (ptr
[len
] != '\0')
111 priv
->buffer
= (LPWSTR
)ptr
;
113 priv
->reference
= TRUE
;
114 *out
= (HSTRING
)header
;
118 /***********************************************************************
119 * WindowsDeleteString (combase.@)
121 HRESULT WINAPI
WindowsDeleteString(HSTRING str
)
123 struct hstring_private
*priv
= impl_from_HSTRING(str
);
128 if (InterlockedDecrement(&priv
->refcount
) == 0)
129 HeapFree(GetProcessHeap(), 0, priv
);
133 /***********************************************************************
134 * WindowsDuplicateString (combase.@)
136 HRESULT WINAPI
WindowsDuplicateString(HSTRING str
, HSTRING
*out
)
138 struct hstring_private
*priv
= impl_from_HSTRING(str
);
147 return WindowsCreateString(priv
->buffer
, priv
->length
, out
);
148 InterlockedIncrement(&priv
->refcount
);
153 /***********************************************************************
154 * WindowsPreallocateStringBuffer (combase.@)
156 HRESULT WINAPI
WindowsPreallocateStringBuffer(UINT32 len
, WCHAR
**outptr
,
159 struct hstring_private
*priv
;
161 if (outptr
== NULL
|| out
== NULL
)
165 *outptr
= (LPWSTR
)empty
;
170 if (!alloc_string(len
, &str
))
171 return E_OUTOFMEMORY
;
172 priv
= impl_from_HSTRING(str
);
173 *outptr
= priv
->buffer
;
174 *out
= (HSTRING_BUFFER
)str
;
178 /***********************************************************************
179 * WindowsDeleteStringBuffer (combase.@)
181 HRESULT WINAPI
WindowsDeleteStringBuffer(HSTRING_BUFFER buf
)
183 return WindowsDeleteString((HSTRING
)buf
);
186 /***********************************************************************
187 * WindowsPromoteStringBuffer (combase.@)
189 HRESULT WINAPI
WindowsPromoteStringBuffer(HSTRING_BUFFER buf
, HSTRING
*out
)
191 struct hstring_private
*priv
= impl_from_HSTRING_BUFFER(buf
);
199 if (priv
->buffer
[priv
->length
] != 0 || priv
->reference
|| priv
->refcount
!= 1)
205 /***********************************************************************
206 * WindowsGetStringLen (combase.@)
208 UINT32 WINAPI
WindowsGetStringLen(HSTRING str
)
210 struct hstring_private
*priv
= impl_from_HSTRING(str
);
216 /***********************************************************************
217 * WindowsGetStringRawBuffer (combase.@)
219 LPCWSTR WINAPI
WindowsGetStringRawBuffer(HSTRING str
, UINT32
*len
)
221 struct hstring_private
*priv
= impl_from_HSTRING(str
);
233 /***********************************************************************
234 * WindowsStringHasEmbeddedNull (combase.@)
236 HRESULT WINAPI
WindowsStringHasEmbeddedNull(HSTRING str
, BOOL
*out
)
239 struct hstring_private
*priv
= impl_from_HSTRING(str
);
247 for (i
= 0; i
< priv
->length
; i
++)
249 if (priv
->buffer
[i
] == '\0')
259 /***********************************************************************
260 * WindowsIsStringEmpty (combase.@)
262 BOOL WINAPI
WindowsIsStringEmpty(HSTRING str
)
264 struct hstring_private
*priv
= impl_from_HSTRING(str
);
267 return priv
->length
== 0;