|
1 /* vim:set ts=2 sw=2 et cindent: */ |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 #include "nsString.h" |
|
7 #include "nsCharTraits.h" |
|
8 |
|
9 #include "nsXPCOMStrings.h" |
|
10 #include "nsNativeCharsetUtils.h" |
|
11 |
|
12 /* ------------------------------------------------------------------------- */ |
|
13 |
|
14 XPCOM_API(nsresult) |
|
15 NS_StringContainerInit(nsStringContainer &aContainer) |
|
16 { |
|
17 NS_ASSERTION(sizeof(nsStringContainer_base) >= sizeof(nsString), |
|
18 "nsStringContainer is not large enough"); |
|
19 |
|
20 // use placement new to avoid heap allocating nsString object |
|
21 new (&aContainer) nsString(); |
|
22 |
|
23 return NS_OK; |
|
24 } |
|
25 |
|
26 XPCOM_API(nsresult) |
|
27 NS_StringContainerInit2(nsStringContainer &aContainer, |
|
28 const char16_t *aData, |
|
29 uint32_t aDataLength, |
|
30 uint32_t aFlags) |
|
31 { |
|
32 NS_ASSERTION(sizeof(nsStringContainer_base) >= sizeof(nsString), |
|
33 "nsStringContainer is not large enough"); |
|
34 |
|
35 if (!aData) |
|
36 { |
|
37 new (&aContainer) nsString(); |
|
38 } |
|
39 else |
|
40 { |
|
41 if (aDataLength == UINT32_MAX) |
|
42 { |
|
43 if (NS_WARN_IF(aFlags & NS_STRING_CONTAINER_INIT_SUBSTRING)) |
|
44 return NS_ERROR_INVALID_ARG; |
|
45 aDataLength = nsCharTraits<char16_t>::length(aData); |
|
46 } |
|
47 |
|
48 if (aFlags & (NS_STRING_CONTAINER_INIT_DEPEND | |
|
49 NS_STRING_CONTAINER_INIT_ADOPT)) |
|
50 { |
|
51 uint32_t flags; |
|
52 if (aFlags & NS_STRING_CONTAINER_INIT_SUBSTRING) |
|
53 flags = nsSubstring::F_NONE; |
|
54 else |
|
55 flags = nsSubstring::F_TERMINATED; |
|
56 |
|
57 if (aFlags & NS_STRING_CONTAINER_INIT_ADOPT) |
|
58 flags |= nsSubstring::F_OWNED; |
|
59 |
|
60 new (&aContainer) nsSubstring(const_cast<char16_t *>(aData), |
|
61 aDataLength, flags); |
|
62 } |
|
63 else |
|
64 { |
|
65 new (&aContainer) nsString(aData, aDataLength); |
|
66 } |
|
67 } |
|
68 |
|
69 return NS_OK; |
|
70 } |
|
71 |
|
72 XPCOM_API(void) |
|
73 NS_StringContainerFinish(nsStringContainer &aContainer) |
|
74 { |
|
75 // call the nsString dtor |
|
76 reinterpret_cast<nsString *>(&aContainer)->~nsString(); |
|
77 } |
|
78 |
|
79 /* ------------------------------------------------------------------------- */ |
|
80 |
|
81 XPCOM_API(uint32_t) |
|
82 NS_StringGetData(const nsAString &aStr, const char16_t **aData, |
|
83 bool *aTerminated) |
|
84 { |
|
85 if (aTerminated) |
|
86 *aTerminated = aStr.IsTerminated(); |
|
87 |
|
88 nsAString::const_iterator begin; |
|
89 aStr.BeginReading(begin); |
|
90 *aData = begin.get(); |
|
91 return begin.size_forward(); |
|
92 } |
|
93 |
|
94 XPCOM_API(uint32_t) |
|
95 NS_StringGetMutableData(nsAString &aStr, uint32_t aDataLength, |
|
96 char16_t **aData) |
|
97 { |
|
98 if (aDataLength != UINT32_MAX) { |
|
99 aStr.SetLength(aDataLength); |
|
100 if (aStr.Length() != aDataLength) { |
|
101 *aData = nullptr; |
|
102 return 0; |
|
103 } |
|
104 } |
|
105 |
|
106 nsAString::iterator begin; |
|
107 aStr.BeginWriting(begin); |
|
108 *aData = begin.get(); |
|
109 return begin.size_forward(); |
|
110 } |
|
111 |
|
112 XPCOM_API(char16_t *) |
|
113 NS_StringCloneData(const nsAString &aStr) |
|
114 { |
|
115 return ToNewUnicode(aStr); |
|
116 } |
|
117 |
|
118 XPCOM_API(nsresult) |
|
119 NS_StringSetData(nsAString &aStr, const char16_t *aData, uint32_t aDataLength) |
|
120 { |
|
121 aStr.Assign(aData, aDataLength); |
|
122 return NS_OK; // XXX report errors |
|
123 } |
|
124 |
|
125 XPCOM_API(nsresult) |
|
126 NS_StringSetDataRange(nsAString &aStr, |
|
127 uint32_t aCutOffset, uint32_t aCutLength, |
|
128 const char16_t *aData, uint32_t aDataLength) |
|
129 { |
|
130 if (aCutOffset == UINT32_MAX) |
|
131 { |
|
132 // append case |
|
133 if (aData) |
|
134 aStr.Append(aData, aDataLength); |
|
135 return NS_OK; // XXX report errors |
|
136 } |
|
137 |
|
138 if (aCutLength == UINT32_MAX) |
|
139 aCutLength = aStr.Length() - aCutOffset; |
|
140 |
|
141 if (aData) |
|
142 { |
|
143 if (aDataLength == UINT32_MAX) |
|
144 aStr.Replace(aCutOffset, aCutLength, nsDependentString(aData)); |
|
145 else |
|
146 aStr.Replace(aCutOffset, aCutLength, Substring(aData, aDataLength)); |
|
147 } |
|
148 else |
|
149 aStr.Cut(aCutOffset, aCutLength); |
|
150 |
|
151 return NS_OK; // XXX report errors |
|
152 } |
|
153 |
|
154 XPCOM_API(nsresult) |
|
155 NS_StringCopy(nsAString &aDest, const nsAString &aSrc) |
|
156 { |
|
157 aDest.Assign(aSrc); |
|
158 return NS_OK; // XXX report errors |
|
159 } |
|
160 |
|
161 XPCOM_API(void) |
|
162 NS_StringSetIsVoid(nsAString &aStr, const bool aIsVoid) |
|
163 { |
|
164 aStr.SetIsVoid(aIsVoid); |
|
165 } |
|
166 |
|
167 XPCOM_API(bool) |
|
168 NS_StringGetIsVoid(const nsAString &aStr) |
|
169 { |
|
170 return aStr.IsVoid(); |
|
171 } |
|
172 |
|
173 /* ------------------------------------------------------------------------- */ |
|
174 |
|
175 XPCOM_API(nsresult) |
|
176 NS_CStringContainerInit(nsCStringContainer &aContainer) |
|
177 { |
|
178 NS_ASSERTION(sizeof(nsStringContainer_base) >= sizeof(nsCString), |
|
179 "nsCStringContainer is not large enough"); |
|
180 |
|
181 // use placement new to avoid heap allocating nsCString object |
|
182 new (&aContainer) nsCString(); |
|
183 |
|
184 return NS_OK; |
|
185 } |
|
186 |
|
187 XPCOM_API(nsresult) |
|
188 NS_CStringContainerInit2(nsCStringContainer &aContainer, |
|
189 const char *aData, |
|
190 uint32_t aDataLength, |
|
191 uint32_t aFlags) |
|
192 { |
|
193 NS_ASSERTION(sizeof(nsStringContainer_base) >= sizeof(nsCString), |
|
194 "nsStringContainer is not large enough"); |
|
195 |
|
196 if (!aData) |
|
197 { |
|
198 new (&aContainer) nsCString(); |
|
199 } |
|
200 else |
|
201 { |
|
202 if (aDataLength == UINT32_MAX) |
|
203 { |
|
204 if (NS_WARN_IF(aFlags & NS_CSTRING_CONTAINER_INIT_SUBSTRING)) |
|
205 return NS_ERROR_INVALID_ARG; |
|
206 aDataLength = nsCharTraits<char>::length(aData); |
|
207 } |
|
208 |
|
209 if (aFlags & (NS_CSTRING_CONTAINER_INIT_DEPEND | |
|
210 NS_CSTRING_CONTAINER_INIT_ADOPT)) |
|
211 { |
|
212 uint32_t flags; |
|
213 if (aFlags & NS_CSTRING_CONTAINER_INIT_SUBSTRING) |
|
214 flags = nsCSubstring::F_NONE; |
|
215 else |
|
216 flags = nsCSubstring::F_TERMINATED; |
|
217 |
|
218 if (aFlags & NS_CSTRING_CONTAINER_INIT_ADOPT) |
|
219 flags |= nsCSubstring::F_OWNED; |
|
220 |
|
221 new (&aContainer) nsCSubstring(const_cast<char *>(aData), |
|
222 aDataLength, flags); |
|
223 } |
|
224 else |
|
225 { |
|
226 new (&aContainer) nsCString(aData, aDataLength); |
|
227 } |
|
228 } |
|
229 |
|
230 return NS_OK; |
|
231 } |
|
232 |
|
233 XPCOM_API(void) |
|
234 NS_CStringContainerFinish(nsCStringContainer &aContainer) |
|
235 { |
|
236 // call the nsCString dtor |
|
237 reinterpret_cast<nsCString *>(&aContainer)->~nsCString(); |
|
238 } |
|
239 |
|
240 /* ------------------------------------------------------------------------- */ |
|
241 |
|
242 XPCOM_API(uint32_t) |
|
243 NS_CStringGetData(const nsACString &aStr, const char **aData, |
|
244 bool *aTerminated) |
|
245 { |
|
246 if (aTerminated) |
|
247 *aTerminated = aStr.IsTerminated(); |
|
248 |
|
249 nsACString::const_iterator begin; |
|
250 aStr.BeginReading(begin); |
|
251 *aData = begin.get(); |
|
252 return begin.size_forward(); |
|
253 } |
|
254 |
|
255 XPCOM_API(uint32_t) |
|
256 NS_CStringGetMutableData(nsACString &aStr, uint32_t aDataLength, char **aData) |
|
257 { |
|
258 if (aDataLength != UINT32_MAX) { |
|
259 aStr.SetLength(aDataLength); |
|
260 if (aStr.Length() != aDataLength) { |
|
261 *aData = nullptr; |
|
262 return 0; |
|
263 } |
|
264 } |
|
265 |
|
266 nsACString::iterator begin; |
|
267 aStr.BeginWriting(begin); |
|
268 *aData = begin.get(); |
|
269 return begin.size_forward(); |
|
270 } |
|
271 |
|
272 XPCOM_API(char *) |
|
273 NS_CStringCloneData(const nsACString &aStr) |
|
274 { |
|
275 return ToNewCString(aStr); |
|
276 } |
|
277 |
|
278 XPCOM_API(nsresult) |
|
279 NS_CStringSetData(nsACString &aStr, const char *aData, uint32_t aDataLength) |
|
280 { |
|
281 aStr.Assign(aData, aDataLength); |
|
282 return NS_OK; // XXX report errors |
|
283 } |
|
284 |
|
285 XPCOM_API(nsresult) |
|
286 NS_CStringSetDataRange(nsACString &aStr, |
|
287 uint32_t aCutOffset, uint32_t aCutLength, |
|
288 const char *aData, uint32_t aDataLength) |
|
289 { |
|
290 if (aCutOffset == UINT32_MAX) |
|
291 { |
|
292 // append case |
|
293 if (aData) |
|
294 aStr.Append(aData, aDataLength); |
|
295 return NS_OK; // XXX report errors |
|
296 } |
|
297 |
|
298 if (aCutLength == UINT32_MAX) |
|
299 aCutLength = aStr.Length() - aCutOffset; |
|
300 |
|
301 if (aData) |
|
302 { |
|
303 if (aDataLength == UINT32_MAX) |
|
304 aStr.Replace(aCutOffset, aCutLength, nsDependentCString(aData)); |
|
305 else |
|
306 aStr.Replace(aCutOffset, aCutLength, Substring(aData, aDataLength)); |
|
307 } |
|
308 else |
|
309 aStr.Cut(aCutOffset, aCutLength); |
|
310 |
|
311 return NS_OK; // XXX report errors |
|
312 } |
|
313 |
|
314 XPCOM_API(nsresult) |
|
315 NS_CStringCopy(nsACString &aDest, const nsACString &aSrc) |
|
316 { |
|
317 aDest.Assign(aSrc); |
|
318 return NS_OK; // XXX report errors |
|
319 } |
|
320 |
|
321 XPCOM_API(void) |
|
322 NS_CStringSetIsVoid(nsACString &aStr, const bool aIsVoid) |
|
323 { |
|
324 aStr.SetIsVoid(aIsVoid); |
|
325 } |
|
326 |
|
327 XPCOM_API(bool) |
|
328 NS_CStringGetIsVoid(const nsACString &aStr) |
|
329 { |
|
330 return aStr.IsVoid(); |
|
331 } |
|
332 |
|
333 /* ------------------------------------------------------------------------- */ |
|
334 |
|
335 XPCOM_API(nsresult) |
|
336 NS_CStringToUTF16(const nsACString &aSrc, |
|
337 nsCStringEncoding aSrcEncoding, |
|
338 nsAString &aDest) |
|
339 { |
|
340 switch (aSrcEncoding) |
|
341 { |
|
342 case NS_CSTRING_ENCODING_ASCII: |
|
343 CopyASCIItoUTF16(aSrc, aDest); |
|
344 break; |
|
345 case NS_CSTRING_ENCODING_UTF8: |
|
346 CopyUTF8toUTF16(aSrc, aDest); |
|
347 break; |
|
348 case NS_CSTRING_ENCODING_NATIVE_FILESYSTEM: |
|
349 NS_CopyNativeToUnicode(aSrc, aDest); |
|
350 break; |
|
351 default: |
|
352 return NS_ERROR_NOT_IMPLEMENTED; |
|
353 } |
|
354 |
|
355 return NS_OK; // XXX report errors |
|
356 } |
|
357 |
|
358 XPCOM_API(nsresult) |
|
359 NS_UTF16ToCString(const nsAString &aSrc, |
|
360 nsCStringEncoding aDestEncoding, |
|
361 nsACString &aDest) |
|
362 { |
|
363 switch (aDestEncoding) |
|
364 { |
|
365 case NS_CSTRING_ENCODING_ASCII: |
|
366 LossyCopyUTF16toASCII(aSrc, aDest); |
|
367 break; |
|
368 case NS_CSTRING_ENCODING_UTF8: |
|
369 CopyUTF16toUTF8(aSrc, aDest); |
|
370 break; |
|
371 case NS_CSTRING_ENCODING_NATIVE_FILESYSTEM: |
|
372 NS_CopyUnicodeToNative(aSrc, aDest); |
|
373 break; |
|
374 default: |
|
375 return NS_ERROR_NOT_IMPLEMENTED; |
|
376 } |
|
377 |
|
378 return NS_OK; // XXX report errors |
|
379 } |