Mozilla internal string guide

  • Revision slug: Mozilla_internal_string_guide
  • Revision title: Mozilla internal string guide
  • Revision id: 63373
  • Created:
  • Creator: Tservo
  • Is current revision? No
  • Comment /* Searching strings - looking for substrings, characters, etc. */

Revision Content

Introduction

The string classes are a library of C++ classes which are used to manage buffers of unicode and single-byte character strings. They reside in the mozilla codebase in the xpcom/string directory.

Abstract (interface) classes begin with "nsA" and concrete classes simply begin with "ns". Classes with a "CString" in the name store 8-bit bytes (char's) which may refer to single byte ASCII strings, or multibyte Unicode strings encoded in UTF-8 or a (multibyte or single byte) legacy character encoding (e.g. ISO-8859-1, Shift_JIS, GB2312, KOI8-R). All other classes simply have "String" in their name and refer to 16-bit strings made up of PRUnichar's, For example: nsAString is an abstract class for storing Unicode characters in UTF-16 encoding, and nsDependentCString is a concrete class which stores a 8-bit string. Every 16-bit string class has an equivalent 8-bit string class. For example: nsCString is the 8-bit string class which corresponds to nsString.

8-bit and 16-bit string classes have completely separate base classes, but share the same APIs. As a result, you cannot assign a 8-bit string to a 16-bit string without some kind of conversion helper class or routine. For the purpose of this document, we will refer to the 16-bit string classes in class documentation. It is safe to assume that every 16-bit class has an equivalent 8-bit class.

String Guidelines

Follow these simple rules in your code to keep your fellow developers, reviewers, and users happy.

The Abstract Classes

Every string class dervives from nsAString (or nsACString). This class provides the fundamental interface for access and manipulation of strings. While concrete classes derive from nsAString, nsAString itself cannot be instantiated.

This is very similar to the idea of an "interface" that mozilla uses to describe abstract object descriptions in the rest of the codebase. In the case of interfaces, class names begin with "nsI" where "I" refers to "Interface". In the case of strings, abstract classes begin with "nsA" and the "A" means "Abstract".

There are a number of abstract classes which derive from nsAString. These abstract subclasses also cannot be instantiated, but they describe a string in slightly more detail than nsAString. They guarantee that the underlying implementation behind the abstract class provides specific capabilities above and beyond nsAString.

The list below describes the main base classes. Once you are familiar with them, see the appendix describing What Class to Use When.

  • nsAString: the abstract base class for all strings. It provides an API for assignment, individual character access, basic manipulation of characters in the string, and string comparison. This class corresponds to the XPIDL AString parameter type.
  • nsSubstring: the common base class for all of the string classes. Provides optimized access to data within the string. A nsSubstring is not necessarily null-terminated. (For backwards compatibility, nsASingleFragmentString is a typedef for this string class.)
  • nsString: builds on nsSubstring by guaranteeing a null-terminated storage. This allows for a method (.get()) to access the underlying character buffer. (For backwards compatibility, nsAFlatString is a typedef for this string class.)

The remainder of the string classes inherit from either nsSubstring or nsString. Thus, every string class is compatible with nsAString.

It's important to note that nsSubstring and nsAString both represent a contiguous array of characters that are not necessarily null-terminated. One might ask then ask why two different yet similar string classes need to exist. Well, nsSubstring exists primarily as an optimization since nsAString must retain binary compatibility with the frozen nsAString class that shipped with Mozilla 1.0. Up until the release of Mozilla 1.7, nsAString was capable of representing a string broken into multiple fragments. The cost associated with supporting multi-fragment strings was high and offered limited benefits. It was decided to eliminate support for multi-fragment strings in an effort to reduce the complexity of the string classes and improve performance. See bug 231995 for more details.

Though nsSubstring provides a more efficient interface to its underlying buffer than nsAString, nsAString is still the most commonly used class for parameter passing. This is because it is the string class corresponding to AString in XPIDL. Therefore, this string guide will continue to discuss the string classes with an emphasis on nsAString.

Since every string derives from nsAString (or nsACString), they all share a simple API. Common read-only methods:

  • .Length() - the number of code units (bytes for 8-bit string classes and PRUnichar's for 16-bit string classes) in the string.
  • .IsEmpty() - the fastest way of determining if the string has any value. Use this instead of testing string.Length == 0
  • .Equals(string) - TRUE if the given string has the same value as the current string.

Common methods that modify the string:

  • .Assign(string) - Assigns a new value to the string.
  • .Append(string) - Appends a value to the string.
  • .Insert(string, position) - Inserts the given string before the code unit at position.
  • .Truncate(length) - shortens the string to the given length.

Complete documentation can be found in the Appendix.

Read-only strings

The const attribute on a string determines if the string is writable. If a string is defined as a const nsAString then the data in the string cannot be manipulated. If one tries to call a non-const method on a const string the compiler will flag this as an error at build time.

For example:


void nsFoo::ReverseCharacters(nsAString& str) {
      ...
     str.Assign(reversedStr); // modifies the string
}


This should not compile, because you're assigning to a const class:

 void nsFoo::ReverseCharacters(const nsAString& str) {
       ...
      '''str.Assign(reversedStr);'''
 }

As function parameters

It is recommended that you use the most abstract interface possible as a function parameter, instead of using concrete classes. The convention is to use C++ references (the '&' character) instead of pointers (the '*' character) when passing string references around. For example:

// abstract reference
nsFoo::PrintString('''const nsAString&''' str) {..}
// using a concrete class!
nsFoo::PrintString('''const nsString&''' str) {..}
      
// using a pointer!
nsFoo::PrintString('''const nsAString*''' str) {..}

The abstract classes are also sometimes used to store temporary references to objects. You can see both of these uses in Common Patterns, below.

The Concrete Classes - which classes to use when

The concrete classes are for use in code that actually needs to store string data. The most common uses of the concrete classes are as local variables, and members in classes or structs. Whereas the abstract classes differ in storage mechansim, for the most part the concrete classes differ in storage policy.

The following is a list of the most common concrete classes. Once you are familiar with them, see the appendix describing What Class to Use When.

  • nsString / nsCString- a null-terminated string whose buffer is allocated on the heap. Destroys its buffer when the string object goes away.
  • nsAutoString / nsCAutoString- derived from nsString, a string which owns a 64 code unit buffer in the same storage space as the string itself. If a string less than 64 code units is assigned to an nsAutoString, then no extra storage will be allocated. For larger strings, a new buffer is allocated on the heap.
  • nsXPIDLString / nsXPIDLCString- derived from nsString, this class supports the getter_Copies() operator which allows easy access to XPIDL out wstring / string parameters. This class also supports the notion of a null-valued buffer, whereas nsString's buffer is never null.
  • nsDependentString- derived from nsString, this string does not own its buffer. It is useful for converting a raw string (const PRUnichar* or const char*) into a class of type nsAString.
  • nsPrintfCString- derived from nsCString, this string behaves like an nsCAutoString. The constructor takes parameters which allows it to construct a 8-bit string from a printf-style format string and parameter list.
  • NS_LITERAL_STRING/NS_NAMED_LITERAL_STRING- these convert a literal string (such as "abc") to a nsString or a subclass of nsString. On platforms supporting double-byte string literals (e.g., MSVC++ or GCC with the -fshort-wchar option), these are simply macros around the nsDependentString class. They are slightly faster than just wrapping them with an nsDependentString because they use the compiler to calculate their length, and they also hide the messy cross-platform details of non-byte literal strings.

There are also a number of concrete classes that are created as a side-effect of helper routines, etc. You should avoid direct use of these classes. Let the string library create the class for you.

Of course, there are times when it is necessary to reference these string classes in your code, but as a general rule they should be avoided.

Iterators

Iterators are objects that retain a reference to a position in a string. In some ways they are like a number which refers to an index in an array, or a character-pointer that refers to a position in a character string. They also provide a syntactic means to distinguish between reading and writing to a string.

Iterators are most often used to extract substrings of a string. They provide the capability to modify the contents of a string, but often helper routines, or the string's own methods are quicker at complex string transformations.

Iterators are declared from the string class which they are iterating:

nsAString::const_iterator start, end; // reading-only iterators for nsAString
nsString::iterator substr_start, substr_end; // writing iterators for nsString

Iterators are initialized with one of 4 methods on the string you wish to reference:

// let's read from 'str'
str.BeginReading(start); // initialize 'start' to the beginning of 'str'
str.EndReading(end); // 'end' will be at the end of the string

// say we also want to write to 'url'
url.BeginWriting(substr_start);
url.EndWriting(substr_end);

You can access the code unit that an iterator points to with the dereference operator *.

if (*start == '[')
     printf("Starts with a bracket\n");

Note in the above examples, that 'end' and 'substr_end' will actually point to the code unit past the end of the string, so you should never dereference the direct result of .EndReading().

You can test if two iterators point to the same position with == or !=. You can advance iterators with ++. Putting the ++ before your iterator is preferred, and will prevent creation of a temporary iterator.

while (start != end) // iterate through the whole string
     ++start;

You can effectively write to a string with writing iterators (as opposed to const-iterators):

// change all * to !
while (substr_start != substr_end) {
     if (*substr_start == '*')
           *substr_start = '!';
     ++substr_start;
}

With the patch for bug 231995, this loop is now as efficient as iterating with raw character pointers.

Helper Classes and Functions

Searching strings - looking for substrings, characters, etc.

FindInReadable() is the replacement for the old string.Find(..). The syntax is:

PRBool FindInReadable(const nsAString& pattern,
                      nsAString::const_iterator start, nsAString::const_iterator end,
                      nsStringComparator& aComparator = nsDefaultStringComparator());

To use this, start and end should point to the beginning and end of a string that you would like to search. If the search string is found, start and end will be adjusted to point to the beginning and end of the found pattern. The return value is PR_TRUE or PR_FALSE, indicating whether or not the string was found.

An example:

const nsAString& str = GetSomeString();
nsAString::const_iterator start, end;

str.BeginReading(start);
str.EndReading(end);

NS_NAMED_LITERAL_STRING(valuePrefix, "value=");

if (FindInReadable(valuePrefix, start, end)) {
    // end now points to the character after the pattern
    valueStart = end;

}

Memory Allocation - how to avoid it, which methods to use

Substrings (string fragments)

Unicode Conversion ns*CString vs. ns*String

Common Patterns

Callee-allocated Parameters

Literal Strings

String Concatenation

Local variables

Member variables

Raw Character Pointers

IDL

IDL String types

C++ Signatures

Appendix A - What class to use when

Appendix B - nsAString Reference

Revision Source

<p>
</p>
<h2 name="Introduction"> Introduction </h2>
<p>The string classes are a library of C++ classes which are used to manage buffers of unicode and single-byte character strings. They reside in the mozilla codebase in the xpcom/string  directory.
</p><p>Abstract (interface) classes begin with "nsA" and concrete classes simply begin with "ns". Classes with a "<code>CString</code>" in the name store 8-bit bytes (<code>char</code>'s) which may refer to single byte ASCII strings, or multibyte Unicode strings encoded in UTF-8 or a (multibyte or single byte) legacy character encoding (e.g. ISO-8859-1, Shift_JIS, GB2312, KOI8-R). All other classes simply have "<code>String</code>" in their name and refer to 16-bit strings made up of <code>PRUnichar</code>'s, For example: <code>nsAString</code> is an abstract class for storing Unicode characters in UTF-16 encoding, and <code>nsDependentCString</code> is a concrete class which stores a 8-bit string. Every 16-bit string class has an equivalent 8-bit string class. For example: <code>nsCString</code> is the 8-bit string class which corresponds to <code>nsString</code>.
</p><p>8-bit and 16-bit string classes have completely separate base classes, but share the same APIs. As a result, you cannot assign a 8-bit string to a 16-bit string without some kind of conversion helper class or routine. For the purpose of this document, we will refer to the 16-bit string classes in class documentation. It is safe to assume that every 16-bit class has an equivalent 8-bit class.
</p>
<h2 name="String_Guidelines"> String Guidelines </h2>
<p>Follow these simple rules in your code to keep your fellow developers, reviewers, and users happy.
</p>
<ul><li> Avoid <code><a href="#Unicode_Conversion_ns.2ACString_vs._ns.2AString">*WithConversion</a></code> functions at all costs: <code>AssignWithConversion</code>, <code>AppendWithConversion</code>, <code>EqualsWithConversion</code>, etc
</li><li> Use the most abstract string class that you can. Usually this is:
<ul><li> <code><a href="#The_Abstract_Classes">nsAString</a></code> for function parameters
</li><li> <code><a href="#The_Concrete_Classes_-_which_classes_to_use_when">nsString</a></code> for member variables
</li><li> <a href="#The_Concrete_Classes_-_which_classes_to_use_when"><code>nsAutoString</code> or <code>nsXPIDLString</code></a> for local (stack-based) variables 
</li></ul>
</li><li> Use <a href="#Literal_Strings"><code>NS_LITERAL_{{mediawiki.external('C')}}STRING</code> / <code>NS_NAMED_LITERAL_{{mediawiki.external('C')}}STRING</code></a> to represent literal strings (i.e. "foo") as nsAString-compatible objects.
</li><li> Use <a href="#String_Concatenation">string concatenation</a> (i.e. the "+" operator) when combining strings.
</li><li> Use <code><a href="#Raw_Character_Pointers">nsDependentString</a></code> when you have a raw character pointer that you need to convert to an nsAString-compatible string.
</li><li> Use <code><a href="#Substrings_.28string_fragments.29">Substring()</a></code> to extract fragments of existing strings.
</li><li> Use <a href="#Iterators">iterators</a> to parse and extract string fragments.
</li></ul>
<h2 name="The_Abstract_Classes"> The Abstract Classes </h2>
<p>Every string class dervives from <code>nsAString</code> (or <code>nsACString</code>). This class provides the fundamental interface for access and manipulation of strings. While concrete classes derive from <code>nsAString</code>, <code>nsAString</code> itself cannot be instantiated.
</p><p>This is very similar to the idea of an "interface" that mozilla uses to describe abstract object descriptions in the rest of the codebase. In the case of interfaces, class names begin with "nsI" where "I" refers to "Interface". In the case of strings, abstract classes begin with "nsA" and the "A" means "Abstract".
</p><p>There are a number of abstract classes which derive from <code>nsAString</code>. These abstract subclasses also cannot be instantiated, but they describe a string in slightly more detail than <code>nsAString</code>. They guarantee that the underlying implementation behind the abstract class provides specific capabilities above and beyond <code>nsAString</code>.
</p><p>The list below describes the main base classes. Once you are familiar with them, see the appendix describing What Class to Use When.
</p>
<ul><li> <b><code>nsAString</code></b>: the abstract base class for all strings. It provides an API for assignment, individual character access, basic manipulation of characters in the string, and string comparison. This class corresponds to the XPIDL <code>AString</code> parameter type.
</li><li> <b><code>nsSubstring</code></b>: the common base class for all of the string classes. Provides optimized access to data within the string. A <code>nsSubstring</code> is not necessarily null-terminated. (For backwards compatibility, <code>nsASingleFragmentString</code> is a typedef for this string class.)
</li><li> <b><code>nsString</code></b>: builds on <code>nsSubstring</code> by guaranteeing a null-terminated storage. This allows for a method (<code>.get()</code>) to access the underlying character buffer. (For backwards compatibility, <code>nsAFlatString</code> is a typedef for this string class.)
</li></ul>
<p>The remainder of the string classes inherit from either <code>nsSubstring</code> or <code>nsString</code>. Thus, every string class is compatible with <code>nsAString</code>.
</p><p>It's important to note that <code>nsSubstring</code> and <code>nsAString</code> both represent a contiguous array of characters that are not necessarily null-terminated. One might ask then ask why two different yet similar string classes need to exist. Well, <code>nsSubstring</code> exists primarily as an optimization since <code>nsAString</code> must retain binary compatibility with the frozen <code>nsAString</code> class that shipped with Mozilla 1.0. Up until the release of Mozilla 1.7, <code>nsAString</code> was capable of representing a string broken into multiple fragments. The cost associated with supporting multi-fragment strings was high and offered limited benefits. It was decided to eliminate support for multi-fragment strings in an effort to reduce the complexity of the string classes and improve performance. See <a class="external" href="http://bugzilla.mozilla.org/show_bug.cgi?id=231995">bug 231995</a> for more details.
</p><p>Though <code>nsSubstring</code> provides a more efficient interface to its underlying buffer than <code>nsAString</code>, <code>nsAString</code> is still the most commonly used class for parameter passing. This is because it is the string class corresponding to <code>AString</code> in XPIDL. Therefore, this string guide will continue to discuss the string classes with an emphasis on <code>nsAString</code>.
</p><p>Since every string derives from <code>nsAString</code> (or <code>nsACString</code>), they all share a simple API.
Common read-only methods:
</p>
<ul><li> <b><code>.Length()</code></b> - the number of code units (bytes for 8-bit string classes and PRUnichar's for 16-bit string classes) in the string.
</li><li> <b><code>.IsEmpty()</code></b> - the fastest way of determining if the string has any value. Use this instead of testing <code>string.Length</code> == 0
</li><li> <b><code>.Equals(string)</code></b> - TRUE if the given string has the same value as the current string. 
</li></ul>
<p>Common methods that modify the string:
</p>
<ul><li> <b><code>.Assign(string)</code></b> - Assigns a new value to the string.
</li><li> <b><code>.Append(string)</code></b> - Appends a value to the string.
</li><li> <b><code>.Insert(string, position)</code></b> - Inserts the given string before the code unit at position.
</li><li> <b><code>.Truncate(length)</code></b> - shortens the string to the given length. 
</li></ul>
<p>Complete documentation can be found in the <a href="#Appendix_B_-_nsAString_Reference">Appendix</a>. 
</p>
<h3 name="Read-only_strings"> Read-only strings </h3>
<p>The <code>const</code> attribute on a string determines if the string is writable. If a string is defined as a <code>const nsAString</code> then the data in the string cannot be manipulated. If one tries to call a non-<code>const</code> method on a <code>const</code> string the compiler will flag this as an error at build time.
</p><p>For example:
</p><p><br>
</p>
<pre class="eval">void nsFoo::ReverseCharacters(nsAString&amp; str) {
      ...
     str.Assign(reversedStr); // modifies the string
}
</pre>
<p><br>
This should not compile, because you're assigning to a <code>const</code> class:
</p>
<pre class="wrong-source-code"> void nsFoo::ReverseCharacters(const nsAString&amp; str) {
       ...
      '''str.Assign(reversedStr);'''
 }
</pre>
<h3 name="As_function_parameters"> As function parameters </h3>
<p>It is recommended that you use the most abstract interface possible as a function parameter, instead of using concrete classes. The convention is to use C++ references (the '&amp;' character) instead of pointers (the '*' character) when passing string references around. For example:
</p>
<pre class="right-source-code">// abstract reference
nsFoo::PrintString('''const nsAString&amp;''' str) {..}
</pre>
<pre class="wrong-source-code">// using a concrete class!
nsFoo::PrintString('''const nsString&amp;''' str) {..}
      
// using a pointer!
nsFoo::PrintString('''const nsAString*''' str) {..}
</pre>
<p>The abstract classes are also sometimes used to store temporary references to objects. You can see both of these uses in <a href="#Common_Patterns">Common Patterns</a>, below.
</p>
<h2 name="The_Concrete_Classes_-_which_classes_to_use_when"> The Concrete Classes - which classes to use when </h2>
<p>The concrete classes are for use in code that actually needs to store string data. The most common uses of the concrete classes are as local variables, and members in classes or structs. Whereas the abstract classes differ in storage mechansim, for the most part the concrete classes differ in storage policy.
</p><p>The following is a list of the most common concrete classes. Once you are familiar with them, see the appendix describing <a href="#Appendix_A_-_What_Class_to_Use_When">What Class to Use When.</a>
</p>
<ul><li> <code><b>nsString / nsCString</b></code>- a null-terminated string whose buffer is allocated on the heap. Destroys its buffer when the string object goes away.
</li><li> <code><b>nsAutoString / nsCAutoString</b></code>- derived from <code>nsString</code>, a string which owns a 64 code unit buffer in the same storage space as the string itself.  If a string less than 64 code units is assigned to an <code>nsAutoString</code>, then no extra storage will be allocated. For larger strings, a new buffer is allocated on the heap.
</li><li> <code><b>nsXPIDLString / nsXPIDLCString</b></code>- derived from <code>nsString</code>, this class supports the <code>getter_Copies()</code> operator which allows easy access to XPIDL <code>out wstring / string</code> parameters.  This class also supports the notion of a null-valued buffer, whereas <code>nsString</code>'s buffer is never null.
</li><li> <code><b>nsDependentString</b></code>- derived from <code>nsString</code>, this string does <i>not</i> own its buffer. It is useful for converting a raw string (<code>const PRUnichar*</code> or <code>const char*</code>) into a class of type <code>nsAString</code>.
</li><li> <code><b>nsPrintfCString</b></code>- derived from <code>nsCString</code>, this string behaves like an <code>nsCAutoString</code>. The constructor takes parameters which allows it to construct a 8-bit string from a <code>printf</code>-style format string and parameter list.
</li><li> <code><b>NS_LITERAL_STRING/NS_NAMED_LITERAL_STRING</b></code>- these convert a literal string (such as "abc") to a <code>nsString</code> or a subclass of <code>nsString</code>.  On platforms supporting double-byte string literals (e.g., MSVC++ or GCC with the -fshort-wchar option), these are simply macros around the <code>nsDependentString</code> class.  They are slightly faster than just wrapping them with an <code>nsDependentString</code> because they use the compiler to calculate their length, and they also hide the messy cross-platform details of non-byte literal strings.
</li></ul>
<p>There are also a number of concrete classes that are created as a side-effect of helper routines, etc. You should avoid direct use of these classes. Let the string library create the class for you.
</p>
<ul><li> <code><b>nsSubstringTuple</b></code> - created via <a href="#String_Concatenation">string concatenation</a>
</li><li> <code><b>nsDependentSubstring</b></code> - created through <a href="#Substrings_.28string_fragments.29">Substring</a>
</li><li> <code><b>nsPromiseFlatString</b></code> - created through <code><b><a href="#Raw_Character_Pointers">PromiseFlatString()</a></b></code>
</li></ul>
<p>Of course, there are times when it is necessary to reference these string classes in your code, but as a general rule they should be avoided.
</p>
<h2 name="Iterators"> Iterators </h2>
<p>Iterators are objects that retain a reference to a position in a string. In some ways they are like a number which refers to an index in an array, or a character-pointer that refers to a position in a character string. They also provide a syntactic means to distinguish between reading and writing to a string.
</p><p>Iterators are most often used to extract substrings of a string. They provide the capability to modify the contents of a string, but often helper routines, or the string's own methods are quicker at complex string transformations.
</p><p>Iterators are declared from the string class which they are iterating:
</p>
<pre class="eval">nsAString::const_iterator start, end; // reading-only iterators for nsAString
nsString::iterator substr_start, substr_end; // writing iterators for nsString
</pre>
<p>Iterators are initialized with one of 4 methods on the string you wish to reference:
</p>
<pre class="eval">// let's read from 'str'
str.BeginReading(start); // initialize 'start' to the beginning of 'str'
str.EndReading(end); // 'end' will be at the end of the string

// say we also want to write to 'url'
url.BeginWriting(substr_start);
url.EndWriting(substr_end);
</pre>
<p>You can access the code unit that an iterator points to with the dereference operator *.
</p>
<pre class="eval">if (*start == '[')
     printf("Starts with a bracket\n");
</pre>
<p>Note in the above examples, that '<code>end</code>' and '<code>substr_end</code>' will actually point to the code unit past the end of the string, so you should never dereference the direct result of <code>.EndReading()</code>.
</p><p>You can test if two iterators point to the same position with == or !=. You can advance iterators with ++. Putting the ++ before your iterator is preferred, and will prevent creation of a temporary iterator.
</p>
<pre class="eval">while (start != end) // iterate through the whole string
     ++start;
</pre>
<p>You can effectively write to a string with writing iterators (as opposed to const-iterators):
</p>
<pre class="eval">// change all * to !
while (substr_start != substr_end) {
     if (*substr_start == '*')
           *substr_start = '!';
     ++substr_start;
}
</pre>
<p>With the patch for <a class="external" href="http://bugzilla.mozilla.org/show_bug.cgi?id=231995">bug 231995</a>, this loop is now as efficient as iterating with raw character pointers.
</p>
<h2 name="Helper_Classes_and_Functions"> Helper Classes and Functions </h2>
<h3 name="Searching_strings_-_looking_for_substrings.2C_characters.2C_etc."> Searching strings - looking for substrings, characters, etc. </h3>
<p><code>FindInReadable()</code> is the replacement for the old <code>string.Find(..)</code>. The syntax is:
</p>
<pre class="eval">PRBool FindInReadable(const nsAString&amp; pattern,
                      nsAString::const_iterator start, nsAString::const_iterator end,
                      nsStringComparator&amp; aComparator = nsDefaultStringComparator());
</pre>
<p>To use this, <code>start</code> and <code>end</code> should point to the beginning and end of a string that you would like to search. If the search string is found, <code>start</code> and <code>end</code> will be adjusted to point to the beginning and end of the found pattern. The return value is PR_TRUE or PR_FALSE, indicating whether or not the string was found.
</p><p>An example:
</p>
<pre class="eval">const nsAString&amp; str = GetSomeString();
nsAString::const_iterator start, end;

str.BeginReading(start);
str.EndReading(end);

NS_NAMED_LITERAL_STRING(valuePrefix, "value=");

if (FindInReadable(valuePrefix, start, end)) {
    // end now points to the character after the pattern
    valueStart = end;

}
</pre>
<h3 name="Memory_Allocation_-_how_to_avoid_it.2C_which_methods_to_use"> Memory Allocation - how to avoid it, which methods to use </h3>
<h3 name="Substrings_.28string_fragments.29"> Substrings (string fragments) </h3>
<h2 name="Unicode_Conversion_ns.2ACString_vs._ns.2AString"> Unicode Conversion ns*CString vs. ns*String </h2>
<h2 name="Common_Patterns"> Common Patterns </h2>
<h3 name="Callee-allocated_Parameters"> Callee-allocated Parameters </h3>
<h3 name="Literal_Strings"> Literal Strings </h3>
<h3 name="String_Concatenation"> String Concatenation </h3>
<h3 name="Local_variables"> Local variables </h3>
<h3 name="Member_variables"> Member variables </h3>
<h3 name="Raw_Character_Pointers"> Raw Character Pointers </h3>
<h2 name="IDL"> IDL </h2>
<h3 name="IDL_String_types"> IDL String types </h3>
<h3 name="C.2B.2B_Signatures"> C++ Signatures </h3>
<h2 name="Appendix_A_-_What_class_to_use_when"> Appendix A - What class to use when </h2>
<h2 name="Appendix_B_-_nsAString_Reference"> Appendix B - nsAString Reference </h2>
Revert to this revision