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 BOOL
alloc_string(UINT32 len
, HSTRING
*out
)
52 struct hstring_private
*priv
;
53 priv
= HeapAlloc(GetProcessHeap(), 0, sizeof(*priv
) + (len
+ 1) * sizeof(*priv
->buffer
));
56 priv
->buffer
= (LPWSTR
)(priv
+ 1);
58 priv
->reference
= FALSE
;
60 priv
->buffer
[len
] = '\0';
65 /***********************************************************************
66 * WindowsCreateString (combase.@)
68 HRESULT WINAPI
WindowsCreateString(LPCWSTR ptr
, UINT32 len
,
71 struct hstring_private
*priv
;
74 if (ptr
== NULL
&& len
> 0)
81 if (!alloc_string(len
, out
))
83 priv
= impl_from_HSTRING(*out
);
84 memcpy(priv
->buffer
, ptr
, len
* sizeof(*priv
->buffer
));
88 /***********************************************************************
89 * WindowsCreateStringReference (combase.@)
91 HRESULT WINAPI
WindowsCreateStringReference(LPCWSTR ptr
, UINT32 len
,
92 HSTRING_HEADER
*header
, HSTRING
*out
)
94 struct hstring_private
*priv
= impl_from_HSTRING_HEADER(header
);
95 if (out
== NULL
|| header
== NULL
)
97 if (ptr
== NULL
&& len
> 0)
106 priv
->buffer
= (LPWSTR
)ptr
;
108 priv
->reference
= TRUE
;
109 *out
= (HSTRING
)header
;
113 /***********************************************************************
114 * WindowsDeleteString (combase.@)
116 HRESULT WINAPI
WindowsDeleteString(HSTRING str
)
118 struct hstring_private
*priv
= impl_from_HSTRING(str
);
123 if (InterlockedDecrement(&priv
->refcount
) == 0)
124 HeapFree(GetProcessHeap(), 0, priv
);
128 /***********************************************************************
129 * WindowsDuplicateString (combase.@)
131 HRESULT WINAPI
WindowsDuplicateString(HSTRING str
, HSTRING
*out
)
133 struct hstring_private
*priv
= impl_from_HSTRING(str
);
142 return WindowsCreateString(priv
->buffer
, priv
->length
, out
);
143 InterlockedIncrement(&priv
->refcount
);
148 /***********************************************************************
149 * WindowsGetStringLen (combase.@)
151 UINT32 WINAPI
WindowsGetStringLen(HSTRING str
)
153 struct hstring_private
*priv
= impl_from_HSTRING(str
);
159 /***********************************************************************
160 * WindowsGetStringRawBuffer (combase.@)
162 LPCWSTR WINAPI
WindowsGetStringRawBuffer(HSTRING str
, UINT32
*len
)
164 struct hstring_private
*priv
= impl_from_HSTRING(str
);
176 /***********************************************************************
177 * WindowsStringHasEmbeddedNull (combase.@)
179 HRESULT WINAPI
WindowsStringHasEmbeddedNull(HSTRING str
, BOOL
*out
)
182 struct hstring_private
*priv
= impl_from_HSTRING(str
);
190 for (i
= 0; i
< priv
->length
; i
++)
192 if (priv
->buffer
[i
] == '\0')
202 /***********************************************************************
203 * WindowsIsStringEmpty (combase.@)
205 BOOL WINAPI
WindowsIsStringEmpty(HSTRING str
)
207 struct hstring_private
*priv
= impl_from_HSTRING(str
);
210 return priv
->length
== 0;