1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 // IWYU pragma: private, include "nsString.h"
7 
8 #ifndef nsReadableUtils_h___
9 #define nsReadableUtils_h___
10 
11 /**
12  * I guess all the routines in this file are all mis-named.
13  * According to our conventions, they should be |NS_xxx|.
14  */
15 
16 #include "mozilla/Assertions.h"
17 #include "nsAString.h"
18 #include "mozilla/TextUtils.h"
19 
20 #include "nsTArrayForwardDeclare.h"
21 
22 // From the nsstring crate
23 extern "C" {
24 bool nsstring_fallible_append_utf8_impl(nsAString* aThis, const char* aOther,
25                                         size_t aOtherLen, size_t aOldLen);
26 
27 bool nsstring_fallible_append_latin1_impl(nsAString* aThis, const char* aOther,
28                                           size_t aOtherLen, size_t aOldLen,
29                                           bool aAllowShrinking);
30 
31 bool nscstring_fallible_append_utf16_to_utf8_impl(nsACString* aThis,
32                                                   const char16_t*,
33                                                   size_t aOtherLen,
34                                                   size_t aOldLen);
35 
36 bool nscstring_fallible_append_utf16_to_latin1_lossy_impl(nsACString* aThis,
37                                                           const char16_t*,
38                                                           size_t aOtherLen,
39                                                           size_t aOldLen,
40                                                           bool aAllowShrinking);
41 
42 bool nscstring_fallible_append_utf8_to_latin1_lossy_check(
43     nsACString* aThis, const nsACString* aOther, size_t aOldLen);
44 
45 bool nscstring_fallible_append_latin1_to_utf8_check(nsACString* aThis,
46                                                     const nsACString* aOther,
47                                                     size_t aOldLen);
48 }
49 
Distance(const nsReadingIterator<char16_t> & aStart,const nsReadingIterator<char16_t> & aEnd)50 inline size_t Distance(const nsReadingIterator<char16_t>& aStart,
51                        const nsReadingIterator<char16_t>& aEnd) {
52   MOZ_ASSERT(aStart.get() <= aEnd.get());
53   return static_cast<size_t>(aEnd.get() - aStart.get());
54 }
55 
Distance(const nsReadingIterator<char> & aStart,const nsReadingIterator<char> & aEnd)56 inline size_t Distance(const nsReadingIterator<char>& aStart,
57                        const nsReadingIterator<char>& aEnd) {
58   MOZ_ASSERT(aStart.get() <= aEnd.get());
59   return static_cast<size_t>(aEnd.get() - aStart.get());
60 }
61 
62 // NOTE: Operations that don't need an operand to be an XPCOM string
63 // are in mozilla/TextUtils.h and mozilla/Utf8.h.
64 
65 // UTF-8 to UTF-16
66 // Invalid UTF-8 byte sequences are replaced with the REPLACEMENT CHARACTER.
67 
CopyUTF8toUTF16(mozilla::Span<const char> aSource,nsAString & aDest,const mozilla::fallible_t &)68 [[nodiscard]] inline bool CopyUTF8toUTF16(mozilla::Span<const char> aSource,
69                                           nsAString& aDest,
70                                           const mozilla::fallible_t&) {
71   return nsstring_fallible_append_utf8_impl(&aDest, aSource.Elements(),
72                                             aSource.Length(), 0);
73 }
74 
CopyUTF8toUTF16(mozilla::Span<const char> aSource,nsAString & aDest)75 inline void CopyUTF8toUTF16(mozilla::Span<const char> aSource,
76                             nsAString& aDest) {
77   if (MOZ_UNLIKELY(!CopyUTF8toUTF16(aSource, aDest, mozilla::fallible))) {
78     aDest.AllocFailed(aSource.Length());
79   }
80 }
81 
AppendUTF8toUTF16(mozilla::Span<const char> aSource,nsAString & aDest,const mozilla::fallible_t &)82 [[nodiscard]] inline bool AppendUTF8toUTF16(mozilla::Span<const char> aSource,
83                                             nsAString& aDest,
84                                             const mozilla::fallible_t&) {
85   return nsstring_fallible_append_utf8_impl(&aDest, aSource.Elements(),
86                                             aSource.Length(), aDest.Length());
87 }
88 
AppendUTF8toUTF16(mozilla::Span<const char> aSource,nsAString & aDest)89 inline void AppendUTF8toUTF16(mozilla::Span<const char> aSource,
90                               nsAString& aDest) {
91   if (MOZ_UNLIKELY(!AppendUTF8toUTF16(aSource, aDest, mozilla::fallible))) {
92     aDest.AllocFailed(aDest.Length() + aSource.Length());
93   }
94 }
95 
96 // Latin1 to UTF-16
97 // Interpret each incoming unsigned byte value as a Unicode scalar value (not
98 // windows-1252!). The function names say "ASCII" instead of "Latin1" for
99 // legacy reasons.
100 
CopyASCIItoUTF16(mozilla::Span<const char> aSource,nsAString & aDest,const mozilla::fallible_t &)101 [[nodiscard]] inline bool CopyASCIItoUTF16(mozilla::Span<const char> aSource,
102                                            nsAString& aDest,
103                                            const mozilla::fallible_t&) {
104   return nsstring_fallible_append_latin1_impl(&aDest, aSource.Elements(),
105                                               aSource.Length(), 0, true);
106 }
107 
CopyASCIItoUTF16(mozilla::Span<const char> aSource,nsAString & aDest)108 inline void CopyASCIItoUTF16(mozilla::Span<const char> aSource,
109                              nsAString& aDest) {
110   if (MOZ_UNLIKELY(!CopyASCIItoUTF16(aSource, aDest, mozilla::fallible))) {
111     aDest.AllocFailed(aSource.Length());
112   }
113 }
114 
AppendASCIItoUTF16(mozilla::Span<const char> aSource,nsAString & aDest,const mozilla::fallible_t &)115 [[nodiscard]] inline bool AppendASCIItoUTF16(mozilla::Span<const char> aSource,
116                                              nsAString& aDest,
117                                              const mozilla::fallible_t&) {
118   return nsstring_fallible_append_latin1_impl(
119       &aDest, aSource.Elements(), aSource.Length(), aDest.Length(), false);
120 }
121 
AppendASCIItoUTF16(mozilla::Span<const char> aSource,nsAString & aDest)122 inline void AppendASCIItoUTF16(mozilla::Span<const char> aSource,
123                                nsAString& aDest) {
124   if (MOZ_UNLIKELY(!AppendASCIItoUTF16(aSource, aDest, mozilla::fallible))) {
125     aDest.AllocFailed(aDest.Length() + aSource.Length());
126   }
127 }
128 
129 // UTF-16 to UTF-8
130 // Unpaired surrogates are replaced with the REPLACEMENT CHARACTER.
131 
CopyUTF16toUTF8(mozilla::Span<const char16_t> aSource,nsACString & aDest,const mozilla::fallible_t &)132 [[nodiscard]] inline bool CopyUTF16toUTF8(mozilla::Span<const char16_t> aSource,
133                                           nsACString& aDest,
134                                           const mozilla::fallible_t&) {
135   return nscstring_fallible_append_utf16_to_utf8_impl(
136       &aDest, aSource.Elements(), aSource.Length(), 0);
137 }
138 
CopyUTF16toUTF8(mozilla::Span<const char16_t> aSource,nsACString & aDest)139 inline void CopyUTF16toUTF8(mozilla::Span<const char16_t> aSource,
140                             nsACString& aDest) {
141   if (MOZ_UNLIKELY(!CopyUTF16toUTF8(aSource, aDest, mozilla::fallible))) {
142     aDest.AllocFailed(aSource.Length());
143   }
144 }
145 
AppendUTF16toUTF8(mozilla::Span<const char16_t> aSource,nsACString & aDest,const mozilla::fallible_t &)146 [[nodiscard]] inline bool AppendUTF16toUTF8(
147     mozilla::Span<const char16_t> aSource, nsACString& aDest,
148     const mozilla::fallible_t&) {
149   return nscstring_fallible_append_utf16_to_utf8_impl(
150       &aDest, aSource.Elements(), aSource.Length(), aDest.Length());
151 }
152 
AppendUTF16toUTF8(mozilla::Span<const char16_t> aSource,nsACString & aDest)153 inline void AppendUTF16toUTF8(mozilla::Span<const char16_t> aSource,
154                               nsACString& aDest) {
155   if (MOZ_UNLIKELY(!AppendUTF16toUTF8(aSource, aDest, mozilla::fallible))) {
156     aDest.AllocFailed(aDest.Length() + aSource.Length());
157   }
158 }
159 
160 // UTF-16 to Latin1
161 // If all code points in the input are below U+0100, represents each scalar
162 // value as an unsigned byte. (This is not windows-1252!) If there are code
163 // points above U+00FF, memory-safely produces garbage and will likely start
164 // asserting in future debug builds. The nature of the garbage may differ
165 // based on CPU architecture and must not be relied upon. The names say
166 // "ASCII" instead of "Latin1" for legacy reasons.
167 
LossyCopyUTF16toASCII(mozilla::Span<const char16_t> aSource,nsACString & aDest,const mozilla::fallible_t &)168 [[nodiscard]] inline bool LossyCopyUTF16toASCII(
169     mozilla::Span<const char16_t> aSource, nsACString& aDest,
170     const mozilla::fallible_t&) {
171   return nscstring_fallible_append_utf16_to_latin1_lossy_impl(
172       &aDest, aSource.Elements(), aSource.Length(), 0, true);
173 }
174 
LossyCopyUTF16toASCII(mozilla::Span<const char16_t> aSource,nsACString & aDest)175 inline void LossyCopyUTF16toASCII(mozilla::Span<const char16_t> aSource,
176                                   nsACString& aDest) {
177   if (MOZ_UNLIKELY(!LossyCopyUTF16toASCII(aSource, aDest, mozilla::fallible))) {
178     aDest.AllocFailed(aSource.Length());
179   }
180 }
181 
LossyAppendUTF16toASCII(mozilla::Span<const char16_t> aSource,nsACString & aDest,const mozilla::fallible_t &)182 [[nodiscard]] inline bool LossyAppendUTF16toASCII(
183     mozilla::Span<const char16_t> aSource, nsACString& aDest,
184     const mozilla::fallible_t&) {
185   return nscstring_fallible_append_utf16_to_latin1_lossy_impl(
186       &aDest, aSource.Elements(), aSource.Length(), aDest.Length(), false);
187 }
188 
LossyAppendUTF16toASCII(mozilla::Span<const char16_t> aSource,nsACString & aDest)189 inline void LossyAppendUTF16toASCII(mozilla::Span<const char16_t> aSource,
190                                     nsACString& aDest) {
191   if (MOZ_UNLIKELY(
192           !LossyAppendUTF16toASCII(aSource, aDest, mozilla::fallible))) {
193     aDest.AllocFailed(aDest.Length() + aSource.Length());
194   }
195 }
196 
197 // Latin1 to UTF-8
198 // Interpret each incoming unsigned byte value as a Unicode scalar value (not
199 // windows-1252!).
200 // If the input is ASCII, the heap-allocated nsStringBuffer is shared if
201 // possible.
202 
CopyLatin1toUTF8(const nsACString & aSource,nsACString & aDest,const mozilla::fallible_t &)203 [[nodiscard]] inline bool CopyLatin1toUTF8(const nsACString& aSource,
204                                            nsACString& aDest,
205                                            const mozilla::fallible_t&) {
206   return nscstring_fallible_append_latin1_to_utf8_check(&aDest, &aSource, 0);
207 }
208 
CopyLatin1toUTF8(const nsACString & aSource,nsACString & aDest)209 inline void CopyLatin1toUTF8(const nsACString& aSource, nsACString& aDest) {
210   if (MOZ_UNLIKELY(!CopyLatin1toUTF8(aSource, aDest, mozilla::fallible))) {
211     aDest.AllocFailed(aSource.Length());
212   }
213 }
214 
AppendLatin1toUTF8(const nsACString & aSource,nsACString & aDest,const mozilla::fallible_t &)215 [[nodiscard]] inline bool AppendLatin1toUTF8(const nsACString& aSource,
216                                              nsACString& aDest,
217                                              const mozilla::fallible_t&) {
218   return nscstring_fallible_append_latin1_to_utf8_check(&aDest, &aSource,
219                                                         aDest.Length());
220 }
221 
AppendLatin1toUTF8(const nsACString & aSource,nsACString & aDest)222 inline void AppendLatin1toUTF8(const nsACString& aSource, nsACString& aDest) {
223   if (MOZ_UNLIKELY(!AppendLatin1toUTF8(aSource, aDest, mozilla::fallible))) {
224     aDest.AllocFailed(aDest.Length() + aSource.Length());
225   }
226 }
227 
228 // UTF-8 to Latin1
229 // If all code points in the input are below U+0100, represents each scalar
230 // value as an unsigned byte. (This is not windows-1252!) If there are code
231 // points above U+00FF, memory-safely produces garbage in release builds and
232 // asserts in debug builds. The nature of the garbage may differ
233 // based on CPU architecture and must not be relied upon.
234 // If the input is ASCII, the heap-allocated nsStringBuffer is shared if
235 // possible.
236 
LossyCopyUTF8toLatin1(const nsACString & aSource,nsACString & aDest,const mozilla::fallible_t &)237 [[nodiscard]] inline bool LossyCopyUTF8toLatin1(const nsACString& aSource,
238                                                 nsACString& aDest,
239                                                 const mozilla::fallible_t&) {
240   return nscstring_fallible_append_utf8_to_latin1_lossy_check(&aDest, &aSource,
241                                                               0);
242 }
243 
LossyCopyUTF8toLatin1(const nsACString & aSource,nsACString & aDest)244 inline void LossyCopyUTF8toLatin1(const nsACString& aSource,
245                                   nsACString& aDest) {
246   if (MOZ_UNLIKELY(!LossyCopyUTF8toLatin1(aSource, aDest, mozilla::fallible))) {
247     aDest.AllocFailed(aSource.Length());
248   }
249 }
250 
LossyAppendUTF8toLatin1(const nsACString & aSource,nsACString & aDest,const mozilla::fallible_t &)251 [[nodiscard]] inline bool LossyAppendUTF8toLatin1(const nsACString& aSource,
252                                                   nsACString& aDest,
253                                                   const mozilla::fallible_t&) {
254   return nscstring_fallible_append_utf8_to_latin1_lossy_check(&aDest, &aSource,
255                                                               aDest.Length());
256 }
257 
LossyAppendUTF8toLatin1(const nsACString & aSource,nsACString & aDest)258 inline void LossyAppendUTF8toLatin1(const nsACString& aSource,
259                                     nsACString& aDest) {
260   if (MOZ_UNLIKELY(
261           !LossyAppendUTF8toLatin1(aSource, aDest, mozilla::fallible))) {
262     aDest.AllocFailed(aDest.Length() + aSource.Length());
263   }
264 }
265 
266 /**
267  * Returns a new |char| buffer containing a zero-terminated copy of |aSource|.
268  *
269  * Infallibly allocates and returns a new |char| buffer which you must
270  * free with |free|.
271  * Performs a conversion with LossyConvertUTF16toLatin1() writing into the
272  * newly-allocated buffer.
273  *
274  * The new buffer is zero-terminated, but that may not help you if |aSource|
275  * contains embedded nulls.
276  *
277  * @param aSource a 16-bit wide string
278  * @return a new |char| buffer you must free with |free|.
279  */
280 char* ToNewCString(const nsAString& aSource);
281 
282 /* A fallible version of ToNewCString. Returns nullptr on failure. */
283 char* ToNewCString(const nsAString& aSource,
284                    const mozilla::fallible_t& aFallible);
285 
286 /**
287  * Returns a new |char| buffer containing a zero-terminated copy of |aSource|.
288  *
289  * Infallibly allocates and returns a new |char| buffer which you must
290  * free with |free|.
291  *
292  * The new buffer is zero-terminated, but that may not help you if |aSource|
293  * contains embedded nulls.
294  *
295  * @param aSource an 8-bit wide string
296  * @return a new |char| buffer you must free with |free|.
297  */
298 char* ToNewCString(const nsACString& aSource);
299 
300 /* A fallible version of ToNewCString. Returns nullptr on failure. */
301 char* ToNewCString(const nsACString& aSource,
302                    const mozilla::fallible_t& aFallible);
303 
304 /**
305  * Returns a new |char| buffer containing a zero-terminated copy of |aSource|.
306  *
307  * Infallibly allocates and returns a new |char| buffer which you must
308  * free with |free|.
309  * Performs an encoding conversion from a UTF-16 string to a UTF-8 string with
310  * unpaired surrogates replaced with the REPLACEMENT CHARACTER copying
311  * |aSource| to your new buffer.
312  *
313  * The new buffer is zero-terminated, but that may not help you if |aSource|
314  * contains embedded nulls.
315  *
316  * @param aSource a UTF-16 string (made of char16_t's)
317  * @param aUTF8Count the number of 8-bit units that was returned
318  * @return a new |char| buffer you must free with |free|.
319  */
320 char* ToNewUTF8String(const nsAString& aSource, uint32_t* aUTF8Count = nullptr);
321 
322 /* A fallible version of ToNewUTF8String. Returns nullptr on failure. */
323 char* ToNewUTF8String(const nsAString& aSource, uint32_t* aUTF8Count,
324                       const mozilla::fallible_t& aFallible);
325 
326 /**
327  * Returns a new |char16_t| buffer containing a zero-terminated copy
328  * of |aSource|.
329  *
330  * Infallibly allocates and returns a new |char16_t| buffer which you must
331  * free with |free|.
332  *
333  * The new buffer is zero-terminated, but that may not help you if |aSource|
334  * contains embedded nulls.
335  *
336  * @param aSource a UTF-16 string
337  * @return a new |char16_t| buffer you must free with |free|.
338  */
339 char16_t* ToNewUnicode(const nsAString& aSource);
340 
341 /* A fallible version of ToNewUnicode. Returns nullptr on failure. */
342 char16_t* ToNewUnicode(const nsAString& aSource,
343                        const mozilla::fallible_t& aFallible);
344 
345 /**
346  * Returns a new |char16_t| buffer containing a zero-terminated copy
347  * of |aSource|.
348  *
349  * Infallibly allocates and returns a new |char16_t| buffer which you must
350  * free with|free|.
351  *
352  * Performs an encoding conversion by 0-padding 8-bit wide characters up to
353  * 16-bits wide (i.e. Latin1 to UTF-16 conversion) while copying |aSource|
354  * to your new buffer.
355  *
356  * The new buffer is zero-terminated, but that may not help you if |aSource|
357  * contains embedded nulls.
358  *
359  * @param aSource a Latin1 string
360  * @return a new |char16_t| buffer you must free with |free|.
361  */
362 char16_t* ToNewUnicode(const nsACString& aSource);
363 
364 /* A fallible version of ToNewUnicode. Returns nullptr on failure. */
365 char16_t* ToNewUnicode(const nsACString& aSource,
366                        const mozilla::fallible_t& aFallible);
367 
368 /**
369  * Returns a new |char16_t| buffer containing a zero-terminated copy
370  * of |aSource|.
371  *
372  * Infallibly allocates and returns a new |char| buffer which you must
373  * free with |free|.  Performs an encoding conversion from UTF-8 to UTF-16
374  * while copying |aSource| to your new buffer.  Malformed byte sequences
375  * are replaced with the REPLACEMENT CHARACTER.
376  *
377  * The new buffer is zero-terminated, but that may not help you if |aSource|
378  * contains embedded nulls.
379  *
380  * @param aSource an 8-bit wide string, UTF-8 encoded
381  * @param aUTF16Count the number of 16-bit units that was returned
382  * @return a new |char16_t| buffer you must free with |free|.
383  *         (UTF-16 encoded)
384  */
385 char16_t* UTF8ToNewUnicode(const nsACString& aSource,
386                            uint32_t* aUTF16Count = nullptr);
387 
388 /* A fallible version of UTF8ToNewUnicode. Returns nullptr on failure. */
389 char16_t* UTF8ToNewUnicode(const nsACString& aSource, uint32_t* aUTF16Count,
390                            const mozilla::fallible_t& aFallible);
391 
392 /**
393  * Copies |aLength| 16-bit code units from the start of |aSource| to the
394  * |char16_t| buffer |aDest|.
395  *
396  * After this operation |aDest| is not null terminated.
397  *
398  * @param aSource a UTF-16 string
399  * @param aSrcOffset start offset in the source string
400  * @param aDest a |char16_t| buffer
401  * @param aLength the number of 16-bit code units to copy
402  * @return pointer to destination buffer - identical to |aDest|
403  */
404 char16_t* CopyUnicodeTo(const nsAString& aSource, uint32_t aSrcOffset,
405                         char16_t* aDest, uint32_t aLength);
406 
407 /**
408  * Replaces unpaired surrogates with U+FFFD in the argument.
409  *
410  * Copies a shared string buffer or an otherwise read-only
411  * buffer only if there are unpaired surrogates.
412  */
EnsureUTF16Validity(nsAString & aString)413 [[nodiscard]] inline bool EnsureUTF16Validity(nsAString& aString) {
414   uint32_t upTo = mozilla::Utf16ValidUpTo(aString);
415   uint32_t len = aString.Length();
416   if (upTo == len) {
417     return true;
418   }
419   char16_t* ptr = aString.BeginWriting(mozilla::fallible);
420   if (!ptr) {
421     return false;
422   }
423   auto span = mozilla::MakeSpan(ptr, len);
424   span[upTo] = 0xFFFD;
425   mozilla::EnsureUtf16ValiditySpan(span.From(upTo + 1));
426   return true;
427 }
428 
429 void ParseString(const nsACString& aSource, char aDelimiter,
430                  nsTArray<nsCString>& aArray);
431 
432 /**
433  * Converts case in place in the argument string.
434  */
435 void ToUpperCase(nsACString&);
436 
437 void ToLowerCase(nsACString&);
438 
439 void ToUpperCase(nsACString&);
440 
441 void ToLowerCase(nsACString&);
442 
443 /**
444  * Converts case from string aSource to aDest.
445  */
446 void ToUpperCase(const nsACString& aSource, nsACString& aDest);
447 
448 void ToLowerCase(const nsACString& aSource, nsACString& aDest);
449 
450 /**
451  * Finds the leftmost occurrence of |aPattern|, if any in the range
452  * |aSearchStart|..|aSearchEnd|.
453  *
454  * Returns |true| if a match was found, and adjusts |aSearchStart| and
455  * |aSearchEnd| to point to the match.  If no match was found, returns |false|
456  * and makes |aSearchStart == aSearchEnd|.
457  *
458  * Currently, this is equivalent to the O(m*n) implementation previously on
459  * |ns[C]String|.
460  *
461  * If we need something faster, then we can implement that later.
462  */
463 
464 bool FindInReadable(const nsAString& aPattern, nsAString::const_iterator&,
465                     nsAString::const_iterator&,
466                     nsStringComparator = nsTDefaultStringComparator);
467 bool FindInReadable(const nsACString& aPattern, nsACString::const_iterator&,
468                     nsACString::const_iterator&,
469                     nsCStringComparator = nsTDefaultStringComparator);
470 
471 /* sometimes we don't care about where the string was, just that we
472  * found it or not */
473 inline bool FindInReadable(
474     const nsAString& aPattern, const nsAString& aSource,
475     nsStringComparator aCompare = nsTDefaultStringComparator) {
476   nsAString::const_iterator start, end;
477   aSource.BeginReading(start);
478   aSource.EndReading(end);
479   return FindInReadable(aPattern, start, end, aCompare);
480 }
481 
482 inline bool FindInReadable(
483     const nsACString& aPattern, const nsACString& aSource,
484     nsCStringComparator aCompare = nsTDefaultStringComparator) {
485   nsACString::const_iterator start, end;
486   aSource.BeginReading(start);
487   aSource.EndReading(end);
488   return FindInReadable(aPattern, start, end, aCompare);
489 }
490 
491 bool CaseInsensitiveFindInReadable(const nsACString& aPattern,
492                                    nsACString::const_iterator&,
493                                    nsACString::const_iterator&);
494 
495 /**
496  * Finds the rightmost occurrence of |aPattern|
497  * Returns |true| if a match was found, and adjusts |aSearchStart| and
498  * |aSearchEnd| to point to the match.  If no match was found, returns |false|
499  * and makes |aSearchStart == aSearchEnd|.
500  */
501 bool RFindInReadable(const nsAString& aPattern, nsAString::const_iterator&,
502                      nsAString::const_iterator&,
503                      nsStringComparator = nsTDefaultStringComparator);
504 bool RFindInReadable(const nsACString& aPattern, nsACString::const_iterator&,
505                      nsACString::const_iterator&,
506                      nsCStringComparator = nsTDefaultStringComparator);
507 
508 /**
509  * Finds the leftmost occurrence of |aChar|, if any in the range
510  * |aSearchStart|..|aSearchEnd|.
511  *
512  * Returns |true| if a match was found, and adjusts |aSearchStart| to
513  * point to the match.  If no match was found, returns |false| and
514  * makes |aSearchStart == aSearchEnd|.
515  */
516 bool FindCharInReadable(char16_t aChar, nsAString::const_iterator& aSearchStart,
517                         const nsAString::const_iterator& aSearchEnd);
518 bool FindCharInReadable(char aChar, nsACString::const_iterator& aSearchStart,
519                         const nsACString::const_iterator& aSearchEnd);
520 
521 bool StringBeginsWith(const nsAString& aSource, const nsAString& aSubstring);
522 bool StringBeginsWith(const nsAString& aSource, const nsAString& aSubstring,
523                       nsStringComparator);
524 bool StringBeginsWith(const nsACString& aSource, const nsACString& aSubstring);
525 bool StringBeginsWith(const nsACString& aSource, const nsACString& aSubstring,
526                       nsCStringComparator);
527 bool StringEndsWith(const nsAString& aSource, const nsAString& aSubstring);
528 bool StringEndsWith(const nsAString& aSource, const nsAString& aSubstring,
529                     nsStringComparator);
530 bool StringEndsWith(const nsACString& aSource, const nsACString& aSubstring);
531 bool StringEndsWith(const nsACString& aSource, const nsACString& aSubstring,
532                     nsCStringComparator);
533 
534 const nsString& EmptyString();
535 const nsCString& EmptyCString();
536 
537 const nsString& VoidString();
538 const nsCString& VoidCString();
539 
540 /**
541  * Compare a UTF-8 string to an UTF-16 string.
542  *
543  * Returns 0 if the strings are equal, -1 if aUTF8String is less
544  * than aUTF16Count, and 1 in the reverse case. Errors are replaced
545  * with U+FFFD and then the U+FFFD is compared as if it had occurred
546  * in the input. If aErr is not nullptr, *aErr is set to true if
547  * either string had malformed sequences.
548  */
549 int32_t CompareUTF8toUTF16(const nsACString& aUTF8String,
550                            const nsAString& aUTF16String, bool* aErr = nullptr);
551 
552 void AppendUCS4ToUTF16(const uint32_t aSource, nsAString& aDest);
553 
554 #endif  // !defined(nsReadableUtils_h___)
555