String Quick Reference

Function declarations

What: Use abstract classes instead of concrete classes when passing strings across function boundaries

Why: using abstract classes allows the caller to choose the storage mechanism, allowing for possible sharing or more efficient handling of string fragments.

Old way: use nsString& and nsCString&

void MyMethod(const nsString& input, nsString& output);

New way: use nsAString& and nsACString&

void MyMethod(const nsAString& input, nsAString& output);


Substrings

What: Get direct references to string fragments

Why: Avoid making multiple copies of the string

Old way: use a bunch of nsAutoStrings, and use Left(), Right() and Mid() to grab a segment of a string:

// get an 8-character string starting at the 4th position
nsAutoString leftside;
str.Left(leftside, 12);
nsAutoString middle;
leftside.Right(middle, 8);

New way: use Substring() to grab a direct reference to those characters:

// get an 8-character string starting at the 4th position
const nsAString& middle = Substring(str, 4, 8);


Unicode literals

What: Use macro tricks to make wide-character literal strings.

Why: Avoid copying and conversion from literal char-based strings to UTF16 strings.

Old way: use nsAutoString and AssignWithConversion()

nsAutoString wideString;
wideString.AssignWithConversion("some string");
CallWideFunction(wideString);
// use wideString again, but need a const PRUnichar*
CallWideWithFlatString(wideString.get())
nsAutoString wideString2;
wideString2.AssignWithConversion("another string");
CallWideFunction(wideString2);

New way: use NS_LITERAL_STRING or NS_NAMED_LITERAL_STRING

// pre-declare the variable if you'll use it multiple times
NS_NAMED_LITERAL_STRING(wideString, "some string");
CallWideFunction(wideString);
// use wideString again, but need a const PRUnichar*
CallWideWithFlatString(wideString.get());
// inline the string with NS_LITERAL_STRING
CallWideFunction(NS_LITERAL_STRING("another string"));


Converting literal strings to string objects

What: Converting from const PRUnichar*/const char* to the appropriate string type

Why: Avoid making extra copies of strings, just to convert between types!

Note: may involve changing existing APIs

Old way: wrap with nsCAutoString()

// foo is a PRUnichar* string
// call
// void HandleString(const nsString& str);
HandleString(nsAutoString(foo));

New way: wrap with nsDependentString

// foo is a PRUnichar* string
// fix caller to be
// void HandleString(const nsAString& str);
HandleString(nsDependentString(foo));

Stack-based strings

What: use of special stack-oriented classes

Why: to avoid excess heap allocations and memory leaks

Wrong: use nsString/nsCString or raw characters

// call GetStringValue(nsAString& out);
nsString value;
GetStringValue(value);
// call GetStringValue(char** out);
char *result;
GetStringValue(&result); // don't forget to free result!

Right: use nsAutoString/nsCAutoString and nsXPIDLString/nsXPIDLCString

// call GetStringValue(nsAString& out);
nsAutoString value; // 64-character buffer on stack
GetStringValue(value);
// call GetStringValue(char** out);
nsXPIDLCString result;
GetStringValue(getter_Copies(result)); // result will free automatically


Original Document Information

  • Author: Alec Flett
  • Last Updated Date: April 30, 2003
  • Copyright Information: Portions of this content are © 1998–2007 by individual mozilla.org contributors; content available under a Creative Commons license | Details.