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
26 struct hstring_private
34 static const WCHAR empty
[1];
36 C_ASSERT(sizeof(struct hstring_private
) <= sizeof(HSTRING_HEADER
));
38 static inline struct hstring_private
*impl_from_HSTRING(HSTRING string
)
40 return (struct hstring_private
*)string
;
43 static inline struct hstring_private
*impl_from_HSTRING_HEADER(HSTRING_HEADER
*header
)
45 return (struct hstring_private
*)header
;
48 static inline struct hstring_private
*impl_from_HSTRING_BUFFER(HSTRING_BUFFER buffer
)
50 return (struct hstring_private
*)buffer
;
53 static BOOL
alloc_string(UINT32 len
, HSTRING
*out
)
55 struct hstring_private
*priv
;
56 priv
= HeapAlloc(GetProcessHeap(), 0, sizeof(*priv
) + (len
+ 1) * sizeof(*priv
->buffer
));
59 priv
->buffer
= (LPWSTR
)(priv
+ 1);
61 priv
->reference
= FALSE
;
63 priv
->buffer
[len
] = '\0';
68 /***********************************************************************
69 * WindowsCreateString (combase.@)
71 HRESULT WINAPI
WindowsCreateString(LPCWSTR ptr
, UINT32 len
,
74 struct hstring_private
*priv
;
77 if (ptr
== NULL
&& len
> 0)
84 if (!alloc_string(len
, out
))
86 priv
= impl_from_HSTRING(*out
);
87 memcpy(priv
->buffer
, ptr
, len
* sizeof(*priv
->buffer
));
91 /***********************************************************************
92 * WindowsCreateStringReference (combase.@)
94 HRESULT WINAPI
WindowsCreateStringReference(LPCWSTR ptr
, UINT32 len
,
95 HSTRING_HEADER
*header
, HSTRING
*out
)
97 struct hstring_private
*priv
= impl_from_HSTRING_HEADER(header
);
98 if (out
== NULL
|| header
== NULL
)
100 if (ptr
== NULL
&& len
> 0)
107 if (ptr
[len
] != '\0')
109 priv
->buffer
= (LPWSTR
)ptr
;
111 priv
->reference
= TRUE
;
112 *out
= (HSTRING
)header
;
116 /***********************************************************************
117 * WindowsDeleteString (combase.@)
119 HRESULT WINAPI
WindowsDeleteString(HSTRING str
)
121 struct hstring_private
*priv
= impl_from_HSTRING(str
);
126 if (InterlockedDecrement(&priv
->refcount
) == 0)
127 HeapFree(GetProcessHeap(), 0, priv
);
131 /***********************************************************************
132 * WindowsDuplicateString (combase.@)
134 HRESULT WINAPI
WindowsDuplicateString(HSTRING str
, HSTRING
*out
)
136 struct hstring_private
*priv
= impl_from_HSTRING(str
);
145 return WindowsCreateString(priv
->buffer
, priv
->length
, out
);
146 InterlockedIncrement(&priv
->refcount
);
151 /***********************************************************************
152 * WindowsPreallocateStringBuffer (combase.@)
154 HRESULT WINAPI
WindowsPreallocateStringBuffer(UINT32 len
, WCHAR
**outptr
,
157 struct hstring_private
*priv
;
159 if (outptr
== NULL
|| out
== NULL
)
163 *outptr
= (LPWSTR
)empty
;
168 if (!alloc_string(len
, &str
))
169 return E_OUTOFMEMORY
;
170 priv
= impl_from_HSTRING(str
);
171 *outptr
= priv
->buffer
;
172 *out
= (HSTRING_BUFFER
)str
;
176 /***********************************************************************
177 * WindowsDeleteStringBuffer (combase.@)
179 HRESULT WINAPI
WindowsDeleteStringBuffer(HSTRING_BUFFER buf
)
181 return WindowsDeleteString((HSTRING
)buf
);
184 /***********************************************************************
185 * WindowsPromoteStringBuffer (combase.@)
187 HRESULT WINAPI
WindowsPromoteStringBuffer(HSTRING_BUFFER buf
, HSTRING
*out
)
189 struct hstring_private
*priv
= impl_from_HSTRING_BUFFER(buf
);
197 if (priv
->buffer
[priv
->length
] != 0 || priv
->reference
|| priv
->refcount
!= 1)
203 /***********************************************************************
204 * WindowsGetStringLen (combase.@)
206 UINT32 WINAPI
WindowsGetStringLen(HSTRING str
)
208 struct hstring_private
*priv
= impl_from_HSTRING(str
);
214 /***********************************************************************
215 * WindowsGetStringRawBuffer (combase.@)
217 LPCWSTR WINAPI
WindowsGetStringRawBuffer(HSTRING str
, UINT32
*len
)
219 struct hstring_private
*priv
= impl_from_HSTRING(str
);
231 /***********************************************************************
232 * WindowsStringHasEmbeddedNull (combase.@)
234 HRESULT WINAPI
WindowsStringHasEmbeddedNull(HSTRING str
, BOOL
*out
)
237 struct hstring_private
*priv
= impl_from_HSTRING(str
);
245 for (i
= 0; i
< priv
->length
; i
++)
247 if (priv
->buffer
[i
] == '\0')
257 /***********************************************************************
258 * WindowsIsStringEmpty (combase.@)
260 BOOL WINAPI
WindowsIsStringEmpty(HSTRING str
)
262 struct hstring_private
*priv
= impl_from_HSTRING(str
);
265 return priv
->length
== 0;