summaryrefslogtreecommitdiffstats
path: root/src/libs/xpcom18a4/xpcom/string
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 03:01:46 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-06 03:01:46 +0000
commitf8fe689a81f906d1b91bb3220acde2a4ecb14c5b (patch)
tree26484e9d7e2c67806c2d1760196ff01aaa858e8c /src/libs/xpcom18a4/xpcom/string
parentInitial commit. (diff)
downloadvirtualbox-upstream.tar.xz
virtualbox-upstream.zip
Adding upstream version 6.0.4-dfsg.upstream/6.0.4-dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/libs/xpcom18a4/xpcom/string')
-rw-r--r--src/libs/xpcom18a4/xpcom/string/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/xpcom/string/Makefile.in54
-rw-r--r--src/libs/xpcom18a4/xpcom/string/README.html44
-rw-r--r--src/libs/xpcom18a4/xpcom/string/doc/README.html44
-rw-r--r--src/libs/xpcom18a4/xpcom/string/doc/string-guide.html2508
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/Makefile.in86
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsAString.h96
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsAlgorithm.h131
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsCharTraits.h784
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsDependentString.h60
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsDependentSubstring.h56
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsEmbedString.h158
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsLiteralString.h116
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsObsoleteAString.h102
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsPrintfCString.h87
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsPromiseFlatString.h56
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsReadableUtils.h370
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsString.h237
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsStringAPI.h853
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsStringFwd.h96
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsStringIterator.h373
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsSubstring.h74
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsSubstringTuple.h56
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsTAString.h618
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsTDependentString.h137
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsTDependentSubstring.h142
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsTObsoleteAString.h165
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsTPromiseFlatString.h158
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsTString.h721
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsTSubstring.h575
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsTSubstringTuple.h113
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsUTF8Utils.h462
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/nsXPIDLString.h46
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/string-template-def-char.h58
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/string-template-def-unichar.h58
-rw-r--r--src/libs/xpcom18a4/xpcom/string/public/string-template-undef.h59
-rw-r--r--src/libs/xpcom18a4/xpcom/string/src/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/xpcom/string/src/Makefile.in77
-rw-r--r--src/libs/xpcom18a4/xpcom/string/src/nsAString.cpp51
-rw-r--r--src/libs/xpcom18a4/xpcom/string/src/nsDependentSubstring.cpp50
-rw-r--r--src/libs/xpcom18a4/xpcom/string/src/nsObsoleteAStringThunk.cpp52
-rw-r--r--src/libs/xpcom18a4/xpcom/string/src/nsPrintfCString.cpp83
-rw-r--r--src/libs/xpcom18a4/xpcom/string/src/nsPromiseFlatString.cpp49
-rw-r--r--src/libs/xpcom18a4/xpcom/string/src/nsReadableUtils.cpp1122
-rw-r--r--src/libs/xpcom18a4/xpcom/string/src/nsString.cpp49
-rw-r--r--src/libs/xpcom18a4/xpcom/string/src/nsStringComparator.cpp75
-rw-r--r--src/libs/xpcom18a4/xpcom/string/src/nsStringObsolete.cpp1327
-rw-r--r--src/libs/xpcom18a4/xpcom/string/src/nsSubstring.cpp250
-rw-r--r--src/libs/xpcom18a4/xpcom/string/src/nsSubstringTuple.cpp64
-rw-r--r--src/libs/xpcom18a4/xpcom/string/src/nsTAString.cpp509
-rw-r--r--src/libs/xpcom18a4/xpcom/string/src/nsTDependentSubstring.cpp65
-rw-r--r--src/libs/xpcom18a4/xpcom/string/src/nsTObsoleteAStringThunk.cpp235
-rw-r--r--src/libs/xpcom18a4/xpcom/string/src/nsTPromiseFlatString.cpp66
-rw-r--r--src/libs/xpcom18a4/xpcom/string/src/nsTString.cpp63
-rw-r--r--src/libs/xpcom18a4/xpcom/string/src/nsTStringComparator.cpp79
-rw-r--r--src/libs/xpcom18a4/xpcom/string/src/nsTStringObsolete.cpp518
-rw-r--r--src/libs/xpcom18a4/xpcom/string/src/nsTSubstring.cpp656
-rw-r--r--src/libs/xpcom18a4/xpcom/string/src/nsTSubstringTuple.cpp127
59 files changed, 15323 insertions, 0 deletions
diff --git a/src/libs/xpcom18a4/xpcom/string/.cvsignore b/src/libs/xpcom18a4/xpcom/string/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/xpcom/string/Makefile.in b/src/libs/xpcom18a4/xpcom/string/Makefile.in
new file mode 100644
index 00000000..6a664cb9
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/Makefile.in
@@ -0,0 +1,54 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications.
+# Portions created by the Initial Developer are Copyright (C) 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Johnny Stenback <jst@netscape.com> (original author)
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = string
+DIRS = public src
+
+#ifdef ENABLE_TESTS
+#DIRS += \
+# tests
+#endif
+
+include $(topsrcdir)/config/rules.mk
diff --git a/src/libs/xpcom18a4/xpcom/string/README.html b/src/libs/xpcom18a4/xpcom/string/README.html
new file mode 100644
index 00000000..1fdcfdd1
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/README.html
@@ -0,0 +1,44 @@
+<html>
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Mozilla.
+ -
+ - The Initial Developer of the Original Code is
+ - Netscape Communications.
+ - Portions created by the Initial Developer are Copyright (C) 2001
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ - Scott Collins <scc@mozilla.org> (original author)
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either of the GNU General Public License Version 2 or later (the "GPL"),
+ - or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+<body>
+ <h1><span class="LXRSHORTDESC">managing sequences of characters</span></h1>
+<p>
+ <span class="LXRLONGDESC"></span>
+</p>
+</body>
+</html>
diff --git a/src/libs/xpcom18a4/xpcom/string/doc/README.html b/src/libs/xpcom18a4/xpcom/string/doc/README.html
new file mode 100644
index 00000000..154b7969
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/doc/README.html
@@ -0,0 +1,44 @@
+<html>
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Mozilla.
+ -
+ - The Initial Developer of the Original Code is
+ - Netscape Communications.
+ - Portions created by the Initial Developer are Copyright (C) 2001
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ - Scott Collins <scc@mozilla.org> (original author)
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either of the GNU General Public License Version 2 or later (the "GPL"),
+ - or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the GPL or the LGPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+<body>
+ <h1><span class="LXRSHORTDESC">documentation aimed at programmers who are clients of the string library</span></h1>
+<p>
+ <span class="LXRLONGDESC"></span>
+</p>
+</body>
+</html>
diff --git a/src/libs/xpcom18a4/xpcom/string/doc/string-guide.html b/src/libs/xpcom18a4/xpcom/string/doc/string-guide.html
new file mode 100644
index 00000000..41dbd217
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/doc/string-guide.html
@@ -0,0 +1,2508 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
+<html>
+ <head>
+ <title>an incomplete guide to mozilla/string</title>
+
+ <link rel="stylesheet" href="http://www.mozilla.org/projects/string/string-guide.css" title="remote stylesheet" type="text/css">
+ <link rel="alternate stylesheet" href="string-guide.css" title="local stylesheet" type="text/css">
+ </head>
+ <body>
+<!-- ----|---------|---------|---------|---------|---------|---------|---------| -->
+<!-- ...............................................................Front Matter -->
+<h1>an incomplete guide to <a class="exact-uri" href="http://lxr.mozilla.org/seamonkey/source/string/">mozilla/string</a></h1>
+ <h1><font color="red">This document is now deprecated in favor of <a href="http://www.mozilla.org/projects/xpcom/string-guide.html">The new string guide</a>.</font></h1>
+<div class="author-note">
+ <p>by <a href="http://ScottCollins.net/">Scott Collins</a><!-- /p -->
+ <p>last modified 8 April 2001<!-- /p -->
+</div>
+
+<div class="abstract">
+ <p>
+ <h1>Abstract</h1>
+ This document <span class="LXRSHORTDESC">provides
+ an <a href="#users_guide">introduction</a> to the design and use of the string classes in mozilla,
+ <a href="#implementors_guide">detailed information</a> on their implementation and how one may extend them,
+ and <a href="#faq">answers</a> to frequently asked questions about strings</span>.
+ </p>
+</div>
+
+
+
+<h2><a name="contents">contents</a></h2>
+
+<div class="contents">
+ <ul>
+ <li><a href="#users_guide" >user's guide</a></li>
+ <li><a href="#implementors_guide">implementor's guide</a></li>
+ <li><a href="#faq" >frequently asked questions</a></li>
+ </ul>
+</div>
+
+<p>
+ Please direct all comments, requests, and contributions to,
+ in order of preference,
+ the tracking bug <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=70076">#70076</a> for this document,
+ the author <a class="exact-uri" href="mailto:scc@mozilla.org?subject=string-guide">scc@mozilla.org</a>, and/or
+ the newsgroup <a class="exact-uri" href="news:netscape.public.mozilla.xpcom">news:netscape.public.mozilla.xpcom</a>
+ (should there be a strings newsgroup?)
+</p>
+
+<div class="author-note">
+ <p>
+ A note to potential editors:
+ don't even <strong>consider</strong> modifying this document with an HTML editor.
+ That would destroy the internal formatting,
+ and make patches unmanagable.
+ </p>
+</div>
+
+
+
+
+<!-- ...............................................................User's Guide -->
+<hr>
+<h1><a name="users_guide">user's guide</a></h1>
+
+<div class="author-note">
+ <p>
+ Strings in mozilla are a world apart from <span class="code">char*</span>s.
+ If you don't know why they are different,
+ this section is the place for you to start.
+ If you're already familiar with the hierarchy of string classes in mozilla,
+ then you might want to skip ahead to the <a href="#implementors_guide">implementor's guide</a>
+ or the <a href="#faq">FAQ</a>.
+ </p>
+</div>
+
+<div class="contents">
+ <ul>
+ <li><a href="#users_guide_introduction">introduction</a></li>
+ <li><a href="#users_guide_how_to" >using the string classes correctly; using the correct string class</a></li>
+ <li><a href="#users_guide_iterators" >using string iterators</a></li>
+ <li><a href="#users_guide_summary" >summary</a></li>
+ </ul>
+</div>
+
+<h2><a name="users_guide_introduction">introduction</a></h2>
+ <h3>what and what isn't a string?</h3>
+<p>
+ A string is an opaque container holding a, possibly zero length, linear sequence of characters.
+ Understanding the implications of this statement is the foundation for understanding all mozilla's string classes.
+</p>
+
+ <h3>readable and writable</h3>
+ <h3>dependent strings</h3>
+ <h3>flat strings</h3>
+ <h3>encoding</h3>
+ <h3>sharing</h3>
+
+<h2><a name="users_guide_how_to">using the string classes correctly; using the correct string class</a></h2>
+ <h3>basic string operations</h3>
+ <h4>comparison</h4>
+ <h4>concatenation</h4>
+ <h4>substrings</h4>
+ <h4>find and replace</h4>
+ <h3>conversions</h3>
+ <h4>calling a function that expects a different kind of string</h4>
+ <h4>converting between string classes</h4>
+ <h4>converting between encodings</h4>
+ <h3>selecting the right string class</h3>
+ <h4>user string classes</h4>
+ <h4>selecting the right string class for a parameter</h4>
+ <h4>selecting the right string class for a local variable</h4>
+ <h4>selecting the right string class for a member variable</h4>
+ <h4>selecting the right string class for a return value</h4>
+ <h4>selecting the right string class in IDL</h4>
+ <h3>dont's</h3>
+
+<h2><a name="users_guide_iterators">using string iterators</a></h2>
+ <h3>what is an iterator?</h3>
+ <h3>reading iterators and writing iterators</h3>
+ <h3>`chunky' iterating for efficiency</h3>
+ <h3><span class="code">copy_string</span>, character sources and sinks</h3>
+ <h3>encoding conversion iterators</h3>
+
+<h2><a name="users_guide_summary">summary</a></h2>
+
+
+<!-- ........................................................Implementor's Guide -->
+<hr>
+<h1><a name="implementors_guide">implementor's guide</a></h1>
+
+<div class="author-note">
+ <p>
+
+ </p>
+</div>
+
+<div class="contents">
+ <ul>
+ <!-- li></li -->
+ </ul>
+</div>
+
+
+
+<!-- ........................................................................FAQ -->
+<hr>
+<h1><a name="faq">frequently asked questions</a></h1>
+
+<div class="author-note">
+</div>
+
+<div class="contents">
+ <ul>
+<!--
+ <li>
+ I have a wide string, i.e., an instance of a class derived from <span class="code">nsAString</span>
+ <ul>
+ <li>I want a pointer to the characters</span>
+ <li>I want a narrow string</li>
+ <li>I want to <span class="code">printf</span> it</li>
+ </ul>
+ </li>
+ <li>
+ I have a <span class="code">PRUnichar*</span>
+ <ul>
+ <li>I want a wide string</span>
+ <li>I want a narrow string</span>
+ <li>I want to <span class="code">printf</span> it</li>
+ </ul>
+ </li>
+ <li>
+ I have a narrow string, i.e., an instance of a class derived from <span class="code">nsACString</span>
+ <ul>
+ <li>I want a pointer to the characters</span>
+ <li>I want a narrow string</li>
+ <li>I want to <span class="code">printf</span> it</li>
+ </ul>
+ </li>
+ <li>
+ I have a <span class="code">char*</span>
+ <ul>
+ <li>I want a wide string</span>
+ <li>I want a narrow string</span>
+ </ul>
+ </li>
+ <li>
+ I have a literal character sequence, e.g., <span class="code">"Hello, World!\n"</span>
+ <ul>
+ <li>I want a wide string</span>
+ <li>I want a narrow string</span>
+ </ul>
+ </li>
+ <li>What's the best way to return a string?</li>
+ <li>How can I get a pointer to the characters in a string?</li>
+ <li>How can I <span class="code">printf</span> a string?</li>
+ </ul>
+-->
+</div>
+
+
+<table class="chart">
+ <tr>
+ <th></th>
+ <th colspan="5">you have some <span class="code">char</span>s</th>
+ </tr>
+ <tr>
+ <th>you want</th>
+ <th><span class="code">'x'</span></th>
+ <th><span class="code">char c</span></th>
+ <th><span class="code">"foo"</span></th>
+ <th><span class="code">char* cp</span></th>
+ <th><span class="code">nsACString& cs</span></th>
+ </tr>
+ <tr>
+ <th class="row-label"><span class="code">char</span></th>
+ <td colspan="2">.</td>
+<!-- "foo" --> <td><span class="code">[]</span></td>
+<!-- char* cp --> <td><span class="code">[]</span></td>
+<!-- nsACString& cs --> <td><a href="#faq_how_to_extract_a_character">extract a character</a></td>
+ </tr>
+ <tr>
+ <th class="row-label"><span class="code">PRUnichar</span></th>
+<!-- 'x' --> <td><span class="code">PRUnichar('x')</span></td>
+<!-- char c --> <td><span class="code">PRUnichar(c)</span></td>
+ <td colspan="3"><a href="#faq_how_to_convert_encoding">convert encoding</a>, <a href="#faq_how_to_extract_a_character">extract a character</a></td>
+ </tr>
+ <tr>
+ <th class="row-label"><span class="code">char*</span></th>
+<!-- 'x' --> <td><span class="code">&amp;</span></td>
+<!-- char c --> <td><span class="code">&amp;</span></td>
+<!-- "foo" --> <td><span class="code">&amp;</span></td>
+<!-- char* cp --> <td>.</td>
+<!-- nsACString& cs --> <td><a href="#faq_how_to_get_a_pointer">get a pointer</a></td>
+ </tr>
+ <tr>
+ <th class="row-label"><span class="code">PRUnichar*</span></th>
+ <td colspan="5"><a href="#faq_how_to_convert_encoding">convert encoding</a>, <a href="#faq_how_to_get_a_pointer">get a pointer</a></td>
+ </tr>
+ <tr>
+ <th class="row-label"><span class="code">nsACString</span></th>
+<!-- 'x' --> <td><span class="code">NS_LITERAL_CSTRING("x")</span></td>
+<!-- char c --> <td><a href="#faq_how_to_make_a_string">make a string</a></td>
+<!-- "foo" --> <td><span class="code">NS_LITERAL_CSTRING("foo")</td>
+<!-- char* cp --> <td><a href="#faq_how_to_make_a_string">make a string</a></td>
+<!-- nsACString& cs --> <td>.</td>
+ </tr>
+ <tr>
+ <th class="row-label"><span class="code">nsAString</span></th>
+<!-- 'x' --> <td><span class="code">NS_LITERAL_STRING("x")</span></td>
+<!-- char c --> <td><a href="#faq_how_to_convert_encoding">convert encoding</a></td>
+<!-- "foo" --> <td><span class="code">NS_LITERAL_STRING("foo")</span></td>
+ <td colspan="2"><a href="#faq_how_to_convert_encoding">convert encoding</a></td>
+ </tr>
+ <tr>
+ <th class="row-label">to call <span class="code">printf</span></th>
+ <td colspan="4">.</td>
+<!-- nsACString& cs --> <td><a href="#faq_how_to_call_printf">call <span class="code">printf</span></a></td>
+ </tr>
+</table>
+
+<table class="chart">
+ <tr>
+ <th></th>
+ <th colspan="3">you have some <span class="code">PRUnichar</span>s</th>
+ </tr>
+ <tr>
+ <th>you want</th>
+ <th><span class="code">PRUnichar w</span></th>
+ <th><span class="code">PRUnichar* wp</span></th>
+ <th><span class="code">nsAString& s</span></th>
+ </tr>
+ <tr>
+ <th class="row-label"><span class="code">char</span></th>
+<!-- PRUnichar w --> <td></td>
+<!-- PRUnichar* wp --> <td></td>
+<!-- nsAString& s --> <td></td>
+ </tr>
+ <tr>
+ <th class="row-label"><span class="code">PRUnichar</span></th>
+<!-- PRUnichar w --> <td></td>
+<!-- PRUnichar* wp --> <td><span class="code">[]</span></td>
+<!-- nsAString& s --> <td><a href="#faq_how_to_extract_a_character">extract a character</a></td>
+ </tr>
+ <tr>
+ <th class="row-label"><span class="code">char*</span></th>
+<!-- PRUnichar w --> <td></td>
+<!-- PRUnichar* wp --> <td></td>
+<!-- nsAString& s --> <td></td>
+ </tr>
+ <tr>
+ <th class="row-label"><span class="code">PRUnichar*</span></th>
+<!-- PRUnichar w --> <td><span class="code">&amp;</span></td>
+<!-- PRUnichar* wp --> <td></td>
+<!-- nsAString& s --> <td><a href="#faq_how_to_get_a_pointer">get a pointer</a></td>
+ </tr>
+ <tr>
+ <th class="row-label"><span class="code">nsACString</span></th>
+<!-- PRUnichar w --> <td></td>
+<!-- PRUnichar* wp --> <td></td>
+<!-- nsAString& s --> <td></td>
+ </tr>
+ <tr>
+ <th class="row-label"><span class="code">nsAString</span></th>
+<!-- PRUnichar w --> <td></td>
+<!-- PRUnichar* wp --> <td></td>
+<!-- nsAString& s --> <td></td>
+ </tr>
+ <tr>
+ <th class="row-label">to call <span class="code">printf</span></th>
+<!-- PRUnichar w --> <td></td>
+<!-- PRUnichar* wp --> <td></td>
+<!-- nsAString& s --> <td><a href="#faq_how_to_call_printf">call <span class="code">printf</span></a></td>
+ </tr>
+</table>
+
+<div class="faq">
+ <dl>
+ <dt>
+ is there any string doc?
+ </dt>
+ <dd>
+ Yes, you're soaking in it!
+ </dd>
+
+
+
+<!-- getting a pointer -->
+ <dt>
+ <a name="faq_how_to_get_a_pointer">I have a string, how do I get a pointer to the characters?</a>
+ </dt>
+ <dd>
+ You want to avoid this situation.
+ In your own interfaces, prefer string types over raw pointers.
+ Any interface that wants to process a string using a single pointer is making two expensive assumptions.
+ First, that the string is stored in one contiguous hunk; and
+ second, that the string is zero-terminated.
+ If this isn't the case,
+ then to get a pointer, storage must be allocated and the entire string must be copied to it and zero-terminated.
+ You may not be able to avoid needing a pointer when interacting with system calls.
+ </dd>
+ <dd>
+ Some string classes guarantee that they are `flat'.
+ That is, that their data is stored in one contiguous zero-terminated hunk.
+ This <strong>does not</strong> imply that there are no embedded nulls. Caveat emptor.
+ All strings that explicitly promise flatness
+ inherit from the class <span class="code">nsAFlatString</span>
+ or <span class="code">nsAFlatCString</span>
+ and can produce a constant pointer to their data with the <span class="code">get()</span> member function.
+ Even strings that don't explicitly promise to be flat
+ may happen to be flat.
+ The helper function <span class="code">PromiseFlatString</span> will produce
+ a <span class="code">const</span> dependent string that is guaranteed to be flat.
+ If you use this on a string that already happens to be flat,
+ the result is simply a reference through to that string.
+ Otherwise,
+ <span class="code">PromiseFlatString</span> does the work to allocate, copy, terminate, and manage
+ a temporary flat string.
+ Since the result of <span class="code">PromiseFlatString</span> is a temporary,
+ you must be careful not to get and hold a pointer to its data for longer than the temporary itself lives.
+ </dd>
+ <dd>
+<div class="source-code">
+<pre>
+ /* I have a string, how do I get a pointer to the characters? */
+
+extern void EvilNarrowOSFunction( const char* ); // evil OS routines that want a pointers
+extern void EvilWideOSFunction( const PRUnichar* );
+
+void func( const nsAString&amp; aString, const nsACString&amp; aCString )
+ {
+ EvilWideOSFunction( NS_LITERAL_STRING("Hello, World!").<span class="notice">get()</span> );
+ // literal strings are flat already (as are |nsString|s, et al), just use |.get()|
+
+ EvilWideOSFunction( <span class="notice">PromiseFlatString(</span>aString<span class="notice">).get()</span> );
+ // for strings that don't explicitly guarantee flatness, use |PromiseFlatString|
+
+
+ // beware holding the pointer for longer than the life of the promise
+ <span class="warning">const PRUnichar* wp = PromiseFlatString(aString).get(); // BAD! |wp| dangles
+ EvilWideOSFunction(wp);</span>
+
+ // if you really need to use the pointer from |PromiseFlatString| in more than one expression...
+ const nsAFlatString&amp; flat = <span class="notice">PromiseFlatString(</span>aString<span class="notice">)</span>;
+ EvilWideOSFunction(flat.<span class="notice">get()</span>);
+ SomeOtherFunction(flat.<span class="notice">get()</span>);
+
+ // similarly for |char| strings
+ EvilNarrowOSFunction( <span class="notice">PromiseFlatCString(</span>aCString<span class="notice">).get()</span> );
+ }
+</pre>
+</div>
+ </dd>
+
+
+
+<!-- extracting a character -->
+ <dt>
+ <a name="faq_how_to_extract_a_character">How do I get a particular character out of a string?</a>
+ </dt>
+ <dd>
+ Flat strings provide <span class="code">operator[]</span> and <span class="code">CharAt()</span>.
+ All strings provide <span class="code">First()</span>, <span class="code">Last()</span>, and access with iterators.
+ <strong>Don't</strong> promise a string flat just to do character indexing.
+ Prefer, instead, to get an iterator and <span class="code">advance</span> it to the position you care about.
+ </dd>
+ <dd>
+<div class="source-code">
+<pre>
+ /* How do I get a particular character out of a string? */
+
+PRUnichar Get5thCharacterOf( const nsAString& aString )
+ {
+ if ( aString.Length() >= 5 )
+ {
+ nsAString::const_iterator iter;
+ aString.BeginReading(iter); // make |iter| point to the beginning of |aString|
+ iter.advance(5);
+ return *iter;
+ }
+
+ return PRUnichar(0);
+ }
+</pre>
+</div>
+ </dd>
+ <dd>
+ Using iterators isn't as bad as the example above makes it feel.
+ The typical use is for advancing through a string, examining many characters.
+ </dd>
+
+
+
+<!-- how to convert encoding -->
+ <dt>
+ <a name="faq_how_to_convert_encoding">How do I convert from one encoding to another?</a>
+ </dt>
+ <dd>
+ </dd>
+
+
+
+<!-- how to make a string -->
+ <dt>
+ <a name="faq_how_to_make_a_string">How do I create a string?</a>
+ </dt>
+ <dd>
+ </dd>
+
+
+<!-- how to return a string -->
+ <dt>
+ What is the best way to return a string?
+ </dt>
+ <dd>
+ <p>
+ There are several reasonable ways to produce a string result from a function.
+ If you are already holding the answer as a sharable string,
+ you can simply return that string (pass-by-value).
+ Otherwise,
+ the most efficient and flexible way to return a string is
+ to assign your result into a non-<span class="code">const</span> reference parameter.
+ Don't bother to create a sharable string from scratch with your generated result.
+ </p>
+ <p>
+ Why?
+ The two things you want to minimize in string manipulation are,
+ in order of importance,
+ heap allocation, and
+ moving characters around.
+ </p>
+ </dd>
+ <dd>
+<div class="source-code">
+<pre>
+ /* What is the best way to return a string? */
+
+class foo
+ {
+ public:
+ // ...
+ void GetShortName( nsAString&amp; aResult ) const;
+ nsCommonString GetFullName() const;
+
+ private:
+ nsCommonString mFullName;
+
+ const PRUnichar* mShortName;
+ PRUint32 mShortNameLength;
+
+ };
+
+nsCommonString
+foo::GetFullName() const
+ {
+ return mFullName;
+ }
+
+void
+foo::GetShortName( nsAString&amp; aResult ) const
+ {
+ aResult = DependentString(mShortName, mShortNameLength);
+ }
+</pre>
+</div>
+ </dd>
+
+
+ <dt>
+ <a name="faq_how_to_call_printf">How do I <span class="code">printf</span> a string, e.g., for debugging.</a>
+ </dt>
+ <dd>
+ If your string is already narrow, you just have to worry about <a href="#faq_how_to_get_a_pointer">making it flat, and then getting a pointer</a>.
+ </dd>
+ <dd>
+ If your string happens to be wide,
+ you'll need to convert it before you can <span class="code">printf</span> something reasonable.
+ If it's just for debugging,
+ you probably wouldn't care if something odd was printed in the case of a Unicode character that didn't have
+ an ASCII equivalent. (If you have a UTF-8 terminal, the result is
+ perfectly legible and nothing odd is printed.)
+ The simplest thing in this case is to make a temporary conversion using <span class="code">NS_ConvertUTF16toUTF8</span>.
+ The result is conveniently flat already, so getting the pointer is simple.
+ Remember not to hold onto the pointer you get out of this beyond the lifetime of temporary.
+ </dd>
+ <dd>
+<div class="source-code">
+<pre>
+ /* How do I |printf| a string? */
+
+
+void PrintSomeStrings( const nsAString& aString, const PRUnichar* aKey, const nsACString& aCString )
+ {
+ // |printf|ing a narrow string is easy
+ printf("%s\n", <span class="notice">PromiseFlatCString(</span>aCString<span class="notice">).get()</span>); // GOOD
+
+ // the simplest way to get a |printf|-able |const char*| out of a string
+ printf("%s\n", <span class="notice">NS_ConvertUTF16toUTF8(</span>aKey<span class="notice">).get()</span>); // GOOD
+
+ // works just as well with an formal wide string type...
+ printf("%s\n", <span class="notice">NS_ConvertUTF16toUTF8(</span>aString<span class="notice">).get()</span>);
+
+
+ // But don't hold onto the pointer longer than the lifetime of the temporary!
+ <span class="warning">const char* cstring = NS_ConvertUTF16toUTF8(aKey).get(); // BAD! |cstring| is dangling
+ printf("%s\n", cstring);</span>
+ }
+</pre>
+</div>
+ </dd>
+
+ </dl>
+
+<p>
+ Here are the email answers I have yet to format into the FAQ.
+ Some of the URLs may be out-dated or moved.
+ The messages are in order from oldest to newest.
+</p>
+<p class="editnote">[Note : In June, 2003, these emails were modified
+to better reflect what is stored in 'wide' string
+classes (UTF-16 string instead of UCS-2) and what
+related methods do as a part of the patch for <a href=
+"http://bugzilla.mozilla.org/show_bug.cgi?id=183156"
+title="replace UCS2 in function/class/method names with UTF16">bug 183156</a>.
+Therefore, they're a little different from the original emails
+written by <a href="http://ScottCollins.net/">Scott Collins</a>]
+</p>
+<hr>
+<pre>
+Date: Thu, 13 Apr 2000 19:41:47 -0400
+</pre>
+
+<p>Encoding Wars
+
+<p>This message is all about strings and the various encodings that might
+be used to interpret their contents, the ramifications of that, and
+where we're heading. The point of this message is to say what we're
+currently thinking, and get feedback. I apologize in advance for the
+rambling, and for the fact that this message may accidentally mix
+discussion of how things <strong>are</strong> and how they will be.
+
+<p>There are many different possible encodings. Three in common use in
+the Mozilla source base are: ASCII, UTF-16, and UTF-8. In ASCII, every
+<!--the Mozilla source base are: ASCII, UCS2, and UTF8. In ASCII, every-->
+character fits in 7-bits and is typically stored in an 8-bit byte. We
+usually represent ASCII strings with <span class="code">nsCString</span>s, <span class="code">nsXPIDLCString</span>s,
+or <span class="code">char</span> string literals. In UTF-16, characters occupy one 16-bit code unit (
+<a href="http://www.unicode.org/glossary/index.html#BMP_character">
+<abbr title="Basic Multilingual Plane">BMP</abbr>characters</a>)
+or two 16-bit code units
+(<a href="http://www.unicode.org/glossary/index.html#supplementary_character">
+<abbr title="Supplementary Plane : Plane 1 through 16">non-BMP</abbr> characters</a>).
+We usually represent UTF-16 strings as <span class="code">nsString</span>s, etc., i.e., two-byte
+or `wide' strings. UTF-8 is a multi-byte encoding. A character might
+occupy one, two, three, or four bytes. It is easiest to store and
+manipulate such a string within a single-byte or `narrow' string
+implementation.
+
+<p>None of our current string implementations know the encoding of the
+data they hold at any given moment. An <span class="code">nsCString</span> might legitimately
+hold data encoded in ASCII, UTF-8 or even EBCDIC for that matter.
+
+<p>Operations that convert from one encoding to another, or operations
+that are encoding sensitive (e.g., <span class="code">to_upper</span>), rightly belong in
+i18n. The fact that our current string interfaces automatically and
+implicitly convert between wide and narrow strings is actually the
+source of many errors in two particular categories: (1) unintended
+extra work, (2) mistaken re-encoding, e.g., accidentally `converting'
+a UTF-8 string to UTF-16 by pretending the UTF-8 string is ASCII and then
+padding with <span class="code">'\0'</span>s.
+
+<p>We've known these were bad for a long time, and have been trying to
+find the right way to fix them. The current thinking is to just byte
+the bullet and eliminate implicit conversions. That has interesting
+ramifications.
+
+<div class="source-code">
+<pre>
+void foo( const nsString&amp; aUTF16string );
+
+foo("hello"); // works! constructs a temporary |nsString| by
+ // converting the ASCII literal with padding.
+ // Note: this requires an allocation
+</pre>
+</div>
+
+<p>Though we've always hated this form since it requires a heap
+allocation. In current code, we recommend
+
+<div class="source-code">
+<pre>
+foo( nsAutoString("hello") );
+</pre>
+</div>
+
+<p>which still copy/converts, but at least it probably doesn't need to do
+a heap allocation. In the best of all worlds, no conversion, copying,
+or allocation would be necessary. To do that, you would need to be
+able to directly specify a UTF-16 string, e.g., with the <span class="code">L"hello"</span>
+notation, and wrap that in an interface that just held a pointer.
+E.g., something like
+
+<div class="source-code">
+<pre>
+void foo( const nsAReadableString&amp; aUTF16string );
+
+foo( nsLiteralString(L"hello") );
+</pre>
+</div>
+
+<p>There are problems with this example, however. The <span class="code">L</span> notation
+specifically makes objects that are arrays of <span class="code">wchar_t</span>, which under
+GCC is a 4-byte element. This leads to incompatibility with JS, and
+the annoyance of possibly bloated storage (I'm sort of minimizing the
+situation here. It's worse that I make it sound). More about tricks
+to get around this in a bit, but first, let me talk about what to do
+in the meantime while we're just getting rid of implicit constructors.
+ Initially to get around this problem (what problem? The problem that
+<span class="code">foo("hello")</span> stopped compiling on my machine when I threw the
+switch) I made a routine called <span class="code">NS_ConvertToString</span> which looked like
+this
+
+<div class="source-code">
+<pre>
+inline
+nsAutoString
+NS_ConvertToString( const char* anASCIIstring )
+ {
+ nsAutoString aUCS2string;
+ aUCS2string.AssignWithConversion(anASCIIstring);
+ return aUCS2string;
+ }
+</pre>
+</div>
+
+<p>Which lets me write
+
+<div class="source-code">
+<pre>
+foo( NS_ConvertToString("hello") );
+</pre>
+</div>
+
+<p>This was <strong>OK</strong>, but in discussion there were concerns about performance
+on machines that didn't <span class="code">inline</span> well, and issues about naming. In
+that meeting we came up with an alternate naming strategy that we
+think has room for growth and an implementation more likely to be
+efficient on every platform. The implementation is to define a new
+class that derives from <span class="code">nsAutoString</span>, but allows construction from a
+<span class="code">char*</span>
+
+<div class="source-code">
+<pre>
+class NS_ConvertASCIItoUTF16 : public nsAutoString
+ {
+ public:
+ NS_ConvertASCIItoUTF16( const char* );
+ // ...
+ };
+</pre>
+</div>
+
+<p>Which gives identical (though renamed) notation for calling <span class="code">foo</span>:
+
+<div class="source-code">
+<pre>
+foo( NS_ConvertASCIItoUTF16("hello") );
+</pre>
+</div>
+
+<p>It looks like a function call to an explicit encoding conversion. It
+acts like a function call to an explicit encoding conversion. It <strong>is</strong>
+a function call to an explicit encoding conversion. We think that
+this naming pattern has room for growth. In the meeting, we concluded
+that the best representation for encoding conversions is a family of
+functions, and <span class="code">NS_ConvertASCIItoUTF16</span> fits right in. We think that
+XPCOM probably can't live without the ASCII to UTF-16 conversion (though
+as explicit as possible) but that all others rightly belong in i18n
+land.
+
+<p>You can probably deduce from the clues in <span class="code">NS_ConvertToString</span>, above,
+that constructors weren't the only thing that became explicit.
+Assignment, appending, comparison, et al, got renamed so that when
+assigning, appending, or comparing to a value in a different encoding
+the `WithConversion' form must be used. E.g.,
+
+<div class="source-code">
+<pre>
+nsString aUTF16string;
+nsCString anASCIIstring;
+// ...
+
+aUTF16string += anASCIIstring; // Currently legal, but not for long
+aUTF16string.Append(anASCIIstring); // same
+
+aUTF16string.AppendWithConversion(anASCIIstring); // the new way
+
+if ( aUTF16string == anASCIIstring ) // Sorry, this is going away too
+ // ...
+
+if ( aUTF16string.EqualsWithConversion(anASCIIstring) )
+ // ...
+</pre>
+</div>
+
+<p>Yes, it's long and annoying. Just like the extra work you were
+implicitly asking to have done, perhaps incorrectly. There are other
+reasons to rename these functions. When <span class="code">nsString</span> and <span class="code">nsCString</span>
+defined a ton of, e.g., <span class="code">Append</span>s each there was no problem, because
+nobody wanted to override <span class="code">Append</span>. Now, with strings inheriting from
+abstract base classes we immediately run into the problem that
+overriding and overloading don't mix very well in C++. Because of a
+feature of C++ called name hiding, it is problematic to override only
+a single signature of a name overloaded in a base class. The base
+<span class="code">nsAWritableString</span> provides several <span class="code">Append</span>s, all for objects of
+(hopefully) the same encoding. <span class="code">nsString</span> can't easily add a bunch of
+new <span class="code">Append</span>s (the converting ones) without running face first into
+the name hiding problem. The discussion of the fix for this is mostly
+unrelated to encoding issues, so I'll defer it to another post.
+
+<p>In hindsight, after the meeting, it seemed clear that all the
+`WithConversion' forms would be better named
+
+<div class="source-code">
+<pre>
+xxxConvertingASCIItoUTF16
+xxxConvertingUTF16toASCII
+</pre>
+</div>
+
+<p>however, the <strong>real</strong> goal (probably) is to move most such conversions
+into i18n. Just bringing attention to the previously implicit
+conversions is a good first step. Renaming these conversions as just
+suggested is probably the right thing to do, though it sort of
+validates them, which I'm not sure we really want. This is a decision
+we need to discuss further.
+
+<p>Now, back to the string literal problem above. One possible solution
+is to use a macro. Imagine
+
+<div class="source-code">
+<pre>
+NS_LITERAL_STRING("Hello")
+</pre>
+</div>
+
+<p>which on a machine where the <span class="code">L</span> trick works, turns into
+
+<div class="source-code">
+<pre>
+nsLiteralString(L"Hello")
+</pre>
+</div>
+
+<p>but on a machine where there is trouble, turns into something less
+appealing, but more likely to work, like
+
+<div class="source-code">
+<pre>
+NS_ConvertASCIItoUTF16("Hello")
+</pre>
+</div>
+
+<p>Another solution is to add a compilation step that fixes <span class="code">L</span> strings
+on bad platforms to be non-<span class="code">L</span> strings, but padded with <span class="code">\0</span>s. E.g.,
+<span class="code">L"Hello"</span> gets preprocessed into <span class="code">"\000H\000e\000l\000l\000o\000"</span>.
+This solution is more annoying to the developer, where the prior
+solution is more annoying during the runtime.
+
+<p>Before we go to too much trouble on this specific feature, we will
+probably want to do more measurement to see just how much and how
+often we are converting constant literal strings, and why.
+
+
+<p>I'm currently ripping through the tree fixing things to use the
+`WithConversion' forms where appropriate. I was also converting
+things to use <span class="code">NS_ConvertToString</span> where appropriate; unless I get
+talked out of it, I want to switch midstream to
+<span class="code">NS_ConvertASCIItoUTF16</span>, then go back and fix up the
+<span class="code">NS_ConvertToString</span> instances later. I've set things up so I can
+check in as I go. After all these conversions have been done, I'll be
+able to throw the switch (what switch? NEW_STRING_APIS) which will
+make <span class="code">nsString</span> inherit from <span class="code">nsAWritableString</span>, etc. and allow us to
+start exploiting these other opportunities (e.g., for literal strings,
+shared strings, etc. See
+<a class="exact-uri" href="http://bugzilla.mozilla.org/show_bug.cgi?id=28221">http://bugzilla.mozilla.org/show_bug.cgi?id=28221</a> for details and
+reasoning.)
+
+<p>I guess I'm expecting comments on:
+
+<ul>
+ <li>how really annoying this whole topic is
+ <li>how bad <span class="code">L"xxx"</span> is
+ <li>whether to move forward with <span class="code">NS_ConvertASCIItoUTF16</span>
+ <li>whether we should move to xxxConvertingASCIItoUTF16 etc instead
+ of `WithConverting'
+ <li>arguments about where encoding conversions should live
+ <li>arguments about whether going between 1 and 2 byte storage is an
+ encoding conversion
+ <li>questions about stuff I didn't mention or didn't explain well
+ <li>pointing out stuff I'm just plain wrong about, or things I forgot
+ <li>etc
+</ul>
+
+<p>So as not to jumble the discussion, I'll be separately posting other
+requests for comments about specific features of the design of the new
+string hierarchy.
+
+<p>I hope this helps keep everybody filled in on what we're thinking and
+able to point out what we're forgetting or screwing up :-)
+
+
+
+
+
+<hr>
+<pre>
+Date: Wed, 19 Apr 2000 21:12:47 -0400
+Subject: more string info
+</pre>
+
+<p> <a class="exact-uri" href="news://news.mozilla.org/scc-705460.16423913042000@news.mozilla.org">news://news.mozilla.org/scc-705460.16423913042000@news.mozilla.org</a>
+
+
+
+
+
+<hr>
+<pre>
+Date: Fri, 26 May 2000 15:31:37 -0400
+Subject: Re: Question on ==
+</pre>
+
+<p>I would prefer you compare with <span class="code">Equals</span> (which should really be named
+<span class="code">IsEqualTo</span>) rather than <span class="code">operator==()</span> because of this:
+
+<div class="source-code">
+<pre>
+char* a;
+char* b;
+
+// ...
+
+if ( a == b )
+ // ...
+</pre>
+</div>
+
+<p>Comparing two raw `string' pointers doesn't compare the characters
+they point to, but instead compares the bits of the pointers. For
+this reason, I may eventually make comparison of a string with a
+pointer using operators just go away.
+
+
+
+
+
+<hr>
+<pre>
+Date: Wed, 14 Jun 2000 14:38:55 -0400
+Subject: Re: Fix to XprtDefs.h
+</pre>
+
+<p>Yes, we're aware that turning off <span class="code">wchar_t</span> support makes <span class="code">wchar_t</span> be
+a synonym for <span class="code">unsigned short</span> under Metrowerks. We know that the
+current version of VC++ also makes these types equivalent. In theory,
+though, the types are distinct even when they are the same size and
+shape. By using real <span class="code">wchar_t</span> support, we are forced to recognize
+the distinction and navigate it appropriately with <span class="code">reinterpret_cast</span>
+(via <span class="code">NS_REINTERPRET_CAST</span>). The win here is that we aren't caught by
+compiler changes that suddenly make some set of compilers compliant
+and therefore break our code. We will add an autoconf test that lets
+UNIX compilers opt in to our string scheme when they have an
+appropriately shaped <span class="code">wchar_t</span>. If these happen to be compliant
+compilers, all will be well. If they don't, the casts don't hurt,
+because they are type correct. We are writing our code to meet the
+standard as we move forward.
+
+<p>The win for us is realized by the following macros
+
+<div class="source-code">
+<pre>
+#ifdef HAVE_CPP_2BYTE_WCHAR_T
+ #define NS_LITERAL_STRING(s) nsLiteralString(L##s, \
+ (sizeof(L##s)/sizeof(wchar_t))-1)
+#else
+ #define NS_LITERAL_STRING(s) NS_ConvertASCIItoUTF16(s, \
+ sizeof(s)-1)
+#endif
+</pre>
+</div>
+
+<p>An <span class="code">nsLiteralString</span> points directly to the literal characters. No
+copying, no conversion, and the length calculation happens at compile
+time. This has turned out to be as large a savings as 15% of code
+space and 8% of data space, net, in our string test harness It's
+faster as well, again by eliminating the copying, conversion, and
+length calculation. We don't know yet what those numbers translate
+into in our real code base, but we have high hopes.
+
+<p>I don't want to be in the position to ask you to change your code. I
+don't think it's appropriate for me to do so. The AIM application
+that is your client is our client as well. They need to resolve this
+difference between us in whatever way they think best. That may mean
+asking you if changing your apis is the right thing to do. Or it may
+mean applying the casts. Our code-base and yours, Justin, are more
+like cousins. I don't think you should have to change just to conform
+to us. You may think my arguments for using real <span class="code">wchar_t</span> have
+merit, and adopt similar usage just because you agree; but I think the
+only obligation you have is to follow the technical solution you think
+is right for your code.
+
+<p>If you decide to make this api change, it will mean shipping a new
+binary (on Mac) for your library to clients who want to switch over to
+the new api (since the name mangling will be different, and therefore,
+the link requirements will change).
+
+<p>Hope this helps,
+
+
+
+
+
+<hr>
+<pre>
+Date: Thu, 15 Jun 2000 19:36:55 -0400
+Subject: Re: Checkin approval for bug 32336
+</pre>
+
+<div class="source-code">
+<pre>
+S.Equals(NS_LITERAL_STRING("bar"), PR_TRUE, 3)
+</pre>
+</div>
+
+<p>doesn't compile because there is no three parameter form for <span class="code">Equals</span>.
+ For all definitions of <span class="code">Equals</span> on strings, see "nsAReadableString.h"
+
+<p><a class="exact-uri" href="http://lxr.mozilla.org/seamonkey/source/xpcom/ds/nsAReadableString.h">http://lxr.mozilla.org/seamonkey/source/xpcom/ds/nsAReadableString.h</a>
+
+<p>There is an <span class="code">EqualsWithConversion</span> that takes three parameters.
+
+<p> <a class="exact-uri" href="http://lxr.mozilla.org/seamonkey/source/xpcom/ds/nsString2.h#731">http://lxr.mozilla.org/seamonkey/source/xpcom/ds/nsString2.h#731</a>
+
+<p>It is ``EqualsWithConversion'' because it admits the possibility of an
+encoding specific transformation, in this case to provide
+case-insensitive comparison. This also wouldn't compile, however,
+since, at the moment, an <span class="code">nsLiteralString</span> doesn't provide an operator
+to produce a <span class="code">const PRUnichar*</span> (though perhaps it should), and it
+doesn't satisfy the other interfaces that match this call, e.g., a
+<span class="code">const nsString&</span>.
+
+<p>Perhaps I need to move case-insensitive comparison up out of
+<span class="code">nsString</span> into a global encoding specific transformations and
+algorithms file (which was on its way anyway as Waterson, knows); this
+use is one bit of evidence to support this. In the short term, this
+can be fixed (if we think the current behavior is wrong) by providing
+<span class="code">operator const CharT*() const</span> on literal string.
+
+<p>If you can live with out case-folding, the earlier form is preferred
+
+<div class="source-code">
+<pre>
+S == NS_LITERAL_STRING("bar")
+</pre>
+</div>
+
+<p>if you can't, then one of the fixes I mentioned is in order.
+
+
+
+
+
+<hr>
+<pre>
+Date: Thu, 15 Jun 2000 19:47:12 -0400
+Subject: Re: [Fwd: how to use nsString ?]
+</pre>
+
+<pre class="email-quote">
+ >I see these same examples time and again in the embedding
+ >samples/docs, but I can't compile them.
+</pre>
+
+<p>Apologies. Documentation mentioning strings is getting out of date.
+Here are some specific answers.
+
+
+<pre class="email-quote">
+ >nsString URLString("http://www.mozilla.org");
+</pre>
+
+<p>...is now perhaps best expressed as
+
+ nsString URLString( NS_LITERAL_STRING("http://www.mozilla.org") );
+
+<p>since an <span class="code">nsString</span> is a sequence of 2-byte wide characters, and the
+routines that implicitly convert 1-byte sequences (like the literal
+sequence you specified, "http:...") are now gone.
+
+<p>Up until not too long ago, one would have had to say
+
+<div class="source-code">
+<pre>
+nsString URLString;
+URLString.AssignWithConversion("http://www.mozilla.org");
+</pre>
+</div>
+
+<p>The <span class="code">NS_LITERAL_STRING</span> construction is new machinery that has the
+potential to make many operations much more efficient.
+
+<pre class="email-quote">
+ >nsString URLString;
+ >URLString.SetString("www.mozilla.org");
+</pre>
+
+<p><span class="code">SetString</span> was a synonym for <span class="code">Assign</span> or assignment with
+<span class="code">operator=()</span>, it too went away. The equivalent is the second
+example I gave above, that is, the one with <span class="code">AssignWithConversion</span>.
+
+<p><span class="code">Assign</span> still exists. <span class="code">AssignWithConversion</span> takes on that
+functionality for assignments that require encoding transformations
+(e.g., from ASCII to UTF16). <span class="code">SetString</span> is gone, since it was always
+a synonym for <span class="code">Assign</span>.
+
+<p>Learn more about the general APIs for strings that we are trying to
+move to by examining
+
+<a class="exact-uri" href="http://lxr.mozilla.org/seamonkey/source/xpcom/ds/nsAReadableString.h">http://lxr.mozilla.org/seamonkey/source/xpcom/ds/nsAReadableString.h</a>
+<a class="exact-uri" href="http://lxr.mozilla.org/seamonkey/source/xpcom/ds/nsAWritableString.h">http://lxr.mozilla.org/seamonkey/source/xpcom/ds/nsAWritableString.h</a>
+
+<p>Hope this helps,
+
+
+
+
+
+<hr>
+<pre>
+Date: Thu, 15 Jun 2000 21:26:51 -0400
+Subject: Re: Checkin approval for bug 32336
+</pre>
+
+<pre class="email-quote">
+ >I *need* the count attribute, because I need to compare only the first
+ >chars (that's inherent to the logic).
+</pre>
+
+<p>This is what substrings are for. In that case, you could use
+
+<div class="source-code">
+<pre>
+Substring(S, 0, 3) == NS_LITERAL_STRING("bar")
+</pre>
+</div>
+
+<p>As for case-folding, it's best if you can case-fold everything up
+front, instead of doing it repeatedly. I'll have to get back to you
+on a general solution to that problem, or what my schedule for getting
+it checked in would be. I'm sorry, I know that's not what you needed
+to hear. If the source string is an <span class="code">nsString</span>, you can continue to
+exploit its implementation of these routines, e.g., <span class="code">ToLower</span> all
+up-front.
+
+<p>Hope this helps,
+
+
+
+
+
+<hr>
+<pre>
+Date: Mon, 19 Jun 2000 14:23:47 -0400
+Subject: Re: string fu
+</pre>
+
+<pre class="email-quote">
+ >It seems less convenient to have to first check path.IsEmpty, and
+ >then if false get path.Last and test it.
+</pre>
+
+<p>What would you prefer? That extracting a character not in the string
+always return <span class="code">CharT(0)</span>? Can't do it for two reasons: (1) <span class="code">0</span> may be
+a valid character in a particular encoding, so it can't be used in
+general as a ``no character at that position'' marker; and (2) I can't
+control what an individual string implementation does when asked to
+get an out-of-bounds fragment, it's explicitly undefined. That means
+the result of <span class="code">CharAt</span> is explicitly undefined for indexes outside the
+defined contents of the string. As a debugging convenience, I have
+made this assert, but it has always been the case that retrieving such
+a character had undefined results ... even in [the old] code.
+
+<p>OK, you might say, well at least let me ask for a character that is
+only off the end by one. E.g., <span class="code">Last</span> of an empty string. Reason (1)
+from above still applies. How bad is it to say, for the case you gave
+
+<div class="source-code">
+<pre>
+PRBool needsDelim = PR_FALSE;
+if ( !path.IsEmpty() )
+ {
+ PRUnichar last = path.Last();
+ needsDelim = !(last == '/' || last == '\\');
+ }
+</pre>
+</div>
+
+<p>In general, you probably want to opt out of a whole lot of work when
+the source string is empty. It is slightly less convenient, but it
+doesn't tie us to a bunch of implementation specific mojo.
+
+
+<pre class="email-quote">
+ >Can we fix GetUnicode in this case?
+</pre>
+
+<p>This is an annoying property of auto strings, e.g., that they always
+have an allocated buffer. I'm happy to fix this bug, however, be
+aware that <span class="code">GetUnicode</span> and <span class="code">GetBuffer</span> are artifacts of [the old]
+implementation that we don't want to support. They are not part of
+the abstract interface. We will keep them no longer than we have to.
+They don't support our multi-fragment paradigm. People who require a
+contiguous hunk of characters in the future, and are unwilling to
+switch over to chunky-iterators, may be forced to copy the string to
+their own buffer. There will be an implementation of narrow character
+string that guarantees contiguous allocation and a zero-terminator,
+much as <span class="code">nsCString</span> does now, for compatibility with platform uses,
+but this won't be the default string class.
+
+
+
+
+
+<hr>
+<pre>
+Date: Mon, 19 Jun 2000 17:22:31 -0400
+</pre>
+
+<p>Clarifying String Sematics
+
+<p>Recently, I added an assert to the string operations that extract
+characters, namely <span class="code">First()</span>, <span class="code">Last()</span>, <span class="code">CharAt()</span>, and
+<span class="code">operator[]()</span>. This assert fires when any of these routines are used
+to access a character outside the defined contents of the string. For
+<span class="code">First()</span> and <span class="code">Last()</span> that means whenever they are applied to an
+empty string. For <span class="code">CharAt()</span> and <span class="code">operator[]()</span>, that means whenever
+they are used to access an index outside the range of
+<span class="code">0</span>..<span class="code">Length()-1</span>. There have been some complaints, however, the
+result was always undefined. What follows is extracted from an email
+exchange between me and warren on this topic. I hope it clarifies
+strings semantics
+
+<p>Warren writes:
+<pre class="email-quote">
+ >I hit your funky CharAt assertion tonight in this piece of code:
+
+ >NS_IMETHODIMP
+ >nsIOService::ResolveRelativePath(
+ > const char *relativePath,
+ > const char* basePath,
+ > char **result )
+ > {
+ > nsCAutoString name;
+ > nsCAutoString path(basePath);
+ >
+ > PRUnichar last = path.Last();
+ > PRBool needsDelim = !(last == '/' || last == '\\' || last ==
+ > '\0');
+ > ...
+
+ >where basePath is null. It seems less convenient to have to first
+ >check path.IsEmpty, and then if false get path.Last and test it.
+</pre>
+
+<p>I replied:
+<pre class="email-quote">
+ >What would you prefer? That extracting a character not in the
+ >string always return <span class="code">CharT(0)</span>? Can't do it for two reasons:
+ >(1) <span class="code">0</span> may be a valid character in a particular encoding, so it
+ >can't be used in general as a ``no character at that position''
+ >marker; and (2) I can't control what an individual string
+ >implementation does when asked to get an out-of-bounds fragment,
+ >it's explicitly undefined. That means the result of <span class="code">CharAt</span> is
+ >explicitly undefined for indexes outside the defined contents of
+ >the string. As a debugging convenience, I have made this assert,
+ >but it has always been the case that retrieving such a character
+ >had undefined results ... even in [the old] code.
+
+ >OK, you might say, well at least let me ask for a character that
+ >is only off the end by one. E.g., <span class="code">Last</span> of an empty string.
+ >Reason (1) from above still applies. How bad is it to say, for the
+ >case you gave
+
+ > PRBool needsDelim = PR_FALSE;
+ > if ( !path.IsEmpty() )
+ > {
+ > PRUnichar last = path.Last();
+ > needsDelim = !(last == '/' || last == '\\');
+ > }
+
+ >In general, you probably want to opt out of a whole lot of work
+ >when the source string is empty. It is slightly less convenient,
+ >but it doesn't tie us to a bunch of implementation specific mojo.
+</pre>
+
+<p>Warren also asks:
+<pre class="email-quote">
+ >Here's another issue, perhaps more serious. If I say this:
+
+ > foo(const PRUnichar* s) {
+ > nsAutoString str(s);
+ > bar(str.get());
+ > }
+
+ >where s is null, bar will get passed a zero-length PRUnichar
+ >sequence instead of null. This makes it so that you can't just
+ >test for the argument == null. You have to nsCRT::strlen(arg) == 0
+ >which is much less efficient. Can we fix GetUnicode in this case?
+</pre>
+
+<p>And I reply:
+<pre class="email-quote">
+ >This is an annoying property of auto strings, e.g., that they
+ >always have an allocated buffer. I'm happy to fix this bug,
+ >however, be aware that <span class="code">GetUnicode</span> and <span class="code">GetBuffer</span> are artifacts
+ >of [the old] implementation that we don't want to support. They
+ >are not part of the abstract interface. We will keep them no
+ >longer than we have to. They don't support our multi-fragment
+ >paradigm. People who require a contiguous hunk of characters in
+ >the future, and are unwilling to switch over to chunky-iterators,
+ >may be forced to copy the string to their own buffer. There will
+ >be an implementation of narrow character string that guarantees
+ >contiguous allocation and a zero-terminator, much as <span class="code">nsCString</span>
+ >does now, for compatibility with platform uses, but this won't be
+ >the default string class.
+</pre>
+
+<p>In a later message, Chris Waterson asks a related question
+<pre class="email-quote">
+ >scc: should we add <span class="code">operator PRUnichar*()</span> to
+ >NS_ConvertASCIItoUTF16?
+</pre>
+
+<p>And I reply:
+<pre class="email-quote">
+ >It seems reasonable. A lot more reasonable that forcing people to
+ >call <span class="code">GetUnicode()</span>. I alluded to platform specific classes in an
+ >earlier message to warren that you were cc'd on, Chris. I imagine
+ >that the <span class="code">...Convert...</span> routines would be required to produce
+ >contiguous allocation 0-terminated strings (though the as yet
+ >unimplemented <span class="code">...Copy...</span> forms, of course wouldn't. So <span class="code">operator
+ >const PRUnichar*() const</span> makes perfect sense to me here.
+</pre>
+
+<p>Hope this makes sense,
+
+
+
+
+<hr>
+<pre>
+Date: Tue, 20 Jun 2000 04:05:31 -0400
+Subject: Re: NS_LITERAL_STRING is broken
+</pre>
+
+<p>The behavior you describe sounds exactly like when you say
+
+<div class="source-code">
+<pre>
+const char* foobar = "foobar";
+
+... NS_LITERAL_STRING(foobar).get() ...
+</pre>
+</div>
+
+<p>because in this case, the thing passed in is a <span class="code">const char*</span>.
+<span class="code">NS_LITERAL_STRING</span> is not meant to be used in this way. It is only
+meant to be used around a <span class="code">"</span> delimited string. The type of such is
+<span class="code">const char[N]</span> where N is the number of characters in the string + 1
+for the zero terminator it helpfully adds. <span class="code">sizeof</span> such a type is
+<span class="code">N</span>.
+
+<p>Are you sure you had the actual string as an argument, as in your
+example to me? Or could the actual code have been like my sample,
+above?
+
+
+
+
+
+<hr>
+<pre>
+Date: Thu, 29 Jun 2000 13:35:10 -0400
+Subject: Re: a fix
+</pre>
+
+<pre class="email-quote">
+ > + if (Length() == 0) { return nsnull; }
+</pre>
+
+
+<p>Dave,
+
+<p>please read
+
+ <a class="exact-uri" href="news://news.mozilla.org/scc-314ABF.14261619062000@news.mozilla.org">news://news.mozilla.org/scc-314ABF.14261619062000@news.mozilla.org</a>
+
+<p>It's just plain wrong to let people try to index into a string outside
+its defined contents. I can't just return <span class="code">'\0'</span> or <span class="code">PRUnichar('\0')</span>
+there as that <strong>could</strong> be a legal value to have somewhere in your
+string for some encodings ... and the encoding is not specified. So
+your patch has the basic problem of defeating my plan to stop people
+from doing this bad thing.
+
+<p>The second problem with your patch is that you use the symbolic
+constant <span class="code">nsnull</span>, which is ostensibly a pointer value; <span class="code">Last</span> returns
+a character. <span class="code">nsnull</span> is not appropriate for that purpose. In fact,
+C++ gurus pretty much eschew the use of symbolic constants for <span class="code">0</span>.
+<span class="code">NULL</span> is to be avoided. <span class="code">nsnull</span> is wrong-headed in that it presumes
+we could have some <strong>other</strong> application specific value for <span class="code">NULL</span>. We
+can't, it would never work. It's just wasted brain-print. Always use
+<span class="code">0</span> for these situations, and if you want to communicate the fact that
+something is a pointer type, either use a comment or a
+(construction-style) cast, like so (graded examples from worst to
+best:)
+
+<ul>
+ <li>F: FindChildByNameWithHint("Chuck", nsnull);
+
+ <li>D: FindChildByNameWithHint("Chuck", NULL);
+
+ <li>C: FindChildByNameWithHint("Chuck", /* Child* */ 0);
+
+ <li>B: typedef Child* Child_ptr;
+ FindChildByNameWithHint("Chuck", Child_ptr(0));
+
+ <li>A: FindChildByNameWithHint("Chuck", 0);
+</ul>
+
+<p>Don't let this discourage you; keep up the good work :-)
+
+
+
+
+
+<hr>
+<pre>
+Date: Tue, 8 Aug 2000 23:47:16 -0400
+Subject: Re: nsWritingIterator?
+</pre>
+
+<pre class="email-quote">
+ >Can you give me any pointers to examples, or docs, or just some
+ >general advice?
+</pre>
+
+ <a class="exact-uri" href="http://ScottCollins.net/Journal/discussion/string_iterators.html">http://ScottCollins.net/Journal/discussion/string_iterators.html</a>
+
+<p>does this help?
+
+<p>I can personally walk you through any specific scenario you need.
+
+
+
+
+
+<hr>
+<pre>
+Date: Wed, 9 Aug 2000 02:35:03 -0400
+Subject: Re: nsWritingIterator?
+</pre>
+
+<p>You got it right... it's <span class="code">nsWritingIterator<CharT></span> for whichever
+character type you care about, either <span class="code">char</span> or <span class="code">PRUnichar</span>. You
+_can_ use this iterator like a character pointer ... that is, you can
+dereference it, assign into its dereference, etc. It is more
+efficient, though, to directly address a particular range of
+characters around where it points by asking it for its actual
+character pointer with <span class="code">get</span>, and knowing that there are
+<span class="code">size_forward()</span> characters available ahead of that pointer and
+<span class="code">size_backward()</span> characters available behind it. After examining
+those characters by hand, you can advance the iterator beyond the
+characters you have examined (and possibly into the next chunk, should
+one exist) by adding into it (with +=) the count of the characters you
+have processed.
+
+<p>Here are three examples of running through a string and modifying some
+of the characters in it. All use <span class="code">nsWritingIterator</span>s.
+
+
+<div class="source-code">
+<pre>
+ // inefficient, but works in a pinch:
+ // iterators can hide all details of chunks by acting like
+ // a raw character pointer
+
+nsWritingIterator&lt;PRUnichar&gt; s = S.BeginWriting();
+nsWritingIterator&lt;PRUnichar&gt; done_with_string = S.EndWriting();
+
+ // for each character in the string |S|
+while ( s != done_with_string )
+ {
+ // if the character is lower case, capitalize it
+ if ( 'a' &lt;= *s &amp;&amp; *s &lt;= 'z' )
+ *s = *s -'a' + 'A';
+ }
+
+
+
+
+ // efficient
+ // iterators provide a mechanism by which you can process
+ // a chunk-at-a-time
+
+nsWritingIterator&lt;PRUnichar&gt; iter = S.BeginWriting();
+nsWritingIterator&lt;PRUnichar&gt; done_with_string = S.EndWriting();
+
+ // for each chunk of the string
+while ( iter != done_with_string )
+ {
+ size_t N = iter.size_forward(); // # of chars in this chunk
+ PRUnichar* s = iter.get();
+ PRUnichar* done_with_chunk = s + N;
+
+ // for each character in this chunk
+ for ( ; s &lt; done_with_chunk; ++s )
+ {
+ // if the character is lower case, capitalize it
+ if ( 'a' &lt;= *s &amp;&amp; *s &lt;= 'z' )
+ *s = *s - 'a' + 'A';
+ }
+
+ // advance the iterator past characters
+ // we examined (and into the next chunk, if any)
+ s += N;
+ }
+
+
+
+ // elegant
+ // pull your transformation into a `sink', and |copy_string|
+ // will efficiently pump any kind of string into it
+
+struct Capitalize
+ {
+ // inline
+ PRUint32
+ write( PRUnichar* s, PRUint32 N )
+ // processes one chunk, called repeatedly by |copy_string|
+ {
+ PRUnichar* done_with_chunk = s + N;
+
+ // for each character in this chunk
+ for ( ; s &lt; done_with_chunk; ++s )
+ {
+ // if the character is lower case, capitalize it
+ if ( 'a' &lt;= *s &amp;&amp; *s &lt;= 'z' )
+ *s = *s - 'a' + 'A';
+ }
+ }
+ };
+
+copy_string(S.BeginWriting(), S.EndWriting(), Capitalize());
+</pre>
+</div>
+
+
+
+<p>Does this show it better?
+
+
+
+
+
+<hr>
+<pre>
+Date: Thu, 17 Aug 2000 18:23:22 -0400
+</pre>
+
+<pre class="email-quote">
+ >I tried looking at the string header files but they
+ >are awfully complicated.
+</pre>
+
+<p>I'll explain things in a little <strong>more</strong> detail than you need, then so
+that some of the stuff you see in these headers will make more sense.
+I'll also answer your questions out of order.
+
+<p>First: the string hierarchy looks like this
+
+<a class="exact-uri" href="http://ScottCollins.net/Journal/discussion/string_hierarchy.gif">http://ScottCollins.net/Journal/discussion/string_hierarchy.gif</a>
+
+<p>The two most important headers are:
+
+<a class="exact-uri" href="http://lxr.mozilla.org/seamonkey/source/xpcom/ds/nsAReadableString.h">http://lxr.mozilla.org/seamonkey/source/xpcom/ds/nsAReadableString.h</a>
+<a class="exact-uri" href="http://lxr.mozilla.org/seamonkey/source/xpcom/ds/nsAWritableString.h">http://lxr.mozilla.org/seamonkey/source/xpcom/ds/nsAWritableString.h</a>
+
+<p>These abstract classes, <span class="code">nsAReadable[C]String</span>, and
+<span class="code">nsAWritable[C]String</span> are typically what you will want to use in the
+interfaces of new code. If you write a piece of code that takes a
+string for input, consider, e.g.,
+
+<div class="source-code">
+<pre>
+void consumes_a_string( const nsAReadableString&amp; aInput );
+</pre>
+</div>
+
+<p>If you write a piece of code that modifies a string, consider
+
+<div class="source-code">
+<pre>
+void modifies_a_string( nsAWritableString&amp; aResult );
+</pre>
+</div>
+
+
+<p>When creating your own classes, member strings will typically be
+<span class="code">nsString</span>s. When you can't avoid creating a short string that you
+need only temporarily during a function, you will typically use
+<span class="code">nsAutoString</span>. When someone passes you a raw pointer, or a raw
+pointer and a length, representing a buffer of characters that you may
+examine, but won't own, you can treat it like a string by wrapping it
+in an <span class="code">nsLiteralString</span>, e.g.,
+
+<div class="source-code">
+<pre>
+void
+reads_a_buffer( const PRUnichar* aInput, PRUint32 aInputLength )
+ {
+ nsLiteralString input(aInput, aInputLength);
+ // doesn't allocate or copy
+
+ // ...
+ }
+</pre>
+</div>
+
+<p>You will use <span class="code">nsLiteralString</span> around quoted constant strings as well,
+though typically through the <span class="code">NS_LITERAL_STRING</span> macro, to avoid doing
+a length calculation
+
+<div class="source-code">
+<pre>
+NS_LITERAL_STRING("x")
+</pre>
+</div>
+
+<p>expands to
+
+<div class="source-code">
+<pre>
+nsLiteralString(L"x", (sizeof(L"x")/sizeof(PRUnichar) - 1))
+</pre>
+</div>
+
+<p>if <span class="code">L</span> notation works as needed on your platform.
+
+Those are the basics. Now onto your questions:
+
+
+<pre class="email-quote">
+ >For example this won't compile. [...]
+
+ >str1 += L"abc " + str2 + L"def";
+</pre>
+
+
+<p><span class="code">L"abc "</span> makes a an object that is a <span class="code">const wchar_t[5]</span>, and none of
+the string code knows about <span class="code">wchar_t</span>. The main reason is that
+<span class="code">wchar_t</span> is not necessarily the right size (it can be 4 bytes under
+gcc). If you wrap these constant expressions in <span class="code">NS_LITERAL_STRING</span>,
+as described above, you should get the right thing, e.g.,
+
+<div class="source-code">
+<pre>
+str1 += NS_LITERAL_STRING("abc ") + str2 + NS_LITERAL_STRING("def");
+</pre>
+</div>
+
+
+<pre class="email-quote">
+ >Another one is:
+ >function(const PRUnichar *foo);
+ >call function(L"abc " + str2);
+
+ >It won't create a temporary nsString.
+</pre>
+
+<p>This one, I have a quick and easy explanation for. If <span class="code">function</span> was
+declared like this
+
+<div class="source-code">
+<pre>
+function( const nsAReadableString&amp; )
+</pre>
+</div>
+
+<p>then, no problem, since a <span class="code">nsPromiseConcatenation</span> (which was the
+result of adding those two things together) <strong>is</strong> a readable string.
+No other objects need to be created; no copying needs to be performed.
+
+<p>In all cases, we want the creation of <span class="code">nsString</span>s et al, to be
+<span class="code">explicit</span>, since creation is unbelievably expensive, requiring heap
+allocation, locks, copying, etc.
+
+<p>I hope this answers both your posts,
+
+
+
+
+
+<hr>
+<pre>
+Date: Thu, 17 Aug 2000 20:57:08 -0400
+Subject: re our conversation
+</pre>
+
+ return ToNewUnicode( nsLiteralCString(buffer) );
+
+
+
+
+
+
+<hr>
+<pre>
+Date: Fri, 18 Aug 2000 02:52:45 -0400
+Subject: Re: More questions and new string API
+</pre>
+
+<pre class="email-quote">
+ >1) How do I return a static string?
+
+ >const nsAReadableString&amp; foo() {return NS_LITERAL_STRING("x");}
+ >errors on taking the address of a temporary variable.
+</pre>
+
+<p>Unfortunately, <span class="code">NS_LITERAL_STRING</span>s definition is not particularly
+amenable to this use. Instead, you would have to say something like
+this:
+
+<div class="source-code">
+<pre>
+const nsAReadableString&
+foo()
+ {
+#ifdef HAVE_CPP_2BYTE_WCHAR_T
+ static nsLiteralString static_foo(L"x", 1);
+#else
+ static nsLiteralString static_foo;
+ static PRBool initialized = PR_FALSE;
+ if ( !initialized )
+ {
+ static_foo.AssignWithConversion("x", 1);
+ initialized = PR_TRUE;
+ }
+#endif
+ return static_foo;
+ }
+</pre>
+</div>
+
+
+<pre class="email-quote">
+ >2) I'm using these with the STL library in an XPCOM component.
+ >What type should I use with map? This doesn't work...
+
+ >typedef map<const nsAReadableString&, myType*> mapStringMyType;
+ >mapStringMyType foo;
+ >foo.find(nsAReadableString); - I want to find on a ReadableString
+</pre>
+
+<p>I don't know what errors you are getting; but it probably doesn't work
+because a reference isn't an assignable type. This is just a guess.
+You may need to use
+
+<div class="source-code">
+<pre>
+map<const nsAReadableString*, myType*>
+</pre>
+</div>
+
+<p>If you actually want the map to manage ownership of the keys, then
+you'll want to use a concrete type, e.g.,
+
+<div class="source-code">
+<pre>
+map<nsString, myType*>
+</pre>
+</div>
+
+<p>or perhaps
+
+<div class="source-code">
+<pre>
+map<nsSharedStringPtr, myType*>
+</pre>
+</div>
+
+<p>Or maybe there's something else wrong. Send me the error messages.
+If you end up using a pointer, then of course you'll have to supply a
+comparison function to the <span class="code">map</span> template. You won't be satisfied
+with the default comparison of pointers :-) Sorry I couldn't answer
+this one more completely.
+
+
+<pre class="email-quote">
+ >3) How do a get a raw PRUnichar pointer out of nsAReadableString
+ >when I need to call something that wants 'unsigned short *'?
+</pre>
+
+<p>The problem with this scenario is that an <span class="code">nsAReadableString</span> doesn't
+promise that all its data is contiguous, nor that it is
+zero-terminated, which is what I suspect you want in this case. If
+the function you want to call can take {pointer, length} tuples, and
+can consume the string in hunks without zero termination ... then you
+can use <span class="code">copy_string</span> to pump the string into your function, see
+
+ <a class="exact-uri" href="http://ScottCollins.net/Journal/discussion/string_iterators.html">http://ScottCollins.net/Journal/discussion/string_iterators.html</a>
+
+<p>If not, and you absolutely have to have a contiguous zero-terminated
+buffer, then there is a new facility (part of the DOMAPI branch) that
+does what you need. It's not checked in on the trunk; it should
+be in early next week. It is <span class="code">nsPromiseFlatString</span>. This class
+promises a contiguous zero-terminated buffer; and has an <span class="code">operator
+PRUnichar*</span> to produce a pointer to that buffer automatically. If the
+underlying class <strong>is</strong> one that happens to be a single fragment and
+zero-terminated, then, like <span class="code">nsPromiseSubstring</span> and
+<span class="code">nsPromiseConcatenation</span>, this class merely holds a reference into the
+original data. If, however, the underlying string is multi-fragment
+or not zero-terminated, then <span class="code">nsPromiseFlatString</span> allocates a
+contiguous buffer of appropriate size and copies the fragmented string
+data to it. So given
+
+<div class="source-code">
+<pre>
+void ReadBuffer( PRUnichar* );
+</pre>
+</div>
+
+<p>You can call this as efficiently as possible with an arbitrary string
+like so
+
+<div class="source-code">
+<pre>
+ReadBuffer( nsPromiseFlatString(aString) );
+</pre>
+</div>
+
+
+<p>If the function you are calling needs to take ownership of the buffer
+you hand it, then you will probably call <span class="code">ToNewUnicode</span> like so
+
+<div class="source-code">
+<pre>
+void ConsumeBuffer( PRUnichar* );
+
+ConsumeBuffer( ToNewUnicode(aString) );
+</pre>
+</div>
+
+<p>The global function <span class="code">ToNewUnicode</span> is declared in "nsReadableUtils.h",
+and was only recently added to the build. It is currently being used
+in the DOMAPI branch. It is part of the build, but the file
+"dlldeps.c" in XPCOM may need to be modified to ensure it is exported
+on your platform if you are building the tip.
+
+Needless to say, you want to avoid functions that require bare
+pointers for several reasons: (a) they typically assume
+zero-termination, which is not guaranteed by the normal encodings; (b)
+they require contiguous allocation, which may not be possible; (c)
+they scan for the end of the string, at linear cost (if the encoding
+makes it possible at all), when the length could be known in advance.
+If you have to do it, the above mechanisms work, but be aware of the
+cost and the potential need to copy.
+
+
+<pre class="email-quote">
+ >4) How do I declare a local variable to hold a nsAReadableString?
+ >and a member variable?
+</pre>
+
+<p><span class="code">nsAReadableString</span> is an abstract type. So you can't have a concrete
+instance of it. All strings in the hierarchy are readable strings.
+If you just want a reference to a readable string, you can say, e.g.,
+
+<div class="source-code">
+<pre>
+struct foo
+ {
+ const nsAReadableString&amp; mString;
+ // ...
+
+ foo( const nsAReadableString&amp; aString ) : mString(aString) { }
+ };
+</pre>
+</div>
+
+<p>...similarly with pointers; but I suspect you are looking for
+something more concrete. An <span class="code">nsString</span> is a <span class="code">nsAReadableString</span>, and
+is the typical thing you want as a member variable. An <span class="code">nsAutoString</span>
+is also an <span class="code">nsAReadableString</span> and is typically what you would use for
+a short (in length) temporary (in lifetime) local variable, as I
+mentioned in my previous post.
+
+
+<pre class="email-quote">
+ >5) If I call a function that returns a PRUnichar* and I want t
+ >use it as a nsAReadableString should I wrap it in a
+ >nsLiteralString?
+</pre>
+
+<p>Yes, though remember, an <span class="code">nsLiteralString</span> assumes the lifetime of the
+underlying data is under someone else's control. If the called
+function gives you a buffer that you need to <span class="code">delete</span>, you will have
+to manage that yourself. Currently, people often use <span class="code">nsXPIDLString</span>
+to handle that. XPIDL strings are <strong>not</strong> part of the hierarchy. They
+are only used as a sort of string-<span class="code">auto_ptr</span>. However, I'm
+integrating their functionality into <span class="code">nsString</span>. There is no problem
+in wrapping the same pointer in both as two separate local variables,
+one to give you the readable interface, and one to manage the
+lifetime.
+
+<p>If it's OK with you, I'd like to post this reply (including your
+quoted questions) to n.p.m.xpcom and also put a copy near the string
+iterator discussion I provided a link to above, so that other people
+with similar questions can see these answers.
+
+<p>Hope this helps,
+
+
+
+
+
+<hr>
+<pre>
+Date: Sun, 3 Sep 2000 03:52:17 -0400
+</pre>
+
+<p>In article <8nu9m2$eo14@secnews.netscape.com>, "Jon Smirl"
+<jonsmirl@mediaone.com> wrote:
+
+> I have the new strings up and running in my app. They work as
+> advertised and
+> I haven't found any bugs. Thanks for the good job in designing and
+> implementing them. Here's are a summary of issues I've encountered
+> so far...
+
+<p>Thanks, and I appreciate your comments and insights.
+
+
+>
+> 1) Should there be a nsSegmentedString derived from nsString instead
+> of building segment support into nsString? None of my strings are
+> segmented but
+> I keep executing code that is supports it. nsPromiseFlatString would
+> be trivial in the non-segmented case.
+
+<p>The general case is that a string does not promise to have contiguous
+data. A specific case is that, for some implementations, it does.
+You couldn't do it the other way around, because a segmented string
+couldn't satisfy all the promises of a flat string. However, through
+the use of chunky iterators, operating on strings that happen to be
+flat is very efficient. In fact, <span class="code">nsPromiseFlatString</span> is trivial in
+the non-segmented case. In addition, I'll be adding an abstract flat
+class into the hierarchy, which will present additional interface ...
+in your local routines where you actually have declared a concrete
+string instance that happens to be flat, the compiler will give you
+the benefit of using the flat specific routines (e.g., a substring
+object over a flat string is simpler than the general purpose
+substring). I need to be cautious about this, though, since I don't
+automatically want people propagating the flat type through their
+interfaces. That would put us in the same boat we're in right now ...
+where routines only work on a specific kind of string, which denies
+other parts of the code the opportunity to use an implementation
+beneficial to its specific needs, and typically for no good reason.
+
+>
+> 2) Should nsAWritableString have a way to get the buffer and then
+> return it?
+> I need to get the buffer to pass it to OS calls. I'm doing this now
+> by passing around nsStrings instead of the interface. If I just use
+> the interface I encur an extra copy since I have to use a temporary
+> buffer.
+
+<p>A specific string implementation could promise this, but in general, a
+writable could not. After all, a writable doesn't even guarantee
+contiguous storage. To some degree, this is what
+<span class="code">nsPromiseFlatString</span> is for. However, this is a readable promise
+only. It will also be the case that <span class="code">ns[C]String</span>s, in the very near
+future will be able to just assume ownership of an arbitrary buffer
+allocated on the free store with the XPCOM allocators ... getting one
+to give up its buffer, on the other hand, presents some problems. Do
+you have a lot of places where the system writes into your string
+buffer space? Or do you have a lot of system routines that return you
+new buffers? I can imagine using <span class="code">nsPromiseFlatString</span> for this, but
+what happens when the OS alters the underlying data? If the promise
+had generated that flat data on behalf of a multi-fragment string,
+should it now put the changes back? It's possible to do, I just want
+to know if it's correct to allow this situation to happen.
+
+
+
+>
+> 3) There needs to be a NS_LITERAL_CHAR() to go along with
+> NS_LITERAL_STRING().
+
+<p>OK.
+
+
+
+> Having NS_LITERAL_STRING() all over the code clutters
+> it up and makes it hard to tell what the code is doing, could we
+> have a standard short alias for this?
+
+<p>Yes, I'll try to think of something ... perhaps <span class="code">NS_LSTR</span>?
+
+
+> 4) nsLiteralString should support n.ToInteger(&error);
+
+<p><span class="code">ToInteger</span> is actually a bad interface. It's only good if your
+entire string is the number; this encourages you to edit your string
+until it is one, or perhaps copy the numeric part to another string.
+Better if you just <span class="code">sscanf</span> a string (don't know if I can provide
+that in the general case, but I'm thinking about it), or else use
+regular C++ extractors (which wouldn't be too hard for me to
+provide), or else I could give you a <span class="code">ToInteger</span> that works on a pair
+of iterators, extracting the integer from the digits between them.
+
+>
+> 5) There should be a global define for an interface to a readonly
+> empty string.
+
+<p>Yes, there will be.
+
+
+>
+> 6) Something is wrong with concatenation....
+
+<p>Hopefully I've fixed this now.
+
+
+
+> 8) A forward definition is missing in the h files
+
+<p>I'll check it out.
+
+
+
+<p>My understanding is that you have already found the answers to your
+other questions.
+
+<p>I hope this helps,
+
+
+
+
+<hr>
+<pre>
+Date: Wed, 20 Sep 2000 17:32:13 -0400
+Subject: Re: how to free an nsString::ToNewCString
+</pre>
+
+<pre class="email-quote">
+ >What's the current approved way to free an nsString::ToNewCString?
+</pre>
+
+<p><span class="code">nsMemory::Free</span>
+
+
+
+
+
+<hr>
+
+<p>You use several <span class="code">NS_ConvertASCIItoUTF16("...").get()</span>, these should be
+
+ NS_LITERAL_STRING("...").get()
+
+<p>Don't do this to the very first case where you aren't wrapping an actual literal string.
+The first instance would should exploit <span class="code">NS_LITERAL_STRING</span> technology as well,
+around the initial declarations of the strings ... probably want to do this with
+<span class="code">NS_NAMED_LITERAL_STRING</span>.
+
+
+
+<hr>
+<pre>
+Date: Thu, 12 Oct 2000 00:57:28 -0400
+Subject: string answers
+</pre>
+
+<div class="source-code">
+<pre>
+nsresult
+DoSomething( nsAWritableString&amp; answer )
+ {
+ nsresult rv;
+
+ nsXPIDLString registry_data;
+ Fetch("key", getter_Shares(registry_data));
+
+ nsLiteralString path(not_my_string);
+
+ PRInt32 first_colon = path.FindChar(PRUnichar(':'));
+ if ( first_colon != -1 )
+ {
+ // convert ... extract path from |path|
+ nsCOMPtr<nsILocalFile> localFile( do_CreateInstance(CID, &rv)
+);
+ if ( localFile )
+ {
+
+localFile->SetPersistentDescriptor(NS_ConvertUTF16toUTF8(path));
+
+ nsXPIDLString converted_path;
+ localFile->GetUnicodePath(getter_Copies(converted_path));
+ answer = converted_path.get();
+ }
+ }
+ else
+ {
+ answer = path;
+ }
+
+
+ return rv;
+ }
+</pre>
+</div>
+
+
+
+
+
+<hr>
+<pre>
+Date: Thu, 12 Oct 2000 02:03:49 -0400
+Subject: Re: and the answer is ...
+</pre>
+
+<p>You can see from the line of code that you're on, that this should
+have been fine. <span class="code">nsMemory::Alloc</span> would be asked to allocate a 1 byte
+object. But it failed trying to allocate that. Which suggests that
+the allocator was busy and non-reentrant and the debugger tried to
+misuse it. Yes?
+
+<p>Of course, this doesn't solve your problem. Perhaps we need to go
+back to the idea of a function that returns a pointer to the first
+hunk of the string.
+
+<div class="source-code">
+<pre>
+const char*
+debug_string( const nsAReadableCString& aCString )
+ {
+ nsReadingIterator&lt;char&gt; iter;
+ aCString.BeginReading(iter);
+ return aCString.IsEmpty() ? "" : iter.get();
+ }
+</pre>
+</div>
+
+<p>This code should work regardless of what the allocator is doing. The
+downsides are (a) it only returns the first hunk of the string, in the
+case of a multi-fragment string; and (b) that hunk <strong>might</strong> not be
+zero-terminated.
+
+<p>Hope this helps,
+
+
+
+
+
+<hr>
+<pre>
+Date: Thu, 12 Oct 2000 08:30:32 -0400
+Subject: Re: Self healing the cache :-)
+</pre>
+
+<p>At 3:04 PM -0400 10/11/00, Mike Shaver wrote:
+<pre class="email-quote">
+ >NS_LITERAL_STRING(NS_XPCOM_SHUTDOWN_OBSERVER_ID);
+</pre>
+
+<p>Macro ugliness makes <span class="code">NS_LITERAL_STRING</span> inappropriate for use over
+other macros. In other words:
+
+<div class="source-code">
+<pre>
+NS_LITERAL_STRING("foo")
+</pre>
+</div>
+
+<p>is <strong>good</strong>.
+
+<div class="source-code">
+<pre>
+#define FOO "foo"
+NS_LITERAL_STRING(FOO)
+</pre>
+</div>
+
+<p>is <strong>bad</strong>. Why? Because it turns into
+
+<div class="source-code">
+<pre>
+nsLiteralString(LFOO, sizeof(LFOO)...
+</pre>
+</div>
+
+<p>and there is no <span class="code">LFOO</span>. Sorry. If you have to do this to a
+macro-ized string, do the magic by hand, e.g.,
+
+<div class="source-code">
+<pre>
+nsLiteralString(FOO, sizeof(FOO)/sizeof(PRUnichar)
+ + sizeof(PRUnichar('\0')))
+</pre>
+</div>
+
+<p>or else if you don't care that <span class="code">nsLiteralString</span> will scan for the
+length, just say
+
+<div class="source-code">
+<pre>
+nsLiteralString(FOO)
+</pre>
+</div>
+
+<p>Hope this helps,
+
+
+
+
+
+<hr>
+<pre>
+Date: Thu, 12 Oct 2000 08:36:14 -0400
+Subject: Re: Self healing the cache :-)
+</pre>
+
+<p>Actually, I'm not even sure you can do it by hand, since you didn't
+
+<div class="source-code">
+<pre>
+#define FOO L"foo"
+</pre>
+</div>
+
+<p>and <strong>can't</strong> do that cross-platform. The other way around this is to
+define a global instead of a macro, that is, instead of saying
+
+<div class="source-code">
+<pre>
+#define FOO "foo"
+</pre>
+</div>
+
+<p>at the top of your file, say
+
+<div class="source-code">
+<pre>
+NS_NAMED_LITERAL_STRING(FOO, "foo")
+</pre>
+</div>
+
+<p>or else, if the macro was used only in one spot ... perhaps you could
+just eliminate the macro in favor of <span class="code">NS_NAMED_LITERAL</span> in situ.
+
+<p>Arghh. In this case, you may be stuck with the extra work of
+<span class="code">AssignWithConversion</span>.
+
+
+
+
+
+<hr>
+<pre>
+Date: Sun, 3 Dec 2000 16:38:07 -0400
+Subject: Re: another copy_string question
+</pre>
+
+<pre class="email-quote">
+ >Is there a way to tell, inside the write() sink, if one is in the
+ >final hunk? I need to do some special processing at the end.
+</pre>
+
+<p>No, there isn't. But you could move such special processing into the
+destructor of the sink. Remember, the sink is passed by reference, so
+you can exactly control its lifetime.
+
+<div class="source-code">
+<pre>
+{
+ MySink sink;
+ nsReadingIterator&lt;PRUnichar&gt; sourceStart = aStr.BeginReading();
+ nsReadingIterator&lt;PRUnichar&gt; sourceEnd = aStr.EndReading();
+ copy_string(sourceStart, sourceEnd, sink);
+ // |sink| destructor executed here
+}
+</pre>
+</div>
+
+<p>Hope this helps,
+
+
+
+
+
+<hr>
+<pre>
+Date: Fri, 15 Dec 2000 20:02:08 -0400
+Subject: fragment of code
+</pre>
+
+<div class="source-code">
+<pre>
+nsPromiseFlatString flatKey(aReadable);
+
+flatKey.get()
+</pre>
+</div>
+
+
+
+
+
+
+<hr>
+<pre>
+Date: Tue, 16 Jan 2001 16:47:37 -0400
+Subject: Re: a few string questions...
+</pre>
+
+>I've accumulated a few questions I've been wanting to ask you, mostly
+>about string stuff. Nothing urgent, but I want to ask them before I
+>forget. So here goes...:
+>
+>1) Is it acceptable to use nsLiteralCString or nsLiteralString on
+>something that's not a literal? This can be useful in some places,
+>for example, to convert a char* to PRUnichar*:
+>
+>PRUnichar* new = ToNewUnicode(nsLiteralCString(myCharPtr));
+
+<p>This is explicitly allowed. That's why I'm proposing to change the
+names of those classes to <span class="code">nsLocal[C]String</span>.
+
+
+>2) Should nsString2x.h and nsString2x.cpp go away? They look like a
+>never-completed rewrite or something...
+
+<p>Yes. They should go away. They are uncompleted [old] bullshit,
+exactly as you diagnosed.
+
+<p>I'll look into the other two questions.
+
+
+
+
+
+<hr>
+<pre>
+Date: Thu, 1 Feb 2001 15:12:41 -0400
+Subject: Re: [Fwd: bad string, bad string]
+</pre>
+
+<p>We've been removing implicit conversion operators because they
+_always_ lead to trouble. Usually they make it harder to pick the
+right function when overloading is involved and in the past they have
+led to huge performance suckage because we ended up doing conversions
+when we didn't need to because the implicit operator made us pick the
+wrong function.
+
+<p>It's borderline when the class implements something that is <strong>so</strong>
+close, as with a guaranteed flat string or an <span class="code">nsCOMPtr</span> ... but the
+general recommendation is to avoid implicit conversions.
+
+<p>See bug #53057.
+
+
+
+
+
+<hr>
+<pre>
+Date: Tue, 6 Feb 2001 18:52:23 -0400
+Subject: seeking review for bug #57087
+</pre>
+
+<p> bug:
+ <a class="exact-uri" href="http://bugzilla.mozilla.org/show_bug.cgi?id=57087">http://bugzilla.mozilla.org/show_bug.cgi?id=57087</a>
+
+ patch:
+ <a class="exact-uri" href="http://bugzilla.mozilla.org/showattachment.cgi?attach_id=24576">http://bugzilla.mozilla.org/showattachment.cgi?attach_id=24576</a>
+
+<p>This patch is supposed to add the ability to define very long literal
+strings more easily by breaking lines, e.g.,
+
+<div class="source-code">
+<pre>
+NS_MULTILINE_LITERAL( NS_L("This is the start of a very long line")
+ NS_L(" which actually continues across")
+ NS_L(" a couple more.") )
+</pre>
+</div>
+
+<p>The main danger in this scheme is callers who omit the inner <span class="code">NS_L</span>
+wrapping. Though I believe this will be caught at compile time as the
+wrong type initializer.
+
+<p>Seeking input from everybody, and waterson in particular.
+
+
+
+
+
+<hr>
+<pre>
+Date: Wed, 14 Feb 2001 16:09:10 -0400
+Subject: Re: Question...
+</pre>
+
+<p>There are some utilities in "xpcom/ds/nsReadableUtils.h". In
+particular, if you want to get back a new heap-allocated ASCII string
+with the minimal work, you would say
+
+<div class="source-code">
+<pre>
+PRUnichar* sourceChars = ...;
+
+char* destChars = ToNewCString(nsLiteralString(sourceChars));
+</pre>
+</div>
+
+
+<p>It's more efficient if you happen to already know the length. If you
+don't, don't bother counting, that's what I'll do in the constructor
+for <span class="code">nsLiteralString</span>. If you do, then call like this
+
+<div class="source-code">
+<pre>
+destChars = ToNewCString( nsLiteralString(sourceChars, length) );
+</pre>
+</div>
+
+<p>Other routines in that file will help you if, for instance, you wanted
+to translate into a buffer you had already allocated.
+
+<p>Hope this helps,
+
+
+
+
+
+<hr>
+<pre>
+Date: Fri, 23 Feb 2001 03:12:58 -0400
+Subject: string snippet
+</pre>
+
+<div class="source-code">
+<pre>
+nsCString aInput;
+
+
+
+nsReadingIterator&lt;char&gt; search_start;
+aInput.BeginReading(search_start);
+
+nsReadingIterator&lt;char&gt; search_end;
+aInput.EndReading(search_end);
+
+if ( FindCharInReadable(':', search_start, search_end) )
+ {
+ ++search_start;
+ return ToNewCString( Substring(aInput, search_start, search_end)
+);
+ }
+</pre>
+</div>
+
+
+
+
+
+
+<hr>
+<pre>
+Date: Wed, 7 Mar 2001 19:44:08 -0400
+Subject: string help
+</pre>
+
+<p>Here you go, Mike:
+
+ http://scottcollins.net/journal/discussion/mjudge-scratch.cpp
+
+
+
+
+
+
+<hr>
+<pre>
+Date: Fri, 9 Mar 2001 20:56:07 -0400
+Subject: Re: string assertions
+</pre>
+
+<p>If you get an iterator into a string and you advance it all the way to
+the end of the string, and then <strong>keep</strong> trying to advance it, you hit
+this assert. This could happen, for example if you tried to copy 10
+characters out of a 9 character string. I've tried to make this
+impossible to get to. As far as I know, all my routines trim requests
+in advance of manipulating iterators. When you see this, you should
+get the stack. That will take you right to the bad spot.
+
+
+
+
+
+<hr>
+<pre>
+Date: Sat, 31 Mar 2001 11:04:03 -0400
+Subject: Re: Sun bustage and string advice
+</pre>
+
+<p>You do know you are comparing two pointers now? It seems unlikely
+those two pointers would ever be the same pointer. You probably want
+to say something like
+
+<div class="source-code">
+<pre>
+NS_LITERAL_STRING("foo").Equals(aTopic) // or
+
+NS_LITERAL_STRING("foo") == nsLiteralString(aTopic)
+</pre>
+</div>
+
+<p>...so that you compare the <strong>contents</strong> of two strings. Right now,
+you're just testing to see if two pointers both point to the same
+location in memory. A lot of people make this mistake. I would like
+to make it obvious to people that comparing two pointers does not
+compare strings. Can you tell me what gave you that impression so
+that I can figure out how to better educate people not to do this? By
+the way, it's not that I don't <strong>want</strong> to make this compare two
+strings; it's that in C++, you can't override operations for built-in
+types. And pointers are built-in types. So I can't make
+<span class="code">operator==(const PRUnichar*, const PRUnichar*)</span> do anything different
+than it already does, which is the same thing it does for any other
+pointer.
+
+
+
+
+
+
+</div>
+
+
+
+<!-- .................................................................End Matter -->
+
+
+
+ </body>
+</html>
diff --git a/src/libs/xpcom18a4/xpcom/string/public/.cvsignore b/src/libs/xpcom18a4/xpcom/string/public/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/xpcom/string/public/Makefile.in b/src/libs/xpcom18a4/xpcom/string/public/Makefile.in
new file mode 100644
index 00000000..d3582bcc
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/Makefile.in
@@ -0,0 +1,86 @@
+# vim:set ts=8 sw=8 sts=8 noet:
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications.
+# Portions created by the Initial Developer are Copyright (C) 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Johnny Stenback <jst@netscape.com> (original author)
+# Scott Collins <scc@mozilla.org>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = string
+
+EXPORTS = \
+ nsAString.h \
+ nsAlgorithm.h \
+ nsCharTraits.h \
+ nsDependentString.h \
+ nsDependentSubstring.h \
+ nsLiteralString.h \
+ nsObsoleteAString.h \
+ nsPrintfCString.h \
+ nsPromiseFlatString.h \
+ nsReadableUtils.h \
+ nsString.h \
+ nsStringFwd.h \
+ nsStringIterator.h \
+ nsSubstring.h \
+ nsSubstringTuple.h \
+ nsTAString.h \
+ nsTDependentString.h \
+ nsTDependentSubstring.h \
+ nsTObsoleteAString.h \
+ nsTPromiseFlatString.h \
+ nsTString.h \
+ nsTSubstring.h \
+ nsTSubstringTuple.h \
+ nsUTF8Utils.h \
+ nsXPIDLString.h \
+ string-template-def-unichar.h \
+ string-template-def-char.h \
+ string-template-undef.h \
+ $(NULL)
+
+SDK_HEADERS = \
+ nsStringAPI.h \
+ nsEmbedString.h \
+ $(NULL)
+
+include $(topsrcdir)/config/rules.mk
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsAString.h b/src/libs/xpcom18a4/xpcom/string/public/nsAString.h
new file mode 100644
index 00000000..3675989c
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsAString.h
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsAString_h___
+#define nsAString_h___
+
+#ifndef nsStringFwd_h___
+#include "nsStringFwd.h"
+#endif
+
+#ifndef nsStringIterator_h___
+#include "nsStringIterator.h"
+#endif
+
+#ifndef nsObsoleteAString_h___
+#include "nsObsoleteAString.h"
+#endif
+
+// If some platform(s) can't handle our template that matches literal strings,
+// then we'll disable it on those platforms.
+#ifndef NS_DISABLE_LITERAL_TEMPLATE
+# if (defined(_MSC_VER) && (_MSC_VER < 1310)) || (defined(__SUNPRO_CC) & (__SUNPRO_CC < 0x560)) || (defined(__HP_aCC) && (__HP_aCC <= 012100))
+# define NS_DISABLE_LITERAL_TEMPLATE
+# endif
+#endif /* !NS_DISABLE_LITERAL_TEMPLATE */
+
+#include <string.h>
+
+ // declare nsAString
+#include "string-template-def-unichar.h"
+#include "nsTAString.h"
+#include "string-template-undef.h"
+
+
+ // declare nsACString
+#include "string-template-def-char.h"
+#include "nsTAString.h"
+#include "string-template-undef.h"
+
+
+ /**
+ * ASCII case-insensitive comparator. (for Unicode case-insensitive
+ * comparision, see nsUnicharUtils.h)
+ */
+class NS_COM nsCaseInsensitiveCStringComparator
+ : public nsCStringComparator
+ {
+ public:
+ typedef char char_type;
+
+ virtual int operator()( const char_type*, const char_type*, PRUint32 length ) const;
+ virtual int operator()( char_type, char_type ) const;
+ };
+
+
+ // included here for backwards compatibility
+#ifndef nsSubstringTuple_h___
+#include "nsSubstringTuple.h"
+#endif
+
+#endif // !defined(nsAString_h___)
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsAlgorithm.h b/src/libs/xpcom18a4/xpcom/string/public/nsAlgorithm.h
new file mode 100644
index 00000000..e81e6f57
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsAlgorithm.h
@@ -0,0 +1,131 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Scott Collins <scc@mozilla.org> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsAlgorithm_h___
+#define nsAlgorithm_h___
+
+#ifndef nsCharTraits_h___
+#include "nsCharTraits.h"
+ // for |nsCharSourceTraits|, |nsCharSinkTraits|
+#endif
+
+#ifndef prtypes_h___
+#include "prtypes.h"
+ // for |PRUint32|...
+#endif
+
+#ifndef nsDebug_h___
+#include "nsDebug.h"
+ // for NS_ASSERTION
+#endif
+
+template <class T>
+inline
+const T&
+NS_MIN( const T& a, const T& b )
+ {
+ return b < a ? b : a;
+ }
+
+template <class T>
+inline
+const T&
+NS_MAX( const T& a, const T& b )
+ {
+ return a > b ? a : b;
+ }
+
+template <class InputIterator, class T>
+inline
+PRUint32
+NS_COUNT( InputIterator& first, const InputIterator& last, const T& value )
+ {
+ PRUint32 result = 0;
+ for ( ; first != last; ++first )
+ if ( *first == value )
+ ++result;
+ return result;
+ }
+
+template <class InputIterator, class OutputIterator>
+inline
+OutputIterator&
+copy_string( InputIterator& first, const InputIterator& last, OutputIterator& result )
+ {
+ typedef nsCharSourceTraits<InputIterator> source_traits;
+ typedef nsCharSinkTraits<OutputIterator> sink_traits;
+
+ while ( first != last )
+ {
+ PRInt32 count_copied = PRInt32(sink_traits::write(result, source_traits::read(first), source_traits::readable_distance(first, last)));
+ NS_ASSERTION(count_copied > 0, "|copy_string| will never terminate");
+ source_traits::advance(first, count_copied);
+ }
+
+ return result;
+ }
+
+template <class InputIterator, class OutputIterator>
+OutputIterator&
+copy_string_backward( const InputIterator& first, InputIterator& last, OutputIterator& result )
+ {
+ while ( first != last )
+ {
+ last.normalize_backward();
+ result.normalize_backward();
+ PRUint32 lengthToCopy = PRUint32( NS_MIN(last.size_backward(), result.size_backward()) );
+ if ( first.fragment().mStart == last.fragment().mStart )
+ lengthToCopy = NS_MIN(lengthToCopy, PRUint32(last.get() - first.get()));
+
+ NS_ASSERTION(lengthToCopy, "|copy_string_backward| will never terminate");
+
+#ifdef _MSC_VER
+ // XXX Visual C++ can't stomach 'typename' where it rightfully should
+ nsCharTraits<OutputIterator::value_type>::move(result.get()-lengthToCopy, last.get()-lengthToCopy, lengthToCopy);
+#else
+ nsCharTraits<typename OutputIterator::value_type>::move(result.get()-lengthToCopy, last.get()-lengthToCopy, lengthToCopy);
+#endif
+
+ last.advance( -PRInt32(lengthToCopy) );
+ result.advance( -PRInt32(lengthToCopy) );
+ }
+
+ return result;
+ }
+
+#endif // !defined(nsAlgorithm_h___)
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsCharTraits.h b/src/libs/xpcom18a4/xpcom/string/public/nsCharTraits.h
new file mode 100644
index 00000000..e7713c95
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsCharTraits.h
@@ -0,0 +1,784 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Scott Collins <scc@mozilla.org> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsCharTraits_h___
+#define nsCharTraits_h___
+
+#include <ctype.h>
+ // for |EOF|, |WEOF|
+
+#define FORCED_CPP_2BYTE_WCHAR_T
+ // disable special optimizations for now through this hack
+
+#if defined(HAVE_CPP_2BYTE_WCHAR_T) && !defined(FORCED_CPP_2BYTE_WCHAR_T)
+#define USE_CPP_WCHAR_FUNCS
+#endif
+
+#ifdef USE_CPP_WCHAR_FUNCS
+#include <wchar.h>
+ // for |wmemset|, et al
+#endif
+
+#include <string.h>
+ // for |memcpy|, et al
+
+#ifndef nscore_h___
+#include "nscore.h"
+ // for |PRUnichar|
+#endif
+
+#ifndef nsDebug_h__
+#include "nsDebug.h"
+ // for NS_ASSERTION
+#endif
+
+#ifdef HAVE_CPP_BOOL
+ typedef bool nsCharTraits_bool;
+#else
+ typedef PRBool nsCharTraits_bool;
+#endif
+
+template <class CharT> struct nsCharTraits {};
+
+NS_SPECIALIZE_TEMPLATE
+struct nsCharTraits<PRUnichar>
+ {
+ typedef PRUnichar char_type;
+ typedef PRUint16 unsigned_char_type;
+ typedef char incompatible_char_type;
+
+ NS_COM static const char_type *sEmptyBuffer;
+
+ static
+ void
+ assign( char_type& lhs, char_type rhs )
+ {
+ lhs = rhs;
+ }
+
+
+ // integer representation of characters:
+
+#ifdef USE_CPP_WCHAR_FUNCS
+ typedef wint_t int_type;
+#else
+ typedef int int_type;
+#endif
+
+ static
+ char_type
+ to_char_type( int_type c )
+ {
+ return char_type(c);
+ }
+
+ static
+ int_type
+ to_int_type( char_type c )
+ {
+ return int_type( NS_STATIC_CAST(unsigned_char_type, c) );
+ }
+
+ static
+ nsCharTraits_bool
+ eq_int_type( int_type lhs, int_type rhs )
+ {
+ return lhs == rhs;
+ }
+
+
+ // |char_type| comparisons:
+
+ static
+ nsCharTraits_bool
+ eq( char_type lhs, char_type rhs )
+ {
+ return lhs == rhs;
+ }
+
+ static
+ nsCharTraits_bool
+ lt( char_type lhs, char_type rhs )
+ {
+ return lhs < rhs;
+ }
+
+
+ // operations on s[n] arrays:
+
+ static
+ char_type*
+ move( char_type* s1, const char_type* s2, size_t n )
+ {
+ return NS_STATIC_CAST(char_type*, memmove(s1, s2, n * sizeof(char_type)));
+ }
+
+ static
+ char_type*
+ copy( char_type* s1, const char_type* s2, size_t n )
+ {
+ return NS_STATIC_CAST(char_type*, memcpy(s1, s2, n * sizeof(char_type)));
+ }
+
+ static
+ char_type*
+ copyASCII( char_type* s1, const char* s2, size_t n )
+ {
+ for (char_type* s = s1; n--; ++s, ++s2) {
+ NS_ASSERTION(!(*s2 & ~0x7F), "Unexpected non-ASCII character");
+ *s = *s2;
+ }
+ return s1;
+ }
+
+ static
+ char_type*
+ assign( char_type* s, size_t n, char_type c )
+ {
+#ifdef USE_CPP_WCHAR_FUNCS
+ return NS_STATIC_CAST(char_type*, wmemset(s, to_int_type(c), n));
+#else
+ char_type* result = s;
+ while ( n-- )
+ assign(*s++, c);
+ return result;
+#endif
+ }
+
+ static
+ int
+ compare( const char_type* s1, const char_type* s2, size_t n )
+ {
+#ifdef USE_CPP_WCHAR_FUNCS
+ return wmemcmp(s1, s2, n);
+#else
+ for ( ; n--; ++s1, ++s2 )
+ {
+ if ( !eq(*s1, *s2) )
+ return to_int_type(*s1) - to_int_type(*s2);
+ }
+
+ return 0;
+#endif
+ }
+
+ static
+ int
+ compareASCII( const char_type* s1, const char* s2, size_t n )
+ {
+ for ( ; n--; ++s1, ++s2 )
+ {
+ NS_ASSERTION(!(*s2 & ~0x7F), "Unexpected non-ASCII character");
+ if ( !eq_int_type(to_int_type(*s1), to_int_type(*s2)) )
+ return to_int_type(*s1) - to_int_type(*s2);
+ }
+
+ return 0;
+ }
+
+ // this version assumes that s2 is null-terminated and s1 has length n.
+ // if s1 is shorter than s2 then we return -1; if s1 is longer than s2,
+ // we return 1.
+ static
+ int
+ compareASCIINullTerminated( const char_type* s1, size_t n, const char* s2 )
+ {
+ for ( ; n--; ++s1, ++s2 )
+ {
+ if ( !*s2 )
+ return 1;
+ NS_ASSERTION(!(*s2 & ~0x7F), "Unexpected non-ASCII character");
+ if ( !eq_int_type(to_int_type(*s1), to_int_type(*s2)) )
+ return to_int_type(*s1) - to_int_type(*s2);
+ }
+
+ if ( *s2 )
+ return -1;
+
+ return 0;
+ }
+
+ /**
+ * Convert c to its lower-case form, but only if the lower-case form is
+ * ASCII. Otherwise leave it alone.
+ *
+ * There are only two non-ASCII Unicode characters whose lowercase
+ * equivalents are ASCII: KELVIN SIGN and LATIN CAPITAL LETTER I WITH
+ * DOT ABOVE. So it's a simple matter to handle those explicitly.
+ */
+ static
+ char_type
+ ASCIIToLower( char_type c )
+ {
+ if (c < 0x100)
+ return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c;
+ else
+ {
+ if (c == 0x212A) // KELVIN SIGN
+ return 'k';
+ if (c == 0x0130) // LATIN CAPITAL LETTER I WITH DOT ABOVE
+ return 'i';
+ return c;
+ }
+ }
+
+ static
+ int
+ compareLowerCaseToASCII( const char_type* s1, const char* s2, size_t n )
+ {
+ for ( ; n--; ++s1, ++s2 )
+ {
+ NS_ASSERTION(!(*s2 & ~0x7F), "Unexpected non-ASCII character");
+ NS_ASSERTION(!(*s2 >= 'A' && *s2 <= 'Z'),
+ "Unexpected uppercase character");
+ char_type lower_s1 = ASCIIToLower(*s1);
+ if ( lower_s1 != to_char_type(*s2) )
+ return to_int_type(lower_s1) - to_int_type(*s2);
+ }
+
+ return 0;
+ }
+
+ // this version assumes that s2 is null-terminated and s1 has length n.
+ // if s1 is shorter than s2 then we return -1; if s1 is longer than s2,
+ // we return 1.
+ static
+ int
+ compareLowerCaseToASCIINullTerminated( const char_type* s1, size_t n, const char* s2 )
+ {
+ for ( ; n--; ++s1, ++s2 )
+ {
+ if ( !*s2 )
+ return 1;
+ NS_ASSERTION(!(*s2 & ~0x7F), "Unexpected non-ASCII character");
+ NS_ASSERTION(!(*s2 >= 'A' && *s2 <= 'Z'),
+ "Unexpected uppercase character");
+ char_type lower_s1 = ASCIIToLower(*s1);
+ if ( lower_s1 != to_char_type(*s2) )
+ return to_int_type(lower_s1) - to_int_type(*s2);
+ }
+
+ if ( *s2 )
+ return -1;
+
+ return 0;
+ }
+
+ static
+ size_t
+ length( const char_type* s )
+ {
+#ifdef USE_CPP_WCHAR_FUNCS
+ return wcslen(s);
+#else
+ size_t result = 0;
+ while ( !eq(*s++, char_type(0)) )
+ ++result;
+ return result;
+#endif
+ }
+
+ static
+ const char_type*
+ find( const char_type* s, size_t n, char_type c )
+ {
+#ifdef USE_CPP_WCHAR_FUNCS
+ return NS_REINTERPRET_CAST(const char_type*, wmemchr(s, to_int_type(c), n));
+#else
+ while ( n-- )
+ {
+ if ( eq(*s, c) )
+ return s;
+ ++s;
+ }
+
+ return 0;
+#endif
+ }
+
+#if 0
+ // I/O related:
+
+ typedef streamoff off_type;
+ typedef streampos pos_type;
+ typedef mbstate_t state_type;
+
+ static
+ int_type
+ eof()
+ {
+#ifdef USE_CPP_WCHAR_FUNCS
+ return WEOF;
+#else
+ return EOF;
+#endif
+ }
+
+ static
+ int_type
+ not_eof( int_type c )
+ {
+ return eq_int_type(c, eof()) ? ~eof() : c;
+ }
+
+ // static state_type get_state( pos_type );
+#endif
+ };
+
+NS_SPECIALIZE_TEMPLATE
+struct nsCharTraits<char>
+ {
+ typedef char char_type;
+ typedef unsigned char unsigned_char_type;
+ typedef PRUnichar incompatible_char_type;
+
+ NS_COM static const char_type *sEmptyBuffer;
+
+ static
+ void
+ assign( char_type& lhs, char_type rhs )
+ {
+ lhs = rhs;
+ }
+
+
+ // integer representation of characters:
+
+ typedef int int_type;
+
+ static
+ char_type
+ to_char_type( int_type c )
+ {
+ return char_type(c);
+ }
+
+ static
+ int_type
+ to_int_type( char_type c )
+ {
+ return int_type( NS_STATIC_CAST(unsigned_char_type, c) );
+ }
+
+ static
+ nsCharTraits_bool
+ eq_int_type( int_type lhs, int_type rhs )
+ {
+ return lhs == rhs;
+ }
+
+
+ // |char_type| comparisons:
+
+ static
+ nsCharTraits_bool
+ eq( char_type lhs, char_type rhs )
+ {
+ return lhs == rhs;
+ }
+
+ static
+ nsCharTraits_bool
+ lt( char_type lhs, char_type rhs )
+ {
+ return lhs < rhs;
+ }
+
+
+ // operations on s[n] arrays:
+
+ static
+ char_type*
+ move( char_type* s1, const char_type* s2, size_t n )
+ {
+ return NS_STATIC_CAST(char_type*, memmove(s1, s2, n * sizeof(char_type)));
+ }
+
+ static
+ char_type*
+ copy( char_type* s1, const char_type* s2, size_t n )
+ {
+ return NS_STATIC_CAST(char_type*, memcpy(s1, s2, n * sizeof(char_type)));
+ }
+
+ static
+ char_type*
+ copyASCII( char_type* s1, const char* s2, size_t n )
+ {
+ return copy(s1, s2, n);
+ }
+
+ static
+ char_type*
+ assign( char_type* s, size_t n, char_type c )
+ {
+ return NS_STATIC_CAST(char_type*, memset(s, to_int_type(c), n));
+ }
+
+ static
+ int
+ compare( const char_type* s1, const char_type* s2, size_t n )
+ {
+ return memcmp(s1, s2, n);
+ }
+
+ static
+ int
+ compareASCII( const char_type* s1, const char* s2, size_t n )
+ {
+#ifdef DEBUG
+ for (size_t i = 0; i < n; ++i)
+ {
+ NS_ASSERTION(!(s2[i] & ~0x7F), "Unexpected non-ASCII character");
+ }
+#endif
+ return compare(s1, s2, n);
+ }
+
+ // this version assumes that s2 is null-terminated and s1 has length n.
+ // if s1 is shorter than s2 then we return -1; if s1 is longer than s2,
+ // we return 1.
+ static
+ int
+ compareASCIINullTerminated( const char_type* s1, size_t n, const char* s2 )
+ {
+ // can't use strcmp here because we don't want to stop when s1
+ // contains a null
+ for ( ; n--; ++s1, ++s2 )
+ {
+ if ( !*s2 )
+ return 1;
+ NS_ASSERTION(!(*s2 & ~0x7F), "Unexpected non-ASCII character");
+ if ( *s1 != *s2 )
+ return to_int_type(*s1) - to_int_type(*s2);
+ }
+
+ if ( *s2 )
+ return -1;
+
+ return 0;
+ }
+
+ /**
+ * Convert c to its lower-case form, but only if c is ASCII.
+ */
+ static
+ char_type
+ ASCIIToLower( char_type c )
+ {
+ return (c >= 'A' && c <= 'Z') ? (c + ('a' - 'A')) : c;
+ }
+
+ static
+ int
+ compareLowerCaseToASCII( const char_type* s1, const char* s2, size_t n )
+ {
+ for ( ; n--; ++s1, ++s2 )
+ {
+ NS_ASSERTION(!(*s2 & ~0x7F), "Unexpected non-ASCII character");
+ NS_ASSERTION(!(*s2 >= 'A' && *s2 <= 'Z'),
+ "Unexpected uppercase character");
+ char_type lower_s1 = ASCIIToLower(*s1);
+ if ( lower_s1 != *s2 )
+ return to_int_type(lower_s1) - to_int_type(*s2);
+ }
+ return 0;
+ }
+
+ // this version assumes that s2 is null-terminated and s1 has length n.
+ // if s1 is shorter than s2 then we return -1; if s1 is longer than s2,
+ // we return 1.
+ static
+ int
+ compareLowerCaseToASCIINullTerminated( const char_type* s1, size_t n, const char* s2 )
+ {
+ for ( ; n--; ++s1, ++s2 )
+ {
+ if ( !*s2 )
+ return 1;
+ NS_ASSERTION(!(*s2 & ~0x7F), "Unexpected non-ASCII character");
+ NS_ASSERTION(!(*s2 >= 'A' && *s2 <= 'Z'),
+ "Unexpected uppercase character");
+ char_type lower_s1 = ASCIIToLower(*s1);
+ if ( lower_s1 != *s2 )
+ return to_int_type(lower_s1) - to_int_type(*s2);
+ }
+
+ if ( *s2 )
+ return -1;
+
+ return 0;
+ }
+
+ static
+ size_t
+ length( const char_type* s )
+ {
+ return strlen(s);
+ }
+
+ static
+ const char_type*
+ find( const char_type* s, size_t n, char_type c )
+ {
+ return NS_REINTERPRET_CAST(const char_type*, memchr(s, to_int_type(c), n));
+ }
+
+#if 0
+ // I/O related:
+
+ typedef streamoff off_type;
+ typedef streampos pos_type;
+ typedef mbstate_t state_type;
+
+ static
+ int_type
+ eof()
+ {
+ return EOF;
+ }
+
+ static
+ int_type
+ not_eof( int_type c )
+ {
+ return eq_int_type(c, eof()) ? ~eof() : c;
+ }
+
+ // static state_type get_state( pos_type );
+#endif
+ };
+
+template <class InputIterator>
+struct nsCharSourceTraits
+ {
+ typedef typename InputIterator::difference_type difference_type;
+
+ static
+ PRUint32
+ readable_distance( const InputIterator& first, const InputIterator& last )
+ {
+ // assumes single fragment
+ return last.get() - first.get();
+ }
+
+ static
+ const typename InputIterator::value_type*
+ read( const InputIterator& iter )
+ {
+ return iter.get();
+ }
+
+ static
+ void
+ advance( InputIterator& s, difference_type n )
+ {
+ s.advance(n);
+ }
+ };
+
+#ifdef HAVE_CPP_PARTIAL_SPECIALIZATION
+
+template <class CharT>
+struct nsCharSourceTraits<CharT*>
+ {
+ typedef ptrdiff_t difference_type;
+
+ static
+ PRUint32
+ readable_distance( CharT* s )
+ {
+ return PRUint32(nsCharTraits<CharT>::length(s));
+// return numeric_limits<PRUint32>::max();
+ }
+
+ static
+ PRUint32
+ readable_distance( CharT* first, CharT* last )
+ {
+ return PRUint32(last-first);
+ }
+
+ static
+ const CharT*
+ read( CharT* s )
+ {
+ return s;
+ }
+
+ static
+ void
+ advance( CharT*& s, difference_type n )
+ {
+ s += n;
+ }
+ };
+
+#else
+
+NS_SPECIALIZE_TEMPLATE
+struct nsCharSourceTraits<const char*>
+ {
+ typedef ptrdiff_t difference_type;
+
+ static
+ PRUint32
+ readable_distance( const char* s )
+ {
+ return PRUint32(nsCharTraits<char>::length(s));
+// return numeric_limits<PRUint32>::max();
+ }
+
+ static
+ PRUint32
+ readable_distance( const char* first, const char* last )
+ {
+ return PRUint32(last-first);
+ }
+
+ static
+ const char*
+ read( const char* s )
+ {
+ return s;
+ }
+
+ static
+ void
+ advance( const char*& s, difference_type n )
+ {
+ s += n;
+ }
+ };
+
+
+NS_SPECIALIZE_TEMPLATE
+struct nsCharSourceTraits<const PRUnichar*>
+ {
+ typedef ptrdiff_t difference_type;
+
+ static
+ PRUint32
+ readable_distance( const PRUnichar* s )
+ {
+ return PRUint32(nsCharTraits<PRUnichar>::length(s));
+// return numeric_limits<PRUint32>::max();
+ }
+
+ static
+ PRUint32
+ readable_distance( const PRUnichar* first, const PRUnichar* last )
+ {
+ return PRUint32(last-first);
+ }
+
+ static
+ const PRUnichar*
+ read( const PRUnichar* s )
+ {
+ return s;
+ }
+
+ static
+ void
+ advance( const PRUnichar*& s, difference_type n )
+ {
+ s += n;
+ }
+ };
+
+#endif
+
+
+template <class OutputIterator>
+struct nsCharSinkTraits
+ {
+ static
+ PRUint32
+ write( OutputIterator& iter, const typename OutputIterator::value_type* s, PRUint32 n )
+ {
+ return iter.write(s, n);
+ }
+ };
+
+#ifdef HAVE_CPP_PARTIAL_SPECIALIZATION
+
+template <class CharT>
+struct nsCharSinkTraits<CharT*>
+ {
+ static
+ PRUint32
+ write( CharT*& iter, const CharT* s, PRUint32 n )
+ {
+ nsCharTraits<CharT>::move(iter, s, n);
+ iter += n;
+ return n;
+ }
+ };
+
+#else
+
+NS_SPECIALIZE_TEMPLATE
+struct nsCharSinkTraits<char*>
+ {
+ static
+ PRUint32
+ write( char*& iter, const char* s, PRUint32 n )
+ {
+ nsCharTraits<char>::move(iter, s, n);
+ iter += n;
+ return n;
+ }
+ };
+
+NS_SPECIALIZE_TEMPLATE
+struct nsCharSinkTraits<PRUnichar*>
+ {
+ static
+ PRUint32
+ write( PRUnichar*& iter, const PRUnichar* s, PRUint32 n )
+ {
+ nsCharTraits<PRUnichar>::move(iter, s, n);
+ iter += n;
+ return n;
+ }
+ };
+
+#endif
+
+#endif // !defined(nsCharTraits_h___)
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsDependentString.h b/src/libs/xpcom18a4/xpcom/string/public/nsDependentString.h
new file mode 100644
index 00000000..22e05b31
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsDependentString.h
@@ -0,0 +1,60 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsDependentString_h___
+#define nsDependentString_h___
+
+#ifndef nsString_h___
+#include "nsString.h"
+#endif
+
+#ifndef nsDebug_h___
+#include "nsDebug.h"
+#endif
+
+ // declare nsDependentString
+#include "string-template-def-unichar.h"
+#include "nsTDependentString.h"
+#include "string-template-undef.h"
+
+ // declare nsDependentCString
+#include "string-template-def-char.h"
+#include "nsTDependentString.h"
+#include "string-template-undef.h"
+
+#endif /* !defined(nsDependentString_h___) */
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsDependentSubstring.h b/src/libs/xpcom18a4/xpcom/string/public/nsDependentSubstring.h
new file mode 100644
index 00000000..c6459436
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsDependentSubstring.h
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsDependentSubstring_h___
+#define nsDependentSubstring_h___
+
+#ifndef nsSubstring_h___
+#include "nsSubstring.h"
+#endif
+
+ // declare nsDependentSubstring
+#include "string-template-def-unichar.h"
+#include "nsTDependentSubstring.h"
+#include "string-template-undef.h"
+
+ // declare nsDependentCSubstring
+#include "string-template-def-char.h"
+#include "nsTDependentSubstring.h"
+#include "string-template-undef.h"
+
+#endif /* !defined(nsDependentSubstring_h___) */
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsEmbedString.h b/src/libs/xpcom18a4/xpcom/string/public/nsEmbedString.h
new file mode 100644
index 00000000..7af03ee3
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsEmbedString.h
@@ -0,0 +1,158 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is a small implementation of the nsAString and nsACString.
+ *
+ * The Initial Developer of the Original Code is
+ * Peter Annema <jaggernaut@netscape.com>.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2002
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsEmbedString_h___
+#define nsEmbedString_h___
+
+#include "nsStringAPI.h"
+
+class nsEmbedString : public nsStringContainer
+ {
+ public:
+ typedef nsEmbedString self_type;
+ typedef nsAString abstract_string_type;
+
+ nsEmbedString()
+ {
+ NS_StringContainerInit(*this);
+ }
+
+ nsEmbedString(const self_type& aString)
+#ifdef VBOX
+ : nsStringContainer()
+#endif
+ {
+ NS_StringContainerInit(*this);
+ NS_StringCopy(*this, aString);
+ }
+
+ explicit
+ nsEmbedString(const abstract_string_type& aReadable)
+ {
+ NS_StringContainerInit(*this);
+ NS_StringCopy(*this, aReadable);
+ }
+
+ explicit
+ nsEmbedString(const char_type* aData, size_type aLength = PR_UINT32_MAX)
+ {
+ NS_StringContainerInit(*this);
+ NS_StringSetData(*this, aData, aLength);
+ }
+
+ ~nsEmbedString()
+ {
+ NS_StringContainerFinish(*this);
+ }
+
+ const char_type* get() const
+ {
+ const char_type* data;
+ NS_StringGetData(*this, &data);
+ return data;
+ }
+
+ self_type& operator=(const self_type& aString) { Assign(aString); return *this; }
+ self_type& operator=(const abstract_string_type& aReadable) { Assign(aReadable); return *this; }
+ self_type& operator=(const char_type* aPtr) { Assign(aPtr); return *this; }
+ self_type& operator=(char_type aChar) { Assign(aChar); return *this; }
+ };
+
+class nsEmbedCString : public nsCStringContainer
+ {
+ public:
+ typedef nsEmbedCString self_type;
+ typedef nsACString abstract_string_type;
+
+ nsEmbedCString()
+#ifdef VBOX
+ : nsCStringContainer()
+#endif
+ {
+ NS_CStringContainerInit(*this);
+ }
+
+ nsEmbedCString(const self_type& aString)
+#ifdef VBOX
+ : nsCStringContainer()
+#endif
+ {
+ NS_CStringContainerInit(*this);
+ NS_CStringCopy(*this, aString);
+ }
+
+ explicit
+ nsEmbedCString(const abstract_string_type& aReadable)
+#ifdef VBOX
+ : nsCStringContainer()
+#endif
+ {
+ NS_CStringContainerInit(*this);
+ NS_CStringCopy(*this, aReadable);
+ }
+
+ explicit
+ nsEmbedCString(const char_type* aData, size_type aLength = PR_UINT32_MAX)
+#ifdef VBOX
+ : nsCStringContainer()
+#endif
+ {
+ NS_CStringContainerInit(*this);
+ NS_CStringSetData(*this, aData, aLength);
+ }
+
+ ~nsEmbedCString()
+ {
+ NS_CStringContainerFinish(*this);
+ }
+
+ const char_type* get() const
+ {
+ const char_type* data;
+ NS_CStringGetData(*this, &data);
+ return data;
+ }
+
+ self_type& operator=(const self_type& aString) { Assign(aString); return *this; }
+ self_type& operator=(const abstract_string_type& aReadable) { Assign(aReadable); return *this; }
+ self_type& operator=(const char_type* aPtr) { Assign(aPtr); return *this; }
+ self_type& operator=(char_type aChar) { Assign(aChar); return *this; }
+ };
+
+#endif // !defined(nsEmbedString_h___)
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsLiteralString.h b/src/libs/xpcom18a4/xpcom/string/public/nsLiteralString.h
new file mode 100644
index 00000000..ba536297
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsLiteralString.h
@@ -0,0 +1,116 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications.
+ * Portions created by the Initial Developer are Copyright (C) 2001
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Scott Collins <scc@mozilla.org> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsLiteralString_h___
+#define nsLiteralString_h___
+
+#ifndef nscore_h___
+#include "nscore.h"
+#endif
+
+#ifndef nsDependentString_h___
+#include "nsDependentString.h"
+#endif
+
+
+#if 0
+inline
+const nsDependentString
+literal_string( const nsAString::char_type* aPtr )
+ {
+ return nsDependentString(aPtr);
+ }
+
+inline
+const nsDependentString
+literal_string( const nsAString::char_type* aPtr, PRUint32 aLength )
+ {
+ return nsDependentString(aPtr, aLength);
+ }
+
+inline
+const nsDependentCString
+literal_string( const nsACString::char_type* aPtr )
+ {
+ return nsDependentCString(aPtr);
+ }
+
+inline
+const nsDependentCString
+literal_string( const nsACString::char_type* aPtr, PRUint32 aLength )
+ {
+ return nsDependentCString(aPtr, aLength);
+ }
+#endif
+
+#ifdef HAVE_CPP_2BYTE_WCHAR_T
+ #define NS_LL(s) L##s
+ #define NS_MULTILINE_LITERAL_STRING(s) nsDependentString(NS_REINTERPRET_CAST(const nsAString::char_type*, s), PRUint32((sizeof(s)/sizeof(wchar_t))-1))
+ #define NS_MULTILINE_LITERAL_STRING_INIT(n,s) n(NS_REINTERPRET_CAST(const nsAString::char_type*, s), PRUint32((sizeof(s)/sizeof(wchar_t))-1))
+ #define NS_NAMED_MULTILINE_LITERAL_STRING(n,s) const nsDependentString n(NS_REINTERPRET_CAST(const nsAString::char_type*, s), PRUint32((sizeof(s)/sizeof(wchar_t))-1))
+ typedef nsDependentString nsLiteralString;
+#else
+ #define NS_LL(s) s
+ #define NS_MULTILINE_LITERAL_STRING(s) NS_ConvertASCIItoUTF16(s, PRUint32(sizeof(s)-1))
+ #define NS_MULTILINE_LITERAL_STRING_INIT(n,s) n(s, PRUint32(sizeof(s)-1))
+ #define NS_NAMED_MULTILINE_LITERAL_STRING(n,s) const NS_ConvertASCIItoUTF16 n(s, PRUint32(sizeof(s)-1))
+ typedef NS_ConvertASCIItoUTF16 nsLiteralString;
+#endif
+
+/*
+ * Macro arguments used in concatenation or stringification won't be expanded.
+ * Therefore, in order for |NS_L(FOO)| to work as expected (which is to expand
+ * |FOO| before doing whatever |NS_L| needs to do to it) a helper macro needs
+ * to be inserted in between to allow the macro argument to expand.
+ * See "3.10.6 Separate Expansion of Macro Arguments" of the CPP manual for a
+ * more accurate and precise explanation.
+ */
+
+#define NS_L(s) NS_LL(s)
+
+#define NS_LITERAL_STRING(s) NS_STATIC_CAST(const nsAFlatString&, NS_MULTILINE_LITERAL_STRING(NS_LL(s)))
+#define NS_LITERAL_STRING_INIT(n,s) NS_MULTILINE_LITERAL_STRING_INIT(n, NS_LL(s))
+#define NS_NAMED_LITERAL_STRING(n,s) NS_NAMED_MULTILINE_LITERAL_STRING(n, NS_LL(s))
+
+#define NS_LITERAL_CSTRING(s) NS_STATIC_CAST(const nsDependentCString&, nsDependentCString(s, PRUint32(sizeof(s)-1)))
+#define NS_LITERAL_CSTRING_INIT(n,s) n(s, PRUint32(sizeof(s)-1))
+#define NS_NAMED_LITERAL_CSTRING(n,s) const nsDependentCString n(s, PRUint32(sizeof(s)-1))
+
+typedef nsDependentCString nsLiteralCString;
+
+#endif /* !defined(nsLiteralString_h___) */
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsObsoleteAString.h b/src/libs/xpcom18a4/xpcom/string/public/nsObsoleteAString.h
new file mode 100644
index 00000000..00d5892e
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsObsoleteAString.h
@@ -0,0 +1,102 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsObsoleteAString_h___
+#define nsObsoleteAString_h___
+
+/*
+ STRING INTERNALS
+
+ This file defines nsObsoleteAString and nsObsoleteACString. These are
+ abstract classes (interfaces), containing only virtual functions
+ corresponding to the FROZEN nsA[C]String classes. They exist to provide
+ the new non-abstract nsA[C]String classes with a mechanism to maintain
+ backwards binary compatability.
+
+ From a binary point-of-view, the new nsA[C]String classes appear to have a
+ vtable pointer to the vtable of nsObsoleteA[C]StringThunk.
+ nsObsoleteA[C]StringThunk is a subclass of nsObsoleteA[C]String that serves
+ as a simple bridge between the virtual functions that make up the FROZEN
+ nsA[C]String contract and the new ns[C]Substring, which is now our only
+ subclass of nsA[C]String.
+
+ The methods on the new nsA[C]String are now all non-virtual. This reduces
+ codesize at the callsite, and reduces the number of memory dereferences and
+ jumps required to invoke a method on nsA[C]String. The result is improved
+ performance and reduced codesize. However, to maintain binary
+ compatibility, each method on nsA[C]String must check the value of its
+ vtable to determine if it corresponds to the built-in implementation of
+ nsObsoleteA[C]String (i.e., the address of the canonical vtable). If it
+ does, then the vtable can be ignored, and the nsA[C]String object (i.e.,
+ |this|) can be cast to ns[C]Substring directly. In which case, the
+ nsA[C]String methods can be satisfied by invoking the corresponding methods
+ directly on ns[C]Substring. If the vtable address does not correspond to
+ the built-in implementation, then the virtual functions on
+ nsObsoleteA[C]String must be invoked instead.
+
+ So, if a nsA[C]String reference corresponds to an external implementation
+ (such as the old nsEmbed[C]String that shipped with previous versions of
+ Mozilla), then methods invoked on that nsA[C]String will still act like
+ virtual function calls. This ensures binary compatibility while avoiding
+ virtual function calls in most cases.
+
+ Finally, nsObsoleteA[C]String (i.e., the FROZEN nsA[C]String vtable) is
+ now a DEPRECATED interface. See nsStringAPI.h and nsEmbedString.h for
+ the new preferred way to access nsA[C]String references in an external
+ component or Gecko embedding application.
+ */
+
+#ifndef nsStringFwd_h___
+#include "nsStringFwd.h"
+#endif
+
+#ifndef nscore_h___
+#include "nscore.h"
+#endif
+
+ // declare nsObsoleteAString
+#include "string-template-def-unichar.h"
+#include "nsTObsoleteAString.h"
+#include "string-template-undef.h"
+
+ // declare nsObsoleteACString
+#include "string-template-def-char.h"
+#include "nsTObsoleteAString.h"
+#include "string-template-undef.h"
+
+#endif // !defined(nsObsoleteAString_h___)
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsPrintfCString.h b/src/libs/xpcom18a4/xpcom/string/public/nsPrintfCString.h
new file mode 100644
index 00000000..3f3d04d3
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsPrintfCString.h
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsPrintfCString_h___
+#define nsPrintfCString_h___
+
+#ifndef nsString_h___
+#include "nsString.h"
+#endif
+
+
+ /**
+ * |nsPrintfCString| lets you use a formated |printf| string as an |const nsACString|.
+ *
+ * myCStr += nsPrintfCString("%f", 13.917);
+ * // ...a general purpose substitute for |AppendFloat|
+ *
+ * For longer patterns, you'll want to use the constructor that takes a length
+ *
+ * nsPrintfCString(128, "%f, %f, %f, %f, %f, %f, %f, %i, %f", x, y, z, 3.2, j, k, l, 3, 3.1);
+ *
+ * Exceding the default size (which you must specify in the constructor, it is not determined)
+ * causes an allocation, so avoid that. If your formatted string exceeds the allocated space, it is
+ * cut off at the size of the buffer, no error is reported (and no out-of-bounds writing occurs).
+ * This class is intended to be useful for numbers and short
+ * strings, not arbitrary formatting of other strings (e.g., with %s). There is currently no
+ * wide version of this class, since wide |printf| is not generally available. That means
+ * to get a wide version of your formatted data, you must, e.g.,
+ *
+ * CopyASCIItoUTF16(nsPrintfCString("%f", 13.917"), myStr);
+ *
+ * That's another good reason to avoid this class for anything but numbers ... as strings can be
+ * much more efficiently handled with |NS_LITERAL_[C]STRING| and |nsLiteral[C]String|.
+ */
+
+class NS_COM nsPrintfCString : public nsCString
+ {
+ typedef nsCString string_type;
+
+ enum { kLocalBufferSize=15 };
+ // ought to be large enough for most things ... a |long long| needs at most 20 (so you'd better ask)
+ // pinkerton suggests 7. We should measure and decide what's appropriate
+
+ public:
+ // XXX don't these need to be declared CDECL ??
+ explicit nsPrintfCString( const char_type* format, ... );
+ nsPrintfCString( size_type n, const char_type* format, ...);
+
+ private:
+ char_type mLocalBuffer[ kLocalBufferSize + 1 ];
+ };
+
+#endif // !defined(nsPrintfCString_h___)
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsPromiseFlatString.h b/src/libs/xpcom18a4/xpcom/string/public/nsPromiseFlatString.h
new file mode 100644
index 00000000..b98aa1a2
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsPromiseFlatString.h
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsPromiseFlatString_h___
+#define nsPromiseFlatString_h___
+
+#ifndef nsString_h___
+#include "nsString.h"
+#endif
+
+ // declare nsPromiseFlatString
+#include "string-template-def-unichar.h"
+#include "nsTPromiseFlatString.h"
+#include "string-template-undef.h"
+
+ // declare nsPromiseFlatCString
+#include "string-template-def-char.h"
+#include "nsTPromiseFlatString.h"
+#include "string-template-undef.h"
+
+#endif /* !defined(nsPromiseFlatString_h___) */
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsReadableUtils.h b/src/libs/xpcom18a4/xpcom/string/public/nsReadableUtils.h
new file mode 100644
index 00000000..13f94c09
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsReadableUtils.h
@@ -0,0 +1,370 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Scott Collins <scc@mozilla.org> (original author)
+ * Johnny Stenbeck <jst@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsReadableUtils_h___
+#define nsReadableUtils_h___
+
+ /**
+ * I guess all the routines in this file are all mis-named.
+ * According to our conventions, they should be |NS_xxx|.
+ */
+
+#ifndef nsAString_h___
+#include "nsAString.h"
+#endif
+
+inline size_t Distance( const nsReadingIterator<PRUnichar>& start, const nsReadingIterator<PRUnichar>& end )
+ {
+ return end.get() - start.get();
+ }
+inline size_t Distance( const nsReadingIterator<char>& start, const nsReadingIterator<char>& end )
+ {
+ return end.get() - start.get();
+ }
+
+NS_COM void LossyCopyUTF16toASCII( const nsAString& aSource, nsACString& aDest );
+NS_COM void CopyASCIItoUTF16( const nsACString& aSource, nsAString& aDest );
+
+NS_COM void LossyCopyUTF16toASCII( const PRUnichar* aSource, nsACString& aDest );
+NS_COM void CopyASCIItoUTF16( const char* aSource, nsAString& aDest );
+
+NS_COM void CopyUTF16toUTF8( const nsAString& aSource, nsACString& aDest );
+NS_COM void CopyUTF8toUTF16( const nsACString& aSource, nsAString& aDest );
+
+NS_COM void CopyUTF16toUTF8( const PRUnichar* aSource, nsACString& aDest );
+NS_COM void CopyUTF8toUTF16( const char* aSource, nsAString& aDest );
+
+NS_COM void LossyAppendUTF16toASCII( const nsAString& aSource, nsACString& aDest );
+NS_COM void AppendASCIItoUTF16( const nsACString& aSource, nsAString& aDest );
+
+NS_COM void LossyAppendUTF16toASCII( const PRUnichar* aSource, nsACString& aDest );
+NS_COM void AppendASCIItoUTF16( const char* aSource, nsAString& aDest );
+
+NS_COM void AppendUTF16toUTF8( const nsAString& aSource, nsACString& aDest );
+NS_COM void AppendUTF8toUTF16( const nsACString& aSource, nsAString& aDest );
+
+NS_COM void AppendUTF16toUTF8( const PRUnichar* aSource, nsACString& aDest );
+NS_COM void AppendUTF8toUTF16( const char* aSource, nsAString& aDest );
+
+// Backward compatibility
+inline
+NS_COM void CopyUCS2toASCII( const nsAString& aSource, nsACString& aDest )
+{ LossyCopyUTF16toASCII(aSource, aDest); }
+inline
+NS_COM void CopyASCIItoUCS2( const nsACString& aSource, nsAString& aDest )
+{ CopyASCIItoUTF16(aSource, aDest); }
+
+ /**
+ * Returns a new |char| buffer containing a zero-terminated copy of |aSource|.
+ *
+ * Allocates and returns a new |char| buffer which you must free with |nsMemory::Free|.
+ * Performs a lossy encoding conversion by chopping 16-bit wide characters down to 8-bits wide while copying |aSource| to your new buffer.
+ * This conversion is not well defined; but it reproduces legacy string behavior.
+ * The new buffer is zero-terminated, but that may not help you if |aSource| contains embedded nulls.
+ *
+ * @param aSource a 16-bit wide string
+ * @return a new |char| buffer you must free with |nsMemory::Free|.
+ */
+NS_COM char* ToNewCString( const nsAString& aSource );
+
+
+ /**
+ * Returns a new |char| buffer containing a zero-terminated copy of |aSource|.
+ *
+ * Allocates and returns a new |char| buffer which you must free with |nsMemory::Free|.
+ * The new buffer is zero-terminated, but that may not help you if |aSource| contains embedded nulls.
+ *
+ * @param aSource an 8-bit wide string
+ * @return a new |char| buffer you must free with |nsMemory::Free|.
+ */
+NS_COM char* ToNewCString( const nsACString& aSource );
+
+ /**
+ * Returns a new |char| buffer containing a zero-terminated copy of |aSource|.
+ *
+ * Allocates and returns a new |char| buffer which you must free with
+ * |nsMemory::Free|.
+ * Performs an encoding conversion from a UTF-16 string to a UTF-8 string
+ * copying |aSource| to your new buffer.
+ * The new buffer is zero-terminated, but that may not help you if |aSource|
+ * contains embedded nulls.
+ *
+ * @param aSource a UTF-16 string (made of PRUnichar's)
+ * @param aUTF8Count the number of 8-bit units that was returned
+ * @return a new |char| buffer you must free with |nsMemory::Free|.
+ */
+
+NS_COM char* ToNewUTF8String( const nsAString& aSource, PRUint32 *aUTF8Count = nsnull );
+
+
+ /**
+ * Returns a new |PRUnichar| buffer containing a zero-terminated copy of
+ * |aSource|.
+ *
+ * Allocates and returns a new |PRUnichar| buffer which you must free with
+ * |nsMemory::Free|.
+ * The new buffer is zero-terminated, but that may not help you if |aSource|
+ * contains embedded nulls.
+ *
+ * @param aSource a UTF-16 string
+ * @return a new |PRUnichar| buffer you must free with |nsMemory::Free|.
+ */
+NS_COM PRUnichar* ToNewUnicode( const nsAString& aSource );
+
+
+ /**
+ * Returns a new |PRUnichar| buffer containing a zero-terminated copy of |aSource|.
+ *
+ * Allocates and returns a new |PRUnichar| buffer which you must free with |nsMemory::Free|.
+ * Performs an encoding conversion by 0-padding 8-bit wide characters up to 16-bits wide while copying |aSource| to your new buffer.
+ * This conversion is not well defined; but it reproduces legacy string behavior.
+ * The new buffer is zero-terminated, but that may not help you if |aSource| contains embedded nulls.
+ *
+ * @param aSource an 8-bit wide string (a C-string, NOT UTF-8)
+ * @return a new |PRUnichar| buffer you must free with |nsMemory::Free|.
+ */
+NS_COM PRUnichar* ToNewUnicode( const nsACString& aSource );
+
+ /**
+ * Returns a new |PRUnichar| buffer containing a zero-terminated copy
+ * of |aSource|.
+ *
+ * Allocates and returns a new |char| buffer which you must free with
+ * |nsMemory::Free|. Performs an encoding conversion from UTF-8 to UTF-16
+ * while copying |aSource| to your new buffer. This conversion is well defined
+ * for a valid UTF-8 string. The new buffer is zero-terminated, but that
+ * may not help you if |aSource| contains embedded nulls.
+ *
+ * @param aSource an 8-bit wide string, UTF-8 encoded
+ * @param aUTF16Count the number of 16-bit units that was returned
+ * @return a new |PRUnichar| buffer you must free with |nsMemory::Free|.
+ * (UTF-16 encoded)
+ */
+NS_COM PRUnichar* UTF8ToNewUnicode( const nsACString& aSource, PRUint32 *aUTF16Count = nsnull );
+
+ /**
+ * Copies |aLength| 16-bit code units from the start of |aSource| to the
+ * |PRUnichar| buffer |aDest|.
+ *
+ * After this operation |aDest| is not null terminated.
+ *
+ * @param aSource a UTF-16 string
+ * @param aSrcOffset start offset in the source string
+ * @param aDest a |PRUnichar| buffer
+ * @param aLength the number of 16-bit code units to copy
+ * @return pointer to destination buffer - identical to |aDest|
+ */
+NS_COM PRUnichar* CopyUnicodeTo( const nsAString& aSource,
+ PRUint32 aSrcOffset,
+ PRUnichar* aDest,
+ PRUint32 aLength );
+
+
+ /**
+ * Copies 16-bit characters between iterators |aSrcStart| and
+ * |aSrcEnd| to the writable string |aDest|. Similar to the
+ * |nsString::Mid| method.
+ *
+ * After this operation |aDest| is not null terminated.
+ *
+ * @param aSrcStart start source iterator
+ * @param aSrcEnd end source iterator
+ * @param aDest destination for the copy
+ */
+NS_COM void CopyUnicodeTo( const nsAString::const_iterator& aSrcStart,
+ const nsAString::const_iterator& aSrcEnd,
+ nsAString& aDest );
+
+ /**
+ * Appends 16-bit characters between iterators |aSrcStart| and
+ * |aSrcEnd| to the writable string |aDest|.
+ *
+ * After this operation |aDest| is not null terminated.
+ *
+ * @param aSrcStart start source iterator
+ * @param aSrcEnd end source iterator
+ * @param aDest destination for the copy
+ */
+NS_COM void AppendUnicodeTo( const nsAString::const_iterator& aSrcStart,
+ const nsAString::const_iterator& aSrcEnd,
+ nsAString& aDest );
+
+ /**
+ * Returns |PR_TRUE| if |aString| contains only ASCII characters, that is, characters in the range (0x00, 0x7F).
+ *
+ * @param aString a 16-bit wide string to scan
+ */
+NS_COM PRBool IsASCII( const nsAString& aString );
+
+ /**
+ * Returns |PR_TRUE| if |aString| contains only ASCII characters, that is, characters in the range (0x00, 0x7F).
+ *
+ * @param aString a 8-bit wide string to scan
+ */
+NS_COM PRBool IsASCII( const nsACString& aString );
+
+
+ /**
+ * Returns |PR_TRUE| if |aString| is a valid UTF-8 string.
+ * XXX This is not bullet-proof and nor an all-purpose UTF-8 validator.
+ * It is mainly written to replace and roughly equivalent to
+ *
+ * str.Equals(NS_ConvertUTF16toUTF8(NS_ConvertUTF8toUTF16(str)))
+ *
+ * (see bug 191541)
+ * As such, it does not check for non-UTF-8 7bit encodings such as
+ * ISO-2022-JP and HZ. However, it filters out UTF-8 representation
+ * of surrogate codepoints and non-characters ( 0xFFFE and 0xFFFF
+ * in planes 0 through 16.) as well as overlong UTF-8 sequences.
+ * Also note that it regards UTF-8 sequences corresponding to
+ * codepoints above 0x10FFFF as invalid in accordance with
+ * http://www.ietf.org/internet-drafts/draft-yergeau-rfc2279bis-04.txt
+ *
+ * @param aString an 8-bit wide string to scan
+ */
+NS_COM PRBool IsUTF8( const nsACString& aString );
+
+
+ /**
+ * Converts case in place in the argument string.
+ */
+NS_COM void ToUpperCase( nsACString& );
+
+NS_COM void ToLowerCase( nsACString& );
+
+NS_COM void ToUpperCase( nsCSubstring& );
+
+NS_COM void ToLowerCase( nsCSubstring& );
+
+ /**
+ * Converts case from string aSource to aDest.
+ */
+NS_COM void ToUpperCase( const nsACString& aSource, nsACString& aDest );
+
+NS_COM void ToLowerCase( const nsACString& aSource, nsACString& aDest );
+
+ /**
+ * Finds the leftmost occurance of |aPattern|, if any in the range |aSearchStart|..|aSearchEnd|.
+ *
+ * Returns |PR_TRUE| if a match was found, and adjusts |aSearchStart| and |aSearchEnd| to
+ * point to the match. If no match was found, returns |PR_FALSE| and makes |aSearchStart == aSearchEnd|.
+ *
+ * Currently, this is equivalent to the O(m*n) implementation previously on |ns[C]String|.
+ * If we need something faster, then we can implement that later.
+ */
+
+NS_COM PRBool FindInReadable( const nsAString& aPattern, nsAString::const_iterator&, nsAString::const_iterator&, const nsStringComparator& = nsDefaultStringComparator() );
+NS_COM PRBool FindInReadable( const nsACString& aPattern, nsACString::const_iterator&, nsACString::const_iterator&, const nsCStringComparator& = nsDefaultCStringComparator() );
+
+/* sometimes we don't care about where the string was, just that we
+ * found it or not */
+inline PRBool FindInReadable( const nsAString& aPattern, const nsAString& aSource, const nsStringComparator& compare = nsDefaultStringComparator() )
+{
+ nsAString::const_iterator start, end;
+ aSource.BeginReading(start);
+ aSource.EndReading(end);
+ return FindInReadable(aPattern, start, end, compare);
+}
+
+inline PRBool FindInReadable( const nsACString& aPattern, const nsACString& aSource, const nsCStringComparator& compare = nsDefaultCStringComparator() )
+{
+ nsACString::const_iterator start, end;
+ aSource.BeginReading(start);
+ aSource.EndReading(end);
+ return FindInReadable(aPattern, start, end, compare);
+}
+
+
+NS_COM PRBool CaseInsensitiveFindInReadable( const nsACString& aPattern, nsACString::const_iterator&, nsACString::const_iterator& );
+
+ /**
+ * Finds the rightmost occurance of |aPattern|
+ * Returns |PR_TRUE| if a match was found, and adjusts |aSearchStart| and |aSearchEnd| to
+ * point to the match. If no match was found, returns |PR_FALSE| and makes |aSearchStart == aSearchEnd|.
+ *
+ * Currently, this is equivalent to the O(m*n) implementation previously on |ns[C]String|.
+ * If we need something faster, then we can implement that later.
+ */
+NS_COM PRBool RFindInReadable( const nsAString& aPattern, nsAString::const_iterator&, nsAString::const_iterator&, const nsStringComparator& = nsDefaultStringComparator() );
+NS_COM PRBool RFindInReadable( const nsACString& aPattern, nsACString::const_iterator&, nsACString::const_iterator&, const nsCStringComparator& = nsDefaultCStringComparator() );
+
+ /**
+ * Finds the leftmost occurance of |aChar|, if any in the range
+ * |aSearchStart|..|aSearchEnd|.
+ *
+ * Returns |PR_TRUE| if a match was found, and adjusts |aSearchStart| to
+ * point to the match. If no match was found, returns |PR_FALSE| and
+ * makes |aSearchStart == aSearchEnd|.
+ */
+NS_COM PRBool FindCharInReadable( PRUnichar aChar, nsAString::const_iterator& aSearchStart, const nsAString::const_iterator& aSearchEnd );
+NS_COM PRBool FindCharInReadable( char aChar, nsACString::const_iterator& aSearchStart, const nsACString::const_iterator& aSearchEnd );
+
+ /**
+ * Finds the number of occurences of |aChar| in the string |aStr|
+ */
+NS_COM PRUint32 CountCharInReadable( const nsAString& aStr,
+ PRUnichar aChar );
+NS_COM PRUint32 CountCharInReadable( const nsACString& aStr,
+ char aChar );
+
+NS_COM PRBool
+StringBeginsWith( const nsAString& aSource, const nsAString& aSubstring,
+ const nsStringComparator& aComparator =
+ nsDefaultStringComparator() );
+NS_COM PRBool
+StringBeginsWith( const nsACString& aSource, const nsACString& aSubstring,
+ const nsCStringComparator& aComparator =
+ nsDefaultCStringComparator() );
+NS_COM PRBool
+StringEndsWith( const nsAString& aSource, const nsAString& aSubstring,
+ const nsStringComparator& aComparator =
+ nsDefaultStringComparator() );
+NS_COM PRBool
+StringEndsWith( const nsACString& aSource, const nsACString& aSubstring,
+ const nsCStringComparator& aComparator =
+ nsDefaultCStringComparator() );
+
+NS_COM PRUint32 HashString( const nsAString& aStr );
+NS_COM PRUint32 HashString( const nsACString& aStr );
+
+NS_COM const nsAFlatString& EmptyString();
+NS_COM const nsAFlatCString& EmptyCString();
+
+
+#endif // !defined(nsReadableUtils_h___)
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsString.h b/src/libs/xpcom18a4/xpcom/string/public/nsString.h
new file mode 100644
index 00000000..67376d19
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsString.h
@@ -0,0 +1,237 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsString_h___
+#define nsString_h___
+
+
+#ifndef nsSubstring_h___
+#include "nsSubstring.h"
+#endif
+
+#ifndef nsDependentSubstring_h___
+#include "nsDependentSubstring.h"
+#endif
+
+#ifndef nsReadableUtils_h___
+#include "nsReadableUtils.h"
+#endif
+
+#include NEW_H
+
+ // enable support for the obsolete string API if not explicitly disabled
+#ifndef MOZ_STRING_WITH_OBSOLETE_API
+#define MOZ_STRING_WITH_OBSOLETE_API 1
+#endif
+
+#if MOZ_STRING_WITH_OBSOLETE_API
+ // radix values for ToInteger/AppendInt
+#define kRadix10 (10)
+#define kRadix16 (16)
+#define kAutoDetect (100)
+#define kRadixUnknown (kAutoDetect+1)
+#define IGNORE_CASE (PR_TRUE)
+#endif
+
+
+ // declare nsString, et. al.
+#include "string-template-def-unichar.h"
+#include "nsTString.h"
+#include "string-template-undef.h"
+
+ // declare nsCString, et. al.
+#include "string-template-def-char.h"
+#include "nsTString.h"
+#include "string-template-undef.h"
+
+
+ /**
+ * A helper class that converts a UTF-16 string to ASCII in a lossy manner
+ */
+class NS_LossyConvertUTF16toASCII : public nsCAutoString
+ {
+ public:
+ explicit
+ NS_LossyConvertUTF16toASCII( const PRUnichar* aString )
+ {
+ LossyAppendUTF16toASCII(aString, *this);
+ }
+
+ NS_LossyConvertUTF16toASCII( const PRUnichar* aString, PRUint32 aLength )
+ {
+ LossyAppendUTF16toASCII(Substring(aString, aString + aLength), *this);
+ }
+
+ explicit
+ NS_LossyConvertUTF16toASCII( const nsAString& aString )
+ {
+ LossyAppendUTF16toASCII(aString, *this);
+ }
+
+ private:
+ // NOT TO BE IMPLEMENTED
+ NS_LossyConvertUTF16toASCII( char );
+ };
+
+
+class NS_ConvertASCIItoUTF16 : public nsAutoString
+ {
+ public:
+ explicit
+ NS_ConvertASCIItoUTF16( const char* aCString )
+ {
+ AppendASCIItoUTF16(aCString, *this);
+ }
+
+ NS_ConvertASCIItoUTF16( const char* aCString, PRUint32 aLength )
+ {
+ AppendASCIItoUTF16(Substring(aCString, aCString + aLength), *this);
+ }
+
+ explicit
+ NS_ConvertASCIItoUTF16( const nsACString& aCString )
+ {
+ AppendASCIItoUTF16(aCString, *this);
+ }
+
+ private:
+ // NOT TO BE IMPLEMENTED
+ NS_ConvertASCIItoUTF16( PRUnichar );
+ };
+
+
+ /**
+ * A helper class that converts a UTF-16 string to UTF-8
+ */
+class NS_ConvertUTF16toUTF8 : public nsCAutoString
+ {
+ public:
+ explicit
+ NS_ConvertUTF16toUTF8( const PRUnichar* aString )
+ {
+ AppendUTF16toUTF8(aString, *this);
+ }
+
+ NS_ConvertUTF16toUTF8( const PRUnichar* aString, PRUint32 aLength )
+ {
+ AppendUTF16toUTF8(Substring(aString, aString + aLength), *this);
+ }
+
+ explicit
+ NS_ConvertUTF16toUTF8( const nsAString& aString )
+ {
+ AppendUTF16toUTF8(aString, *this);
+ }
+
+ private:
+ // NOT TO BE IMPLEMENTED
+ NS_ConvertUTF16toUTF8( char );
+ };
+
+
+class NS_ConvertUTF8toUTF16 : public nsAutoString
+ {
+ public:
+ explicit
+ NS_ConvertUTF8toUTF16( const char* aCString )
+ {
+ AppendUTF8toUTF16(aCString, *this);
+ }
+
+ NS_ConvertUTF8toUTF16( const char* aCString, PRUint32 aLength )
+ {
+ AppendUTF8toUTF16(Substring(aCString, aCString + aLength), *this);
+ }
+
+ explicit
+ NS_ConvertUTF8toUTF16( const nsACString& aCString )
+ {
+ AppendUTF8toUTF16(aCString, *this);
+ }
+
+ private:
+ // NOT TO BE IMPLEMENTED
+ NS_ConvertUTF8toUTF16( PRUnichar );
+ };
+
+
+// the following are included/declared for backwards compatibility
+
+typedef NS_ConvertUTF16toUTF8 NS_ConvertUCS2toUTF8;
+typedef NS_LossyConvertUTF16toASCII NS_LossyConvertUCS2toASCII;
+typedef NS_ConvertASCIItoUTF16 NS_ConvertASCIItoUCS2;
+typedef NS_ConvertUTF8toUTF16 NS_ConvertUTF8toUCS2;
+typedef nsAutoString nsVoidableString;
+
+#ifndef nsDependentString_h___
+#include "nsDependentString.h"
+#endif
+
+#ifndef nsLiteralString_h___
+#include "nsLiteralString.h"
+#endif
+
+#ifndef nsPromiseFlatString_h___
+#include "nsPromiseFlatString.h"
+#endif
+
+// need to include these for backwards compatibility
+#include "nsMemory.h"
+#include <string.h>
+#include <stdio.h>
+#include "plhash.h"
+
+inline PRInt32 MinInt(PRInt32 x, PRInt32 y)
+ {
+ return NS_MIN(x, y);
+ }
+
+inline PRInt32 MaxInt(PRInt32 x, PRInt32 y)
+ {
+ return NS_MAX(x, y);
+ }
+
+/**
+ * Deprecated: don't use |Recycle|, just call |nsMemory::Free| directly
+ *
+ * Return the given buffer to the heap manager. Calls allocator::Free()
+ */
+inline void Recycle( char* aBuffer) { nsMemory::Free(aBuffer); }
+inline void Recycle( PRUnichar* aBuffer) { nsMemory::Free(aBuffer); }
+
+#endif // !defined(nsString_h___)
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsStringAPI.h b/src/libs/xpcom18a4/xpcom/string/public/nsStringAPI.h
new file mode 100644
index 00000000..cc0818b6
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsStringAPI.h
@@ -0,0 +1,853 @@
+/* vim:set ts=2 sw=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsStringAPI_h__
+#define nsStringAPI_h__
+
+/**
+ * nsStringAPI.h
+ *
+ * This file describes a minimal API for working with XPCOM's abstract
+ * string classes. It divorces the consumer from having any run-time
+ * dependency on the implementation details of the abstract string types.
+ */
+
+#include "nscore.h"
+
+#ifdef VBOX_WITH_XPCOM_NAMESPACE_CLEANUP
+#define NS_CStringContainerInit VBoxNsxpNS_CStringContainerInit
+#define NS_CStringContainerFinish VBoxNsxpNS_CStringContainerFinish
+#define NS_CStringCloneData VBoxNsxpNS_CStringCloneData
+#define NS_CStringCopy VBoxNsxpNS_CStringCopy
+#define NS_CStringGetData VBoxNsxpNS_CStringGetData
+#define NS_CStringSetData VBoxNsxpNS_CStringSetData
+#define NS_CStringSetDataRange VBoxNsxpNS_CStringSetDataRange
+#define NS_UTF16ToCString VBoxNsxpNS_UTF16ToCString
+#define NS_CStringToUTF16 VBoxNsxpNS_CStringToUTF16
+#define NS_StringContainerInit VBoxNsxpNS_StringContainerInit
+#define NS_StringContainerFinish VBoxNsxpNS_StringContainerFinish
+#define NS_StringCloneData VBoxNsxpNS_StringCloneData
+#define NS_StringCopy VBoxNsxpNS_StringCopy
+#define NS_StringGetData VBoxNsxpNS_StringGetData
+#define NS_StringSetData VBoxNsxpNS_StringSetData
+#define NS_StringSetDataRange VBoxNsxpNS_StringSetDataRange
+#endif /* VBOX_WITH_XPCOM_NAMESPACE_CLEANUP */
+
+#define NS_STRINGAPI(x) extern "C" NS_COM x
+
+/* The base string types */
+class nsAString;
+class nsACString;
+
+/* ------------------------------------------------------------------------- */
+
+/**
+ * nsStringContainer
+ *
+ * This is an opaque data type that is large enough to hold the canonical
+ * implementation of nsAString. The binary structure of this class is an
+ * implementation detail.
+ *
+ * The string data stored in a string container is always single fragment
+ * and null-terminated.
+ *
+ * Typically, string containers are allocated on the stack for temporary
+ * use. However, they can also be malloc'd if necessary. In either case,
+ * a string container is not useful until it has been initialized with a
+ * call to NS_StringContainerInit. The following example shows how to use
+ * a string container to call a function that takes a |nsAString &| out-param.
+ *
+ * NS_METHOD GetBlah(nsAString &aBlah);
+ *
+ * nsresult MyCode()
+ * {
+ * nsresult rv;
+ *
+ * nsStringContainer sc;
+ * rv = NS_StringContainerInit(sc);
+ * if (NS_FAILED(rv))
+ * return rv;
+ *
+ * rv = GetBlah(sc);
+ * if (NS_SUCCEEDED(rv))
+ * {
+ * const PRUnichar *data;
+ * NS_StringGetData(sc, &data);
+ * //
+ * // |data| now points to the result of the GetBlah function
+ * //
+ * }
+ *
+ * NS_StringContainerFinish(sc);
+ * return rv;
+ * }
+ *
+ * The following example show how to use a string container to pass a string
+ * parameter to a function taking a |const nsAString &| in-param.
+ *
+ * NS_METHOD SetBlah(const nsAString &aBlah);
+ *
+ * nsresult MyCode()
+ * {
+ * nsresult rv;
+ *
+ * nsStringContainer sc;
+ * rv = NS_StringContainerInit(sc);
+ * if (NS_FAILED(rv))
+ * return rv;
+ *
+ * const PRUnichar kData[] = {'x','y','z','\0'};
+ * rv = NS_StringSetData(sc, kData, sizeof(kData)/2 - 1);
+ * if (NS_SUCCEEDED(rv))
+ * rv = SetBlah(sc);
+ *
+ * NS_StringContainerFinish(sc);
+ * return rv;
+ * }
+ */
+class nsStringContainer;
+
+/**
+ * NS_StringContainerInit
+ *
+ * @param aContainer string container reference
+ * @return NS_OK if string container successfully initialized
+ *
+ * This function may allocate additional memory for aContainer. When
+ * aContainer is no longer needed, NS_StringContainerFinish should be called.
+ *
+ * @status FROZEN
+ */
+NS_STRINGAPI(nsresult)
+NS_StringContainerInit(nsStringContainer &aContainer);
+
+/**
+ * NS_StringContainerFinish
+ *
+ * @param aContainer string container reference
+ *
+ * This function frees any memory owned by aContainer.
+ *
+ * @status FROZEN
+ */
+NS_STRINGAPI(void)
+NS_StringContainerFinish(nsStringContainer &aContainer);
+
+/* ------------------------------------------------------------------------- */
+
+/**
+ * NS_StringGetData
+ *
+ * This function returns a const character pointer to the string's internal
+ * buffer, the length of the string, and a boolean value indicating whether
+ * or not the buffer is null-terminated.
+ *
+ * @param aStr abstract string reference
+ * @param aData out param that will hold the address of aStr's
+ * internal buffer
+ * @param aTerminated if non-null, this out param will be set to indicate
+ * whether or not aStr's internal buffer is null-
+ * terminated
+ * @return length of aStr's internal buffer
+ *
+ * @status FROZEN
+ */
+NS_STRINGAPI(PRUint32)
+NS_StringGetData
+ (const nsAString &aStr, const PRUnichar **aData,
+ PRBool *aTerminated = nsnull);
+
+/**
+ * NS_StringCloneData
+ *
+ * This function returns a null-terminated copy of the string's
+ * internal buffer.
+ *
+ * @param aStr abstract string reference
+ * @return null-terminated copy of the string's internal buffer
+ * (it must be free'd using using nsMemory::Free)
+ *
+ * @status FROZEN
+ */
+NS_STRINGAPI(PRUnichar *)
+NS_StringCloneData
+ (const nsAString &aStr);
+
+/**
+ * NS_StringSetData
+ *
+ * This function copies aData into aStr.
+ *
+ * @param aStr abstract string reference
+ * @param aData character buffer
+ * @param aDataLength number of characters to copy from source string (pass
+ * PR_UINT32_MAX to copy until end of aData, designated by
+ * a null character)
+ * @return NS_OK if function succeeded
+ *
+ * This function does not necessarily null-terminate aStr after copying data
+ * from aData. The behavior depends on the implementation of the abstract
+ * string, aStr. If aStr is a reference to a nsStringContainer, then its data
+ * will be null-terminated by this function.
+ *
+ * @status FROZEN
+ */
+NS_STRINGAPI(nsresult)
+NS_StringSetData
+ (nsAString &aStr, const PRUnichar *aData,
+ PRUint32 aDataLength = PR_UINT32_MAX);
+
+/**
+ * NS_StringSetDataRange
+ *
+ * This function copies aData into a section of aStr. As a result it can be
+ * used to insert new characters into the string.
+ *
+ * @param aStr abstract string reference
+ * @param aCutOffset starting index where the string's existing data
+ * is to be overwritten (pass PR_UINT32_MAX to cause
+ * aData to be appended to the end of aStr, in which
+ * case the value of aCutLength is ignored).
+ * @param aCutLength number of characters to overwrite starting at
+ * aCutOffset (pass PR_UINT32_MAX to overwrite until the
+ * end of aStr).
+ * @param aData character buffer (pass null to cause this function
+ * to simply remove the "cut" range)
+ * @param aDataLength number of characters to copy from source string (pass
+ * PR_UINT32_MAX to copy until end of aData, designated by
+ * a null character)
+ * @return NS_OK if function succeeded
+ *
+ * This function does not necessarily null-terminate aStr after copying data
+ * from aData. The behavior depends on the implementation of the abstract
+ * string, aStr. If aStr is a reference to a nsStringContainer, then its data
+ * will be null-terminated by this function.
+ *
+ * @status FROZEN
+ */
+NS_STRINGAPI(nsresult)
+NS_StringSetDataRange
+ (nsAString &aStr, PRUint32 aCutOffset, PRUint32 aCutLength,
+ const PRUnichar *aData, PRUint32 aDataLength = PR_UINT32_MAX);
+
+/**
+ * NS_StringCopy
+ *
+ * This function makes aDestStr have the same value as aSrcStr. It is
+ * provided as an optimization.
+ *
+ * @param aDestStr abstract string reference to be modified
+ * @param aSrcStr abstract string reference containing source string
+ * @return NS_OK if function succeeded
+ *
+ * This function does not necessarily null-terminate aDestStr after copying
+ * data from aSrcStr. The behavior depends on the implementation of the
+ * abstract string, aDestStr. If aDestStr is a reference to a
+ * nsStringContainer, then its data will be null-terminated by this function.
+ *
+ * @status FROZEN
+ */
+NS_STRINGAPI(nsresult)
+NS_StringCopy
+ (nsAString &aDestStr, const nsAString &aSrcStr);
+
+/**
+ * NS_StringAppendData
+ *
+ * This function appends data to the existing value of aStr.
+ *
+ * @param aStr abstract string reference to be modified
+ * @param aData character buffer
+ * @param aDataLength number of characters to append (pass PR_UINT32_MAX to
+ * append until a null-character is encountered)
+ * @return NS_OK if function succeeded
+ *
+ * This function does not necessarily null-terminate aStr upon completion.
+ * The behavior depends on the implementation of the abstract string, aStr.
+ * If aStr is a reference to a nsStringContainer, then its data will be null-
+ * terminated by this function.
+ */
+inline NS_HIDDEN_(nsresult)
+NS_StringAppendData(nsAString &aStr, const PRUnichar *aData,
+ PRUint32 aDataLength = PR_UINT32_MAX)
+{
+ return NS_StringSetDataRange(aStr, PR_UINT32_MAX, 0, aData, aDataLength);
+}
+
+/**
+ * NS_StringInsertData
+ *
+ * This function inserts data into the existing value of aStr at the specified
+ * offset.
+ *
+ * @param aStr abstract string reference to be modified
+ * @param aOffset specifies where in the string to insert aData
+ * @param aData character buffer
+ * @param aDataLength number of characters to append (pass PR_UINT32_MAX to
+ * append until a null-character is encountered)
+ * @return NS_OK if function succeeded
+ *
+ * This function does not necessarily null-terminate aStr upon completion.
+ * The behavior depends on the implementation of the abstract string, aStr.
+ * If aStr is a reference to a nsStringContainer, then its data will be null-
+ * terminated by this function.
+ */
+inline NS_HIDDEN_(nsresult)
+NS_StringInsertData(nsAString &aStr, PRUint32 aOffset, const PRUnichar *aData,
+ PRUint32 aDataLength = PR_UINT32_MAX)
+{
+ return NS_StringSetDataRange(aStr, aOffset, 0, aData, aDataLength);
+}
+
+/**
+ * NS_StringCutData
+ *
+ * This function shortens the existing value of aStr, by removing characters
+ * at the specified offset.
+ *
+ * @param aStr abstract string reference to be modified
+ * @param aCutOffset specifies where in the string to insert aData
+ * @param aCutLength number of characters to remove
+ * @return NS_OK if function succeeded
+ */
+inline NS_HIDDEN_(nsresult)
+NS_StringCutData(nsAString &aStr, PRUint32 aCutOffset, PRUint32 aCutLength)
+{
+ return NS_StringSetDataRange(aStr, aCutOffset, aCutLength, nsnull, 0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/**
+ * nsCStringContainer
+ *
+ * This is an opaque data type that is large enough to hold the canonical
+ * implementation of nsACString. The binary structure of this class is an
+ * implementation detail.
+ *
+ * The string data stored in a string container is always single fragment
+ * and null-terminated.
+ *
+ * @see nsStringContainer for use cases and further documentation.
+ */
+class nsCStringContainer;
+
+/**
+ * NS_CStringContainerInit
+ *
+ * @param aContainer string container reference
+ * @return NS_OK if string container successfully initialized
+ *
+ * This function may allocate additional memory for aContainer. When
+ * aContainer is no longer needed, NS_CStringContainerFinish should be called.
+ *
+ * @status FROZEN
+ */
+NS_STRINGAPI(nsresult)
+NS_CStringContainerInit(nsCStringContainer &aContainer);
+
+/**
+ * NS_CStringContainerFinish
+ *
+ * @param aContainer string container reference
+ *
+ * This function frees any memory owned by aContainer.
+ *
+ * @status FROZEN
+ */
+NS_STRINGAPI(void)
+NS_CStringContainerFinish(nsCStringContainer &aContainer);
+
+/* ------------------------------------------------------------------------- */
+
+/**
+ * NS_CStringGetData
+ *
+ * This function returns a const character pointer to the string's internal
+ * buffer, the length of the string, and a boolean value indicating whether
+ * or not the buffer is null-terminated.
+ *
+ * @param aStr abstract string reference
+ * @param aData out param that will hold the address of aStr's
+ * internal buffer
+ * @param aTerminated if non-null, this out param will be set to indicate
+ * whether or not aStr's internal buffer is null-
+ * terminated
+ * @return length of aStr's internal buffer
+ *
+ * @status FROZEN
+ */
+NS_STRINGAPI(PRUint32)
+NS_CStringGetData
+ (const nsACString &aStr, const char **aData,
+ PRBool *aTerminated = nsnull);
+
+/**
+ * NS_CStringCloneData
+ *
+ * This function returns a null-terminated copy of the string's
+ * internal buffer.
+ *
+ * @param aStr abstract string reference
+ * @return null-terminated copy of the string's internal buffer
+ * (it must be free'd using using nsMemory::Free)
+ *
+ * @status FROZEN
+ */
+NS_STRINGAPI(char *)
+NS_CStringCloneData
+ (const nsACString &aStr);
+
+/**
+ * NS_CStringSetData
+ *
+ * This function copies aData into aStr.
+ *
+ * @param aStr abstract string reference
+ * @param aData character buffer
+ * @param aDataLength number of characters to copy from source string (pass
+ * PR_UINT32_MAX to copy until end of aData, designated by
+ * a null character)
+ * @return NS_OK if function succeeded
+ *
+ * This function does not necessarily null-terminate aStr after copying data
+ * from aData. The behavior depends on the implementation of the abstract
+ * string, aStr. If aStr is a reference to a nsStringContainer, then its data
+ * will be null-terminated by this function.
+ *
+ * @status FROZEN
+ */
+NS_STRINGAPI(nsresult)
+NS_CStringSetData
+ (nsACString &aStr, const char *aData,
+ PRUint32 aDataLength = PR_UINT32_MAX);
+
+/**
+ * NS_CStringSetDataRange
+ *
+ * This function copies aData into a section of aStr. As a result it can be
+ * used to insert new characters into the string.
+ *
+ * @param aStr abstract string reference
+ * @param aCutOffset starting index where the string's existing data
+ * is to be overwritten (pass PR_UINT32_MAX to cause
+ * aData to be appended to the end of aStr, in which
+ * case the value of aCutLength is ignored).
+ * @param aCutLength number of characters to overwrite starting at
+ * aCutOffset (pass PR_UINT32_MAX to overwrite until the
+ * end of aStr).
+ * @param aData character buffer (pass null to cause this function
+ * to simply remove the "cut" range)
+ * @param aDataLength number of characters to copy from source string (pass
+ * PR_UINT32_MAX to copy until end of aData, designated by
+ * a null character)
+ * @return NS_OK if function succeeded
+ *
+ * This function does not necessarily null-terminate aStr after copying data
+ * from aData. The behavior depends on the implementation of the abstract
+ * string, aStr. If aStr is a reference to a nsStringContainer, then its data
+ * will be null-terminated by this function.
+ *
+ * @status FROZEN
+ */
+NS_STRINGAPI(nsresult)
+NS_CStringSetDataRange
+ (nsACString &aStr, PRUint32 aCutOffset, PRUint32 aCutLength,
+ const char *aData, PRUint32 aDataLength = PR_UINT32_MAX);
+
+/**
+ * NS_CStringCopy
+ *
+ * This function makes aDestStr have the same value as aSrcStr. It is
+ * provided as an optimization.
+ *
+ * @param aDestStr abstract string reference to be modified
+ * @param aSrcStr abstract string reference containing source string
+ * @return NS_OK if function succeeded
+ *
+ * This function does not necessarily null-terminate aDestStr after copying
+ * data from aSrcStr. The behavior depends on the implementation of the
+ * abstract string, aDestStr. If aDestStr is a reference to a
+ * nsStringContainer, then its data will be null-terminated by this function.
+ *
+ * @status FROZEN
+ */
+NS_STRINGAPI(nsresult)
+NS_CStringCopy
+ (nsACString &aDestStr, const nsACString &aSrcStr);
+
+/**
+ * NS_CStringAppendData
+ *
+ * This function appends data to the existing value of aStr.
+ *
+ * @param aStr abstract string reference to be modified
+ * @param aData character buffer
+ * @param aDataLength number of characters to append (pass PR_UINT32_MAX to
+ * append until a null-character is encountered)
+ * @return NS_OK if function succeeded
+ *
+ * This function does not necessarily null-terminate aStr upon completion.
+ * The behavior depends on the implementation of the abstract string, aStr.
+ * If aStr is a reference to a nsStringContainer, then its data will be null-
+ * terminated by this function.
+ */
+inline NS_HIDDEN_(nsresult)
+NS_CStringAppendData(nsACString &aStr, const char *aData,
+ PRUint32 aDataLength = PR_UINT32_MAX)
+{
+ return NS_CStringSetDataRange(aStr, PR_UINT32_MAX, 0, aData, aDataLength);
+}
+
+/**
+ * NS_CStringInsertData
+ *
+ * This function inserts data into the existing value of aStr at the specified
+ * offset.
+ *
+ * @param aStr abstract string reference to be modified
+ * @param aOffset specifies where in the string to insert aData
+ * @param aData character buffer
+ * @param aDataLength number of characters to append (pass PR_UINT32_MAX to
+ * append until a null-character is encountered)
+ * @return NS_OK if function succeeded
+ *
+ * This function does not necessarily null-terminate aStr upon completion.
+ * The behavior depends on the implementation of the abstract string, aStr.
+ * If aStr is a reference to a nsStringContainer, then its data will be null-
+ * terminated by this function.
+ */
+inline NS_HIDDEN_(nsresult)
+NS_CStringInsertData(nsACString &aStr, PRUint32 aOffset, const char *aData,
+ PRUint32 aDataLength = PR_UINT32_MAX)
+{
+ return NS_CStringSetDataRange(aStr, aOffset, 0, aData, aDataLength);
+}
+
+/**
+ * NS_CStringCutData
+ *
+ * This function shortens the existing value of aStr, by removing characters
+ * at the specified offset.
+ *
+ * @param aStr abstract string reference to be modified
+ * @param aCutOffset specifies where in the string to insert aData
+ * @param aCutLength number of characters to remove
+ * @return NS_OK if function succeeded
+ */
+inline NS_HIDDEN_(nsresult)
+NS_CStringCutData(nsACString &aStr, PRUint32 aCutOffset, PRUint32 aCutLength)
+{
+ return NS_CStringSetDataRange(aStr, aCutOffset, aCutLength, nsnull, 0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/**
+ * Encodings that can be used with the following conversion routines.
+ */
+enum nsCStringEncoding {
+ /* Conversion between ASCII and UTF-16 assumes that all bytes in the source
+ * string are 7-bit ASCII and can be inflated to UTF-16 by inserting null
+ * bytes. Reverse conversion is done by truncating every other byte. The
+ * conversion may result in loss and/or corruption of information if the
+ * strings do not strictly contain ASCII data. */
+ NS_CSTRING_ENCODING_ASCII = 0,
+
+ /* Conversion between UTF-8 and UTF-16 is non-lossy. */
+ NS_CSTRING_ENCODING_UTF8 = 1,
+
+ /* Conversion from UTF-16 to the native filesystem charset may result in a
+ * loss of information. No attempt is made to protect against data loss in
+ * this case. The native filesystem charset applies to strings passed to
+ * the "Native" method variants on nsIFile and nsILocalFile. */
+ NS_CSTRING_ENCODING_NATIVE_FILESYSTEM = 2
+};
+
+/**
+ * NS_CStringToUTF16
+ *
+ * This function converts the characters in a nsACString to an array of UTF-16
+ * characters, in the platform endianness. The result is stored in a nsAString
+ * object.
+ *
+ * @param aSource abstract string reference containing source string
+ * @param aSrcEncoding character encoding of the source string
+ * @param aDest abstract string reference to hold the result
+ *
+ * @status FROZEN
+ */
+NS_STRINGAPI(nsresult)
+NS_CStringToUTF16(const nsACString &aSource, nsCStringEncoding aSrcEncoding,
+ nsAString &aDest);
+
+/**
+ * NS_UTF16ToCString
+ *
+ * This function converts the UTF-16 characters in a nsAString to a single-byte
+ * encoding. The result is stored in a nsACString object. In some cases this
+ * conversion may be lossy. In such cases, the conversion may succeed with a
+ * return code indicating loss of information. The exact behavior is not
+ * specified at this time.
+ *
+ * @param aSource abstract string reference containing source string
+ * @param aDestEncoding character encoding of the resulting string
+ * @param aDest abstract string reference to hold the result
+ *
+ * @status FROZEN
+ */
+NS_STRINGAPI(nsresult)
+NS_UTF16ToCString(const nsAString &aSource, nsCStringEncoding aDestEncoding,
+ nsACString &aDest);
+
+/* ------------------------------------------------------------------------- */
+
+/**
+ * Below we define nsAString and nsACString. The "_external" suffix is an
+ * implementation detail. nsAString_external is the name of the external
+ * representation of nsAString from the point of view of the Mozilla codebase.
+ * To a user of this API, nsAString_external is exactly nsAString.
+ *
+ * These classes should be treated as abstract classes with unspecified
+ * structure. The inline methods are provided as helper functions around the
+ * C-style API provided above.
+ *
+ * Do not try to mix these definitions of nsAString and nsACString with the
+ * internal definition of these classes from nsAString.h in the Mozilla tree.
+ */
+
+#ifndef NS_STRINGAPI_IMPL
+#define nsAString_external nsAString
+#define nsACString_external nsACString
+#endif
+
+class nsAString_external
+{
+#ifndef NS_STRINGAPI_IMPL
+
+public:
+ typedef PRUnichar char_type;
+ typedef nsAString_external self_type;
+ typedef PRUint32 size_type;
+ typedef PRUint32 index_type;
+
+ NS_HIDDEN_(const char_type*) BeginReading() const
+ {
+ const char_type *data;
+ NS_StringGetData(*this, &data);
+ return data;
+ }
+
+ NS_HIDDEN_(const char_type*) EndReading() const
+ {
+ const char_type *data;
+ PRUint32 len = NS_StringGetData(*this, &data);
+ return data + len;
+ }
+
+ NS_HIDDEN_(size_type) Length() const
+ {
+ const char_type* data;
+ return NS_StringGetData(*this, &data);
+ }
+
+ NS_HIDDEN_(void) Assign(const self_type& aString)
+ {
+ NS_StringCopy(*this, aString);
+ }
+ NS_HIDDEN_(void) Assign(const char_type* aData, size_type aLength = PR_UINT32_MAX)
+ {
+ NS_StringSetData(*this, aData, aLength);
+ }
+ NS_HIDDEN_(void) Assign(char_type aChar)
+ {
+ NS_StringSetData(*this, &aChar, 1);
+ }
+
+ NS_HIDDEN_(self_type&) operator=(const self_type& aString) { Assign(aString); return *this; }
+ NS_HIDDEN_(self_type&) operator=(const char_type* aPtr) { Assign(aPtr); return *this; }
+ NS_HIDDEN_(self_type&) operator=(char_type aChar) { Assign(aChar); return *this; }
+
+ NS_HIDDEN_(void) Replace( index_type cutStart, size_type cutLength, const char_type* data, size_type length = size_type(-1) )
+ {
+ NS_StringSetDataRange(*this, cutStart, cutLength, data, length);
+ }
+ NS_HIDDEN_(void) Replace( index_type cutStart, size_type cutLength, char_type c )
+ {
+ Replace(cutStart, cutLength, &c, 1);
+ }
+ NS_HIDDEN_(void) Replace( index_type cutStart, size_type cutLength, const self_type& readable )
+ {
+ const char_type* data;
+ PRUint32 dataLen = NS_StringGetData(readable, &data);
+ NS_StringSetDataRange(*this, cutStart, cutLength, data, dataLen);
+ }
+
+ NS_HIDDEN_(void) Append( char_type c ) { Replace(size_type(-1), 0, c); }
+ NS_HIDDEN_(void) Append( const char_type* data, size_type length = size_type(-1) ) { Replace(size_type(-1), 0, data, length); }
+ NS_HIDDEN_(void) Append( const self_type& readable ) { Replace(size_type(-1), 0, readable); }
+
+ NS_HIDDEN_(self_type&) operator+=( char_type c ) { Append(c); return *this; }
+ NS_HIDDEN_(self_type&) operator+=( const char_type* data ) { Append(data); return *this; }
+ NS_HIDDEN_(self_type&) operator+=( const self_type& readable ) { Append(readable); return *this; }
+
+ NS_HIDDEN_(void) Insert( char_type c, index_type pos ) { Replace(pos, 0, c); }
+ NS_HIDDEN_(void) Insert( const char_type* data, index_type pos, size_type length = size_type(-1) ) { Replace(pos, 0, data, length); }
+ NS_HIDDEN_(void) Insert( const self_type& readable, index_type pos ) { Replace(pos, 0, readable); }
+
+ NS_HIDDEN_(void) Cut( index_type cutStart, size_type cutLength ) { Replace(cutStart, cutLength, nsnull, 0); }
+
+#endif // NS_STRINGAPI_IMPL
+
+private:
+ void *v;
+};
+
+class nsACString_external
+{
+#ifndef NS_STRINGAPI_IMPL
+
+public:
+ typedef char char_type;
+ typedef nsACString_external self_type;
+ typedef PRUint32 size_type;
+ typedef PRUint32 index_type;
+
+ NS_HIDDEN_(const char_type*) BeginReading() const
+ {
+ const char_type *data;
+ NS_CStringGetData(*this, &data);
+ return data;
+ }
+
+ NS_HIDDEN_(const char_type*) EndReading() const
+ {
+ const char_type *data;
+ PRUint32 len = NS_CStringGetData(*this, &data);
+ return data + len;
+ }
+
+ NS_HIDDEN_(size_type) Length() const
+ {
+ const char_type* data;
+ return NS_CStringGetData(*this, &data);
+ }
+
+ NS_HIDDEN_(void) Assign(const self_type& aString)
+ {
+ NS_CStringCopy(*this, aString);
+ }
+ NS_HIDDEN_(void) Assign(const char_type* aData, size_type aLength = PR_UINT32_MAX)
+ {
+ NS_CStringSetData(*this, aData, aLength);
+ }
+ NS_HIDDEN_(void) Assign(char_type aChar)
+ {
+ NS_CStringSetData(*this, &aChar, 1);
+ }
+
+ NS_HIDDEN_(self_type&) operator=(const self_type& aString) { Assign(aString); return *this; }
+ NS_HIDDEN_(self_type&) operator=(const char_type* aPtr) { Assign(aPtr); return *this; }
+ NS_HIDDEN_(self_type&) operator=(char_type aChar) { Assign(aChar); return *this; }
+
+ NS_HIDDEN_(void) Replace( index_type cutStart, size_type cutLength, const char_type* data, size_type length = size_type(-1) )
+ {
+ NS_CStringSetDataRange(*this, cutStart, cutLength, data, length);
+ }
+ NS_HIDDEN_(void) Replace( index_type cutStart, size_type cutLength, char_type c )
+ {
+ Replace(cutStart, cutLength, &c, 1);
+ }
+ NS_HIDDEN_(void) Replace( index_type cutStart, size_type cutLength, const self_type& readable )
+ {
+ const char_type* data;
+ PRUint32 dataLen = NS_CStringGetData(readable, &data);
+ NS_CStringSetDataRange(*this, cutStart, cutLength, data, dataLen);
+ }
+
+ NS_HIDDEN_(void) Append( char_type c ) { Replace(size_type(-1), 0, c); }
+ NS_HIDDEN_(void) Append( const char_type* data, size_type length = size_type(-1) ) { Replace(size_type(-1), 0, data, length); }
+ NS_HIDDEN_(void) Append( const self_type& readable ) { Replace(size_type(-1), 0, readable); }
+
+ NS_HIDDEN_(self_type&) operator+=( char_type c ) { Append(c); return *this; }
+ NS_HIDDEN_(self_type&) operator+=( const char_type* data ) { Append(data); return *this; }
+ NS_HIDDEN_(self_type&) operator+=( const self_type& readable ) { Append(readable); return *this; }
+
+ NS_HIDDEN_(void) Insert( char_type c, index_type pos ) { Replace(pos, 0, c); }
+ NS_HIDDEN_(void) Insert( const char_type* data, index_type pos, size_type length = size_type(-1) ) { Replace(pos, 0, data, length); }
+ NS_HIDDEN_(void) Insert( const self_type& readable, index_type pos ) { Replace(pos, 0, readable); }
+
+ NS_HIDDEN_(void) Cut( index_type cutStart, size_type cutLength ) { Replace(cutStart, cutLength, nsnull, 0); }
+
+#endif // NS_STRINGAPI_IMPL
+
+private:
+ void *v;
+};
+
+/* ------------------------------------------------------------------------- */
+
+/**
+ * Below we define nsStringContainer and nsCStringContainer. These classes
+ * have unspecified structure. In most cases, your code should use
+ * nsEmbedString instead of these classes; however, if you prefer C-style
+ * programming, then look no further...
+ */
+
+class nsStringContainer : public nsAString_external
+{
+private:
+ void *d1;
+ PRUint32 d2;
+ void *d3;
+
+public:
+ nsStringContainer() {} // MSVC6 needs this
+};
+
+class nsCStringContainer : public nsACString_external
+{
+private:
+ void *d1;
+ PRUint32 d2;
+ void *d3;
+
+public:
+ nsCStringContainer() {} // MSVC6 needs this
+};
+
+#endif // nsStringAPI_h__
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsStringFwd.h b/src/libs/xpcom18a4/xpcom/string/public/nsStringFwd.h
new file mode 100644
index 00000000..4c664011
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsStringFwd.h
@@ -0,0 +1,96 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications.
+ * Portions created by the Initial Developer are Copyright (C) 2001
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Scott Collins <scc@mozilla.org> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* nsStringFwd.h --- forward declarations for string classes */
+
+#ifndef nsStringFwd_h___
+#define nsStringFwd_h___
+
+#ifndef nscore_h___
+#include "nscore.h"
+#endif
+
+
+ /**
+ * double-byte (PRUnichar) string types
+ */
+
+class nsAString;
+class nsObsoleteAString;
+class nsSubstring;
+class nsSubstringTuple;
+class nsString;
+class nsAutoString;
+class nsDependentString;
+class nsDependentSubstring;
+class nsPromiseFlatString;
+class nsStringComparator;
+class nsDefaultStringComparator;
+class nsXPIDLString;
+
+
+ /**
+ * single-byte (char) string types
+ */
+
+class nsACString;
+class nsObsoleteACString;
+class nsCSubstring;
+class nsCSubstringTuple;
+class nsCString;
+class nsCAutoString;
+class nsDependentCString;
+class nsDependentCSubstring;
+class nsPromiseFlatCString;
+class nsCStringComparator;
+class nsDefaultCStringComparator;
+class nsXPIDLCString;
+
+
+ /**
+ * typedefs for backwards compatibility
+ */
+
+typedef nsString nsAFlatString;
+typedef nsSubstring nsASingleFragmentString;
+
+typedef nsCString nsAFlatCString;
+typedef nsCSubstring nsASingleFragmentCString;
+
+
+#endif /* !defined(nsStringFwd_h___) */
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsStringIterator.h b/src/libs/xpcom18a4/xpcom/string/public/nsStringIterator.h
new file mode 100644
index 00000000..1848594c
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsStringIterator.h
@@ -0,0 +1,373 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications.
+ * Portions created by the Initial Developer are Copyright (C) 2001
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Scott Collins <scc@mozilla.org> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsStringIterator_h___
+#define nsStringIterator_h___
+
+#ifndef nsCharTraits_h___
+#include "nsCharTraits.h"
+#endif
+
+#ifndef nsAlgorithm_h___
+#include "nsAlgorithm.h"
+#endif
+
+#ifndef nsDebug_h___
+#include "nsDebug.h"
+#endif
+
+ /**
+ * @see nsTAString
+ */
+
+template <class CharT>
+class nsReadingIterator
+ {
+ public:
+ typedef nsReadingIterator<CharT> self_type;
+ typedef ptrdiff_t difference_type;
+ typedef CharT value_type;
+ typedef const CharT* pointer;
+ typedef const CharT& reference;
+
+ private:
+ friend class nsAString;
+ friend class nsACString;
+ friend class nsSubstring;
+ friend class nsCSubstring;
+
+ // unfortunately, the API for nsReadingIterator requires that the
+ // iterator know its start and end positions. this was needed when
+ // we supported multi-fragment strings, but now it is really just
+ // extra baggage. we should remove mStart and mEnd at some point.
+
+ const CharT* mStart;
+ const CharT* mEnd;
+ const CharT* mPosition;
+
+ public:
+ nsReadingIterator() { }
+ // nsReadingIterator( const nsReadingIterator<CharT>& ); // auto-generated copy-constructor OK
+ // nsReadingIterator<CharT>& operator=( const nsReadingIterator<CharT>& ); // auto-generated copy-assignment operator OK
+
+ inline void normalize_forward() {}
+ inline void normalize_backward() {}
+
+ pointer
+ start() const
+ {
+ return mStart;
+ }
+
+ pointer
+ end() const
+ {
+ return mEnd;
+ }
+
+ pointer
+ get() const
+ {
+ return mPosition;
+ }
+
+ CharT
+ operator*() const
+ {
+ return *get();
+ }
+
+#if 0
+ // An iterator really deserves this, but some compilers (notably IBM VisualAge for OS/2)
+ // don't like this when |CharT| is a type without members.
+ pointer
+ operator->() const
+ {
+ return get();
+ }
+#endif
+
+ self_type&
+ operator++()
+ {
+ ++mPosition;
+ return *this;
+ }
+
+ self_type
+ operator++( int )
+ {
+ self_type result(*this);
+ ++mPosition;
+ return result;
+ }
+
+ self_type&
+ operator--()
+ {
+ --mPosition;
+ return *this;
+ }
+
+ self_type
+ operator--( int )
+ {
+ self_type result(*this);
+ --mPosition;
+ return result;
+ }
+
+ difference_type
+ size_forward() const
+ {
+ return mEnd - mPosition;
+ }
+
+ difference_type
+ size_backward() const
+ {
+ return mPosition - mStart;
+ }
+
+ self_type&
+ advance( difference_type n )
+ {
+ if (n > 0)
+ {
+ difference_type step = NS_MIN(n, size_forward());
+
+ NS_ASSERTION(step>0, "can't advance a reading iterator beyond the end of a string");
+
+ mPosition += step;
+ }
+ else if (n < 0)
+ {
+ difference_type step = NS_MAX(n, -size_backward());
+
+ NS_ASSERTION(step<0, "can't advance (backward) a reading iterator beyond the end of a string");
+
+ mPosition += step;
+ }
+ return *this;
+ }
+ };
+
+ /**
+ * @see nsTAString
+ */
+
+template <class CharT>
+class nsWritingIterator
+ {
+ public:
+ typedef nsWritingIterator<CharT> self_type;
+ typedef ptrdiff_t difference_type;
+ typedef CharT value_type;
+ typedef CharT* pointer;
+ typedef CharT& reference;
+
+ private:
+ friend class nsAString;
+ friend class nsACString;
+ friend class nsSubstring;
+ friend class nsCSubstring;
+
+ // unfortunately, the API for nsWritingIterator requires that the
+ // iterator know its start and end positions. this was needed when
+ // we supported multi-fragment strings, but now it is really just
+ // extra baggage. we should remove mStart and mEnd at some point.
+
+ CharT* mStart;
+ CharT* mEnd;
+ CharT* mPosition;
+
+ public:
+ nsWritingIterator() { }
+ // nsWritingIterator( const nsWritingIterator<CharT>& ); // auto-generated copy-constructor OK
+ // nsWritingIterator<CharT>& operator=( const nsWritingIterator<CharT>& ); // auto-generated copy-assignment operator OK
+
+ inline void normalize_forward() {}
+ inline void normalize_backward() {}
+
+ pointer
+ start() const
+ {
+ return mStart;
+ }
+
+ pointer
+ end() const
+ {
+ return mEnd;
+ }
+
+ pointer
+ get() const
+ {
+ return mPosition;
+ }
+
+ reference
+ operator*() const
+ {
+ return *get();
+ }
+
+#if 0
+ // An iterator really deserves this, but some compilers (notably IBM VisualAge for OS/2)
+ // don't like this when |CharT| is a type without members.
+ pointer
+ operator->() const
+ {
+ return get();
+ }
+#endif
+
+ self_type&
+ operator++()
+ {
+ ++mPosition;
+ return *this;
+ }
+
+ self_type
+ operator++( int )
+ {
+ self_type result(*this);
+ ++mPosition;
+ return result;
+ }
+
+ self_type&
+ operator--()
+ {
+ --mPosition;
+ return *this;
+ }
+
+ self_type
+ operator--( int )
+ {
+ self_type result(*this);
+ --mPosition;
+ return result;
+ }
+
+ difference_type
+ size_forward() const
+ {
+ return mEnd - mPosition;
+ }
+
+ difference_type
+ size_backward() const
+ {
+ return mPosition - mStart;
+ }
+
+ self_type&
+ advance( difference_type n )
+ {
+ if (n > 0)
+ {
+ difference_type step = NS_MIN(n, size_forward());
+
+ NS_ASSERTION(step>0, "can't advance a writing iterator beyond the end of a string");
+
+ mPosition += step;
+ }
+ else if (n < 0)
+ {
+ difference_type step = NS_MAX(n, -size_backward());
+
+ NS_ASSERTION(step<0, "can't advance (backward) a writing iterator beyond the end of a string");
+
+ mPosition += step;
+ }
+ return *this;
+ }
+
+ PRUint32
+ write( const value_type* s, PRUint32 n )
+ {
+ NS_ASSERTION(size_forward() > 0, "You can't |write| into an |nsWritingIterator| with no space!");
+
+ nsCharTraits<value_type>::move(mPosition, s, n);
+ advance( difference_type(n) );
+ return n;
+ }
+ };
+
+template <class CharT>
+inline
+PRBool
+operator==( const nsReadingIterator<CharT>& lhs, const nsReadingIterator<CharT>& rhs )
+ {
+ return lhs.get() == rhs.get();
+ }
+
+template <class CharT>
+inline
+PRBool
+operator!=( const nsReadingIterator<CharT>& lhs, const nsReadingIterator<CharT>& rhs )
+ {
+ return lhs.get() != rhs.get();
+ }
+
+
+ //
+ // |nsWritingIterator|s
+ //
+
+template <class CharT>
+inline
+PRBool
+operator==( const nsWritingIterator<CharT>& lhs, const nsWritingIterator<CharT>& rhs )
+ {
+ return lhs.get() == rhs.get();
+ }
+
+template <class CharT>
+inline
+PRBool
+operator!=( const nsWritingIterator<CharT>& lhs, const nsWritingIterator<CharT>& rhs )
+ {
+ return lhs.get() != rhs.get();
+ }
+
+#endif /* !defined(nsStringIterator_h___) */
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsSubstring.h b/src/libs/xpcom18a4/xpcom/string/public/nsSubstring.h
new file mode 100644
index 00000000..35a1a568
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsSubstring.h
@@ -0,0 +1,74 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsSubstring_h___
+#define nsSubstring_h___
+
+#ifndef nsAString_h___
+#include "nsAString.h"
+#endif
+
+#define kNotFound -1
+
+// If some platform(s) can't handle our template that matches literal strings,
+// then we'll disable it on those platforms.
+#ifndef NS_DISABLE_LITERAL_TEMPLATE
+# if (defined(_MSC_VER) && (_MSC_VER < 1310)) || (defined(__SUNPRO_CC) & (__SUNPRO_CC < 0x560)) || (defined(__HP_aCC) && (__HP_aCC <= 012100))
+# define NS_DISABLE_LITERAL_TEMPLATE
+# endif
+#endif /* !NS_DISABLE_LITERAL_TEMPLATE */
+
+#include <string.h>
+
+ // declare nsSubstring
+#include "string-template-def-unichar.h"
+#include "nsTSubstring.h"
+#include "string-template-undef.h"
+
+
+ // declare nsCSubstring
+#include "string-template-def-char.h"
+#include "nsTSubstring.h"
+#include "string-template-undef.h"
+
+
+#ifndef nsSubstringTuple_h___
+#include "nsSubstringTuple.h"
+#endif
+
+#endif // !defined(nsSubstring_h___)
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsSubstringTuple.h b/src/libs/xpcom18a4/xpcom/string/public/nsSubstringTuple.h
new file mode 100644
index 00000000..8cf6f803
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsSubstringTuple.h
@@ -0,0 +1,56 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsSubstringTuple_h___
+#define nsSubstringTuple_h___
+
+#ifndef nsSubstring_h___
+#include "nsSubstring.h"
+#endif
+
+ // declare nsSubstringTuple
+#include "string-template-def-unichar.h"
+#include "nsTSubstringTuple.h"
+#include "string-template-undef.h"
+
+ // declare nsCSubstringTuple
+#include "string-template-def-char.h"
+#include "nsTSubstringTuple.h"
+#include "string-template-undef.h"
+
+#endif // !defined(nsSubstringTuple_h___)
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsTAString.h b/src/libs/xpcom18a4/xpcom/string/public/nsTAString.h
new file mode 100644
index 00000000..93b88443
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsTAString.h
@@ -0,0 +1,618 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Scott Collins <scc@mozilla.org> (original author)
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+ /**
+ * The base for string comparators
+ */
+class NS_COM nsTStringComparator_CharT
+ {
+ public:
+ typedef CharT char_type;
+
+ nsTStringComparator_CharT() {}
+
+ virtual int operator()( const char_type*, const char_type*, PRUint32 length ) const = 0;
+ virtual int operator()( char_type, char_type ) const = 0;
+ };
+
+
+ /**
+ * The default string comparator (case-sensitive comparision)
+ */
+class NS_COM nsTDefaultStringComparator_CharT
+ : public nsTStringComparator_CharT
+ {
+ public:
+ typedef CharT char_type;
+
+ nsTDefaultStringComparator_CharT() {}
+
+ virtual int operator()( const char_type*, const char_type*, PRUint32 length ) const;
+ virtual int operator()( char_type, char_type ) const;
+ };
+
+
+ /**
+ * nsTAString is the most abstract class in the string hierarchy.
+ *
+ * In its original inception, nsTAString was designed to allow the data
+ * storage for a string to be separated into multiple fragments. This was
+ * intended to enable lazy string flattening or avoid string flattening
+ * altogether in some cases. This abstraction, however, meant that every
+ * single string operation (including simple operations such as IsEmpty() and
+ * BeginReading()) required virtual function calls. A virtual destructor was
+ * also required. This not only meant additional overhead for invoking
+ * string methods but also added to additional codesize at every callsite (to
+ * load the virtual function address).
+ *
+ * Today nsTAString exists mainly for backwards compatibility of the string
+ * API. It is restricted to representing a contiguous array of characters,
+ * where the character array is not necessarily null-terminated. Moreover,
+ * since nsTAString's virtual function table was frozen for Mozilla 1.0,
+ * nsTAString necessarily maintains ABI compatibility with older versions of
+ * Gecko. (nsTObsoleteAString provides that frozen ABI. See
+ * nsObsoleteAString.h for a description of how we solve the ABI
+ * compatibility requirement while eliminating virtual function calls on
+ * nsTAString.)
+ *
+ * XPIDL still generates C++ header files with references to nsTAStrings, so
+ * nsTAString will still be heavily used in real code.
+ *
+ * If the opportunity to break ABI compatibility with Mozilla 1.0 were to
+ * ever arise, our first move should be to make nsTAString equate to
+ * nsTSubstring. This may in fact be an option today for some Gecko-based
+ * products.
+ */
+class nsTAString_CharT
+ {
+ public:
+
+ typedef CharT char_type;
+ typedef nsCharTraits<char_type> char_traits;
+
+ typedef char_traits::incompatible_char_type incompatible_char_type;
+
+ typedef nsTAString_CharT self_type;
+ typedef nsTAString_CharT abstract_string_type;
+ typedef nsTObsoleteAString_CharT obsolete_string_type;
+ typedef nsTSubstring_CharT substring_type;
+ typedef nsTSubstringTuple_CharT substring_tuple_type;
+
+ typedef nsReadingIterator<char_type> const_iterator;
+ typedef nsWritingIterator<char_type> iterator;
+
+ typedef nsTStringComparator_CharT comparator_type;
+
+ typedef PRUint32 size_type;
+ typedef PRUint32 index_type;
+
+ public:
+
+ // this acts like a virtual destructor
+ NS_COM NS_FASTCALL ~nsTAString_CharT();
+
+
+ /**
+ * BeginReading/EndReading can be used to get immutable access to the
+ * string's underlying buffer. EndReading returns a pointer to the
+ * end of the string's buffer. nsReadableUtils.h provides a collection
+ * of utility functions that work with these iterators.
+ */
+
+ inline const_iterator& BeginReading( const_iterator& iter ) const
+ {
+ size_type len = GetReadableBuffer(&iter.mStart);
+ iter.mEnd = iter.mStart + len;
+ iter.mPosition = iter.mStart;
+ return iter;
+ }
+
+ inline const_iterator& EndReading( const_iterator& iter ) const
+ {
+ size_type len = GetReadableBuffer(&iter.mStart);
+ iter.mEnd = iter.mStart + len;
+ iter.mPosition = iter.mEnd;
+ return iter;
+ }
+
+
+ /**
+ * BeginWriting/EndWriting can be used to get mutable access to the
+ * string's underlying buffer. EndWriting returns a pointer to the
+ * end of the string's buffer. This iterator API cannot be used to
+ * grow a buffer. Use SetLength to resize the string's buffer.
+ */
+
+ inline iterator& BeginWriting( iterator& iter )
+ {
+ size_type len = GetWritableBuffer(&iter.mStart);
+ iter.mEnd = iter.mStart + len;
+ iter.mPosition = iter.mStart;
+ return iter;
+ }
+
+ inline iterator& EndWriting( iterator& iter )
+ {
+ size_type len = GetWritableBuffer(&iter.mStart);
+ iter.mEnd = iter.mStart + len;
+ iter.mPosition = iter.mEnd;
+ return iter;
+ }
+
+
+ /**
+ * Length checking functions. IsEmpty is a helper function to avoid
+ * writing code like: |if (str.Length() == 0)|
+ */
+
+ NS_COM size_type NS_FASTCALL Length() const;
+ PRBool IsEmpty() const { return Length() == 0; }
+
+
+ /**
+ * String equality tests. Pass a string comparator if you want to
+ * control how the strings are compared. By default, a binary
+ * "case-sensitive" comparision is performed.
+ */
+
+ NS_COM PRBool NS_FASTCALL Equals( const self_type& ) const;
+ NS_COM PRBool NS_FASTCALL Equals( const self_type&, const comparator_type& ) const;
+ NS_COM PRBool NS_FASTCALL Equals( const char_type* ) const;
+ NS_COM PRBool NS_FASTCALL Equals( const char_type*, const comparator_type& ) const;
+
+ /**
+ * An efficient comparison with ASCII that can be used even
+ * for wide strings. Call this version when you know the
+ * length of 'data'.
+ */
+ NS_COM PRBool NS_FASTCALL EqualsASCII( const char* data, size_type len ) const;
+ /**
+ * An efficient comparison with ASCII that can be used even
+ * for wide strings. Call this version when 'data' is
+ * null-terminated.
+ */
+ NS_COM PRBool NS_FASTCALL EqualsASCII( const char* data ) const;
+
+ // EqualsLiteral must ONLY be applied to an actual literal string.
+ // Do not attempt to use it with a regular char* pointer, or with a char
+ // array variable.
+ // The template trick to acquire the array length at compile time without
+ // using a macro is due to Corey Kosak, with much thanks.
+#ifdef NS_DISABLE_LITERAL_TEMPLATE
+ inline PRBool EqualsLiteral( const char* str ) const
+ {
+ return EqualsASCII(str);
+ }
+#else
+ template<int N>
+ inline PRBool EqualsLiteral( const char (&str)[N] ) const
+ {
+ return EqualsASCII(str, N-1);
+ }
+ template<int N>
+ inline PRBool EqualsLiteral( char (&str)[N] ) const
+ {
+ const char* s = str;
+ return EqualsASCII(s, N-1);
+ }
+#endif
+
+ // The LowerCaseEquals methods compare the lower case version of
+ // this string to some ASCII/Literal string. The ASCII string is
+ // *not* lowercased for you. If you compare to an ASCII or literal
+ // string that contains an uppercase character, it is guaranteed to
+ // return false. We will throw assertions too.
+ NS_COM PRBool NS_FASTCALL LowerCaseEqualsASCII( const char* data, size_type len ) const;
+ NS_COM PRBool NS_FASTCALL LowerCaseEqualsASCII( const char* data ) const;
+
+ // LowerCaseEqualsLiteral must ONLY be applied to an actual
+ // literal string. Do not attempt to use it with a regular char*
+ // pointer, or with a char array variable. Use
+ // LowerCaseEqualsASCII for them.
+#ifdef NS_DISABLE_LITERAL_TEMPLATE
+ inline PRBool LowerCaseEqualsLiteral( const char* str ) const
+ {
+ return LowerCaseEqualsASCII(str);
+ }
+#else
+ template<int N>
+ inline PRBool LowerCaseEqualsLiteral( const char (&str)[N] ) const
+ {
+ return LowerCaseEqualsASCII(str, N-1);
+ }
+ template<int N>
+ inline PRBool LowerCaseEqualsLiteral( char (&str)[N] ) const
+ {
+ const char* s = str;
+ return LowerCaseEqualsASCII(s, N-1);
+ }
+#endif
+
+ /**
+ * A string always references a non-null data pointer. In some
+ * applications (e.g., the DOM) it is necessary for a string class
+ * to have some way to distinguish an empty string from a null (or
+ * void) string. These methods enable support for the concept of
+ * a void string.
+ */
+
+ NS_COM PRBool NS_FASTCALL IsVoid() const;
+ NS_COM void NS_FASTCALL SetIsVoid( PRBool );
+
+
+ /**
+ * This method returns true if the string's underlying buffer is
+ * null-terminated. This should rarely be needed by applications.
+ * The PromiseFlatTString method should be used to ensure that a
+ * string's underlying buffer is null-terminated.
+ */
+
+ NS_COM PRBool NS_FASTCALL IsTerminated() const;
+
+
+ /**
+ * These are contant time since nsTAString uses flat storage
+ */
+ NS_COM char_type NS_FASTCALL First() const;
+ NS_COM char_type NS_FASTCALL Last() const;
+
+
+ /**
+ * Returns the number of occurances of the given character.
+ */
+ NS_COM size_type NS_FASTCALL CountChar( char_type ) const;
+
+
+ /**
+ * Locates the offset of the first occurance of the character. Pass a
+ * non-zero offset to control where the search begins.
+ */
+
+ NS_COM PRInt32 NS_FASTCALL FindChar( char_type, index_type offset = 0 ) const;
+
+
+ /**
+ * SetCapacity is not required to do anything; however, it can be used
+ * as a hint to the implementation to reduce allocations.
+ *
+ * SetCapacity(0) is a suggestion to discard all associated storage.
+ */
+ NS_COM void NS_FASTCALL SetCapacity( size_type );
+
+
+ /**
+ * XXX talk to dbaron about this comment. we do need a method that
+ * XXX allows someone to resize a string's buffer so that it can be
+ * XXX populated using writing iterators. SetLength seems to be the
+ * XXX right method for the job, and we do use it in this capacity
+ * XXX in certain places.
+ *
+ * SetLength is used in two ways:
+ * 1) to |Cut| a suffix of the string;
+ * 2) to prepare to |Append| or move characters around.
+ *
+ * External callers are not allowed to use |SetLength| in this
+ * latter capacity, and should prefer |Truncate| for the former.
+ * In other words, |SetLength| is deprecated for all use outside
+ * of the string library and the internal use may at some point
+ * be replaced as well.
+ *
+ * This distinction makes me think the two different uses should
+ * be split into two distinct functions.
+ */
+ NS_COM void NS_FASTCALL SetLength( size_type );
+
+
+ /**
+ * Can't use |Truncate| to make a string longer!
+ */
+ void Truncate( size_type aNewLength=0 )
+ {
+ NS_ASSERTION(aNewLength <= Length(), "Truncate cannot make string longer");
+ SetLength(aNewLength);
+ }
+
+
+ /**
+ * |Assign| and |operator=| make |this| equivalent to the string or
+ * buffer given as an argument. If possible, they do this by sharing
+ * a reference counted buffer (see |nsTSubstring|). If not, they copy
+ * the buffer into their own buffer.
+ */
+
+ NS_COM void NS_FASTCALL Assign( const self_type& readable );
+ NS_COM void NS_FASTCALL Assign( const substring_tuple_type& tuple );
+ NS_COM void NS_FASTCALL Assign( const char_type* data );
+ NS_COM void NS_FASTCALL Assign( const char_type* data, size_type length );
+ NS_COM void NS_FASTCALL Assign( char_type c );
+
+ NS_COM void NS_FASTCALL AssignASCII( const char* data, size_type length );
+ NS_COM void NS_FASTCALL AssignASCII( const char* data );
+
+ // AssignLiteral must ONLY be applied to an actual literal string.
+ // Do not attempt to use it with a regular char* pointer, or with a char
+ // array variable. Use AssignASCII for those.
+#ifdef NS_DISABLE_LITERAL_TEMPLATE
+ void AssignLiteral( const char* str )
+ { AssignASCII(str); }
+#else
+ template<int N>
+ void AssignLiteral( const char (&str)[N] )
+ { AssignASCII(str, N-1); }
+ template<int N>
+ void AssignLiteral( char (&str)[N] )
+ { AssignASCII(str, N-1); }
+#endif
+
+ // copy-assignment operator. I must define my own if I don't want the compiler to make me one
+ self_type& operator=( const self_type& readable ) { Assign(readable); return *this; }
+ self_type& operator=( const substring_tuple_type& tuple ) { Assign(tuple); return *this; }
+ self_type& operator=( const char_type* data ) { Assign(data); return *this; }
+ self_type& operator=( char_type c ) { Assign(c); return *this; }
+
+
+
+ /**
+ * |Append|, |operator+=| are used to add characters to the end of this string.
+ */
+
+ NS_COM void NS_FASTCALL Append( const self_type& readable );
+ NS_COM void NS_FASTCALL Append( const substring_tuple_type& tuple );
+ NS_COM void NS_FASTCALL Append( const char_type* data );
+ NS_COM void NS_FASTCALL Append( const char_type* data, size_type length );
+ NS_COM void NS_FASTCALL Append( char_type c );
+
+ NS_COM void NS_FASTCALL AppendASCII( const char* data, size_type length );
+ NS_COM void NS_FASTCALL AppendASCII( const char* data );
+
+ // AppendLiteral must ONLY be applied to an actual literal string.
+ // Do not attempt to use it with a regular char* pointer, or with a char
+ // array variable. Use AppendASCII for those.
+#ifdef NS_DISABLE_LITERAL_TEMPLATE
+ void AppendLiteral( const char* str )
+ { AppendASCII(str); }
+#else
+ template<int N>
+ void AppendLiteral( const char (&str)[N] )
+ { AppendASCII(str, N-1); }
+ template<int N>
+ void AppendLiteral( char (&str)[N] )
+ { AppendASCII(str, N-1); }
+#endif
+
+ self_type& operator+=( const self_type& readable ) { Append(readable); return *this; }
+ self_type& operator+=( const substring_tuple_type& tuple ) { Append(tuple); return *this; }
+ self_type& operator+=( const char_type* data ) { Append(data); return *this; }
+ self_type& operator+=( char_type c ) { Append(c); return *this; }
+
+
+ /**
+ * |Insert| is used to add characters into this string at a given position.
+ * NOTE: It's a shame the |pos| parameter isn't at the front of the arg list.
+ */
+
+ NS_COM void NS_FASTCALL Insert( const self_type& readable, index_type pos );
+ NS_COM void NS_FASTCALL Insert( const substring_tuple_type& tuple, index_type pos );
+ NS_COM void NS_FASTCALL Insert( const char_type* data, index_type pos );
+ NS_COM void NS_FASTCALL Insert( const char_type* data, index_type pos, size_type length );
+ NS_COM void NS_FASTCALL Insert( char_type c, index_type pos );
+
+
+ /**
+ * |Cut| is used to remove a range of characters from this string.
+ */
+
+ NS_COM void NS_FASTCALL Cut( index_type cutStart, size_type cutLength );
+
+
+ /**
+ * |Replace| is used overwrite a range of characters from this string.
+ */
+
+ NS_COM void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, const self_type& readable );
+ NS_COM void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, const substring_tuple_type& readable );
+
+
+ /**
+ * this is public to support automatic conversion of tuple to abstract
+ * string, which is necessary to support our API.
+ */
+ nsTAString_CharT(const substring_tuple_type& tuple)
+ : mVTable(obsolete_string_type::sCanonicalVTable)
+ , mData(nsnull)
+ , mLength(0)
+ , mFlags(0)
+ {
+ Assign(tuple);
+ }
+
+ protected:
+
+ friend class nsTSubstringTuple_CharT;
+
+ // GCC 3.2 erroneously needs these (even though they are subclasses!)
+ friend class nsTSubstring_CharT;
+ friend class nsTDependentSubstring_CharT;
+ friend class nsTPromiseFlatString_CharT;
+
+ /**
+ * the address of our virtual function table. required for backwards
+ * compatibility with Mozilla 1.0 frozen nsAC?String interface.
+ */
+ const void* mVTable;
+
+ /**
+ * these fields are "here" only when mVTable == sCanonicalVTable.
+ *
+ * they exist to support automatic construction of a nsTAString
+ * from a nsTSubstringTuple.
+ */
+ char_type* mData;
+ size_type mLength;
+ PRUint32 mFlags;
+
+ /**
+ * nsTAString must be subclassed before it can be instantiated.
+ */
+ nsTAString_CharT(char_type* data, size_type length, PRUint32 flags)
+ : mVTable(obsolete_string_type::sCanonicalVTable)
+ , mData(data)
+ , mLength(length)
+ , mFlags(flags)
+ {}
+
+ /**
+ * optional ctor for use by subclasses.
+ *
+ * NOTE: mData and mLength are intentionally left uninitialized.
+ */
+ explicit
+ nsTAString_CharT(PRUint32 flags)
+ : mVTable(obsolete_string_type::sCanonicalVTable)
+ , mFlags(flags)
+ {}
+
+ /**
+ * get pointer to internal string buffer (may not be null terminated).
+ * return length of buffer.
+ */
+ NS_COM size_type NS_FASTCALL GetReadableBuffer( const char_type **data ) const;
+ NS_COM size_type NS_FASTCALL GetWritableBuffer( char_type **data );
+
+ /**
+ * returns true if this tuple is dependent on (i.e., overlapping with)
+ * the given char sequence.
+ */
+ PRBool NS_FASTCALL IsDependentOn(const char_type *start, const char_type *end) const;
+
+ /**
+ * we can be converted to a const nsTSubstring (dependent on this)
+ */
+ const substring_type NS_FASTCALL ToSubstring() const;
+
+ /**
+ * type cast helpers
+ */
+
+ const obsolete_string_type* AsObsoleteString() const
+ {
+ return NS_REINTERPRET_CAST(const obsolete_string_type*, this);
+ }
+
+ obsolete_string_type* AsObsoleteString()
+ {
+ return NS_REINTERPRET_CAST(obsolete_string_type*, this);
+ }
+
+ const substring_type* AsSubstring() const
+ {
+ return NS_REINTERPRET_CAST(const substring_type*, this);
+ }
+
+ substring_type* AsSubstring()
+ {
+ return NS_REINTERPRET_CAST(substring_type*, this);
+ }
+
+ private:
+
+ // GCC 2.95.3, EGCS-2.91.66, Sun Workshop/Forte, and IBM VisualAge C++
+ // require a public copy-constructor in order to support automatic
+ // construction of a nsTAString from a nsTSubstringTuple. I believe
+ // enabling the default copy-constructor is harmless, but I do not want
+ // it to be enabled by default because that might tempt people into
+ // using it (where it would be invalid).
+#if !defined(__SUNPRO_CC) && \
+ !(defined(_AIX) && defined(__IBMCPP__)) && \
+ (!defined(__GNUC__) || __GNUC__ > 2 || __GNUC_MINOR__ > 95)
+
+ // NOT TO BE IMPLEMENTED
+ nsTAString_CharT( const self_type& );
+
+#endif
+
+ // NOT TO BE IMPLEMENTED
+ void operator= ( incompatible_char_type );
+ void Assign ( incompatible_char_type );
+ void operator+= ( incompatible_char_type );
+ void Append ( incompatible_char_type );
+ void Insert ( incompatible_char_type, index_type );
+ };
+
+
+NS_COM
+int NS_FASTCALL Compare( const nsTAString_CharT& lhs, const nsTAString_CharT& rhs, const nsTStringComparator_CharT& = nsTDefaultStringComparator_CharT() );
+
+
+inline
+PRBool operator!=( const nsTAString_CharT& lhs, const nsTAString_CharT& rhs )
+ {
+ return !lhs.Equals(rhs);
+ }
+
+inline
+PRBool operator< ( const nsTAString_CharT& lhs, const nsTAString_CharT& rhs )
+ {
+ return Compare(lhs, rhs)< 0;
+ }
+
+inline
+PRBool operator<=( const nsTAString_CharT& lhs, const nsTAString_CharT& rhs )
+ {
+ return Compare(lhs, rhs)<=0;
+ }
+
+inline
+PRBool operator==( const nsTAString_CharT& lhs, const nsTAString_CharT& rhs )
+ {
+ return lhs.Equals(rhs);
+ }
+
+inline
+PRBool operator>=( const nsTAString_CharT& lhs, const nsTAString_CharT& rhs )
+ {
+ return Compare(lhs, rhs)>=0;
+ }
+
+inline
+PRBool operator> ( const nsTAString_CharT& lhs, const nsTAString_CharT& rhs )
+ {
+ return Compare(lhs, rhs)> 0;
+ }
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsTDependentString.h b/src/libs/xpcom18a4/xpcom/string/public/nsTDependentString.h
new file mode 100644
index 00000000..91a2b53e
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsTDependentString.h
@@ -0,0 +1,137 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Scott Collins <scc@mozilla.org> (original author)
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+ /**
+ * nsTDependentString_CharT
+ *
+ * Stores a null-terminated, immutable sequence of characters.
+ *
+ * Subclass of nsTString that restricts string value to an immutable
+ * character sequence. This class does not own its data, so the creator
+ * of objects of this type must take care to ensure that a
+ * nsTDependentString continues to reference valid memory for the
+ * duration of its use.
+ */
+class nsTDependentString_CharT : public nsTString_CharT
+ {
+ public:
+
+ typedef nsTDependentString_CharT self_type;
+
+ public:
+
+ /**
+ * verify restrictions
+ */
+ void AssertValid()
+ {
+ NS_ASSERTION(mData, "nsTDependentString must wrap a non-NULL buffer");
+ NS_ASSERTION(mLength != size_type(-1), "nsTDependentString has bogus length");
+ NS_ASSERTION(mData[mLength] == 0, "nsTDependentString must wrap only null-terminated strings");
+ }
+
+
+ /**
+ * constructors
+ */
+
+ nsTDependentString_CharT( const char_type* start, const char_type* end )
+ : string_type(NS_CONST_CAST(char_type*, start), end - start, F_TERMINATED)
+ {
+ AssertValid();
+ }
+
+ nsTDependentString_CharT( const char_type* data, PRUint32 length )
+ : string_type(NS_CONST_CAST(char_type*, data), length, F_TERMINATED)
+ {
+ AssertValid();
+ }
+
+ explicit
+ nsTDependentString_CharT( const char_type* data )
+ : string_type(NS_CONST_CAST(char_type*, data), char_traits::length(data), F_TERMINATED)
+ {
+ AssertValid();
+ }
+
+ explicit
+ nsTDependentString_CharT( const substring_type& str )
+ : string_type(NS_CONST_CAST(char_type*, str.Data()), str.Length(), F_TERMINATED)
+ {
+ AssertValid();
+ }
+
+ // XXX are you sure??
+ // auto-generated copy-constructor OK
+ // auto-generated copy-assignment operator OK
+ // auto-generated destructor OK
+
+
+ /**
+ * allow this class to be bound to a different string...
+ */
+
+ void Rebind( const char_type* data )
+ {
+ mData = NS_CONST_CAST(char_type*, data);
+ mLength = char_traits::length(data);
+ SetDataFlags(F_TERMINATED);
+ AssertValid();
+ }
+
+ void Rebind( const char_type* data, size_type length )
+ {
+ mData = NS_CONST_CAST(char_type*, data);
+ mLength = length;
+ SetDataFlags(F_TERMINATED);
+ AssertValid();
+ }
+
+ void Rebind( const char_type* start, const char_type* end )
+ {
+ Rebind(start, end - start);
+ }
+
+ private:
+
+ // NOT USED
+ nsTDependentString_CharT( const substring_tuple_type& );
+ nsTDependentString_CharT( const abstract_string_type& );
+ };
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsTDependentSubstring.h b/src/libs/xpcom18a4/xpcom/string/public/nsTDependentSubstring.h
new file mode 100644
index 00000000..89d96e13
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsTDependentSubstring.h
@@ -0,0 +1,142 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Scott Collins <scc@mozilla.org> (original author)
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+ /**
+ * nsTDependentSubstring_CharT
+ */
+class nsTDependentSubstring_CharT : public nsTSubstring_CharT
+ {
+ public:
+
+ typedef nsTDependentSubstring_CharT self_type;
+
+ public:
+
+ NS_COM void Rebind( const abstract_string_type&, PRUint32 startPos, PRUint32 length = size_type(-1) );
+ NS_COM void Rebind( const substring_type&, PRUint32 startPos, PRUint32 length = size_type(-1) );
+
+ void Rebind( const char_type* start, const char_type* end )
+ {
+ NS_ASSERTION(start && end, "nsTDependentSubstring must wrap a non-NULL buffer");
+ mData = NS_CONST_CAST(char_type*, start);
+ mLength = end - start;
+ SetDataFlags(F_NONE);
+ }
+
+ nsTDependentSubstring_CharT( const abstract_string_type& str, PRUint32 startPos, PRUint32 length = size_type(-1) )
+ : substring_type(F_NONE)
+ {
+ Rebind(str, startPos, length);
+ }
+
+ nsTDependentSubstring_CharT( const substring_type& str, PRUint32 startPos, PRUint32 length = size_type(-1) )
+ : substring_type(F_NONE)
+ {
+ Rebind(str, startPos, length);
+ }
+
+ nsTDependentSubstring_CharT( const char_type* start, const char_type* end )
+ : substring_type(NS_CONST_CAST(char_type*, start), end - start, F_NONE) {}
+
+ nsTDependentSubstring_CharT( const const_iterator& start, const const_iterator& end )
+ : substring_type(NS_CONST_CAST(char_type*, start.get()), end.get() - start.get(), F_NONE) {}
+
+ // auto-generated copy-constructor OK (XXX really?? what about base class copy-ctor?)
+
+ private:
+ // NOT USED
+ void operator=( const self_type& ); // we're immutable, you can't assign into a substring
+ };
+
+inline
+const nsTDependentSubstring_CharT
+Substring( const nsTAString_CharT& str, PRUint32 startPos, PRUint32 length = PRUint32(-1) )
+ {
+ return nsTDependentSubstring_CharT(str, startPos, length);
+ }
+
+inline
+const nsTDependentSubstring_CharT
+Substring( const nsTSubstring_CharT& str, PRUint32 startPos, PRUint32 length = PRUint32(-1) )
+ {
+ return nsTDependentSubstring_CharT(str, startPos, length);
+ }
+
+inline
+const nsTDependentSubstring_CharT
+Substring( const nsReadingIterator<CharT>& start, const nsReadingIterator<CharT>& end )
+ {
+ return nsTDependentSubstring_CharT(start.get(), end.get());
+ }
+
+inline
+const nsTDependentSubstring_CharT
+Substring( const CharT* start, const CharT* end )
+ {
+ return nsTDependentSubstring_CharT(start, end);
+ }
+
+inline
+const nsTDependentSubstring_CharT
+StringHead( const nsTAString_CharT& str, PRUint32 count )
+ {
+ return nsTDependentSubstring_CharT(str, 0, count);
+ }
+
+inline
+const nsTDependentSubstring_CharT
+StringHead( const nsTSubstring_CharT& str, PRUint32 count )
+ {
+ return nsTDependentSubstring_CharT(str, 0, count);
+ }
+
+inline
+const nsTDependentSubstring_CharT
+StringTail( const nsTAString_CharT& str, PRUint32 count )
+ {
+ return nsTDependentSubstring_CharT(str, str.Length() - count, count);
+ }
+
+inline
+const nsTDependentSubstring_CharT
+StringTail( const nsTSubstring_CharT& str, PRUint32 count )
+ {
+ return nsTDependentSubstring_CharT(str, str.Length() - count, count);
+ }
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsTObsoleteAString.h b/src/libs/xpcom18a4/xpcom/string/public/nsTObsoleteAString.h
new file mode 100644
index 00000000..82d5f56c
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsTObsoleteAString.h
@@ -0,0 +1,165 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+ /**
+ * nsTObsoleteAString_CharT : binary compatible with old nsAC?String vtable
+ *
+ * @status FROZEN
+ */
+class nsTObsoleteAString_CharT
+ {
+ public:
+ /**
+ * This is holds the address of the vtable for the canonical string
+ * implementation (i.e., nsTString).
+ */
+ NS_COM static const void *sCanonicalVTable;
+
+ /**
+ * An |nsFragmentRequest| is used to tell |GetReadableFragment| and
+ * |GetWritableFragment| what to do.
+ *
+ * @see GetReadableFragment
+ */
+ enum nsFragmentRequest { kPrevFragment, kFirstFragment, kLastFragment, kNextFragment, kFragmentAt };
+
+ /**
+ * A |nsReadableFragment| provides |const| access to a contiguous hunk of
+ * string of homogenous units, e.g., bytes (|char|). This doesn't mean it
+ * represents a flat hunk. It could be a variable length encoding, for
+ * instance UTF-8. And the fragment itself need not be zero-terminated.
+ *
+ * An |nsReadableFragment| is the underlying machinery that lets
+ * |nsReadingIterator|s work.
+ *
+ * @see nsReadingIterator
+ * @status FROZEN
+ */
+ struct nsReadableFragment
+ {
+ const CharT* mStart;
+ const CharT* mEnd;
+ const void* mFragmentIdentifier;
+
+ nsReadableFragment() : mStart(0), mEnd(0), mFragmentIdentifier(0) {}
+ };
+
+
+ /**
+ * A |nsWritableFragment| provides non-|const| access to a contiguous hunk of
+ * string of homogenous units, e.g., bytes (|char|). This doesn't mean it
+ * represents a flat hunk. It could be a variable length encoding, for
+ * instance UTF-8. And the fragment itself need not be zero-terminated.
+ *
+ * An |nsWritableFragment| is the underlying machinery that lets
+ * |nsWritingIterator|s work.
+ *
+ * @see nsWritingIterator
+ * @status FROZEN
+ */
+ struct nsWritableFragment
+ {
+ CharT* mStart;
+ CharT* mEnd;
+ void* mFragmentIdentifier;
+
+ nsWritableFragment() : mStart(0), mEnd(0), mFragmentIdentifier(0) {}
+ };
+
+ protected:
+
+ typedef CharT char_type;
+
+ typedef void buffer_handle_type;
+ typedef void shared_buffer_handle_type;
+ typedef nsReadableFragment const_fragment_type;
+ typedef nsWritableFragment fragment_type;
+
+ typedef nsTAString_CharT abstract_string_type;
+
+ typedef PRUint32 size_type;
+ typedef PRUint32 index_type;
+
+ protected:
+
+ friend class nsTAString_CharT;
+ friend class nsTSubstring_CharT;
+
+ /** here's the old nsAC?String vtable **/
+
+ virtual ~nsTObsoleteAString_CharT() { }
+
+ virtual PRUint32 GetImplementationFlags() const = 0;
+ virtual const buffer_handle_type* GetFlatBufferHandle() const = 0;
+ virtual const buffer_handle_type* GetBufferHandle() const = 0;
+ virtual const shared_buffer_handle_type* GetSharedBufferHandle() const = 0;
+
+ virtual size_type Length() const = 0;
+
+ virtual PRBool IsVoid() const = 0;
+ virtual void SetIsVoid( PRBool ) = 0;
+
+ virtual void SetCapacity( size_type ) = 0;
+ virtual void SetLength( size_type ) = 0;
+
+ virtual void Cut( index_type cutStart, size_type cutLength ) = 0;
+
+ virtual void do_AssignFromReadable( const abstract_string_type& ) = 0;
+ virtual void do_AssignFromElementPtr( const char_type* ) = 0;
+ virtual void do_AssignFromElementPtrLength( const char_type*, size_type ) = 0;
+ virtual void do_AssignFromElement( char_type ) = 0;
+
+ virtual void do_AppendFromReadable( const abstract_string_type& ) = 0;
+ virtual void do_AppendFromElementPtr( const char_type* ) = 0;
+ virtual void do_AppendFromElementPtrLength( const char_type*, size_type ) = 0;
+ virtual void do_AppendFromElement( char_type ) = 0;
+
+ virtual void do_InsertFromReadable( const abstract_string_type&, index_type ) = 0;
+ virtual void do_InsertFromElementPtr( const char_type*, index_type ) = 0;
+ virtual void do_InsertFromElementPtrLength( const char_type*, index_type, size_type ) = 0;
+ virtual void do_InsertFromElement( char_type, index_type ) = 0;
+
+ virtual void do_ReplaceFromReadable( index_type, size_type, const abstract_string_type& ) = 0;
+
+ virtual const char_type* GetReadableFragment( const_fragment_type&, nsFragmentRequest, PRUint32 = 0 ) const = 0;
+ virtual char_type* GetWritableFragment( fragment_type&, nsFragmentRequest, PRUint32 = 0 ) = 0;
+ };
+
+ // forward declare implementation
+class nsTObsoleteAStringThunk_CharT;
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsTPromiseFlatString.h b/src/libs/xpcom18a4/xpcom/string/public/nsTPromiseFlatString.h
new file mode 100644
index 00000000..6cf82f60
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsTPromiseFlatString.h
@@ -0,0 +1,158 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Scott Collins <scc@mozilla.org> (original author)
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+ /**
+ * NOTE:
+ *
+ * Try to avoid flat strings. |PromiseFlat[C]String| will help you as a last
+ * resort, and this may be necessary when dealing with legacy or OS calls,
+ * but in general, requiring a null-terminated array of characters kills many
+ * of the performance wins the string classes offer. Write your own code to
+ * use |nsA[C]String&|s for parameters. Write your string proccessing
+ * algorithms to exploit iterators. If you do this, you will benefit from
+ * being able to chain operations without copying or allocating and your code
+ * will be significantly more efficient. Remember, a function that takes an
+ * |const nsA[C]String&| can always be passed a raw character pointer by
+ * wrapping it (for free) in a |nsDependent[C]String|. But a function that
+ * takes a character pointer always has the potential to force allocation and
+ * copying.
+ *
+ *
+ * How to use it:
+ *
+ * A |nsPromiseFlat[C]String| doesn't necessarily own the characters it
+ * promises. You must never use it to promise characters out of a string
+ * with a shorter lifespan. The typical use will be something like this:
+ *
+ * SomeOSFunction( PromiseFlatCString(aCString).get() ); // GOOD
+ *
+ * Here's a BAD use:
+ *
+ * const char* buffer = PromiseFlatCString(aCString).get();
+ * SomeOSFunction(buffer); // BAD!! |buffer| is a dangling pointer
+ *
+ * The only way to make one is with the function |PromiseFlat[C]String|,
+ * which produce a |const| instance. ``What if I need to keep a promise
+ * around for a little while?'' you might ask. In that case, you can keep a
+ * reference, like so
+ *
+ * const nsPromiseFlatString& flat = PromiseFlatString(aString);
+ * // this reference holds the anonymous temporary alive, but remember,
+ * // it must _still_ have a lifetime shorter than that of |aString|
+ *
+ * SomeOSFunction(flat.get());
+ * SomeOtherOSFunction(flat.get());
+ *
+ *
+ * How does it work?
+ *
+ * A |nsPromiseFlat[C]String| is just a wrapper for another string. If you
+ * apply it to a string that happens to be flat, your promise is just a
+ * dependent reference to the string's data. If you apply it to a non-flat
+ * string, then a temporary flat string is created for you, by allocating and
+ * copying. In the event that you end up assigning the result into a sharing
+ * string (e.g., |nsTString|), the right thing happens.
+ */
+
+class nsTPromiseFlatString_CharT : public nsTString_CharT
+ {
+ public:
+
+ typedef nsTPromiseFlatString_CharT self_type;
+
+ private:
+
+ NS_COM void Init( const substring_type& );
+ NS_COM void Init( const abstract_string_type& );
+
+ // NOT TO BE IMPLEMENTED
+ void operator=( const self_type& );
+
+ // NOT TO BE IMPLEMENTED
+ nsTPromiseFlatString_CharT();
+
+ public:
+
+ explicit
+ nsTPromiseFlatString_CharT( const substring_type& str )
+ : string_type()
+ {
+ Init(str);
+ }
+
+ explicit
+ nsTPromiseFlatString_CharT( const abstract_string_type& readable )
+ : string_type()
+ {
+ Init(readable);
+ }
+
+ explicit
+ nsTPromiseFlatString_CharT( const substring_tuple_type& tuple )
+ : string_type()
+ {
+ // nothing else to do here except assign the value of the tuple
+ // into ourselves.
+ Assign(tuple);
+ }
+ };
+
+inline
+const nsTPromiseFlatString_CharT
+TPromiseFlatString_CharT( const nsTAString_CharT& str )
+ {
+ return nsTPromiseFlatString_CharT(str);
+ }
+
+ // e.g., PromiseFlatCString(Substring(s))
+inline
+const nsTPromiseFlatString_CharT
+TPromiseFlatString_CharT( const nsTSubstring_CharT& frag )
+ {
+ return nsTPromiseFlatString_CharT(frag);
+ }
+
+ // e.g., PromiseFlatCString(a + b)
+inline
+const nsTPromiseFlatString_CharT
+TPromiseFlatString_CharT( const nsTSubstringTuple_CharT& tuple )
+ {
+ return nsTPromiseFlatString_CharT(tuple);
+ }
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsTString.h b/src/libs/xpcom18a4/xpcom/string/public/nsTString.h
new file mode 100644
index 00000000..2ef241b2
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsTString.h
@@ -0,0 +1,721 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Rick Gessner <rickg@netscape.com> (original author)
+ * Scott Collins <scc@mozilla.org>
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+ /**
+ * This is the canonical null-terminated string class. All subclasses
+ * promise null-terminated storage. Instances of this class allocate
+ * strings on the heap.
+ *
+ * This class is also known as nsAFlat[C]String, where "flat" is used
+ * to denote a null-terminated string.
+ */
+class nsTString_CharT : public nsTSubstring_CharT
+ {
+ public:
+
+ typedef nsTString_CharT self_type;
+
+ public:
+
+ /**
+ * constructors
+ */
+
+ nsTString_CharT()
+ : substring_type() {}
+
+ explicit
+ nsTString_CharT( char_type c )
+ : substring_type()
+ {
+ Assign(c);
+ }
+
+ explicit
+ nsTString_CharT( const char_type* data, size_type length = size_type(-1) )
+ : substring_type()
+ {
+ Assign(data, length);
+ }
+
+ nsTString_CharT( const self_type& str )
+ : substring_type()
+ {
+ Assign(str);
+ }
+
+ nsTString_CharT( const substring_tuple_type& tuple )
+ : substring_type()
+ {
+ Assign(tuple);
+ }
+
+ explicit
+ nsTString_CharT( const abstract_string_type& readable )
+ : substring_type()
+ {
+ Assign(readable);
+ }
+
+
+ // |operator=| does not inherit, so we must define our own
+ self_type& operator=( char_type c ) { Assign(c); return *this; }
+ self_type& operator=( const char_type* data ) { Assign(data); return *this; }
+ self_type& operator=( const self_type& str ) { Assign(str); return *this; }
+ self_type& operator=( const substring_type& str ) { Assign(str); return *this; }
+ self_type& operator=( const substring_tuple_type& tuple ) { Assign(tuple); return *this; }
+ self_type& operator=( const abstract_string_type& readable ) { Assign(readable); return *this; }
+
+
+ /**
+ * returns the null-terminated string
+ */
+
+ const char_type* get() const
+ {
+ return mData;
+ }
+
+
+ /**
+ * returns character at specified index.
+ *
+ * NOTE: unlike nsTSubstring::CharAt, this function allows you to index
+ * the null terminator character.
+ */
+
+ char_type CharAt( index_type i ) const
+ {
+ NS_ASSERTION(i <= mLength, "index exceeds allowable range");
+ return mData[i];
+ }
+
+ char_type operator[]( index_type i ) const
+ {
+ return CharAt(i);
+ }
+
+
+#if MOZ_STRING_WITH_OBSOLETE_API
+
+
+ /**
+ * Search for the given substring within this string.
+ *
+ * @param aString is substring to be sought in this
+ * @param aIgnoreCase selects case sensitivity
+ * @param aOffset tells us where in this string to start searching
+ * @param aCount tells us how far from the offset we are to search. Use
+ * -1 to search the whole string.
+ * @return offset in string, or kNotFound
+ */
+
+ NS_COM PRInt32 Find( const nsCString& aString, PRBool aIgnoreCase=PR_FALSE, PRInt32 aOffset=0, PRInt32 aCount=-1 ) const;
+ NS_COM PRInt32 Find( const char* aString, PRBool aIgnoreCase=PR_FALSE, PRInt32 aOffset=0, PRInt32 aCount=-1 ) const;
+
+#ifdef CharT_is_PRUnichar
+ NS_COM PRInt32 Find( const nsAFlatString& aString, PRInt32 aOffset=0, PRInt32 aCount=-1 ) const;
+ NS_COM PRInt32 Find( const PRUnichar* aString, PRInt32 aOffset=0, PRInt32 aCount=-1 ) const;
+#endif
+
+
+ /**
+ * This methods scans the string backwards, looking for the given string
+ *
+ * @param aString is substring to be sought in this
+ * @param aIgnoreCase tells us whether or not to do caseless compare
+ * @param aOffset tells us where in this string to start searching.
+ * Use -1 to search from the end of the string.
+ * @param aCount tells us how many iterations to make starting at the
+ * given offset.
+ * @return offset in string, or kNotFound
+ */
+
+ NS_COM PRInt32 RFind( const nsCString& aString, PRBool aIgnoreCase=PR_FALSE, PRInt32 aOffset=-1, PRInt32 aCount=-1 ) const;
+ NS_COM PRInt32 RFind( const char* aCString, PRBool aIgnoreCase=PR_FALSE, PRInt32 aOffset=-1, PRInt32 aCount=-1 ) const;
+
+#ifdef CharT_is_PRUnichar
+ NS_COM PRInt32 RFind( const nsAFlatString& aString, PRInt32 aOffset=-1, PRInt32 aCount=-1 ) const;
+ NS_COM PRInt32 RFind( const PRUnichar* aString, PRInt32 aOffset=-1, PRInt32 aCount=-1 ) const;
+#endif
+
+
+ /**
+ * Search for given char within this string
+ *
+ * @param aChar is the character to search for
+ * @param aOffset tells us where in this strig to start searching
+ * @param aCount tells us how far from the offset we are to search.
+ * Use -1 to search the whole string.
+ * @return offset in string, or kNotFound
+ */
+
+ // PRInt32 FindChar( PRUnichar aChar, PRInt32 aOffset=0, PRInt32 aCount=-1 ) const;
+ NS_COM PRInt32 RFindChar( PRUnichar aChar, PRInt32 aOffset=-1, PRInt32 aCount=-1 ) const;
+
+
+ /**
+ * This method searches this string for the first character found in
+ * the given string.
+ *
+ * @param aString contains set of chars to be found
+ * @param aOffset tells us where in this string to start searching
+ * (counting from left)
+ * @return offset in string, or kNotFound
+ */
+
+ NS_COM PRInt32 FindCharInSet( const char* aString, PRInt32 aOffset=0 ) const;
+ PRInt32 FindCharInSet( const self_type& aString, PRInt32 aOffset=0 ) const
+ {
+ return FindCharInSet(aString.get(), aOffset);
+ }
+
+#ifdef CharT_is_PRUnichar
+ NS_COM PRInt32 FindCharInSet( const PRUnichar* aString, PRInt32 aOffset=0 ) const;
+#endif
+
+
+ /**
+ * This method searches this string for the last character found in
+ * the given string.
+ *
+ * @param aString contains set of chars to be found
+ * @param aOffset tells us where in this string to start searching
+ * (counting from left)
+ * @return offset in string, or kNotFound
+ */
+
+ NS_COM PRInt32 RFindCharInSet( const char_type* aString, PRInt32 aOffset=-1 ) const;
+ PRInt32 RFindCharInSet( const self_type& aString, PRInt32 aOffset=-1 ) const
+ {
+ return RFindCharInSet(aString.get(), aOffset);
+ }
+
+
+ /**
+ * Compares a given string to this string.
+ *
+ * @param aString is the string to be compared
+ * @param aIgnoreCase tells us how to treat case
+ * @param aCount tells us how many chars to compare
+ * @return -1,0,1
+ */
+
+#ifdef CharT_is_char
+ NS_COM PRInt32 Compare( const char* aString, PRBool aIgnoreCase=PR_FALSE, PRInt32 aCount=-1 ) const;
+#endif
+
+
+ /**
+ * Equality check between given string and this string.
+ *
+ * @param aString is the string to check
+ * @param aIgnoreCase tells us how to treat case
+ * @param aCount tells us how many chars to compare
+ * @return boolean
+ */
+#ifdef CharT_is_char
+ PRBool EqualsIgnoreCase( const char* aString, PRInt32 aCount=-1 ) const {
+ return Compare(aString, PR_TRUE, aCount) == 0;
+ }
+#else
+ NS_COM PRBool EqualsIgnoreCase( const char* aString, PRInt32 aCount=-1 ) const;
+
+
+ /**
+ * Copies data from internal buffer onto given char* buffer
+ *
+ * NOTE: This only copies as many chars as will fit in given buffer (clips)
+ * @param aBuf is the buffer where data is stored
+ * @param aBuflength is the max # of chars to move to buffer
+ * @param aOffset is the offset to copy from
+ * @return ptr to given buffer
+ */
+
+ NS_COM char* ToCString( char* aBuf, PRUint32 aBufLength, PRUint32 aOffset=0 ) const;
+
+#endif // !CharT_is_PRUnichar
+
+ /**
+ * Perform string to float conversion.
+ *
+ * @param aErrorCode will contain error if one occurs
+ * @return float rep of string value
+ */
+ NS_COM float ToFloat( PRInt32* aErrorCode ) const;
+
+
+ /**
+ * Perform string to int conversion.
+ * @param aErrorCode will contain error if one occurs
+ * @param aRadix tells us which radix to assume; kAutoDetect tells us to determine the radix for you.
+ * @return int rep of string value, and possible (out) error code
+ */
+ NS_COM PRInt32 ToInteger( PRInt32* aErrorCode, PRUint32 aRadix=kRadix10 ) const;
+
+
+ /**
+ * |Left|, |Mid|, and |Right| are annoying signatures that seem better almost
+ * any _other_ way than they are now. Consider these alternatives
+ *
+ * aWritable = aReadable.Left(17); // ...a member function that returns a |Substring|
+ * aWritable = Left(aReadable, 17); // ...a global function that returns a |Substring|
+ * Left(aReadable, 17, aWritable); // ...a global function that does the assignment
+ *
+ * as opposed to the current signature
+ *
+ * aReadable.Left(aWritable, 17); // ...a member function that does the assignment
+ *
+ * or maybe just stamping them out in favor of |Substring|, they are just duplicate functionality
+ *
+ * aWritable = Substring(aReadable, 0, 17);
+ */
+
+ NS_COM size_type Mid( self_type& aResult, PRUint32 aStartPos, PRUint32 aCount ) const;
+
+ size_type Left( self_type& aResult, size_type aCount ) const
+ {
+ return Mid(aResult, 0, aCount);
+ }
+
+ size_type Right( self_type& aResult, size_type aCount ) const
+ {
+ aCount = NS_MIN(mLength, aCount);
+ return Mid(aResult, mLength - aCount, aCount);
+ }
+
+
+ /**
+ * Set a char inside this string at given index
+ *
+ * @param aChar is the char you want to write into this string
+ * @param anIndex is the ofs where you want to write the given char
+ * @return TRUE if successful
+ */
+
+ NS_COM PRBool SetCharAt( PRUnichar aChar, PRUint32 aIndex );
+
+
+ /**
+ * These methods are used to remove all occurances of the
+ * characters found in aSet from this string.
+ *
+ * @param aSet -- characters to be cut from this
+ */
+ NS_COM void StripChars( const char* aSet );
+
+
+ /**
+ * This method is used to remove all occurances of aChar from this
+ * string.
+ *
+ * @param aChar -- char to be stripped
+ * @param aOffset -- where in this string to start stripping chars
+ */
+
+ NS_COM void StripChar( char_type aChar, PRInt32 aOffset=0 );
+
+
+ /**
+ * This method strips whitespace throughout the string.
+ */
+ NS_COM void StripWhitespace();
+
+
+ /**
+ * swaps occurence of 1 string for another
+ */
+
+ NS_COM void ReplaceChar( char_type aOldChar, char_type aNewChar );
+ NS_COM void ReplaceChar( const char* aSet, char_type aNewChar );
+ NS_COM void ReplaceSubstring( const self_type& aTarget, const self_type& aNewValue);
+ NS_COM void ReplaceSubstring( const char_type* aTarget, const char_type* aNewValue);
+
+
+ /**
+ * This method trims characters found in aTrimSet from
+ * either end of the underlying string.
+ *
+ * @param aSet -- contains chars to be trimmed from both ends
+ * @param aEliminateLeading
+ * @param aEliminateTrailing
+ * @param aIgnoreQuotes -- if true, causes surrounding quotes to be ignored
+ * @return this
+ */
+ NS_COM void Trim( const char* aSet, PRBool aEliminateLeading=PR_TRUE, PRBool aEliminateTrailing=PR_TRUE, PRBool aIgnoreQuotes=PR_FALSE );
+
+ /**
+ * This method strips whitespace from string.
+ * You can control whether whitespace is yanked from start and end of
+ * string as well.
+ *
+ * @param aEliminateLeading controls stripping of leading ws
+ * @param aEliminateTrailing controls stripping of trailing ws
+ */
+ NS_COM void CompressWhitespace( PRBool aEliminateLeading=PR_TRUE, PRBool aEliminateTrailing=PR_TRUE );
+
+
+ /**
+ * assign/append/insert with _LOSSY_ conversion
+ */
+
+ NS_COM void AssignWithConversion( const nsTAString_IncompatibleCharT& aString );
+ NS_COM void AssignWithConversion( const incompatible_char_type* aData, PRInt32 aLength=-1 );
+
+ NS_COM void AppendWithConversion( const nsTAString_IncompatibleCharT& aString );
+ NS_COM void AppendWithConversion( const incompatible_char_type* aData, PRInt32 aLength=-1 );
+
+ /**
+ * Append the given integer to this string
+ */
+ NS_COM void AppendInt( PRInt32 aInteger, PRInt32 aRadix=kRadix10 ); //radix=8,10 or 16
+
+ /**
+ * Append the given unsigned integer to this string
+ */
+ inline void AppendInt( PRUint32 aInteger, PRInt32 aRadix = kRadix10 )
+ {
+ AppendInt(PRInt32(aInteger), aRadix);
+ }
+
+ /**
+ * Append the given 64-bit integer to this string.
+ * @param aInteger The integer to append
+ * @param aRadix The radix to use; can be 8, 10 or 16.
+ */
+ NS_COM void AppendInt( PRInt64 aInteger, PRInt32 aRadix=kRadix10 );
+
+ /**
+ * Append the given float to this string
+ */
+
+ NS_COM void AppendFloat( double aFloat );
+
+#endif // !MOZ_STRING_WITH_OBSOLETE_API
+
+
+ protected:
+
+ explicit
+ nsTString_CharT( PRUint32 flags )
+ : substring_type(flags) {}
+
+ // allow subclasses to initialize fields directly
+ nsTString_CharT( char_type* data, size_type length, PRUint32 flags )
+ : substring_type(data, length, flags) {}
+ };
+
+
+class nsTFixedString_CharT : public nsTString_CharT
+ {
+ public:
+
+ typedef nsTFixedString_CharT self_type;
+ typedef nsTFixedString_CharT fixed_string_type;
+
+ public:
+
+ /**
+ * @param data
+ * fixed-size buffer to be used by the string (the contents of
+ * this buffer may be modified by the string)
+ * @param storageSize
+ * the size of the fixed buffer
+ * @param length (optional)
+ * the length of the string already contained in the buffer
+ */
+
+ nsTFixedString_CharT( char_type* data, size_type storageSize )
+ : string_type(data, char_traits::length(data), F_TERMINATED | F_FIXED | F_CLASS_FIXED)
+ , mFixedCapacity(storageSize - 1)
+ , mFixedBuf(data)
+ {}
+
+ nsTFixedString_CharT( char_type* data, size_type storageSize, size_type length )
+ : string_type(data, length, F_TERMINATED | F_FIXED | F_CLASS_FIXED)
+ , mFixedCapacity(storageSize - 1)
+ , mFixedBuf(data)
+ {
+ // null-terminate
+ mFixedBuf[length] = char_type(0);
+ }
+
+ // |operator=| does not inherit, so we must define our own
+ self_type& operator=( char_type c ) { Assign(c); return *this; }
+ self_type& operator=( const char_type* data ) { Assign(data); return *this; }
+ self_type& operator=( const substring_type& str ) { Assign(str); return *this; }
+ self_type& operator=( const substring_tuple_type& tuple ) { Assign(tuple); return *this; }
+ self_type& operator=( const abstract_string_type& readable ) { Assign(readable); return *this; }
+
+ protected:
+
+ friend class nsTSubstring_CharT;
+
+ size_type mFixedCapacity;
+ char_type *mFixedBuf;
+ };
+
+
+ /**
+ * nsTAutoString_CharT
+ *
+ * Subclass of nsTString_CharT that adds support for stack-based string
+ * allocation. Do not allocate this class on the heap! ;-)
+ */
+class nsTAutoString_CharT : public nsTFixedString_CharT
+ {
+ public:
+
+ typedef nsTAutoString_CharT self_type;
+
+ public:
+
+ /**
+ * constructors
+ */
+
+ nsTAutoString_CharT()
+ : fixed_string_type(mStorage, kDefaultStorageSize, 0)
+ {}
+
+ explicit
+ nsTAutoString_CharT( char_type c )
+ : fixed_string_type(mStorage, kDefaultStorageSize, 0)
+ {
+ Assign(c);
+ }
+
+ explicit
+ nsTAutoString_CharT( const char_type* data, size_type length = size_type(-1) )
+ : fixed_string_type(mStorage, kDefaultStorageSize, 0)
+ {
+ Assign(data, length);
+ }
+
+ nsTAutoString_CharT( const self_type& str )
+ : fixed_string_type(mStorage, kDefaultStorageSize, 0)
+ {
+ Assign(str);
+ }
+
+ explicit
+ nsTAutoString_CharT( const substring_type& str )
+ : fixed_string_type(mStorage, kDefaultStorageSize, 0)
+ {
+ Assign(str);
+ }
+
+ nsTAutoString_CharT( const substring_tuple_type& tuple )
+ : fixed_string_type(mStorage, kDefaultStorageSize, 0)
+ {
+ Assign(tuple);
+ }
+
+ explicit
+ nsTAutoString_CharT( const abstract_string_type& readable )
+ : fixed_string_type(mStorage, kDefaultStorageSize, 0)
+ {
+ Assign(readable);
+ }
+
+ // |operator=| does not inherit, so we must define our own
+ self_type& operator=( char_type c ) { Assign(c); return *this; }
+ self_type& operator=( const char_type* data ) { Assign(data); return *this; }
+ self_type& operator=( const self_type& str ) { Assign(str); return *this; }
+ self_type& operator=( const substring_type& str ) { Assign(str); return *this; }
+ self_type& operator=( const substring_tuple_type& tuple ) { Assign(tuple); return *this; }
+ self_type& operator=( const abstract_string_type& readable ) { Assign(readable); return *this; }
+
+ enum { kDefaultStorageSize = 64 };
+
+ private:
+
+ char_type mStorage[kDefaultStorageSize];
+ };
+
+
+ /**
+ * nsTXPIDLString extends nsTString such that:
+ *
+ * (1) mData can be null
+ * (2) objects of this type can be automatically cast to |const CharT*|
+ * (3) getter_Copies method is supported to adopt data
+ */
+class nsTXPIDLString_CharT : public nsTString_CharT
+ {
+ public:
+
+ typedef nsTXPIDLString_CharT self_type;
+
+ public:
+
+ nsTXPIDLString_CharT()
+ : string_type(NS_CONST_CAST(char_type*, char_traits::sEmptyBuffer), 0, F_TERMINATED | F_VOIDED) {}
+
+ // copy-constructor required to avoid default
+ nsTXPIDLString_CharT( const self_type& str )
+ : string_type(NS_CONST_CAST(char_type*, char_traits::sEmptyBuffer), 0, F_TERMINATED | F_VOIDED)
+ {
+ Assign(str);
+ }
+
+ // return nsnull if we are voided
+ const char_type* get() const
+ {
+ return (mFlags & F_VOIDED) ? nsnull : mData;
+ }
+
+ // this case operator is the reason why this class cannot just be a
+ // typedef for nsTString
+ operator const char_type*() const
+ {
+ return get();
+ }
+
+ // need this to diambiguous operator[int]
+ char_type operator[]( PRInt32 i ) const
+ {
+ return CharAt(index_type(i));
+ }
+
+ // |operator=| does not inherit, so we must define our own
+ self_type& operator=( char_type c ) { Assign(c); return *this; }
+ self_type& operator=( const char_type* data ) { Assign(data); return *this; }
+ self_type& operator=( const self_type& str ) { Assign(str); return *this; }
+ self_type& operator=( const substring_type& str ) { Assign(str); return *this; }
+ self_type& operator=( const substring_tuple_type& tuple ) { Assign(tuple); return *this; }
+ self_type& operator=( const abstract_string_type& readable ) { Assign(readable); return *this; }
+ };
+
+
+ /**
+ * getter_Copies support for use with raw string out params:
+ *
+ * NS_IMETHOD GetBlah(char**);
+ *
+ * void some_function()
+ * {
+ * nsXPIDLCString blah;
+ * GetBlah(getter_Copies(blah));
+ * // ...
+ * }
+ */
+class nsTGetterCopies_CharT
+ {
+ public:
+ typedef CharT char_type;
+
+ nsTGetterCopies_CharT(nsTXPIDLString_CharT& str)
+ : mString(str), mData(nsnull) {}
+
+ ~nsTGetterCopies_CharT()
+ {
+ mString.Adopt(mData); // OK if mData is null
+ }
+
+ operator char_type**()
+ {
+ return &mData;
+ }
+
+ private:
+ nsTXPIDLString_CharT& mString;
+ char_type* mData;
+ };
+
+inline
+nsTGetterCopies_CharT
+getter_Copies( nsTXPIDLString_CharT& aString )
+ {
+ return nsTGetterCopies_CharT(aString);
+ }
+
+
+ /**
+ * nsTAdoptingString extends nsTXPIDLString such that:
+ *
+ * (1) Adopt given string on construction or assignment, i.e. take
+ * the value of what's given, and make what's given forget its
+ * value. Note that this class violates constness in a few
+ * places. Be careful!
+ */
+class nsTAdoptingString_CharT : public nsTXPIDLString_CharT
+ {
+ public:
+
+ typedef nsTAdoptingString_CharT self_type;
+
+ public:
+
+ explicit nsTAdoptingString_CharT() {}
+ explicit nsTAdoptingString_CharT(char_type* str, size_type length = size_type(-1))
+ {
+ Adopt(str, length);
+ }
+
+ // copy-constructor required to adopt on copy. Note that this
+ // will violate the constness of |str| in the operator=()
+ // call. |str| will be truncated as a side-effect of this
+ // constructor.
+ nsTAdoptingString_CharT( const self_type& str )
+#ifdef VBOX /* bird: shut up annoying warnings */
+ : nsTXPIDLString_CharT()
+#endif
+ {
+ *this = str;
+ }
+
+ // |operator=| does not inherit, so we must define our own
+ self_type& operator=( const substring_type& str ) { Assign(str); return *this; }
+ self_type& operator=( const substring_tuple_type& tuple ) { Assign(tuple); return *this; }
+ self_type& operator=( const abstract_string_type& readable ) { Assign(readable); return *this; }
+
+ // Adopt(), if possible, when assigning to a self_type&. Note
+ // that this violates the constness of str, str is always
+ // truncated when this operator is called.
+ NS_COM self_type& operator=( const self_type& str );
+
+ private:
+ // NOT TO BE IMPLEMENTED.
+ self_type& operator=( const char_type* data );
+ self_type& operator=( char_type* data );
+ };
+
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsTSubstring.h b/src/libs/xpcom18a4/xpcom/string/public/nsTSubstring.h
new file mode 100644
index 00000000..aaaf5a64
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsTSubstring.h
@@ -0,0 +1,575 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+ /**
+ * nsTSubstring
+ *
+ * The base string type. This type is not instantiated directly. A sub-
+ * class is instantiated instead. For example, see nsTString.
+ *
+ * This type works like nsTAString except that it does not have the ABI
+ * requirements of that interface. Like nsTAString, nsTSubstring
+ * represents a single contiguous array of characters that may or may not
+ * be null-terminated.
+ *
+ * Many of the accessors on nsTSubstring are inlined as an optimization.
+ *
+ * This class is also known as "nsASingleFragmentC?String".
+ */
+class nsTSubstring_CharT : public nsTAString_CharT
+ {
+ public:
+
+ typedef nsTSubstring_CharT self_type;
+ typedef nsTString_CharT string_type;
+
+ typedef char_type* char_iterator;
+ typedef const char_type* const_char_iterator;
+
+ public:
+
+ /**
+ * reading iterators
+ */
+
+ const_char_iterator BeginReading() const { return mData; }
+ const_char_iterator EndReading() const { return mData + mLength; }
+
+ /**
+ * deprecated reading iterators
+ */
+
+ const_iterator& BeginReading( const_iterator& iter ) const
+ {
+ iter.mStart = mData;
+ iter.mEnd = mData + mLength;
+ iter.mPosition = iter.mStart;
+ return iter;
+ }
+
+ const_iterator& EndReading( const_iterator& iter ) const
+ {
+ iter.mStart = mData;
+ iter.mEnd = mData + mLength;
+ iter.mPosition = iter.mEnd;
+ return iter;
+ }
+
+ const_char_iterator& BeginReading( const_char_iterator& iter ) const
+ {
+ return iter = mData;
+ }
+
+ const_char_iterator& EndReading( const_char_iterator& iter ) const
+ {
+ return iter = mData + mLength;
+ }
+
+
+ /**
+ * writing iterators
+ */
+
+ char_iterator BeginWriting() { EnsureMutable(); return mData; }
+ char_iterator EndWriting() { EnsureMutable(); return mData + mLength; }
+
+ /**
+ * deprecated writing iterators
+ */
+
+ iterator& BeginWriting( iterator& iter )
+ {
+ EnsureMutable();
+ iter.mStart = mData;
+ iter.mEnd = mData + mLength;
+ iter.mPosition = iter.mStart;
+ return iter;
+ }
+
+ iterator& EndWriting( iterator& iter )
+ {
+ EnsureMutable();
+ iter.mStart = mData;
+ iter.mEnd = mData + mLength;
+ iter.mPosition = iter.mEnd;
+ return iter;
+ }
+
+ char_iterator& BeginWriting( char_iterator& iter )
+ {
+ EnsureMutable();
+ return iter = mData;
+ }
+
+ char_iterator& EndWriting( char_iterator& iter )
+ {
+ EnsureMutable();
+ return iter = mData + mLength;
+ }
+
+
+ /**
+ * accessors
+ */
+
+ // returns pointer to string data (not necessarily null-terminated)
+ const char_type *Data() const
+ {
+ return mData;
+ }
+
+ size_type Length() const
+ {
+ return mLength;
+ }
+
+ PRBool IsEmpty() const
+ {
+ return mLength == 0;
+ }
+
+ PRBool IsVoid() const
+ {
+ return mFlags & F_VOIDED;
+ }
+
+ PRBool IsTerminated() const
+ {
+ return mFlags & F_TERMINATED;
+ }
+
+ char_type CharAt( index_type i ) const
+ {
+ NS_ASSERTION(i < mLength, "index exceeds allowable range");
+ return mData[i];
+ }
+
+ char_type operator[]( index_type i ) const
+ {
+ return CharAt(i);
+ }
+
+ char_type First() const
+ {
+ NS_ASSERTION(mLength > 0, "|First()| called on an empty string");
+ return mData[0];
+ }
+
+ inline
+ char_type Last() const
+ {
+ NS_ASSERTION(mLength > 0, "|Last()| called on an empty string");
+ return mData[mLength - 1];
+ }
+
+ NS_COM size_type NS_FASTCALL CountChar( char_type ) const;
+ NS_COM PRInt32 NS_FASTCALL FindChar( char_type, index_type offset = 0 ) const;
+
+
+ /**
+ * equality
+ */
+
+ NS_COM PRBool NS_FASTCALL Equals( const self_type& ) const;
+ NS_COM PRBool NS_FASTCALL Equals( const self_type&, const comparator_type& ) const;
+
+ NS_COM PRBool NS_FASTCALL Equals( const abstract_string_type& readable ) const;
+ NS_COM PRBool NS_FASTCALL Equals( const abstract_string_type& readable, const comparator_type& comp ) const;
+
+ NS_COM PRBool NS_FASTCALL Equals( const char_type* data ) const;
+ NS_COM PRBool NS_FASTCALL Equals( const char_type* data, const comparator_type& comp ) const;
+
+ /**
+ * An efficient comparison with ASCII that can be used even
+ * for wide strings. Call this version when you know the
+ * length of 'data'.
+ */
+ NS_COM PRBool NS_FASTCALL EqualsASCII( const char* data, size_type len ) const;
+ /**
+ * An efficient comparison with ASCII that can be used even
+ * for wide strings. Call this version when 'data' is
+ * null-terminated.
+ */
+ NS_COM PRBool NS_FASTCALL EqualsASCII( const char* data ) const;
+
+ // EqualsLiteral must ONLY be applied to an actual literal string.
+ // Do not attempt to use it with a regular char* pointer, or with a char
+ // array variable.
+ // The template trick to acquire the array length at compile time without
+ // using a macro is due to Corey Kosak, with much thanks.
+#ifdef NS_DISABLE_LITERAL_TEMPLATE
+ inline PRBool EqualsLiteral( const char* str ) const
+ {
+ return EqualsASCII(str);
+ }
+#else
+ template<int N>
+ inline PRBool EqualsLiteral( const char (&str)[N] ) const
+ {
+ return EqualsASCII(str, N-1);
+ }
+ template<int N>
+ inline PRBool EqualsLiteral( char (&str)[N] ) const
+ {
+ const char* s = str;
+ return EqualsASCII(s, N-1);
+ }
+#endif
+
+ // The LowerCaseEquals methods compare the lower case version of
+ // this string to some ASCII/Literal string. The ASCII string is
+ // *not* lowercased for you. If you compare to an ASCII or literal
+ // string that contains an uppercase character, it is guaranteed to
+ // return false. We will throw assertions too.
+ NS_COM PRBool NS_FASTCALL LowerCaseEqualsASCII( const char* data, size_type len ) const;
+ NS_COM PRBool NS_FASTCALL LowerCaseEqualsASCII( const char* data ) const;
+
+ // LowerCaseEqualsLiteral must ONLY be applied to an actual
+ // literal string. Do not attempt to use it with a regular char*
+ // pointer, or with a char array variable. Use
+ // LowerCaseEqualsASCII for them.
+#ifdef NS_DISABLE_LITERAL_TEMPLATE
+ inline PRBool LowerCaseEqualsLiteral( const char* str ) const
+ {
+ return LowerCaseEqualsASCII(str);
+ }
+#else
+ template<int N>
+ inline PRBool LowerCaseEqualsLiteral( const char (&str)[N] ) const
+ {
+ return LowerCaseEqualsASCII(str, N-1);
+ }
+ template<int N>
+ inline PRBool LowerCaseEqualsLiteral( char (&str)[N] ) const
+ {
+ const char* s = str;
+ return LowerCaseEqualsASCII(s, N-1);
+ }
+#endif
+
+ /**
+ * assignment
+ */
+
+ void Assign( char_type c ) { Assign(&c, 1); }
+ NS_COM void NS_FASTCALL Assign( const char_type* data, size_type length = size_type(-1) );
+ NS_COM void NS_FASTCALL Assign( const self_type& );
+ NS_COM void NS_FASTCALL Assign( const substring_tuple_type& );
+ NS_COM void NS_FASTCALL Assign( const abstract_string_type& );
+
+ NS_COM void NS_FASTCALL AssignASCII( const char* data, size_type length );
+ NS_COM void NS_FASTCALL AssignASCII( const char* data );
+
+ // AssignLiteral must ONLY be applied to an actual literal string.
+ // Do not attempt to use it with a regular char* pointer, or with a char
+ // array variable. Use AssignASCII for those.
+#ifdef NS_DISABLE_LITERAL_TEMPLATE
+ void AssignLiteral( const char* str )
+ { AssignASCII(str); }
+#else
+ template<int N>
+ void AssignLiteral( const char (&str)[N] )
+ { AssignASCII(str, N-1); }
+ template<int N>
+ void AssignLiteral( char (&str)[N] )
+ { AssignASCII(str, N-1); }
+#endif
+
+ self_type& operator=( char_type c ) { Assign(c); return *this; }
+ self_type& operator=( const char_type* data ) { Assign(data); return *this; }
+ self_type& operator=( const self_type& str ) { Assign(str); return *this; }
+ self_type& operator=( const substring_tuple_type& tuple ) { Assign(tuple); return *this; }
+ self_type& operator=( const abstract_string_type& readable ) { Assign(readable); return *this; }
+
+ NS_COM void NS_FASTCALL Adopt( char_type* data, size_type length = size_type(-1) );
+
+
+ /**
+ * buffer manipulation
+ */
+
+ void Replace( index_type cutStart, size_type cutLength, char_type c ) { Replace(cutStart, cutLength, &c, 1); }
+ NS_COM void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, const char_type* data, size_type length = size_type(-1) );
+ void Replace( index_type cutStart, size_type cutLength, const self_type& str ) { Replace(cutStart, cutLength, str.Data(), str.Length()); }
+ NS_COM void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, const substring_tuple_type& tuple );
+ NS_COM void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, const abstract_string_type& readable );
+
+ NS_COM void NS_FASTCALL ReplaceASCII( index_type cutStart, size_type cutLength, const char* data, size_type length = size_type(-1) );
+
+ void Append( char_type c ) { Replace(mLength, 0, c); }
+ void Append( const char_type* data, size_type length = size_type(-1) ) { Replace(mLength, 0, data, length); }
+ void Append( const self_type& str ) { Replace(mLength, 0, str); }
+ void Append( const substring_tuple_type& tuple ) { Replace(mLength, 0, tuple); }
+ void Append( const abstract_string_type& readable ) { Replace(mLength, 0, readable); }
+
+ void AppendASCII( const char* data, size_type length = size_type(-1) ) { ReplaceASCII(mLength, 0, data, length); }
+
+ // AppendLiteral must ONLY be applied to an actual literal string.
+ // Do not attempt to use it with a regular char* pointer, or with a char
+ // array variable. Use AppendASCII for those.
+#ifdef NS_DISABLE_LITERAL_TEMPLATE
+ void AppendLiteral( const char* str )
+ { AppendASCII(str); }
+#else
+ template<int N>
+ void AppendLiteral( const char (&str)[N] )
+ { AppendASCII(str, N-1); }
+ template<int N>
+ void AppendLiteral( char (&str)[N] )
+ { AppendASCII(str, N-1); }
+#endif
+
+ self_type& operator+=( char_type c ) { Append(c); return *this; }
+ self_type& operator+=( const char_type* data ) { Append(data); return *this; }
+ self_type& operator+=( const self_type& str ) { Append(str); return *this; }
+ self_type& operator+=( const substring_tuple_type& tuple ) { Append(tuple); return *this; }
+ self_type& operator+=( const abstract_string_type& readable ) { Append(readable); return *this; }
+
+ void Insert( char_type c, index_type pos ) { Replace(pos, 0, c); }
+ void Insert( const char_type* data, index_type pos, size_type length = size_type(-1) ) { Replace(pos, 0, data, length); }
+ void Insert( const self_type& str, index_type pos ) { Replace(pos, 0, str); }
+ void Insert( const substring_tuple_type& tuple, index_type pos ) { Replace(pos, 0, tuple); }
+ void Insert( const abstract_string_type& readable, index_type pos ) { Replace(pos, 0, readable); }
+
+ void Cut( index_type cutStart, size_type cutLength ) { Replace(cutStart, cutLength, char_traits::sEmptyBuffer, 0); }
+
+
+ /**
+ * buffer sizing
+ */
+
+ NS_COM void NS_FASTCALL SetCapacity( size_type capacity );
+
+ NS_COM void NS_FASTCALL SetLength( size_type );
+
+ void Truncate( size_type newLength = 0 )
+ {
+ NS_ASSERTION(newLength <= mLength, "Truncate cannot make string longer");
+ SetLength(newLength);
+ }
+
+
+ /**
+ * string data is never null, but can be marked void. if true, the
+ * string will be truncated. @see nsTSubstring::IsVoid
+ */
+
+ NS_COM void NS_FASTCALL SetIsVoid( PRBool );
+
+
+ public:
+
+ /**
+ * this is public to support automatic conversion of tuple to string
+ * base type, which helps avoid converting to nsTAString.
+ */
+ nsTSubstring_CharT(const substring_tuple_type& tuple)
+ : abstract_string_type(nsnull, 0, F_NONE)
+ {
+ Assign(tuple);
+ }
+
+ protected:
+
+ friend class nsTObsoleteAStringThunk_CharT;
+ friend class nsTAString_CharT;
+ friend class nsTSubstringTuple_CharT;
+
+ // XXX GCC 3.4 needs this :-(
+ friend class nsTPromiseFlatString_CharT;
+
+ // default initialization
+ nsTSubstring_CharT()
+ : abstract_string_type(
+ NS_CONST_CAST(char_type*, char_traits::sEmptyBuffer), 0, F_TERMINATED) {}
+
+ // allow subclasses to initialize fields directly
+ nsTSubstring_CharT( char_type *data, size_type length, PRUint32 flags )
+ : abstract_string_type(data, length, flags) {}
+
+ // version of constructor that leaves mData and mLength uninitialized
+ explicit
+ nsTSubstring_CharT( PRUint32 flags )
+ : abstract_string_type(flags) {}
+
+ // copy-constructor, constructs as dependent on given object
+ // (NOTE: this is for internal use only)
+ nsTSubstring_CharT( const self_type& str )
+ : abstract_string_type(
+ str.mData, str.mLength, str.mFlags & (F_TERMINATED | F_VOIDED)) {}
+
+ /**
+ * this function releases mData and does not change the value of
+ * any of its member variables. inotherwords, this function acts
+ * like a destructor.
+ */
+ void NS_FASTCALL Finalize();
+
+ /**
+ * this function prepares mData to be mutated.
+ *
+ * @param capacity specifies the required capacity of mData
+ * @param old_data returns null or the old value of mData
+ * @param old_flags returns 0 or the old value of mFlags
+ *
+ * if mData is already mutable and of sufficient capacity, then this
+ * function will return immediately. otherwise, it will either resize
+ * mData or allocate a new shared buffer. if it needs to allocate a
+ * new buffer, then it will return the old buffer and the corresponding
+ * flags. this allows the caller to decide when to free the old data.
+ *
+ * XXX we should expose a way for subclasses to free old_data.
+ */
+ PRBool NS_FASTCALL MutatePrep( size_type capacity, char_type** old_data, PRUint32* old_flags );
+
+ /**
+ * this function prepares a section of mData to be modified. if
+ * necessary, this function will reallocate mData and possibly move
+ * existing data to open up the specified section.
+ *
+ * @param cutStart specifies the starting offset of the section
+ * @param cutLength specifies the length of the section to be replaced
+ * @param newLength specifies the length of the new section
+ *
+ * for example, suppose mData contains the string "abcdef" then
+ *
+ * ReplacePrep(2, 3, 4);
+ *
+ * would cause mData to look like "ab____f" where the characters
+ * indicated by '_' have an unspecified value and can be freely
+ * modified. this function will null-terminate mData upon return.
+ */
+ void NS_FASTCALL ReplacePrep( index_type cutStart, size_type cutLength, size_type newLength );
+
+ /**
+ * returns the number of writable storage units starting at mData.
+ * the value does not include space for the null-terminator character.
+ *
+ * NOTE: this function returns size_type(-1) if mData is immutable.
+ */
+ size_type NS_FASTCALL Capacity() const;
+
+ /**
+ * this helper function can be called prior to directly manipulating
+ * the contents of mData. see, for example, BeginWriting.
+ */
+ NS_COM void NS_FASTCALL EnsureMutable();
+
+ /**
+ * returns true if this string overlaps with the given string fragment.
+ */
+ PRBool IsDependentOn( const char_type *start, const char_type *end ) const
+ {
+ /**
+ * if it _isn't_ the case that one fragment starts after the other ends,
+ * or ends before the other starts, then, they conflict:
+ *
+ * !(f2.begin >= f1.end || f2.end <= f1.begin)
+ *
+ * Simplified, that gives us:
+ */
+ return ( start < (mData + mLength) && end > mData );
+ }
+
+ /**
+ * this helper function stores the specified dataFlags in mFlags
+ */
+ void SetDataFlags(PRUint32 dataFlags)
+ {
+ NS_ASSERTION((dataFlags & 0xFFFF0000) == 0, "bad flags");
+ mFlags = dataFlags | (mFlags & 0xFFFF0000);
+ }
+
+ public:
+
+ // mFlags is a bitwise combination of the following flags. the meaning
+ // and interpretation of these flags is an implementation detail.
+ //
+ // NOTE: these flags are declared public _only_ for convenience inside
+ // the string implementation.
+
+ enum
+ {
+ F_NONE = 0, // no flags
+
+ // data flags are in the lower 16-bits
+ F_TERMINATED = 1 << 0, // IsTerminated returns true
+ F_VOIDED = 1 << 1, // IsVoid returns true
+ F_SHARED = 1 << 2, // mData points to a heap-allocated, shared buffer
+ F_OWNED = 1 << 3, // mData points to a heap-allocated, raw buffer
+ F_FIXED = 1 << 4, // mData points to a fixed-size writable, dependent buffer
+
+ // class flags are in the upper 16-bits
+ F_CLASS_FIXED = 1 << 16 // indicates that |this| is of type nsTFixedString
+ };
+
+ //
+ // Some terminology:
+ //
+ // "dependent buffer" A dependent buffer is one that the string class
+ // does not own. The string class relies on some
+ // external code to ensure the lifetime of the
+ // dependent buffer.
+ //
+ // "shared buffer" A shared buffer is one that the string class
+ // allocates. When it allocates a shared string
+ // buffer, it allocates some additional space at
+ // the beginning of the buffer for additional
+ // fields, including a reference count and a
+ // buffer length. See nsStringHeader.
+ //
+ // "adopted buffer" An adopted buffer is a raw string buffer
+ // allocated on the heap (using nsMemory::Alloc)
+ // of which the string class subsumes ownership.
+ //
+ // Some comments about the string flags:
+ //
+ // F_SHARED, F_OWNED, and F_FIXED are all mutually exlusive. They
+ // indicate the allocation type of mData. If none of these flags
+ // are set, then the string buffer is dependent.
+ //
+ // F_SHARED, F_OWNED, or F_FIXED imply F_TERMINATED. This is because
+ // the string classes always allocate null-terminated buffers, and
+ // non-terminated substrings are always dependent.
+ //
+ // F_VOIDED implies F_TERMINATED, and moreover it implies that mData
+ // points to char_traits::sEmptyBuffer. Therefore, F_VOIDED is
+ // mutually exclusive with F_SHARED, F_OWNED, and F_FIXED.
+ //
+ };
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsTSubstringTuple.h b/src/libs/xpcom18a4/xpcom/string/public/nsTSubstringTuple.h
new file mode 100644
index 00000000..2ded17d5
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsTSubstringTuple.h
@@ -0,0 +1,113 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+ /**
+ * nsTSubstringTuple_CharT
+ *
+ * Represents a tuple of string fragments. Built as a recursive binary tree.
+ * It is used to implement the concatenation of two or more string objects.
+ *
+ * NOTE: This class is a private implementation detail and should never be
+ * referenced outside the string code.
+ */
+class nsTSubstringTuple_CharT
+ {
+ public:
+
+ typedef CharT char_type;
+ typedef nsCharTraits<char_type> char_traits;
+
+ typedef nsTSubstringTuple_CharT self_type;
+ typedef nsTSubstring_CharT substring_type;
+ typedef nsTString_CharT string_type;
+ typedef nsTAString_CharT abstract_string_type;
+ typedef nsTObsoleteAString_CharT obsolete_string_type;
+
+ typedef PRUint32 size_type;
+
+ public:
+
+ nsTSubstringTuple_CharT(const abstract_string_type* a, const abstract_string_type* b)
+ : mHead(nsnull)
+ , mFragA(a)
+ , mFragB(b) {}
+
+ nsTSubstringTuple_CharT(const self_type& head, const abstract_string_type* b)
+ : mHead(&head)
+ , mFragA(nsnull) // this fragment is ignored when head != nsnull
+ , mFragB(b) {}
+
+ /**
+ * computes the aggregate string length
+ */
+ NS_COM size_type Length() const;
+
+ /**
+ * writes the aggregate string to the given buffer. bufLen is assumed
+ * to be equal to or greater than the value returned by the Length()
+ * method. the string written to |buf| is not null-terminated.
+ */
+ NS_COM void WriteTo(char_type *buf, PRUint32 bufLen) const;
+
+ /**
+ * returns true if this tuple is dependent on (i.e., overlapping with)
+ * the given char sequence.
+ */
+ NS_COM PRBool IsDependentOn(const char_type *start, const char_type *end) const;
+
+ private:
+
+ const self_type* mHead;
+ const abstract_string_type* mFragA;
+ const abstract_string_type* mFragB;
+ };
+
+inline
+const nsTSubstringTuple_CharT
+operator+(const nsTAString_CharT& a, const nsTAString_CharT& b)
+ {
+ return nsTSubstringTuple_CharT(&a, &b);
+ }
+
+inline
+const nsTSubstringTuple_CharT
+operator+(const nsTSubstringTuple_CharT& head, const nsTAString_CharT& b)
+ {
+ return nsTSubstringTuple_CharT(head, &b);
+ }
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsUTF8Utils.h b/src/libs/xpcom18a4/xpcom/string/public/nsUTF8Utils.h
new file mode 100644
index 00000000..c91079c2
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsUTF8Utils.h
@@ -0,0 +1,462 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2001
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Peter Annema <jaggernaut@netscape.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsUTF8Utils_h_
+#define nsUTF8Utils_h_
+
+class UTF8traits
+ {
+ public:
+ static PRBool isASCII(char c) { return (c & 0x80) == 0x00; }
+ static PRBool isInSeq(char c) { return (c & 0xC0) == 0x80; }
+ static PRBool is2byte(char c) { return (c & 0xE0) == 0xC0; }
+ static PRBool is3byte(char c) { return (c & 0xF0) == 0xE0; }
+ static PRBool is4byte(char c) { return (c & 0xF8) == 0xF0; }
+ static PRBool is5byte(char c) { return (c & 0xFC) == 0xF8; }
+ static PRBool is6byte(char c) { return (c & 0xFE) == 0xFC; }
+ };
+
+#define PLANE1_BASE 0x00010000
+#define UCS2_REPLACEMENT_CHAR 0xfffd
+
+#ifdef __GNUC__
+#define NS_ALWAYS_INLINE __attribute__((always_inline))
+#else
+#define NS_ALWAYS_INLINE
+#endif
+
+/**
+ * A character sink (see |copy_string| in nsAlgorithm.h) for converting
+ * UTF-8 to UTF-16
+ */
+class ConvertUTF8toUTF16
+ {
+ public:
+ typedef nsACString::char_type value_type;
+ typedef nsAString::char_type buffer_type;
+
+ ConvertUTF8toUTF16( buffer_type* aBuffer )
+ : mStart(aBuffer), mBuffer(aBuffer), mErrorEncountered(PR_FALSE) {}
+
+ size_t Length() const { return mBuffer - mStart; }
+
+ PRUint32 NS_ALWAYS_INLINE write( const value_type* start, PRUint32 N )
+ {
+ if ( mErrorEncountered )
+ return N;
+
+ // algorithm assumes utf8 units won't
+ // be spread across fragments
+ const value_type* p = start;
+ const value_type* end = start + N;
+ buffer_type* out = mBuffer;
+ for ( ; p != end /* && *p */; )
+ {
+ char c = *p++;
+
+ if ( UTF8traits::isASCII(c) )
+ {
+ *out++ = buffer_type(c);
+ continue;
+ }
+
+ PRUint32 ucs4;
+ PRUint32 minUcs4;
+ PRInt32 state = 0;
+
+ if ( UTF8traits::is2byte(c) )
+ {
+ ucs4 = (PRUint32(c) << 6) & 0x000007C0L;
+ state = 1;
+ minUcs4 = 0x00000080;
+ }
+ else if ( UTF8traits::is3byte(c) )
+ {
+ ucs4 = (PRUint32(c) << 12) & 0x0000F000L;
+ state = 2;
+ minUcs4 = 0x00000800;
+ }
+ else if ( UTF8traits::is4byte(c) )
+ {
+ ucs4 = (PRUint32(c) << 18) & 0x001F0000L;
+ state = 3;
+ minUcs4 = 0x00010000;
+ }
+ else if ( UTF8traits::is5byte(c) )
+ {
+ ucs4 = (PRUint32(c) << 24) & 0x03000000L;
+ state = 4;
+ minUcs4 = 0x00200000;
+ }
+ else if ( UTF8traits::is6byte(c) )
+ {
+ ucs4 = (PRUint32(c) << 30) & 0x40000000L;
+ state = 5;
+ minUcs4 = 0x04000000;
+ }
+ else
+ {
+ NS_ERROR("Not a UTF-8 string. This code should only be used for converting from known UTF-8 strings.");
+ mErrorEncountered = PR_TRUE;
+ mBuffer = out;
+ return N;
+ }
+
+ while ( state-- )
+ {
+ c = *p++;
+
+ if ( UTF8traits::isInSeq(c) )
+ {
+ PRInt32 shift = state * 6;
+ ucs4 |= (PRUint32(c) & 0x3F) << shift;
+ }
+ else
+ {
+ NS_ERROR("not a UTF8 string");
+ mErrorEncountered = PR_TRUE;
+ mBuffer = out;
+ return N;
+ }
+ }
+
+ if ( ucs4 < minUcs4 )
+ {
+ // Overlong sequence
+ *out++ = UCS2_REPLACEMENT_CHAR;
+ }
+ else if ( ucs4 <= 0xD7FF )
+ {
+ *out++ = ucs4;
+ }
+ else if ( /* ucs4 >= 0xD800 && */ ucs4 <= 0xDFFF )
+ {
+ // Surrogates
+ *out++ = UCS2_REPLACEMENT_CHAR;
+ }
+ else if ( ucs4 == 0xFFFE || ucs4 == 0xFFFF )
+ {
+ // Prohibited characters
+ *out++ = UCS2_REPLACEMENT_CHAR;
+ }
+ else if ( ucs4 >= PLANE1_BASE )
+ {
+ if ( ucs4 >= 0x00110000 )
+ *out++ = UCS2_REPLACEMENT_CHAR;
+ else {
+ // surrogate, see unicode specification 3.7 for following math.
+ ucs4 -= PLANE1_BASE;
+ *out++ = (PRUnichar)(ucs4 >> 10) | 0xd800u;
+ *out++ = (PRUnichar)(ucs4 & 0x3ff) | 0xdc00u;
+ }
+ }
+ else
+ {
+ *out++ = ucs4;
+ }
+ }
+ mBuffer = out;
+ return p - start;
+ }
+
+ void write_terminator()
+ {
+ *mBuffer = buffer_type(0);
+ }
+
+ private:
+ buffer_type* const mStart;
+ buffer_type* mBuffer;
+ PRBool mErrorEncountered;
+ };
+
+/**
+ * A character sink (see |copy_string| in nsAlgorithm.h) for computing
+ * the length of the UTF-16 string equivalent to a UTF-8 string.
+ */
+class CalculateUTF8Length
+ {
+ public:
+ typedef nsACString::char_type value_type;
+
+ CalculateUTF8Length() : mLength(0), mErrorEncountered(PR_FALSE) { }
+
+ size_t Length() const { return mLength; }
+
+ PRUint32 NS_ALWAYS_INLINE write( const value_type* start, PRUint32 N )
+ {
+ // ignore any further requests
+ if ( mErrorEncountered )
+ return N;
+
+ // algorithm assumes utf8 units won't
+ // be spread across fragments
+ const value_type* p = start;
+ const value_type* end = start + N;
+ for ( ; p < end /* && *p */; ++mLength )
+ {
+ if ( UTF8traits::isASCII(*p) )
+ p += 1;
+ else if ( UTF8traits::is2byte(*p) )
+ p += 2;
+ else if ( UTF8traits::is3byte(*p) )
+ p += 3;
+ else if ( UTF8traits::is4byte(*p) ) {
+ p += 4;
+ // Because a UTF-8 sequence of 4 bytes represents a codepoint
+ // greater than 0xFFFF, it will become a surrogate pair in the
+ // UTF-16 string, so add 1 more to mLength.
+ // This doesn't happen with is5byte and is6byte because they
+ // are illegal UTF-8 sequences (greater than 0x10FFFF) so get
+ // converted to a single replacement character.
+ //
+ // XXX: if the 4-byte sequence is an illegal non-shortest form,
+ // it also gets converted to a replacement character, so
+ // mLength will be off by one in this case.
+ ++mLength;
+ }
+ else if ( UTF8traits::is5byte(*p) )
+ p += 5;
+ else if ( UTF8traits::is6byte(*p) )
+ p += 6;
+ else
+ {
+ break;
+ }
+ }
+ if ( p != end )
+ {
+ NS_ERROR("Not a UTF-8 string. This code should only be used for converting from known UTF-8 strings.");
+ mErrorEncountered = PR_TRUE;
+ mLength = 0;
+ return N;
+ }
+ return p - start;
+ }
+
+ private:
+ size_t mLength;
+ PRBool mErrorEncountered;
+ };
+
+/**
+ * A character sink (see |copy_string| in nsAlgorithm.h) for converting
+ * UTF-16 to UTF-8.
+ */
+class ConvertUTF16toUTF8
+ {
+ public:
+ typedef nsAString::char_type value_type;
+ typedef nsACString::char_type buffer_type;
+
+ // The error handling here is more lenient than that in
+ // |ConvertUTF8toUTF16|, but it's that way for backwards
+ // compatibility.
+
+ ConvertUTF16toUTF8( buffer_type* aBuffer )
+ : mStart(aBuffer), mBuffer(aBuffer) {}
+
+ size_t Size() const { return mBuffer - mStart; }
+
+ PRUint32 NS_ALWAYS_INLINE write( const value_type* start, PRUint32 N )
+ {
+ buffer_type *out = mBuffer; // gcc isn't smart enough to do this!
+
+ for (const value_type *p = start, *end = start + N; p < end; ++p )
+ {
+ value_type c = *p;
+ if (! (c & 0xFF80)) // U+0000 - U+007F
+ {
+ *out++ = (char)c;
+ }
+ else if (! (c & 0xF800)) // U+0100 - U+07FF
+ {
+ *out++ = 0xC0 | (char)(c >> 6);
+ *out++ = 0x80 | (char)(0x003F & c);
+ }
+ else if (0xD800 != (0xF800 & c)) // U+0800 - U+D7FF,U+E000 - U+FFFF
+ {
+ *out++ = 0xE0 | (char)(c >> 12);
+ *out++ = 0x80 | (char)(0x003F & (c >> 6));
+ *out++ = 0x80 | (char)(0x003F & c );
+ }
+ else if (0xD800 == (0xFC00 & c)) // U+D800 - U+DBFF
+ {
+ // D800- DBFF - High Surrogate
+ // N = (H- D800) *400 + 10000 + ...
+ PRUint32 ucs4 = 0x10000 + ((0x03FF & c) << 10);
+
+ ++p;
+ if (p == end)
+ {
+ NS_ERROR("Surrogate pair split between fragments");
+ mBuffer = out;
+ return N;
+ }
+ c = *p;
+
+ if (0xDC00 == (0xFC00 & c))
+ {
+ // DC00- DFFF - Low Surrogate
+ // N += ( L - DC00 )
+ ucs4 |= (0x03FF & c);
+
+ // 0001 0000-001F FFFF
+ *out++ = 0xF0 | (char)(ucs4 >> 18);
+ *out++ = 0x80 | (char)(0x003F & (ucs4 >> 12));
+ *out++ = 0x80 | (char)(0x003F & (ucs4 >> 6));
+ *out++ = 0x80 | (char)(0x003F & ucs4);
+ }
+ else
+ {
+ NS_ERROR("got a High Surrogate but no low surrogate");
+ // output nothing.
+ }
+ }
+ else // U+DC00 - U+DFFF
+ {
+ // DC00- DFFF - Low Surrogate
+ NS_ERROR("got a low Surrogate but no high surrogate");
+ // output nothing.
+ }
+ }
+
+ mBuffer = out;
+ return N;
+ }
+
+ void write_terminator()
+ {
+ *mBuffer = buffer_type(0);
+ }
+
+ private:
+ buffer_type* const mStart;
+ buffer_type* mBuffer;
+ };
+
+/**
+ * A character sink (see |copy_string| in nsAlgorithm.h) for computing
+ * the number of bytes a UTF-16 would occupy in UTF-8.
+ */
+class CalculateUTF8Size
+ {
+ public:
+ typedef nsAString::char_type value_type;
+
+ CalculateUTF8Size()
+ : mSize(0) { }
+
+ size_t Size() const { return mSize; }
+
+ PRUint32 NS_ALWAYS_INLINE write( const value_type* start, PRUint32 N )
+ {
+ // Assume UCS2 surrogate pairs won't be spread across fragments.
+ for (const value_type *p = start, *end = start + N; p < end; ++p )
+ {
+ value_type c = *p;
+ if (! (c & 0xFF80)) // U+0000 - U+007F
+ mSize += 1;
+ else if (! (c & 0xF800)) // U+0100 - U+07FF
+ mSize += 2;
+ else if (0xD800 != (0xF800 & c)) // U+0800 - U+D7FF,U+E000 - U+FFFF
+ mSize += 3;
+ else if (0xD800 == (0xFC00 & c)) // U+D800 - U+DBFF
+ {
+ ++p;
+ if (p == end)
+ {
+ NS_ERROR("Surrogate pair split between fragments");
+ return N;
+ }
+ c = *p;
+
+ if (0xDC00 == (0xFC00 & c))
+ mSize += 4;
+ else
+ NS_ERROR("got a high Surrogate but no low surrogate");
+ }
+ else // U+DC00 - U+DFFF
+ NS_ERROR("got a low Surrogate but no high surrogate");
+ }
+
+ return N;
+ }
+
+ private:
+ size_t mSize;
+ };
+
+/**
+ * A character sink that performs a |reinterpret_cast| style conversion
+ * between character types.
+ */
+template <class FromCharT, class ToCharT>
+class LossyConvertEncoding
+ {
+ public:
+ typedef FromCharT value_type;
+
+ typedef FromCharT input_type;
+ typedef ToCharT output_type;
+
+ typedef typename nsCharTraits<FromCharT>::unsigned_char_type unsigned_input_type;
+
+ public:
+ LossyConvertEncoding( output_type* aDestination ) : mDestination(aDestination) { }
+
+ PRUint32
+ write( const input_type* aSource, PRUint32 aSourceLength )
+ {
+ const input_type* done_writing = aSource + aSourceLength;
+ while ( aSource < done_writing )
+ *mDestination++ = (output_type)(unsigned_input_type)(*aSource++); // use old-style cast to mimic old |ns[C]String| behavior
+ return aSourceLength;
+ }
+
+ void
+ write_terminator()
+ {
+ *mDestination = output_type(0);
+ }
+
+ private:
+ output_type* mDestination;
+ };
+
+#endif /* !defined(nsUTF8Utils_h_) */
diff --git a/src/libs/xpcom18a4/xpcom/string/public/nsXPIDLString.h b/src/libs/xpcom18a4/xpcom/string/public/nsXPIDLString.h
new file mode 100644
index 00000000..c66a2d7a
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/nsXPIDLString.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsXPIDLString_h___
+#define nsXPIDLString_h___
+
+#ifndef nsString_h___
+#include "nsString.h"
+#endif
+
+#endif /* !defined(nsXPIDLString_h___) */
diff --git a/src/libs/xpcom18a4/xpcom/string/public/string-template-def-char.h b/src/libs/xpcom18a4/xpcom/string/public/string-template-def-char.h
new file mode 100644
index 00000000..d0f3a907
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/string-template-def-char.h
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#define CharT char
+#define CharT_is_char 1
+#define nsTObsoleteAString_CharT nsObsoleteACString
+#define nsTObsoleteAStringThunk_CharT nsObsoleteACStringThunk
+#define nsTAString_CharT nsACString
+#define nsTAString_IncompatibleCharT nsAString
+#define nsTString_CharT nsCString
+#define nsTFixedString_CharT nsFixedCString
+#define nsTAutoString_CharT nsCAutoString
+#define nsTSubstring_CharT nsCSubstring
+#define nsTSubstringTuple_CharT nsCSubstringTuple
+#define nsTStringComparator_CharT nsCStringComparator
+#define nsTDefaultStringComparator_CharT nsDefaultCStringComparator
+#define nsTDependentString_CharT nsDependentCString
+#define nsTDependentSubstring_CharT nsDependentCSubstring
+#define nsTXPIDLString_CharT nsXPIDLCString
+#define nsTGetterCopies_CharT nsCGetterCopies
+#define nsTAdoptingString_CharT nsAdoptingCString
+#define nsTPromiseFlatString_CharT nsPromiseFlatCString
+#define TPromiseFlatString_CharT PromiseFlatCString
diff --git a/src/libs/xpcom18a4/xpcom/string/public/string-template-def-unichar.h b/src/libs/xpcom18a4/xpcom/string/public/string-template-def-unichar.h
new file mode 100644
index 00000000..c966dfbe
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/string-template-def-unichar.h
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#define CharT PRUnichar
+#define CharT_is_PRUnichar 1
+#define nsTObsoleteAString_CharT nsObsoleteAString
+#define nsTObsoleteAStringThunk_CharT nsObsoleteAStringThunk
+#define nsTAString_CharT nsAString
+#define nsTAString_IncompatibleCharT nsACString
+#define nsTString_CharT nsString
+#define nsTFixedString_CharT nsFixedString
+#define nsTAutoString_CharT nsAutoString
+#define nsTSubstring_CharT nsSubstring
+#define nsTSubstringTuple_CharT nsSubstringTuple
+#define nsTStringComparator_CharT nsStringComparator
+#define nsTDefaultStringComparator_CharT nsDefaultStringComparator
+#define nsTDependentString_CharT nsDependentString
+#define nsTDependentSubstring_CharT nsDependentSubstring
+#define nsTXPIDLString_CharT nsXPIDLString
+#define nsTGetterCopies_CharT nsGetterCopies
+#define nsTAdoptingString_CharT nsAdoptingString
+#define nsTPromiseFlatString_CharT nsPromiseFlatString
+#define TPromiseFlatString_CharT PromiseFlatString
diff --git a/src/libs/xpcom18a4/xpcom/string/public/string-template-undef.h b/src/libs/xpcom18a4/xpcom/string/public/string-template-undef.h
new file mode 100644
index 00000000..45344370
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/public/string-template-undef.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#undef CharT
+#undef CharT_is_PRUnichar
+#undef CharT_is_char
+#undef nsTObsoleteAString_CharT
+#undef nsTObsoleteAStringThunk_CharT
+#undef nsTAString_CharT
+#undef nsTAString_IncompatibleCharT
+#undef nsTString_CharT
+#undef nsTFixedString_CharT
+#undef nsTAutoString_CharT
+#undef nsTSubstring_CharT
+#undef nsTSubstringTuple_CharT
+#undef nsTStringComparator_CharT
+#undef nsTDefaultStringComparator_CharT
+#undef nsTDependentString_CharT
+#undef nsTDependentSubstring_CharT
+#undef nsTXPIDLString_CharT
+#undef nsTGetterCopies_CharT
+#undef nsTAdoptingString_CharT
+#undef nsTPromiseFlatString_CharT
+#undef TPromiseFlatString_CharT
diff --git a/src/libs/xpcom18a4/xpcom/string/src/.cvsignore b/src/libs/xpcom18a4/xpcom/string/src/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/src/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/xpcom/string/src/Makefile.in b/src/libs/xpcom18a4/xpcom/string/src/Makefile.in
new file mode 100644
index 00000000..81033c6c
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/src/Makefile.in
@@ -0,0 +1,77 @@
+# vim:set ts=8 sw=8 sts=8 noet:
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications.
+# Portions created by the Initial Developer are Copyright (C) 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Johnny Stenback <jst@netscape.com> (original author)
+# Scott Collins <scc@mozilla.org>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = string
+LIBRARY_NAME = string_s
+
+REQUIRES = xpcom \
+ $(NULL)
+
+CPPSRCS = \
+ nsAString.cpp \
+ nsDependentSubstring.cpp \
+ nsObsoleteAStringThunk.cpp \
+ nsPrintfCString.cpp \
+ nsPromiseFlatString.cpp \
+ nsReadableUtils.cpp \
+ nsSubstring.cpp \
+ nsSubstringTuple.cpp \
+ nsString.cpp \
+ nsStringComparator.cpp \
+ nsStringObsolete.cpp \
+ $(NULL)
+
+# we don't want the shared lib, but we want to force the creation of a
+# static lib.
+FORCE_STATIC_LIB = 1
+
+# Force use of PIC
+FORCE_USE_PIC = 1
+
+include $(topsrcdir)/config/rules.mk
+
+DEFINES += -D_IMPL_NS_COM
diff --git a/src/libs/xpcom18a4/xpcom/string/src/nsAString.cpp b/src/libs/xpcom18a4/xpcom/string/src/nsAString.cpp
new file mode 100644
index 00000000..5b481662
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/src/nsAString.cpp
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsAString.h"
+#include "nsObsoleteAString.h"
+#include "nsString.h"
+
+ // define nsAString
+#include "string-template-def-unichar.h"
+#include "nsTAString.cpp"
+#include "string-template-undef.h"
+
+ // define nsACString
+#include "string-template-def-char.h"
+#include "nsTAString.cpp"
+#include "string-template-undef.h"
diff --git a/src/libs/xpcom18a4/xpcom/string/src/nsDependentSubstring.cpp b/src/libs/xpcom18a4/xpcom/string/src/nsDependentSubstring.cpp
new file mode 100644
index 00000000..971defc8
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/src/nsDependentSubstring.cpp
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsDependentSubstring.h"
+#include "nsAlgorithm.h"
+
+ // define nsDependentSubstring
+#include "string-template-def-unichar.h"
+#include "nsTDependentSubstring.cpp"
+#include "string-template-undef.h"
+
+ // define nsDependentCSubstring
+#include "string-template-def-char.h"
+#include "nsTDependentSubstring.cpp"
+#include "string-template-undef.h"
diff --git a/src/libs/xpcom18a4/xpcom/string/src/nsObsoleteAStringThunk.cpp b/src/libs/xpcom18a4/xpcom/string/src/nsObsoleteAStringThunk.cpp
new file mode 100644
index 00000000..8b511d1e
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/src/nsObsoleteAStringThunk.cpp
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsObsoleteAString.h"
+#include "nsString.h"
+
+
+ // define nsObsoleteAStringThunk
+#include "string-template-def-unichar.h"
+#include "nsTObsoleteAStringThunk.cpp"
+#include "string-template-undef.h"
+
+
+ // define nsObsoleteACStringThunk
+#include "string-template-def-char.h"
+#include "nsTObsoleteAStringThunk.cpp"
+#include "string-template-undef.h"
diff --git a/src/libs/xpcom18a4/xpcom/string/src/nsPrintfCString.cpp b/src/libs/xpcom18a4/xpcom/string/src/nsPrintfCString.cpp
new file mode 100644
index 00000000..8bb06da6
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/src/nsPrintfCString.cpp
@@ -0,0 +1,83 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsPrintfCString.h"
+#include <stdarg.h>
+#include "prprf.h"
+
+
+// though these classes define a fixed buffer, they do not set the F_FIXED
+// flag. this is because they are not intended to be modified after they have
+// been constructed. we could change this but it would require adding a new
+// class to the hierarchy, one that both this class and nsCAutoString would
+// inherit from. for now, we populate the fixed buffer, and then let the
+// nsCString code treat the buffer as if it were a dependent buffer.
+
+nsPrintfCString::nsPrintfCString( const char_type* format, ... )
+ : string_type(mLocalBuffer, 0, F_TERMINATED)
+ {
+ va_list ap;
+
+ size_type logical_capacity = kLocalBufferSize;
+ size_type physical_capacity = logical_capacity + 1;
+
+ va_start(ap, format);
+ mLength = PR_vsnprintf(mData, physical_capacity, format, ap);
+ va_end(ap);
+ }
+
+nsPrintfCString::nsPrintfCString( size_type n, const char_type* format, ... )
+ : string_type(mLocalBuffer, 0, F_TERMINATED)
+ {
+ va_list ap;
+
+ // make sure there's at least |n| space
+ size_type logical_capacity = kLocalBufferSize;
+ if ( n > logical_capacity )
+ {
+ SetCapacity(n);
+ if (Capacity() < n)
+ return; // out of memory !!
+ logical_capacity = n;
+ }
+ size_type physical_capacity = logical_capacity + 1;
+
+ va_start(ap, format);
+ mLength = PR_vsnprintf(mData, physical_capacity, format, ap);
+ va_end(ap);
+ }
diff --git a/src/libs/xpcom18a4/xpcom/string/src/nsPromiseFlatString.cpp b/src/libs/xpcom18a4/xpcom/string/src/nsPromiseFlatString.cpp
new file mode 100644
index 00000000..aab4f209
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/src/nsPromiseFlatString.cpp
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsPromiseFlatString.h"
+
+ // define nsPromiseFlatString
+#include "string-template-def-unichar.h"
+#include "nsTPromiseFlatString.cpp"
+#include "string-template-undef.h"
+
+ // define nsPromiseFlatCString
+#include "string-template-def-char.h"
+#include "nsTPromiseFlatString.cpp"
+#include "string-template-undef.h"
diff --git a/src/libs/xpcom18a4/xpcom/string/src/nsReadableUtils.cpp b/src/libs/xpcom18a4/xpcom/string/src/nsReadableUtils.cpp
new file mode 100644
index 00000000..24305b6a
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/src/nsReadableUtils.cpp
@@ -0,0 +1,1122 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Scott Collins <scc@mozilla.org> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsReadableUtils.h"
+#include "nsMemory.h"
+#include "nsString.h"
+#include "nsUTF8Utils.h"
+
+NS_COM
+void
+LossyCopyUTF16toASCII( const nsAString& aSource, nsACString& aDest )
+ {
+ aDest.Truncate();
+ LossyAppendUTF16toASCII(aSource, aDest);
+ }
+
+NS_COM
+void
+CopyASCIItoUTF16( const nsACString& aSource, nsAString& aDest )
+ {
+ aDest.Truncate();
+ AppendASCIItoUTF16(aSource, aDest);
+ }
+
+NS_COM
+void
+LossyCopyUTF16toASCII( const PRUnichar* aSource, nsACString& aDest )
+ {
+ aDest.Truncate();
+ if (aSource) {
+ LossyAppendUTF16toASCII(nsDependentString(aSource), aDest);
+ }
+ }
+
+NS_COM
+void
+CopyASCIItoUTF16( const char* aSource, nsAString& aDest )
+ {
+ aDest.Truncate();
+ if (aSource) {
+ AppendASCIItoUTF16(nsDependentCString(aSource), aDest);
+ }
+ }
+
+NS_COM
+void
+CopyUTF16toUTF8( const nsAString& aSource, nsACString& aDest )
+ {
+ aDest.Truncate();
+ AppendUTF16toUTF8(aSource, aDest);
+ }
+
+NS_COM
+void
+CopyUTF8toUTF16( const nsACString& aSource, nsAString& aDest )
+ {
+ aDest.Truncate();
+ AppendUTF8toUTF16(aSource, aDest);
+ }
+
+NS_COM
+void
+CopyUTF16toUTF8( const PRUnichar* aSource, nsACString& aDest )
+ {
+ aDest.Truncate();
+ AppendUTF16toUTF8(aSource, aDest);
+ }
+
+NS_COM
+void
+CopyUTF8toUTF16( const char* aSource, nsAString& aDest )
+ {
+ aDest.Truncate();
+ AppendUTF8toUTF16(aSource, aDest);
+ }
+
+NS_COM
+void
+LossyAppendUTF16toASCII( const nsAString& aSource, nsACString& aDest )
+ {
+ PRUint32 old_dest_length = aDest.Length();
+ aDest.SetLength(old_dest_length + aSource.Length());
+
+ nsAString::const_iterator fromBegin, fromEnd;
+
+ nsACString::iterator dest;
+ aDest.BeginWriting(dest);
+
+ dest.advance(old_dest_length);
+
+ // right now, this won't work on multi-fragment destinations
+ LossyConvertEncoding<PRUnichar, char> converter(dest.get());
+
+ copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), converter);
+ }
+
+NS_COM
+void
+AppendASCIItoUTF16( const nsACString& aSource, nsAString& aDest )
+ {
+ PRUint32 old_dest_length = aDest.Length();
+ aDest.SetLength(old_dest_length + aSource.Length());
+
+ nsACString::const_iterator fromBegin, fromEnd;
+
+ nsAString::iterator dest;
+ aDest.BeginWriting(dest);
+
+ dest.advance(old_dest_length);
+
+ // right now, this won't work on multi-fragment destinations
+ LossyConvertEncoding<char, PRUnichar> converter(dest.get());
+
+ copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), converter);
+ }
+
+NS_COM
+void
+LossyAppendUTF16toASCII( const PRUnichar* aSource, nsACString& aDest )
+ {
+ if (aSource) {
+ LossyAppendUTF16toASCII(nsDependentString(aSource), aDest);
+ }
+ }
+
+NS_COM
+void
+AppendASCIItoUTF16( const char* aSource, nsAString& aDest )
+ {
+ if (aSource) {
+ AppendASCIItoUTF16(nsDependentCString(aSource), aDest);
+ }
+ }
+
+NS_COM
+void
+AppendUTF16toUTF8( const nsAString& aSource, nsACString& aDest )
+ {
+ nsAString::const_iterator source_start, source_end;
+ CalculateUTF8Size calculator;
+ copy_string(aSource.BeginReading(source_start),
+ aSource.EndReading(source_end), calculator);
+
+ PRUint32 count = calculator.Size();
+
+ if (count)
+ {
+ PRUint32 old_dest_length = aDest.Length();
+
+ // Grow the buffer if we need to.
+ aDest.SetLength(old_dest_length + count);
+
+ nsACString::iterator dest;
+ aDest.BeginWriting(dest);
+
+ dest.advance(old_dest_length);
+
+ if (count <= (PRUint32)dest.size_forward())
+ {
+ // aDest has enough room in the fragment just past the end
+ // of its old data that it can hold what we're about to
+ // append. Append using copy_string().
+
+ // All ready? Time to convert
+
+ ConvertUTF16toUTF8 converter(dest.get());
+ copy_string(aSource.BeginReading(source_start),
+ aSource.EndReading(source_end), converter);
+
+ if (converter.Size() != count)
+ {
+ NS_ERROR("Input invalid or incorrect length was calculated");
+
+ aDest.SetLength(old_dest_length);
+ }
+ }
+ else
+ {
+ // This isn't the fastest way to do this, but it gets
+ // complicated to convert UTF16 into a fragmented UTF8
+ // string, so we'll take the easy way out here in this
+ // rare situation.
+
+ aDest.Replace(old_dest_length, count,
+ NS_ConvertUTF16toUTF8(aSource));
+ }
+ }
+ }
+
+NS_COM
+void
+AppendUTF8toUTF16( const nsACString& aSource, nsAString& aDest )
+ {
+ nsACString::const_iterator source_start, source_end;
+ CalculateUTF8Length calculator;
+ copy_string(aSource.BeginReading(source_start),
+ aSource.EndReading(source_end), calculator);
+
+ PRUint32 count = calculator.Length();
+
+ if (count)
+ {
+ PRUint32 old_dest_length = aDest.Length();
+
+ // Grow the buffer if we need to.
+ aDest.SetLength(old_dest_length + count);
+
+ nsAString::iterator dest;
+ aDest.BeginWriting(dest);
+
+ dest.advance(old_dest_length);
+
+ if (count <= (PRUint32)dest.size_forward())
+ {
+ // aDest has enough room in the fragment just past the end
+ // of its old data that it can hold what we're about to
+ // append. Append using copy_string().
+
+ // All ready? Time to convert
+
+ ConvertUTF8toUTF16 converter(dest.get());
+ copy_string(aSource.BeginReading(source_start),
+ aSource.EndReading(source_end), converter);
+
+ if (converter.Length() != count)
+ {
+ NS_ERROR("Input wasn't UTF8 or incorrect length was calculated");
+ aDest.SetLength(old_dest_length);
+ }
+ }
+ else
+ {
+ // This isn't the fastest way to do this, but it gets
+ // complicated to convert parts of a UTF8 string into a
+ // UTF16 string, so we'll take the easy way out here in
+ // this rare situation.
+
+ aDest.Replace(old_dest_length, count,
+ NS_ConvertUTF8toUTF16(aSource));
+ }
+ }
+ }
+
+NS_COM
+void
+AppendUTF16toUTF8( const PRUnichar* aSource, nsACString& aDest )
+ {
+ if (aSource) {
+ AppendUTF16toUTF8(nsDependentString(aSource), aDest);
+ }
+ }
+
+NS_COM
+void
+AppendUTF8toUTF16( const char* aSource, nsAString& aDest )
+ {
+ if (aSource) {
+ AppendUTF8toUTF16(nsDependentCString(aSource), aDest);
+ }
+ }
+
+
+ /**
+ * A helper function that allocates a buffer of the desired character type big enough to hold a copy of the supplied string (plus a zero terminator).
+ *
+ * @param aSource an string you will eventually be making a copy of
+ * @return a new buffer (of the type specified by the second parameter) which you must free with |nsMemory::Free|.
+ *
+ */
+template <class FromStringT, class ToCharT>
+inline
+ToCharT*
+AllocateStringCopy( const FromStringT& aSource, ToCharT* )
+ {
+ return NS_STATIC_CAST(ToCharT*, nsMemory::Alloc((aSource.Length()+1) * sizeof(ToCharT)));
+ }
+
+
+NS_COM
+char*
+ToNewCString( const nsAString& aSource )
+ {
+ char* result = AllocateStringCopy(aSource, (char*)0);
+
+ nsAString::const_iterator fromBegin, fromEnd;
+ LossyConvertEncoding<PRUnichar, char> converter(result);
+ copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), converter).write_terminator();
+ return result;
+ }
+
+NS_COM
+char*
+ToNewUTF8String( const nsAString& aSource, PRUint32 *aUTF8Count )
+ {
+ nsAString::const_iterator start, end;
+ CalculateUTF8Size calculator;
+ copy_string(aSource.BeginReading(start), aSource.EndReading(end),
+ calculator);
+
+ if (aUTF8Count)
+ *aUTF8Count = calculator.Size();
+
+ char *result = NS_STATIC_CAST(char*,
+ nsMemory::Alloc(calculator.Size() + 1));
+
+ ConvertUTF16toUTF8 converter(result);
+ copy_string(aSource.BeginReading(start), aSource.EndReading(end),
+ converter).write_terminator();
+ NS_ASSERTION(calculator.Size() == converter.Size(), "length mismatch");
+
+ return result;
+ }
+
+NS_COM
+char*
+ToNewCString( const nsACString& aSource )
+ {
+ // no conversion needed, just allocate a buffer of the correct length and copy into it
+
+ char* result = AllocateStringCopy(aSource, (char*)0);
+
+ nsACString::const_iterator fromBegin, fromEnd;
+ char* toBegin = result;
+ *copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), toBegin) = char(0);
+ return result;
+ }
+
+NS_COM
+PRUnichar*
+ToNewUnicode( const nsAString& aSource )
+ {
+ // no conversion needed, just allocate a buffer of the correct length and copy into it
+
+ PRUnichar* result = AllocateStringCopy(aSource, (PRUnichar*)0);
+
+ nsAString::const_iterator fromBegin, fromEnd;
+ PRUnichar* toBegin = result;
+ *copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), toBegin) = PRUnichar(0);
+ return result;
+ }
+
+NS_COM
+PRUnichar*
+ToNewUnicode( const nsACString& aSource )
+ {
+ PRUnichar* result = AllocateStringCopy(aSource, (PRUnichar*)0);
+
+ nsACString::const_iterator fromBegin, fromEnd;
+ LossyConvertEncoding<char, PRUnichar> converter(result);
+ copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), converter).write_terminator();
+ return result;
+ }
+
+NS_COM
+PRUnichar*
+UTF8ToNewUnicode( const nsACString& aSource, PRUint32 *aUTF16Count )
+ {
+ nsACString::const_iterator start, end;
+ CalculateUTF8Length calculator;
+ copy_string(aSource.BeginReading(start), aSource.EndReading(end),
+ calculator);
+
+ if (aUTF16Count)
+ *aUTF16Count = calculator.Length();
+
+ PRUnichar *result = NS_STATIC_CAST(PRUnichar*,
+ nsMemory::Alloc(sizeof(PRUnichar) * (calculator.Length() + 1)));
+
+ ConvertUTF8toUTF16 converter(result);
+ copy_string(aSource.BeginReading(start), aSource.EndReading(end),
+ converter).write_terminator();
+ NS_ASSERTION(calculator.Length() == converter.Length(), "length mismatch");
+
+ return result;
+ }
+
+NS_COM
+PRUnichar*
+CopyUnicodeTo( const nsAString& aSource, PRUint32 aSrcOffset, PRUnichar* aDest, PRUint32 aLength )
+ {
+ nsAString::const_iterator fromBegin, fromEnd;
+ PRUnichar* toBegin = aDest;
+ copy_string(aSource.BeginReading(fromBegin).advance( PRInt32(aSrcOffset) ), aSource.BeginReading(fromEnd).advance( PRInt32(aSrcOffset+aLength) ), toBegin);
+ return aDest;
+ }
+
+NS_COM
+void
+CopyUnicodeTo( const nsAString::const_iterator& aSrcStart,
+ const nsAString::const_iterator& aSrcEnd,
+ nsAString& aDest )
+ {
+ nsAString::iterator writer;
+ aDest.SetLength(Distance(aSrcStart, aSrcEnd));
+ aDest.BeginWriting(writer);
+ nsAString::const_iterator fromBegin(aSrcStart);
+
+ copy_string(fromBegin, aSrcEnd, writer);
+ }
+
+NS_COM
+void
+AppendUnicodeTo( const nsAString::const_iterator& aSrcStart,
+ const nsAString::const_iterator& aSrcEnd,
+ nsAString& aDest )
+ {
+ nsAString::iterator writer;
+ PRUint32 oldLength = aDest.Length();
+ aDest.SetLength(oldLength + Distance(aSrcStart, aSrcEnd));
+ aDest.BeginWriting(writer).advance(oldLength);
+ nsAString::const_iterator fromBegin(aSrcStart);
+
+ copy_string(fromBegin, aSrcEnd, writer);
+ }
+
+NS_COM
+PRBool
+IsASCII( const nsAString& aString )
+ {
+ static const PRUnichar NOT_ASCII = PRUnichar(~0x007F);
+
+
+ // Don't want to use |copy_string| for this task, since we can stop at the first non-ASCII character
+
+ nsAString::const_iterator done_reading;
+ aString.EndReading(done_reading);
+
+ // for each chunk of |aString|...
+ PRUint32 fragmentLength = 0;
+ nsAString::const_iterator iter;
+ for ( aString.BeginReading(iter); iter != done_reading; iter.advance( PRInt32(fragmentLength) ) )
+ {
+ fragmentLength = PRUint32(iter.size_forward());
+ const PRUnichar* c = iter.get();
+ const PRUnichar* fragmentEnd = c + fragmentLength;
+
+ // for each character in this chunk...
+ while ( c < fragmentEnd )
+ if ( *c++ & NOT_ASCII )
+ return PR_FALSE;
+ }
+
+ return PR_TRUE;
+ }
+
+NS_COM
+PRBool
+IsASCII( const nsACString& aString )
+ {
+ static const char NOT_ASCII = char(~0x7F);
+
+
+ // Don't want to use |copy_string| for this task, since we can stop at the first non-ASCII character
+
+ nsACString::const_iterator done_reading;
+ aString.EndReading(done_reading);
+
+ // for each chunk of |aString|...
+ PRUint32 fragmentLength = 0;
+ nsACString::const_iterator iter;
+ for ( aString.BeginReading(iter); iter != done_reading; iter.advance( PRInt32(fragmentLength) ) )
+ {
+ fragmentLength = PRUint32(iter.size_forward());
+ const char* c = iter.get();
+ const char* fragmentEnd = c + fragmentLength;
+
+ // for each character in this chunk...
+ while ( c < fragmentEnd )
+ if ( *c++ & NOT_ASCII )
+ return PR_FALSE;
+ }
+
+ return PR_TRUE;
+ }
+
+NS_COM
+PRBool
+IsUTF8( const nsACString& aString )
+ {
+ nsReadingIterator<char> done_reading;
+ aString.EndReading(done_reading);
+
+ PRInt32 state = 0;
+ PRBool overlong = PR_FALSE;
+ PRBool surrogate = PR_FALSE;
+ PRBool nonchar = PR_FALSE;
+ PRUint16 olupper = 0; // overlong byte upper bound.
+ PRUint16 slower = 0; // surrogate byte lower bound.
+
+ // for each chunk of |aString|...
+ PRUint32 fragmentLength = 0;
+ nsReadingIterator<char> iter;
+
+ for ( aString.BeginReading(iter); iter != done_reading; iter.advance( PRInt32(fragmentLength) ) )
+ {
+ fragmentLength = PRUint32(iter.size_forward());
+ const char* ptr = iter.get();
+ const char* fragmentEnd = ptr + fragmentLength;
+
+ // for each character in this chunk...
+ while ( ptr < fragmentEnd )
+ {
+ PRUint8 c;
+
+ if (0 == state)
+ {
+ c = *ptr++;
+
+ if ( UTF8traits::isASCII(c) )
+ continue;
+
+ if ( c <= 0xC1 ) // [80-BF] where not expected, [C0-C1] for overlong.
+ return PR_FALSE;
+ else if ( UTF8traits::is2byte(c) )
+ state = 1;
+ else if ( UTF8traits::is3byte(c) )
+ {
+ state = 2;
+ if ( c == 0xE0 ) // to exclude E0[80-9F][80-BF]
+ {
+ overlong = PR_TRUE;
+ olupper = 0x9F;
+ }
+ else if ( c == 0xED ) // ED[A0-BF][80-BF] : surrogate codepoint
+ {
+ surrogate = PR_TRUE;
+ slower = 0xA0;
+ }
+ else if ( c == 0xEF ) // EF BF [BE-BF] : non-character
+ nonchar = PR_TRUE;
+ }
+ else if ( c <= 0xF4 ) // XXX replace /w UTF8traits::is4byte when it's updated to exclude [F5-F7].(bug 199090)
+ {
+ state = 3;
+ nonchar = PR_TRUE;
+ if ( c == 0xF0 ) // to exclude F0[80-8F][80-BF]{2}
+ {
+ overlong = PR_TRUE;
+ olupper = 0x8F;
+ }
+ else if ( c == 0xF4 ) // to exclude F4[90-BF][80-BF]
+ {
+ // actually not surrogates but codepoints beyond 0x10FFFF
+ surrogate = PR_TRUE;
+ slower = 0x90;
+ }
+ }
+ else
+ return PR_FALSE; // Not UTF-8 string
+ }
+
+ while (ptr < fragmentEnd && state)
+ {
+ c = *ptr++;
+ --state;
+
+ // non-character : EF BF [BE-BF] or F[0-7] [89AB]F BF [BE-BF]
+ if ( nonchar && ( (!state && c < 0xBE) ||
+ (state == 1 && c != 0xBF) ||
+ (state == 2 && 0x0F != (0x0F & c)) ))
+ nonchar = PR_FALSE;
+
+ if ( !UTF8traits::isInSeq(c) || (overlong && c <= olupper) ||
+ (surrogate && slower <= c) || (nonchar && !state) )
+ return PR_FALSE; // Not UTF-8 string
+ overlong = surrogate = PR_FALSE;
+ }
+ }
+ }
+ return !state; // state != 0 at the end indicates an invalid UTF-8 seq.
+ }
+
+ /**
+ * A character sink for in-place case conversion.
+ */
+class ConvertToUpperCase
+ {
+ public:
+ typedef char value_type;
+
+ PRUint32
+ write( const char* aSource, PRUint32 aSourceLength )
+ {
+ char* cp = NS_CONST_CAST(char*,aSource);
+ const char* end = aSource + aSourceLength;
+ while (cp != end) {
+ char ch = *cp;
+ if ((ch >= 'a') && (ch <= 'z'))
+ *cp = ch - ('a' - 'A');
+ ++cp;
+ }
+ return aSourceLength;
+ }
+ };
+
+NS_COM
+void
+ToUpperCase( nsACString& aCString )
+ {
+ nsACString::iterator fromBegin, fromEnd;
+ ConvertToUpperCase converter;
+ copy_string(aCString.BeginWriting(fromBegin), aCString.EndWriting(fromEnd), converter);
+ }
+
+NS_COM
+void
+ToUpperCase( nsCSubstring& aCString )
+ {
+ ConvertToUpperCase converter;
+ char* start;
+ converter.write(aCString.BeginWriting(start), aCString.Length());
+ }
+
+ /**
+ * A character sink for copying with case conversion.
+ */
+class CopyToUpperCase
+ {
+ public:
+ typedef char value_type;
+
+ CopyToUpperCase( nsACString::iterator& aDestIter )
+ : mIter(aDestIter)
+ {
+ }
+
+ PRUint32
+ write( const char* aSource, PRUint32 aSourceLength )
+ {
+ PRUint32 len = PR_MIN(PRUint32(mIter.size_forward()), aSourceLength);
+ char* cp = mIter.get();
+ const char* end = aSource + len;
+ while (aSource != end) {
+ char ch = *aSource;
+ if ((ch >= 'a') && (ch <= 'z'))
+ *cp = ch - ('a' - 'A');
+ else
+ *cp = ch;
+ ++aSource;
+ ++cp;
+ }
+ mIter.advance(len);
+ return len;
+ }
+
+ protected:
+ nsACString::iterator& mIter;
+ };
+
+NS_COM
+void
+ToUpperCase( const nsACString& aSource, nsACString& aDest )
+ {
+ nsACString::const_iterator fromBegin, fromEnd;
+ nsACString::iterator toBegin;
+ aDest.SetLength(aSource.Length());
+ CopyToUpperCase converter(aDest.BeginWriting(toBegin));
+ copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), converter);
+ }
+
+ /**
+ * A character sink for case conversion.
+ */
+class ConvertToLowerCase
+ {
+ public:
+ typedef char value_type;
+
+ PRUint32
+ write( const char* aSource, PRUint32 aSourceLength )
+ {
+ char* cp = NS_CONST_CAST(char*,aSource);
+ const char* end = aSource + aSourceLength;
+ while (cp != end) {
+ char ch = *cp;
+ if ((ch >= 'A') && (ch <= 'Z'))
+ *cp = ch + ('a' - 'A');
+ ++cp;
+ }
+ return aSourceLength;
+ }
+ };
+
+NS_COM
+void
+ToLowerCase( nsACString& aCString )
+ {
+ nsACString::iterator fromBegin, fromEnd;
+ ConvertToLowerCase converter;
+ copy_string(aCString.BeginWriting(fromBegin), aCString.EndWriting(fromEnd), converter);
+ }
+
+NS_COM
+void
+ToLowerCase( nsCSubstring& aCString )
+ {
+ ConvertToLowerCase converter;
+ char* start;
+ converter.write(aCString.BeginWriting(start), aCString.Length());
+ }
+
+ /**
+ * A character sink for copying with case conversion.
+ */
+class CopyToLowerCase
+ {
+ public:
+ typedef char value_type;
+
+ CopyToLowerCase( nsACString::iterator& aDestIter )
+ : mIter(aDestIter)
+ {
+ }
+
+ PRUint32
+ write( const char* aSource, PRUint32 aSourceLength )
+ {
+ PRUint32 len = PR_MIN(PRUint32(mIter.size_forward()), aSourceLength);
+ char* cp = mIter.get();
+ const char* end = aSource + len;
+ while (aSource != end) {
+ char ch = *aSource;
+ if ((ch >= 'A') && (ch <= 'Z'))
+ *cp = ch + ('a' - 'A');
+ else
+ *cp = ch;
+ ++aSource;
+ ++cp;
+ }
+ mIter.advance(len);
+ return len;
+ }
+
+ protected:
+ nsACString::iterator& mIter;
+ };
+
+NS_COM
+void
+ToLowerCase( const nsACString& aSource, nsACString& aDest )
+ {
+ nsACString::const_iterator fromBegin, fromEnd;
+ nsACString::iterator toBegin;
+ aDest.SetLength(aSource.Length());
+ CopyToLowerCase converter(aDest.BeginWriting(toBegin));
+ copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), converter);
+ }
+
+template <class StringT, class IteratorT, class Comparator>
+PRBool
+FindInReadable_Impl( const StringT& aPattern, IteratorT& aSearchStart, IteratorT& aSearchEnd, const Comparator& compare )
+ {
+ PRBool found_it = PR_FALSE;
+
+ // only bother searching at all if we're given a non-empty range to search
+ if ( aSearchStart != aSearchEnd )
+ {
+ IteratorT aPatternStart, aPatternEnd;
+ aPattern.BeginReading(aPatternStart);
+ aPattern.EndReading(aPatternEnd);
+
+ // outer loop keeps searching till we find it or run out of string to search
+ while ( !found_it )
+ {
+ // fast inner loop (that's what it's called, not what it is) looks for a potential match
+ while ( aSearchStart != aSearchEnd &&
+ compare(*aPatternStart, *aSearchStart) )
+ ++aSearchStart;
+
+ // if we broke out of the `fast' loop because we're out of string ... we're done: no match
+ if ( aSearchStart == aSearchEnd )
+ break;
+
+ // otherwise, we're at a potential match, let's see if we really hit one
+ IteratorT testPattern(aPatternStart);
+ IteratorT testSearch(aSearchStart);
+
+ // slow inner loop verifies the potential match (found by the `fast' loop) at the current position
+ for(;;)
+ {
+ // we already compared the first character in the outer loop,
+ // so we'll advance before the next comparison
+ ++testPattern;
+ ++testSearch;
+
+ // if we verified all the way to the end of the pattern, then we found it!
+ if ( testPattern == aPatternEnd )
+ {
+ found_it = PR_TRUE;
+ aSearchEnd = testSearch; // return the exact found range through the parameters
+ break;
+ }
+
+ // if we got to end of the string we're searching before we hit the end of the
+ // pattern, we'll never find what we're looking for
+ if ( testSearch == aSearchEnd )
+ {
+ aSearchStart = aSearchEnd;
+ break;
+ }
+
+ // else if we mismatched ... it's time to advance to the next search position
+ // and get back into the `fast' loop
+ if ( compare(*testPattern, *testSearch) )
+ {
+ ++aSearchStart;
+ break;
+ }
+ }
+ }
+ }
+
+ return found_it;
+ }
+
+
+NS_COM
+PRBool
+FindInReadable( const nsAString& aPattern, nsAString::const_iterator& aSearchStart, nsAString::const_iterator& aSearchEnd, const nsStringComparator& aComparator )
+ {
+ return FindInReadable_Impl(aPattern, aSearchStart, aSearchEnd, aComparator);
+ }
+
+NS_COM
+PRBool
+FindInReadable( const nsACString& aPattern, nsACString::const_iterator& aSearchStart, nsACString::const_iterator& aSearchEnd, const nsCStringComparator& aComparator)
+ {
+ return FindInReadable_Impl(aPattern, aSearchStart, aSearchEnd, aComparator);
+ }
+
+NS_COM
+PRBool
+CaseInsensitiveFindInReadable( const nsACString& aPattern, nsACString::const_iterator& aSearchStart, nsACString::const_iterator& aSearchEnd )
+ {
+ return FindInReadable_Impl(aPattern, aSearchStart, aSearchEnd, nsCaseInsensitiveCStringComparator());
+ }
+
+ /**
+ * This implementation is simple, but does too much work.
+ * It searches the entire string from left to right, and returns the last match found, if any.
+ * This implementation will be replaced when I get |reverse_iterator|s working.
+ */
+NS_COM
+PRBool
+RFindInReadable( const nsAString& aPattern, nsAString::const_iterator& aSearchStart, nsAString::const_iterator& aSearchEnd, const nsStringComparator& aComparator)
+ {
+ PRBool found_it = PR_FALSE;
+
+ nsAString::const_iterator savedSearchEnd(aSearchEnd);
+ nsAString::const_iterator searchStart(aSearchStart), searchEnd(aSearchEnd);
+
+ while ( searchStart != searchEnd )
+ {
+ if ( FindInReadable(aPattern, searchStart, searchEnd, aComparator) )
+ {
+ found_it = PR_TRUE;
+
+ // this is the best match so far, so remember it
+ aSearchStart = searchStart;
+ aSearchEnd = searchEnd;
+
+ // ...and get ready to search some more
+ // (it's tempting to set |searchStart=searchEnd| ... but that misses overlapping patterns)
+ ++searchStart;
+ searchEnd = savedSearchEnd;
+ }
+ }
+
+ // if we never found it, return an empty range
+ if ( !found_it )
+ aSearchStart = aSearchEnd;
+
+ return found_it;
+ }
+
+NS_COM
+PRBool
+RFindInReadable( const nsACString& aPattern, nsACString::const_iterator& aSearchStart, nsACString::const_iterator& aSearchEnd, const nsCStringComparator& aComparator)
+ {
+ PRBool found_it = PR_FALSE;
+
+ nsACString::const_iterator savedSearchEnd(aSearchEnd);
+ nsACString::const_iterator searchStart(aSearchStart), searchEnd(aSearchEnd);
+
+ while ( searchStart != searchEnd )
+ {
+ if ( FindInReadable(aPattern, searchStart, searchEnd, aComparator) )
+ {
+ found_it = PR_TRUE;
+
+ // this is the best match so far, so remember it
+ aSearchStart = searchStart;
+ aSearchEnd = searchEnd;
+
+ // ...and get ready to search some more
+ // (it's tempting to set |searchStart=searchEnd| ... but that misses overlapping patterns)
+ ++searchStart;
+ searchEnd = savedSearchEnd;
+ }
+ }
+
+ // if we never found it, return an empty range
+ if ( !found_it )
+ aSearchStart = aSearchEnd;
+
+ return found_it;
+ }
+
+NS_COM
+PRBool
+FindCharInReadable( PRUnichar aChar, nsAString::const_iterator& aSearchStart, const nsAString::const_iterator& aSearchEnd )
+ {
+ PRInt32 fragmentLength = aSearchEnd.get() - aSearchStart.get();
+
+ const PRUnichar* charFoundAt = nsCharTraits<PRUnichar>::find(aSearchStart.get(), fragmentLength, aChar);
+ if ( charFoundAt ) {
+ aSearchStart.advance( charFoundAt - aSearchStart.get() );
+ return PR_TRUE;
+ }
+
+ aSearchStart.advance(fragmentLength);
+ return PR_FALSE;
+ }
+
+NS_COM
+PRBool
+FindCharInReadable( char aChar, nsACString::const_iterator& aSearchStart, const nsACString::const_iterator& aSearchEnd )
+ {
+ PRInt32 fragmentLength = aSearchEnd.get() - aSearchStart.get();
+
+ const char* charFoundAt = nsCharTraits<char>::find(aSearchStart.get(), fragmentLength, aChar);
+ if ( charFoundAt ) {
+ aSearchStart.advance( charFoundAt - aSearchStart.get() );
+ return PR_TRUE;
+ }
+
+ aSearchStart.advance(fragmentLength);
+ return PR_FALSE;
+ }
+
+NS_COM
+PRUint32
+CountCharInReadable( const nsAString& aStr,
+ PRUnichar aChar )
+{
+ PRUint32 count = 0;
+ nsAString::const_iterator begin, end;
+
+ aStr.BeginReading(begin);
+ aStr.EndReading(end);
+
+ while (begin != end) {
+ if (*begin == aChar) {
+ ++count;
+ }
+ ++begin;
+ }
+
+ return count;
+}
+
+NS_COM
+PRUint32
+CountCharInReadable( const nsACString& aStr,
+ char aChar )
+{
+ PRUint32 count = 0;
+ nsACString::const_iterator begin, end;
+
+ aStr.BeginReading(begin);
+ aStr.EndReading(end);
+
+ while (begin != end) {
+ if (*begin == aChar) {
+ ++count;
+ }
+ ++begin;
+ }
+
+ return count;
+}
+
+NS_COM PRBool
+StringBeginsWith( const nsAString& aSource, const nsAString& aSubstring,
+ const nsStringComparator& aComparator )
+ {
+ nsAString::size_type src_len = aSource.Length(),
+ sub_len = aSubstring.Length();
+ if (sub_len > src_len)
+ return PR_FALSE;
+ return Substring(aSource, 0, sub_len).Equals(aSubstring, aComparator);
+ }
+
+NS_COM PRBool
+StringBeginsWith( const nsACString& aSource, const nsACString& aSubstring,
+ const nsCStringComparator& aComparator )
+ {
+ nsACString::size_type src_len = aSource.Length(),
+ sub_len = aSubstring.Length();
+ if (sub_len > src_len)
+ return PR_FALSE;
+ return Substring(aSource, 0, sub_len).Equals(aSubstring, aComparator);
+ }
+
+NS_COM PRBool
+StringEndsWith( const nsAString& aSource, const nsAString& aSubstring,
+ const nsStringComparator& aComparator )
+ {
+ nsAString::size_type src_len = aSource.Length(),
+ sub_len = aSubstring.Length();
+ if (sub_len > src_len)
+ return PR_FALSE;
+ return Substring(aSource, src_len - sub_len, sub_len).Equals(aSubstring,
+ aComparator);
+ }
+
+NS_COM PRBool
+StringEndsWith( const nsACString& aSource, const nsACString& aSubstring,
+ const nsCStringComparator& aComparator )
+ {
+ nsACString::size_type src_len = aSource.Length(),
+ sub_len = aSubstring.Length();
+ if (sub_len > src_len)
+ return PR_FALSE;
+ return Substring(aSource, src_len - sub_len, sub_len).Equals(aSubstring,
+ aComparator);
+ }
+
+
+
+template <class CharT>
+class CalculateHashCode
+ {
+ public:
+ typedef CharT char_type;
+ typedef PRUint32 hashcode_type;
+ typedef CharT value_type;
+
+ CalculateHashCode() : mHashCode(0) { }
+ hashcode_type GetHashCode() const { return mHashCode; }
+
+ PRUint32 write( const CharT* chars, PRUint32 N )
+ {
+ for ( const CharT *end = chars + N; chars < end; ++chars)
+ mHashCode = (mHashCode>>28) ^ (mHashCode<<4) ^ PRUint32(*chars);
+ return N;
+ }
+
+ private:
+ hashcode_type mHashCode;
+ };
+
+NS_COM PRUint32 HashString( const nsAString& aStr )
+ {
+ CalculateHashCode<nsAString::char_type> sink;
+ nsAString::const_iterator begin, end;
+ aStr.BeginReading(begin);
+ aStr.EndReading(end);
+ copy_string(begin, end, sink);
+ return sink.GetHashCode();
+ }
+
+NS_COM PRUint32 HashString( const nsACString& aStr )
+ {
+ CalculateHashCode<nsACString::char_type> sink;
+ nsACString::const_iterator begin, end;
+ aStr.BeginReading(begin);
+ aStr.EndReading(end);
+ copy_string(begin, end, sink);
+ return sink.GetHashCode();
+ }
+
+static const PRUnichar empty_buffer[1] = { '\0' };
+
+NS_COM const nsAFlatString& EmptyString()
+ {
+ static const nsDependentString sEmpty(empty_buffer);
+
+ return sEmpty;
+ }
+
+NS_COM const nsAFlatCString& EmptyCString()
+ {
+ static const nsDependentCString sEmpty((const char *)empty_buffer);
+
+ return sEmpty;
+ }
diff --git a/src/libs/xpcom18a4/xpcom/string/src/nsString.cpp b/src/libs/xpcom18a4/xpcom/string/src/nsString.cpp
new file mode 100644
index 00000000..aedf3295
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/src/nsString.cpp
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsString.h"
+
+ // define nsString
+#include "string-template-def-unichar.h"
+#include "nsTString.cpp"
+#include "string-template-undef.h"
+
+ // define nsCString
+#include "string-template-def-char.h"
+#include "nsTString.cpp"
+#include "string-template-undef.h"
diff --git a/src/libs/xpcom18a4/xpcom/string/src/nsStringComparator.cpp b/src/libs/xpcom18a4/xpcom/string/src/nsStringComparator.cpp
new file mode 100644
index 00000000..ced75c73
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/src/nsStringComparator.cpp
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <ctype.h>
+#include "nsAString.h"
+#include "plstr.h"
+
+
+ // define nsStringComparator
+#include "string-template-def-unichar.h"
+#include "nsTStringComparator.cpp"
+#include "string-template-undef.h"
+
+ // define nsCStringComparator
+#include "string-template-def-char.h"
+#include "nsTStringComparator.cpp"
+#include "string-template-undef.h"
+
+
+int
+nsCaseInsensitiveCStringComparator::operator()( const char_type* lhs, const char_type* rhs, PRUint32 aLength ) const
+ {
+ PRInt32 result=PRInt32(PL_strncasecmp(lhs, rhs, aLength));
+ //Egads. PL_strncasecmp is returning *very* negative numbers.
+ //Some folks expect -1,0,1, so let's temper its enthusiasm.
+ if (result<0)
+ result=-1;
+ return result;
+ }
+
+int
+nsCaseInsensitiveCStringComparator::operator()( char lhs, char rhs ) const
+ {
+ if (lhs == rhs) return 0;
+
+ lhs = tolower(lhs);
+ rhs = tolower(rhs);
+
+ return lhs - rhs;
+ }
diff --git a/src/libs/xpcom18a4/xpcom/string/src/nsStringObsolete.cpp b/src/libs/xpcom18a4/xpcom/string/src/nsStringObsolete.cpp
new file mode 100644
index 00000000..76106a27
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/src/nsStringObsolete.cpp
@@ -0,0 +1,1327 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsString.h"
+
+
+ /**
+ * nsTString obsolete API support
+ */
+
+#if MOZ_STRING_WITH_OBSOLETE_API
+
+#include "nsDependentString.h"
+#include "nsDependentSubstring.h"
+#include "nsReadableUtils.h"
+#include "nsCRT.h"
+#include "nsUTF8Utils.h"
+#include "prdtoa.h"
+#include "prprf.h"
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+# include <iprt/mem.h>
+#endif
+
+/* ***** BEGIN RICKG BLOCK *****
+ *
+ * NOTE: This section of code was extracted from rickg's bufferRoutines.h file.
+ * For the most part it remains unmodified. We want to eliminate (or at
+ * least clean up) this code at some point. If you find the formatting
+ * in this section somewhat inconsistent, don't blame me! ;-)
+ */
+
+// XXXdarin what is wrong with STDC's tolower?
+inline char
+ascii_tolower(char aChar)
+{
+ if (aChar >= 'A' && aChar <= 'Z')
+ return aChar + ('a' - 'A');
+ return aChar;
+}
+
+//-----------------------------------------------------------------------------
+//
+// This set of methods is used to search a buffer looking for a char.
+//
+
+
+/**
+ * This methods cans the given buffer for the given char
+ *
+ * @update gess 02/17/00
+ * @param aDest is the buffer to be searched
+ * @param aDestLength is the size (in char-units, not bytes) of the buffer
+ * @param anOffset is the start pos to begin searching
+ * @param aChar is the target character we're looking for
+ * @param aCount tells us how many characters to iterate through (which may be different than aLength); -1 means use full length.
+ * @return index of pos if found, else -1 (kNotFound)
+ */
+static PRInt32
+FindChar1(const char* aDest,PRUint32 aDestLength,PRInt32 anOffset,const PRUnichar aChar,PRInt32 aCount) {
+
+ if(anOffset < 0)
+ anOffset=0;
+
+ if(aCount < 0)
+ aCount = (PRInt32)aDestLength;
+
+ if((aChar < 256) && (0 < aDestLength) && ((PRUint32)anOffset < aDestLength)) {
+
+ //We'll only search if the given aChar is within the normal ascii a range,
+ //(Since this string is definitely within the ascii range).
+
+ if(0<aCount) {
+
+ const char* left= aDest+anOffset;
+ const char* last= left+aCount;
+ const char* max = aDest+aDestLength;
+ const char* end = (last<max) ? last : max;
+
+ PRInt32 theMax = end-left;
+ if(0<theMax) {
+
+ unsigned char theChar = (unsigned char) aChar;
+ const char* result=(const char*)memchr(left, (int)theChar, theMax);
+
+ if(result)
+ return result-aDest;
+
+ }
+ }
+ }
+
+ return kNotFound;
+}
+
+
+/**
+ * This methods cans the given buffer for the given char
+ *
+ * @update gess 3/25/98
+ * @param aDest is the buffer to be searched
+ * @param aDestLength is the size (in char-units, not bytes) of the buffer
+ * @param anOffset is the start pos to begin searching
+ * @param aChar is the target character we're looking for
+ * @param aCount tells us how many characters to iterate through (which may be different than aLength); -1 means use full length.
+ * @return index of pos if found, else -1 (kNotFound)
+ */
+static PRInt32
+FindChar2(const PRUnichar* aDest,PRUint32 aDestLength,PRInt32 anOffset,const PRUnichar aChar,PRInt32 aCount) {
+
+ if(anOffset < 0)
+ anOffset=0;
+
+ if(aCount < 0)
+ aCount = (PRInt32)aDestLength;
+
+ if((0<aDestLength) && ((PRUint32)anOffset < aDestLength)) {
+
+ if(0<aCount) {
+
+ const PRUnichar* root = aDest;
+ const PRUnichar* left = root+anOffset;
+ const PRUnichar* last = left+aCount;
+ const PRUnichar* max = root+aDestLength;
+ const PRUnichar* end = (last<max) ? last : max;
+
+ while(left<end){
+
+ if(*left==aChar)
+ return (left-root);
+
+ ++left;
+ }
+ }
+ }
+
+ return kNotFound;
+}
+
+
+/**
+ * This methods cans the given buffer (in reverse) for the given char
+ *
+ * @update gess 02/17/00
+ * @param aDest is the buffer to be searched
+ * @param aDestLength is the size (in char-units, not bytes) of the buffer
+ * @param anOffset is the start pos to begin searching
+ * @param aChar is the target character we're looking for
+ * @param aCount tells us how many characters to iterate through (which may be different than aLength); -1 means use full length.
+ * @return index of pos if found, else -1 (kNotFound)
+ */
+
+static PRInt32
+RFindChar1(const char* aDest,PRUint32 aDestLength,PRInt32 anOffset,const PRUnichar aChar,PRInt32 aCount) {
+
+ if(anOffset < 0)
+ anOffset=(PRInt32)aDestLength-1;
+
+ if(aCount < 0)
+ aCount = PRInt32(aDestLength);
+
+ if((aChar<256) && (0 < aDestLength) && ((PRUint32)anOffset < aDestLength)) {
+
+ //We'll only search if the given aChar is within the normal ascii a range,
+ //(Since this string is definitely within the ascii range).
+
+ if(0 < aCount) {
+
+ const char* rightmost = aDest + anOffset;
+ const char* min = rightmost - aCount + 1;
+ const char* leftmost = (min<aDest) ? aDest: min;
+
+ char theChar=(char)aChar;
+ while(leftmost <= rightmost){
+
+ if((*rightmost) == theChar)
+ return rightmost - aDest;
+
+ --rightmost;
+ }
+ }
+ }
+
+ return kNotFound;
+}
+
+
+/**
+ * This methods cans the given buffer for the given char
+ *
+ * @update gess 3/25/98
+ * @param aDest is the buffer to be searched
+ * @param aDestLength is the size (in char-units, not bytes) of the buffer
+ * @param anOffset is the start pos to begin searching
+ * @param aChar is the target character we're looking for
+ * @param aCount tells us how many characters to iterate through (which may be different than aLength); -1 means use full length.
+ * @return index of pos if found, else -1 (kNotFound)
+ */
+static PRInt32
+RFindChar2(const PRUnichar* aDest,PRUint32 aDestLength,PRInt32 anOffset,const PRUnichar aChar,PRInt32 aCount) {
+
+ if(anOffset < 0)
+ anOffset=(PRInt32)aDestLength-1;
+
+ if(aCount < 0)
+ aCount = PRInt32(aDestLength);
+
+ if((0 < aDestLength) && ((PRUint32)anOffset < aDestLength)) {
+
+ if(0 < aCount) {
+
+ const PRUnichar* root = aDest;
+ const PRUnichar* rightmost = root + anOffset;
+ const PRUnichar* min = rightmost - aCount + 1;
+ const PRUnichar* leftmost = (min<root) ? root: min;
+
+ while(leftmost <= rightmost){
+
+ if((*rightmost) == aChar)
+ return rightmost - root;
+
+ --rightmost;
+ }
+ }
+ }
+
+ return kNotFound;
+}
+
+//-----------------------------------------------------------------------------
+//
+// This set of methods is used to compare one buffer onto another. The
+// functions are differentiated by the size of source and dest character
+// sizes. WARNING: Your destination buffer MUST be big enough to hold all the
+// source bytes. We don't validate these ranges here (this should be done in
+// higher level routines).
+//
+
+
+/**
+ * This method compares the data in one buffer with another
+ * @update gess 01/04/99
+ * @param aStr1 is the first buffer to be compared
+ * @param aStr2 is the 2nd buffer to be compared
+ * @param aCount is the number of chars to compare
+ * @param aIgnoreCase tells us whether to use a case-sensitive comparison
+ * @return -1,0,1 depending on <,==,>
+ */
+static
+#ifdef __SUNPRO_CC
+inline
+#endif /* __SUNPRO_CC */
+PRInt32
+Compare1To1(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase){
+ PRInt32 result=0;
+ if(aIgnoreCase)
+ result=PRInt32(PL_strncasecmp(aStr1, aStr2, aCount));
+ else
+ result=nsCharTraits<char>::compare(aStr1,aStr2,aCount);
+
+ // alien comparisons may return out-of-bound answers
+ // instead of the -1, 0, 1 expected by most clients
+ if ( result < -1 )
+ result = -1;
+ else if ( result > 1 )
+ result = 1;
+ return result;
+}
+
+/**
+ * This method compares the data in one buffer with another
+ * @update gess 01/04/99
+ * @param aStr1 is the first buffer to be compared
+ * @param aStr2 is the 2nd buffer to be compared
+ * @param aCount is the number of chars to compare
+ * @param aIgnoreCase tells us whether to use a case-sensitive comparison
+ * @return -1,0,1 depending on <,==,>
+ */
+static
+#ifdef __SUNPRO_CC
+inline
+#endif /* __SUNPRO_CC */
+PRInt32
+Compare2To2(const PRUnichar* aStr1,const PRUnichar* aStr2,PRUint32 aCount){
+ PRInt32 result;
+
+ if ( aStr1 && aStr2 )
+ result = nsCharTraits<PRUnichar>::compare(aStr1, aStr2, aCount);
+
+ // The following cases are rare and survivable caller errors.
+ // Two null pointers are equal, but any string, even 0 length
+ // is greater than a null pointer. It might not really matter,
+ // but we pick something reasonable anyway.
+ else if ( !aStr1 && !aStr2 )
+ result = 0;
+ else if ( aStr1 )
+ result = 1;
+ else
+ result = -1;
+
+ // alien comparisons may give answers outside the -1, 0, 1 expected by callers
+ if ( result < -1 )
+ result = -1;
+ else if ( result > 1 )
+ result = 1;
+ return result;
+}
+
+
+/**
+ * This method compares the data in one buffer with another
+ * @update gess 01/04/99
+ * @param aStr1 is the first buffer to be compared
+ * @param aStr2 is the 2nd buffer to be compared
+ * @param aCount is the number of chars to compare
+ * @param aIgnoreCase tells us whether to use a case-sensitive comparison
+ * @return -1,0,1 depending on <,==,>
+ */
+static
+#ifdef __SUNPRO_CC
+inline
+#endif /* __SUNPRO_CC */
+PRInt32
+Compare2To1(const PRUnichar* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase){
+ const PRUnichar* s1 = aStr1;
+ const char *s2 = aStr2;
+
+ if (aStr1 && aStr2) {
+ if (aCount != 0) {
+ do {
+
+ PRUnichar c1 = *s1++;
+ PRUnichar c2 = PRUnichar((unsigned char)*s2++);
+
+ if (c1 != c2) {
+#ifdef NS_DEBUG
+ // we won't warn on c1>=128 (the 2-byte value) because often
+ // it is just fine to compare an constant, ascii value (i.e. "body")
+ // against some non-ascii value (i.e. a unicode string that
+ // was downloaded from a web page)
+ if (aIgnoreCase && c2>=128)
+ NS_WARNING("got a non-ASCII string, but we can't do an accurate case conversion!");
+#endif
+
+ // can't do case conversion on characters out of our range
+ if (aIgnoreCase && c1<128 && c2<128) {
+
+ c1 = ascii_tolower(char(c1));
+ c2 = ascii_tolower(char(c2));
+
+ if (c1 == c2) continue;
+ }
+
+ if (c1 < c2) return -1;
+ return 1;
+ }
+ } while (--aCount);
+ }
+ }
+ return 0;
+}
+
+
+/**
+ * This method compares the data in one buffer with another
+ * @update gess 01/04/99
+ * @param aStr1 is the first buffer to be compared
+ * @param aStr2 is the 2nd buffer to be compared
+ * @param aCount is the number of chars to compare
+ * @param aIgnoreCase tells us whether to use a case-sensitive comparison
+ * @return -1,0,1 depending on <,==,>
+ */
+inline PRInt32
+Compare1To2(const char* aStr1,const PRUnichar* aStr2,PRUint32 aCount,PRBool aIgnoreCase){
+ return Compare2To1(aStr2, aStr1, aCount, aIgnoreCase) * -1;
+}
+
+
+//-----------------------------------------------------------------------------
+//
+// This set of methods is used compress char sequences in a buffer...
+//
+
+
+/**
+ * This method compresses duplicate runs of a given char from the given buffer
+ *
+ * @update rickg 03.23.2000
+ * @param aString is the buffer to be manipulated
+ * @param aLength is the length of the buffer
+ * @param aSet tells us which chars to compress from given buffer
+ * @param aEliminateLeading tells us whether to strip chars from the start of the buffer
+ * @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
+ * @return the new length of the given buffer
+ */
+static PRInt32
+CompressChars1(char* aString,PRUint32 aLength,const char* aSet){
+
+ char* from = aString;
+ char* end = aString + aLength;
+ char* to = from;
+
+ //this code converts /n, /t, /r into normal space ' ';
+ //it also compresses runs of whitespace down to a single char...
+ if(aSet && aString && (0 < aLength)){
+ PRUint32 aSetLen=strlen(aSet);
+
+ while (from < end) {
+ char theChar = *from++;
+
+ *to++=theChar; //always copy this char...
+
+ if((kNotFound!=FindChar1(aSet,aSetLen,0,theChar,aSetLen))){
+ while (from < end) {
+ theChar = *from++;
+ if(kNotFound==FindChar1(aSet,aSetLen,0,theChar,aSetLen)){
+ *to++ = theChar;
+ break;
+ }
+ } //while
+ } //if
+ } //if
+ *to = 0;
+ }
+ return to - aString;
+}
+
+
+
+/**
+ * This method compresses duplicate runs of a given char from the given buffer
+ *
+ * @update rickg 03.23.2000
+ * @param aString is the buffer to be manipulated
+ * @param aLength is the length of the buffer
+ * @param aSet tells us which chars to compress from given buffer
+ * @param aEliminateLeading tells us whether to strip chars from the start of the buffer
+ * @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
+ * @return the new length of the given buffer
+ */
+static PRInt32
+CompressChars2(PRUnichar* aString,PRUint32 aLength,const char* aSet){
+
+ PRUnichar* from = aString;
+ PRUnichar* end = from + aLength;
+ PRUnichar* to = from;
+
+ //this code converts /n, /t, /r into normal space ' ';
+ //it also compresses runs of whitespace down to a single char...
+ if(aSet && aString && (0 < aLength)){
+ PRUint32 aSetLen=strlen(aSet);
+
+ while (from < end) {
+ PRUnichar theChar = *from++;
+
+ *to++=theChar; //always copy this char...
+
+ if((theChar<256) && (kNotFound!=FindChar1(aSet,aSetLen,0,theChar,aSetLen))){
+ while (from < end) {
+ theChar = *from++;
+ if(kNotFound==FindChar1(aSet,aSetLen,0,theChar,aSetLen)){
+ *to++ = theChar;
+ break;
+ }
+ } //while
+ } //if
+ } //if
+ *to = 0;
+ }
+ return to - (PRUnichar*)aString;
+}
+
+/**
+ * This method strips chars in a given set from the given buffer
+ *
+ * @update gess 01/04/99
+ * @param aString is the buffer to be manipulated
+ * @param aLength is the length of the buffer
+ * @param aSet tells us which chars to compress from given buffer
+ * @param aEliminateLeading tells us whether to strip chars from the start of the buffer
+ * @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
+ * @return the new length of the given buffer
+ */
+static PRInt32
+StripChars1(char* aString,PRUint32 aLength,const char* aSet){
+
+ // XXXdarin this code should defer writing until necessary.
+
+ char* to = aString;
+ char* from = aString-1;
+ char* end = aString + aLength;
+
+ if(aSet && aString && (0 < aLength)){
+ PRUint32 aSetLen=strlen(aSet);
+ while (++from < end) {
+ char theChar = *from;
+ if(kNotFound==FindChar1(aSet,aSetLen,0,theChar,aSetLen)){
+ *to++ = theChar;
+ }
+ }
+ *to = 0;
+ }
+ return to - (char*)aString;
+}
+
+
+/**
+ * This method strips chars in a given set from the given buffer
+ *
+ * @update gess 01/04/99
+ * @param aString is the buffer to be manipulated
+ * @param aLength is the length of the buffer
+ * @param aSet tells us which chars to compress from given buffer
+ * @param aEliminateLeading tells us whether to strip chars from the start of the buffer
+ * @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
+ * @return the new length of the given buffer
+ */
+static PRInt32
+StripChars2(PRUnichar* aString,PRUint32 aLength,const char* aSet){
+
+ // XXXdarin this code should defer writing until necessary.
+
+ PRUnichar* to = aString;
+ PRUnichar* from = aString-1;
+ PRUnichar* end = to + aLength;
+
+ if(aSet && aString && (0 < aLength)){
+ PRUint32 aSetLen=strlen(aSet);
+ while (++from < end) {
+ PRUnichar theChar = *from;
+ //Note the test for ascii range below. If you have a real unicode char,
+ //and you're searching for chars in the (given) ascii string, there's no
+ //point in doing the real search since it's out of the ascii range.
+ if((255<theChar) || (kNotFound==FindChar1(aSet,aSetLen,0,theChar,aSetLen))){
+ *to++ = theChar;
+ }
+ }
+ *to = 0;
+ }
+ return to - (PRUnichar*)aString;
+}
+
+/* ***** END RICKG BLOCK ***** */
+
+static const char* kWhitespace="\b\t\r\n ";
+
+// This function is used to implement FindCharInSet and friends
+template <class CharT>
+#ifndef __SUNPRO_CC
+static
+#endif /* !__SUNPRO_CC */
+CharT
+GetFindInSetFilter( const CharT* set)
+ {
+ CharT filter = ~CharT(0); // All bits set
+ while (*set) {
+ filter &= ~(*set);
+ ++set;
+ }
+ return filter;
+ }
+
+// This template class is used by our code to access rickg's buffer routines.
+template <class CharT> struct nsBufferRoutines {};
+
+NS_SPECIALIZE_TEMPLATE
+struct nsBufferRoutines<char>
+ {
+ static
+ PRInt32 compare( const char* a, const char* b, PRUint32 max, PRBool ic )
+ {
+ return Compare1To1(a, b, max, ic);
+ }
+
+ static
+ PRInt32 compare( const char* a, const PRUnichar* b, PRUint32 max, PRBool ic )
+ {
+ return Compare1To2(a, b, max, ic);
+ }
+
+ static
+ PRInt32 find_char( const char* s, PRUint32 max, PRInt32 offset, const PRUnichar c, PRInt32 count )
+ {
+ return FindChar1(s, max, offset, c, count);
+ }
+
+ static
+ PRInt32 rfind_char( const char* s, PRUint32 max, PRInt32 offset, const PRUnichar c, PRInt32 count )
+ {
+ return RFindChar1(s, max, offset, c, count);
+ }
+
+ static
+ char get_find_in_set_filter( const char* set )
+ {
+ return GetFindInSetFilter(set);
+ }
+
+ static
+ PRInt32 strip_chars( char* s, PRUint32 len, const char* set )
+ {
+ return StripChars1(s, len, set);
+ }
+
+ static
+ PRInt32 compress_chars( char* s, PRUint32 len, const char* set )
+ {
+ return CompressChars1(s, len, set);
+ }
+ };
+
+NS_SPECIALIZE_TEMPLATE
+struct nsBufferRoutines<PRUnichar>
+ {
+ static
+ PRInt32 compare( const PRUnichar* a, const PRUnichar* b, PRUint32 max, PRBool ic )
+ {
+ NS_ASSERTION(!ic, "no case-insensitive compare here");
+ return Compare2To2(a, b, max);
+ }
+
+ static
+ PRInt32 compare( const PRUnichar* a, const char* b, PRUint32 max, PRBool ic )
+ {
+ return Compare2To1(a, b, max, ic);
+ }
+
+ static
+ PRInt32 find_char( const PRUnichar* s, PRUint32 max, PRInt32 offset, const PRUnichar c, PRInt32 count )
+ {
+ return FindChar2(s, max, offset, c, count);
+ }
+
+ static
+ PRInt32 rfind_char( const PRUnichar* s, PRUint32 max, PRInt32 offset, const PRUnichar c, PRInt32 count )
+ {
+ return RFindChar2(s, max, offset, c, count);
+ }
+
+ static
+ PRUnichar get_find_in_set_filter( const PRUnichar* set )
+ {
+ return GetFindInSetFilter(set);
+ }
+
+ static
+ PRUnichar get_find_in_set_filter( const char* set )
+ {
+ return (~PRUnichar(0)^~char(0)) | GetFindInSetFilter(set);
+ }
+
+ static
+ PRInt32 strip_chars( PRUnichar* s, PRUint32 max, const char* set )
+ {
+ return StripChars2(s, max, set);
+ }
+
+ static
+ PRInt32 compress_chars( PRUnichar* s, PRUint32 len, const char* set )
+ {
+ return CompressChars2(s, len, set);
+ }
+ };
+
+//-----------------------------------------------------------------------------
+
+template <class L, class R>
+#ifndef __SUNPRO_CC
+static
+#endif /* !__SUNPRO_CC */
+PRInt32
+FindSubstring( const L* big, PRUint32 bigLen,
+ const R* little, PRUint32 littleLen,
+ PRBool ignoreCase )
+ {
+ if (littleLen > bigLen)
+ return kNotFound;
+
+ PRInt32 i, max = PRInt32(bigLen - littleLen);
+ for (i=0; i<=max; ++i, ++big)
+ {
+ if (nsBufferRoutines<L>::compare(big, little, littleLen, ignoreCase) == 0)
+ return i;
+ }
+
+ return kNotFound;
+ }
+
+template <class L, class R>
+#ifndef __SUNPRO_CC
+static
+#endif /* !__SUNPRO_CC */
+PRInt32
+RFindSubstring( const L* big, PRUint32 bigLen,
+ const R* little, PRUint32 littleLen,
+ PRBool ignoreCase )
+ {
+ if (littleLen > bigLen)
+ return kNotFound;
+
+ PRInt32 i, max = PRInt32(bigLen - littleLen);
+
+ const L* iter = big + max;
+ for (i=max; iter >= big; --i, --iter)
+ {
+ if (nsBufferRoutines<L>::compare(iter, little, littleLen, ignoreCase) == 0)
+ return i;
+ }
+
+ return kNotFound;
+ }
+
+template <class CharT, class SetCharT>
+#ifndef __SUNPRO_CC
+static
+#endif /* !__SUNPRO_CC */
+PRInt32
+FindCharInSet( const CharT* data, PRUint32 dataLen, const SetCharT* set )
+ {
+ CharT filter = nsBufferRoutines<CharT>::get_find_in_set_filter(set);
+
+ const CharT* end = data + dataLen;
+ for (const CharT* iter = data; iter < end; ++iter)
+ {
+ CharT currentChar = *iter;
+ if (currentChar & filter)
+ continue; // char is not in filter set; go on with next char.
+
+ // test all chars
+ const SetCharT* charInSet = set;
+ CharT setChar = CharT(*charInSet);
+ while (setChar)
+ {
+ if (setChar == currentChar)
+ return iter - data; // found it! return index of the found char.
+
+ setChar = CharT(*(++charInSet));
+ }
+ }
+ return kNotFound;
+ }
+
+template <class CharT, class SetCharT>
+#ifndef __SUNPRO_CC
+static
+#endif /* !__SUNPRO_CC */
+PRInt32
+RFindCharInSet( const CharT* data, PRUint32 dataLen, const SetCharT* set )
+ {
+ CharT filter = nsBufferRoutines<CharT>::get_find_in_set_filter(set);
+
+ for (const CharT* iter = data + dataLen - 1; iter >= data; --iter)
+ {
+ CharT currentChar = *iter;
+ if (currentChar & filter)
+ continue; // char is not in filter set; go on with next char.
+
+ // test all chars
+ const CharT* charInSet = set;
+ CharT setChar = *charInSet;
+ while (setChar)
+ {
+ if (setChar == currentChar)
+ return iter - data; // found it! return index of the found char.
+
+ setChar = *(++charInSet);
+ }
+ }
+ return kNotFound;
+ }
+
+/**
+ * This is a copy of |PR_cnvtf| with a bug fixed. (The second argument
+ * of PR_dtoa is 2 rather than 1.)
+ *
+ * XXXdarin if this is the right thing, then why wasn't it fixed in NSPR?!?
+ */
+void
+Modified_cnvtf(char *buf, int bufsz, int prcsn, double fval)
+{
+ PRIntn decpt, sign, numdigits;
+ char *num, *nump;
+ char *bufp = buf;
+ char *endnum;
+
+ /* If anything fails, we store an empty string in 'buf' */
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+ num = (char*)RTMemAlloc(bufsz);
+#else
+ num = (char*)malloc(bufsz);
+#endif
+ if (num == NULL) {
+ buf[0] = '\0';
+ return;
+ }
+ if (PR_dtoa(fval, 2, prcsn, &decpt, &sign, &endnum, num, bufsz)
+ == PR_FAILURE) {
+ buf[0] = '\0';
+ goto done;
+ }
+ numdigits = endnum - num;
+ nump = num;
+
+ /*
+ * The NSPR code had a fancy way of checking that we weren't dealing
+ * with -0.0 or -NaN, but I'll just use < instead.
+ * XXX Should we check !isnan(fval) as well? Is it portable? We
+ * probably don't need to bother since NAN isn't portable.
+ */
+ if (sign && fval < 0.0f) {
+ *bufp++ = '-';
+ }
+
+ if (decpt == 9999) {
+ while ((*bufp++ = *nump++) != 0) {} /* nothing to execute */
+ goto done;
+ }
+
+ if (decpt > (prcsn+1) || decpt < -(prcsn-1) || decpt < -5) {
+ *bufp++ = *nump++;
+ if (numdigits != 1) {
+ *bufp++ = '.';
+ }
+
+ while (*nump != '\0') {
+ *bufp++ = *nump++;
+ }
+ *bufp++ = 'e';
+ PR_snprintf(bufp, bufsz - (bufp - buf), "%+d", decpt-1);
+ }
+ else if (decpt >= 0) {
+ if (decpt == 0) {
+ *bufp++ = '0';
+ }
+ else {
+ while (decpt--) {
+ if (*nump != '\0') {
+ *bufp++ = *nump++;
+ }
+ else {
+ *bufp++ = '0';
+ }
+ }
+ }
+ if (*nump != '\0') {
+ *bufp++ = '.';
+ while (*nump != '\0') {
+ *bufp++ = *nump++;
+ }
+ }
+ *bufp++ = '\0';
+ }
+ else if (decpt < 0) {
+ *bufp++ = '0';
+ *bufp++ = '.';
+ while (decpt++) {
+ *bufp++ = '0';
+ }
+
+ while (*nump != '\0') {
+ *bufp++ = *nump++;
+ }
+ *bufp++ = '\0';
+ }
+done:
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+ RTMemFree(num);
+#else
+ free(num);
+#endif
+}
+
+ /**
+ * this method changes the meaning of |offset| and |count|:
+ *
+ * upon return,
+ * |offset| specifies start of search range
+ * |count| specifies length of search range
+ */
+static void
+Find_ComputeSearchRange( PRUint32 bigLen, PRUint32 littleLen, PRInt32& offset, PRInt32& count )
+ {
+ // |count| specifies how many iterations to make from |offset|
+
+ if (offset < 0)
+ {
+ offset = 0;
+ }
+ else if (PRUint32(offset) > bigLen)
+ {
+ count = 0;
+ return;
+ }
+
+ PRInt32 maxCount = bigLen - offset;
+ if (count < 0 || count > maxCount)
+ {
+ count = maxCount;
+ }
+ else
+ {
+ count += littleLen;
+ if (count > maxCount)
+ count = maxCount;
+ }
+ }
+
+ /**
+ * this method changes the meaning of |offset| and |count|:
+ *
+ * upon entry,
+ * |offset| specifies the end point from which to search backwards
+ * |count| specifies the number of iterations from |offset|
+ *
+ * upon return,
+ * |offset| specifies start of search range
+ * |count| specifies length of search range
+ *
+ *
+ * EXAMPLE
+ *
+ * + -- littleLen=4 -- +
+ * : :
+ * |____|____|____|____|____|____|____|____|____|____|____|____|
+ * : :
+ * offset=5 bigLen=12
+ *
+ * if count = 4, then we expect this function to return offset = 2 and
+ * count = 7.
+ *
+ */
+static void
+RFind_ComputeSearchRange( PRUint32 bigLen, PRUint32 littleLen, PRInt32& offset, PRInt32& count )
+ {
+ if (littleLen > bigLen)
+ {
+ offset = 0;
+ count = 0;
+ return;
+ }
+
+ if (offset < 0)
+ offset = bigLen - littleLen;
+ if (count < 0)
+ count = offset + 1;
+
+ PRInt32 start = offset - count + 1;
+ if (start < 0)
+ start = 0;
+
+ count = offset + littleLen - start;
+ offset = start;
+ }
+
+//-----------------------------------------------------------------------------
+
+ // define nsString obsolete methods
+#include "string-template-def-unichar.h"
+#include "nsTStringObsolete.cpp"
+#include "string-template-undef.h"
+
+ // define nsCString obsolete methods
+#include "string-template-def-char.h"
+#include "nsTStringObsolete.cpp"
+#include "string-template-undef.h"
+
+//-----------------------------------------------------------------------------
+
+// specialized methods:
+
+PRInt32
+nsString::Find( const nsAFlatString& aString, PRInt32 aOffset, PRInt32 aCount ) const
+ {
+ // this method changes the meaning of aOffset and aCount:
+ Find_ComputeSearchRange(mLength, aString.Length(), aOffset, aCount);
+
+ PRInt32 result = FindSubstring(mData + aOffset, aCount, aString.get(), aString.Length(), PR_FALSE);
+ if (result != kNotFound)
+ result += aOffset;
+ return result;
+ }
+
+PRInt32
+nsString::Find( const PRUnichar* aString, PRInt32 aOffset, PRInt32 aCount ) const
+ {
+ return Find(nsDependentString(aString), aOffset, aCount);
+ }
+
+PRInt32
+nsString::RFind( const nsAFlatString& aString, PRInt32 aOffset, PRInt32 aCount ) const
+ {
+ // this method changes the meaning of aOffset and aCount:
+ RFind_ComputeSearchRange(mLength, aString.Length(), aOffset, aCount);
+
+ PRInt32 result = RFindSubstring(mData + aOffset, aCount, aString.get(), aString.Length(), PR_FALSE);
+ if (result != kNotFound)
+ result += aOffset;
+ return result;
+ }
+
+PRInt32
+nsString::RFind( const PRUnichar* aString, PRInt32 aOffset, PRInt32 aCount ) const
+ {
+ return RFind(nsDependentString(aString), aOffset, aCount);
+ }
+
+PRInt32
+nsString::FindCharInSet( const PRUnichar* aSet, PRInt32 aOffset ) const
+ {
+ if (aOffset < 0)
+ aOffset = 0;
+ else if (aOffset >= PRInt32(mLength))
+ return kNotFound;
+
+ PRInt32 result = ::FindCharInSet(mData + aOffset, mLength - aOffset, aSet);
+ if (result != kNotFound)
+ result += aOffset;
+ return result;
+ }
+
+
+ /**
+ * nsTString::Compare,CompareWithConversion,etc.
+ */
+
+PRInt32
+nsCString::Compare( const char* aString, PRBool aIgnoreCase, PRInt32 aCount ) const
+ {
+ PRUint32 strLen = char_traits::length(aString);
+
+ PRInt32 maxCount = PRInt32(NS_MIN(mLength, strLen));
+
+ PRInt32 compareCount;
+ if (aCount < 0 || aCount > maxCount)
+ compareCount = maxCount;
+ else
+ compareCount = aCount;
+
+ PRInt32 result =
+ nsBufferRoutines<char>::compare(mData, aString, compareCount, aIgnoreCase);
+
+ if (result == 0 &&
+ (aCount < 0 || strLen < PRUint32(aCount) || mLength < PRUint32(aCount)))
+ {
+ // Since the caller didn't give us a length to test, or strings shorter
+ // than aCount, and compareCount characters matched, we have to assume
+ // that the longer string is greater.
+
+ if (mLength != strLen)
+ result = (mLength < strLen) ? -1 : 1;
+ }
+ return result;
+ }
+
+PRBool
+nsString::EqualsIgnoreCase( const char* aString, PRInt32 aCount ) const
+ {
+ PRUint32 strLen = nsCharTraits<char>::length(aString);
+
+ PRInt32 maxCount = PRInt32(NS_MIN(mLength, strLen));
+
+ PRInt32 compareCount;
+ if (aCount < 0 || aCount > maxCount)
+ compareCount = maxCount;
+ else
+ compareCount = aCount;
+
+ PRInt32 result =
+ nsBufferRoutines<PRUnichar>::compare(mData, aString, compareCount, PR_TRUE);
+
+ if (result == 0 &&
+ (aCount < 0 || strLen < PRUint32(aCount) || mLength < PRUint32(aCount)))
+ {
+ // Since the caller didn't give us a length to test, or strings shorter
+ // than aCount, and compareCount characters matched, we have to assume
+ // that the longer string is greater.
+
+ if (mLength != strLen)
+ result = 1; // Arbitrarily using any number != 0
+ }
+ return result == 0;
+ }
+
+ /**
+ * ToCString, ToFloat, ToInteger
+ */
+
+char*
+nsString::ToCString( char* aBuf, PRUint32 aBufLength, PRUint32 aOffset ) const
+ {
+ // because the old implementation checked aBuf
+ if (!(aBuf && aBufLength > 0 && aOffset <= mLength))
+ return nsnull;
+
+ PRUint32 maxCount = NS_MIN(aBufLength-1, mLength - aOffset);
+
+ LossyConvertEncoding<PRUnichar, char> converter(aBuf);
+ converter.write(mData + aOffset, maxCount);
+ converter.write_terminator();
+ return aBuf;
+ }
+
+float
+nsCString::ToFloat(PRInt32* aErrorCode) const
+ {
+ float res = 0.0f;
+ if (mLength > 0)
+ {
+ char *conv_stopped;
+ const char *str = mData;
+ // Use PR_strtod, not strtod, since we don't want locale involved.
+ res = (float)PR_strtod(str, &conv_stopped);
+ if (conv_stopped == str+mLength)
+ *aErrorCode = (PRInt32) NS_OK;
+ else // Not all the string was scanned
+ *aErrorCode = (PRInt32) NS_ERROR_ILLEGAL_VALUE;
+ }
+ else
+ {
+ // The string was too short (0 characters)
+ *aErrorCode = (PRInt32) NS_ERROR_ILLEGAL_VALUE;
+ }
+ return res;
+ }
+
+float
+nsString::ToFloat(PRInt32* aErrorCode) const
+ {
+ float res = 0.0f;
+ char buf[100];
+ if (mLength > 0 && mLength < sizeof(buf))
+ {
+ char *conv_stopped;
+ const char *str = ToCString(buf, sizeof(buf));
+ // Use PR_strtod, not strtod, since we don't want locale involved.
+ res = (float)PR_strtod(str, &conv_stopped);
+ if (conv_stopped == str+mLength)
+ *aErrorCode = (PRInt32) NS_OK;
+ else // Not all the string was scanned
+ *aErrorCode = (PRInt32) NS_ERROR_ILLEGAL_VALUE;
+ }
+ else
+ {
+ // The string was too short (0 characters) or too long (sizeof(buf))
+ *aErrorCode = (PRInt32) NS_ERROR_ILLEGAL_VALUE;
+ }
+ return res;
+ }
+
+
+ /**
+ * nsTString::AssignWithConversion
+ */
+
+void
+nsCString::AssignWithConversion( const nsAString& aData )
+ {
+ LossyCopyUTF16toASCII(aData, *this);
+ }
+
+void
+nsString::AssignWithConversion( const nsACString& aData )
+ {
+ CopyASCIItoUTF16(aData, *this);
+ }
+
+
+ /**
+ * nsTString::AppendWithConversion
+ */
+
+void
+nsCString::AppendWithConversion( const nsAString& aData )
+ {
+ LossyAppendUTF16toASCII(aData, *this);
+ }
+
+void
+nsString::AppendWithConversion( const nsACString& aData )
+ {
+ AppendASCIItoUTF16(aData, *this);
+ }
+
+
+ /**
+ * nsTString::AppendInt
+ */
+
+void
+nsCString::AppendInt( PRInt32 aInteger, PRInt32 aRadix )
+ {
+ char buf[20];
+ const char* fmt;
+ switch (aRadix) {
+ case 8:
+ fmt = "%o";
+ break;
+ case 10:
+ fmt = "%d";
+ break;
+ default:
+ NS_ASSERTION(aRadix == 16, "Invalid radix!");
+ fmt = "%x";
+ }
+ PR_snprintf(buf, sizeof(buf), fmt, aInteger);
+ Append(buf);
+ }
+
+void
+nsString::AppendInt( PRInt32 aInteger, PRInt32 aRadix )
+ {
+ char buf[20];
+ const char* fmt;
+ switch (aRadix) {
+ case 8:
+ fmt = "%o";
+ break;
+ case 10:
+ fmt = "%d";
+ break;
+ default:
+ NS_ASSERTION(aRadix == 16, "Invalid radix!");
+ fmt = "%x";
+ }
+ PR_snprintf(buf, sizeof(buf), fmt, aInteger);
+ AppendASCIItoUTF16(buf, *this);
+ }
+
+void
+nsCString::AppendInt( PRInt64 aInteger, PRInt32 aRadix )
+ {
+ char buf[30];
+ const char* fmt;
+ switch (aRadix) {
+ case 8:
+ fmt = "%llo";
+ break;
+ case 10:
+ fmt = "%lld";
+ break;
+ default:
+ NS_ASSERTION(aRadix == 16, "Invalid radix!");
+ fmt = "%llx";
+ }
+ PR_snprintf(buf, sizeof(buf), fmt, aInteger);
+ Append(buf);
+ }
+
+void
+nsString::AppendInt( PRInt64 aInteger, PRInt32 aRadix )
+ {
+ char buf[30];
+ const char* fmt;
+ switch (aRadix) {
+ case 8:
+ fmt = "%llo";
+ break;
+ case 10:
+ fmt = "%lld";
+ break;
+ default:
+ NS_ASSERTION(aRadix == 16, "Invalid radix!");
+ fmt = "%llx";
+ }
+ PR_snprintf(buf, sizeof(buf), fmt, aInteger);
+ AppendASCIItoUTF16(buf, *this);
+ }
+
+ /**
+ * nsTString::AppendFloat
+ */
+
+void
+nsCString::AppendFloat( double aFloat )
+ {
+ char buf[40];
+ // Use Modified_cnvtf, which is locale-insensitive, instead of the
+ // locale-sensitive PR_snprintf or sprintf(3)
+ Modified_cnvtf(buf, sizeof(buf), 6, aFloat);
+ Append(buf);
+ }
+
+void
+nsString::AppendFloat( double aFloat )
+ {
+ char buf[40];
+ // Use Modified_cnvtf, which is locale-insensitive, instead of the
+ // locale-sensitive PR_snprintf or sprintf(3)
+ Modified_cnvtf(buf, sizeof(buf), 6, aFloat);
+ AppendWithConversion(buf);
+ }
+
+#endif // !MOZ_STRING_WITH_OBSOLETE_API
diff --git a/src/libs/xpcom18a4/xpcom/string/src/nsSubstring.cpp b/src/libs/xpcom18a4/xpcom/string/src/nsSubstring.cpp
new file mode 100644
index 00000000..6ed0c5c8
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/src/nsSubstring.cpp
@@ -0,0 +1,250 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifdef DEBUG
+#define ENABLE_STRING_STATS
+#endif
+
+#ifdef ENABLE_STRING_STATS
+#include <stdio.h>
+#endif
+
+#include <stdlib.h>
+#include "nsSubstring.h"
+#include "nsString.h"
+#include "nsDependentString.h"
+#include "nsMemory.h"
+#include "pratom.h"
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+# include <iprt/mem.h>
+#endif
+
+// ---------------------------------------------------------------------------
+
+static const PRUnichar gNullChar = 0;
+
+const char* nsCharTraits<char> ::sEmptyBuffer = (const char*) &gNullChar;
+const PRUnichar* nsCharTraits<PRUnichar>::sEmptyBuffer = &gNullChar;
+
+// ---------------------------------------------------------------------------
+
+#ifdef ENABLE_STRING_STATS
+class nsStringStats
+ {
+ public:
+ nsStringStats()
+ : mAllocCount(0), mReallocCount(0), mFreeCount(0), mShareCount(0) {}
+
+ ~nsStringStats()
+ {
+ // this is a hack to suppress duplicate string stats printing
+ // in seamonkey as a result of the string code being linked
+ // into seamonkey and libxpcom! :-(
+ if (!mAllocCount && !mAdoptCount)
+ return;
+
+#ifndef VBOX
+ printf("nsStringStats\n");
+ printf(" => mAllocCount: % 10d\n", mAllocCount);
+ printf(" => mReallocCount: % 10d\n", mReallocCount);
+ printf(" => mFreeCount: % 10d", mFreeCount);
+ if (mAllocCount > mFreeCount)
+ printf(" -- LEAKED %d !!!\n", mAllocCount - mFreeCount);
+ else
+ printf("\n");
+ printf(" => mShareCount: % 10d\n", mShareCount);
+ printf(" => mAdoptCount: % 10d\n", mAdoptCount);
+ printf(" => mAdoptFreeCount: % 10d", mAdoptFreeCount);
+ if (mAdoptCount > mAdoptFreeCount)
+ printf(" -- LEAKED %d !!!\n", mAdoptCount - mAdoptFreeCount);
+ else
+ printf("\n");
+#endif
+ }
+
+ PRInt32 mAllocCount;
+ PRInt32 mReallocCount;
+ PRInt32 mFreeCount;
+ PRInt32 mShareCount;
+ PRInt32 mAdoptCount;
+ PRInt32 mAdoptFreeCount;
+ };
+static nsStringStats gStringStats;
+#define STRING_STAT_INCREMENT(_s) PR_AtomicIncrement(&gStringStats.m ## _s ## Count)
+#else
+#define STRING_STAT_INCREMENT(_s)
+#endif
+
+// ---------------------------------------------------------------------------
+
+ /**
+ * This structure precedes the string buffers "we" allocate. It may be the
+ * case that nsTSubstring::mData does not point to one of these special
+ * buffers. The mFlags member variable distinguishes the buffer type.
+ *
+ * When this header is in use, it enables reference counting, and capacity
+ * tracking. NOTE: A string buffer can be modified only if its reference
+ * count is 1.
+ */
+class nsStringHeader
+ {
+ private:
+
+ PRInt32 mRefCount;
+ PRUint32 mStorageSize;
+
+ public:
+
+ void AddRef()
+ {
+ PR_AtomicIncrement(&mRefCount);
+ STRING_STAT_INCREMENT(Share);
+ }
+
+ void Release()
+ {
+ if (PR_AtomicDecrement(&mRefCount) == 0)
+ {
+ STRING_STAT_INCREMENT(Free);
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+ RTMemFree(this); // we were allocated with |malloc|
+#else
+ free(this); // we were allocated with |malloc|
+#endif
+ }
+ }
+
+ /**
+ * Alloc returns a pointer to a new string header with set capacity.
+ */
+ static nsStringHeader* Alloc(size_t size)
+ {
+ STRING_STAT_INCREMENT(Alloc);
+
+ NS_ASSERTION(size != 0, "zero capacity allocation not allowed");
+
+ nsStringHeader *hdr =
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+ (nsStringHeader *) RTMemAlloc(sizeof(nsStringHeader) + size);
+#else
+ (nsStringHeader *) malloc(sizeof(nsStringHeader) + size);
+#endif
+ if (hdr)
+ {
+ hdr->mRefCount = 1;
+ hdr->mStorageSize = size;
+ }
+ return hdr;
+ }
+
+ static nsStringHeader* Realloc(nsStringHeader* hdr, size_t size)
+ {
+ STRING_STAT_INCREMENT(Realloc);
+
+ NS_ASSERTION(size != 0, "zero capacity allocation not allowed");
+
+ // no point in trying to save ourselves if we hit this assertion
+ NS_ASSERTION(!hdr->IsReadonly(), "|Realloc| attempted on readonly string");
+
+#ifdef VBOX_USE_IPRT_IN_XPCOM
+ hdr = (nsStringHeader*) RTMemRealloc(hdr, sizeof(nsStringHeader) + size);
+#else
+ hdr = (nsStringHeader*) realloc(hdr, sizeof(nsStringHeader) + size);
+#endif
+ if (hdr)
+ hdr->mStorageSize = size;
+
+ return hdr;
+ }
+
+ static nsStringHeader* FromData(void* data)
+ {
+ return (nsStringHeader*) ( ((char*) data) - sizeof(nsStringHeader) );
+ }
+
+ void* Data() const
+ {
+ return (void*) ( ((char*) this) + sizeof(nsStringHeader) );
+ }
+
+ PRUint32 StorageSize() const
+ {
+ return mStorageSize;
+ }
+
+ /**
+ * Because nsTSubstring allows only single threaded access, if this
+ * method returns FALSE, then the caller can be sure that it has
+ * exclusive access to the nsStringHeader and associated data.
+ * However, if this function returns TRUE, then other strings may
+ * rely on the data in this buffer being constant and other threads
+ * may access this buffer simultaneously.
+ */
+ PRBool IsReadonly() const
+ {
+ return mRefCount > 1;
+ }
+ };
+
+// ---------------------------------------------------------------------------
+
+inline void
+ReleaseData( void* data, PRUint32 flags )
+ {
+ if (flags & nsSubstring::F_SHARED)
+ {
+ nsStringHeader::FromData(data)->Release();
+ }
+ else if (flags & nsSubstring::F_OWNED)
+ {
+ nsMemory::Free(data);
+ STRING_STAT_INCREMENT(AdoptFree);
+ }
+ // otherwise, nothing to do.
+ }
+
+
+ // define nsSubstring
+#include "string-template-def-unichar.h"
+#include "nsTSubstring.cpp"
+#include "string-template-undef.h"
+
+ // define nsCSubstring
+#include "string-template-def-char.h"
+#include "nsTSubstring.cpp"
+#include "string-template-undef.h"
diff --git a/src/libs/xpcom18a4/xpcom/string/src/nsSubstringTuple.cpp b/src/libs/xpcom18a4/xpcom/string/src/nsSubstringTuple.cpp
new file mode 100644
index 00000000..a5445d7a
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/src/nsSubstringTuple.cpp
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsSubstringTuple.h"
+
+#if 0
+ // convert fragment to |const string_base_type&|
+#define TO_SUBSTRING(_v) \
+ ( (ptrdiff_t(_v) & 0x1) \
+ ? NS_REINTERPRET_CAST(const abstract_string_type*, \
+ ((unsigned long)_v & ~0x1))->ToSubstring() \
+ : *NS_REINTERPRET_CAST(const substring_type*, (_v)) )
+#endif
+
+ // convert fragment to |const substring_type&|
+#define TO_SUBSTRING(_v) \
+ ( (_v)->mVTable == obsolete_string_type::sCanonicalVTable \
+ ? *(_v)->AsSubstring() \
+ : (_v)->ToSubstring() )
+
+ // define nsSubstringTuple
+#include "string-template-def-unichar.h"
+#include "nsTSubstringTuple.cpp"
+#include "string-template-undef.h"
+
+ // define nsCSubstringTuple
+#include "string-template-def-char.h"
+#include "nsTSubstringTuple.cpp"
+#include "string-template-undef.h"
diff --git a/src/libs/xpcom18a4/xpcom/string/src/nsTAString.cpp b/src/libs/xpcom18a4/xpcom/string/src/nsTAString.cpp
new file mode 100644
index 00000000..ffd75fe8
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/src/nsTAString.cpp
@@ -0,0 +1,509 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+ /**
+ * Some comments on this implementation...
+ *
+ * This class is a bridge between the old string implementation and the new
+ * string implementation. If mVTable points to the canonical vtable for the
+ * new string implementation, then we can cast directly to the new string
+ * classes (helped by the AsSubstring() methods). However, if mVTable is not
+ * ours, then we need to call through the vtable to satisfy the nsTAString
+ * methods.
+ *
+ * In most cases we will avoid the vtable.
+ */
+
+
+nsTAString_CharT::~nsTAString_CharT()
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->Finalize();
+ else
+ AsObsoleteString()->~nsTObsoleteAString_CharT();
+ }
+
+
+nsTAString_CharT::size_type
+nsTAString_CharT::Length() const
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ return AsSubstring()->Length();
+
+ return AsObsoleteString()->Length();
+ }
+
+PRBool
+nsTAString_CharT::Equals( const self_type& readable ) const
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ return AsSubstring()->Equals(readable);
+
+ return ToSubstring().Equals(readable);
+ }
+
+PRBool
+nsTAString_CharT::Equals( const self_type& readable, const comparator_type& comparator ) const
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ return AsSubstring()->Equals(readable, comparator);
+
+ return ToSubstring().Equals(readable, comparator);
+ }
+
+PRBool
+nsTAString_CharT::Equals( const char_type* data ) const
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ return AsSubstring()->Equals(data);
+
+ return ToSubstring().Equals(data);
+ }
+
+PRBool
+nsTAString_CharT::Equals( const char_type* data, const comparator_type& comparator ) const
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ return AsSubstring()->Equals(data, comparator);
+
+ return ToSubstring().Equals(data, comparator);
+ }
+
+PRBool
+nsTAString_CharT::EqualsASCII( const char* data, size_type len ) const
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ return AsSubstring()->EqualsASCII(data, len);
+
+ return ToSubstring().EqualsASCII(data, len);
+ }
+
+PRBool
+nsTAString_CharT::EqualsASCII( const char* data ) const
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ return AsSubstring()->EqualsASCII(data);
+
+ return ToSubstring().EqualsASCII(data);
+ }
+
+PRBool
+nsTAString_CharT::LowerCaseEqualsASCII( const char* data, size_type len ) const
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ return AsSubstring()->LowerCaseEqualsASCII(data, len);
+
+ return ToSubstring().LowerCaseEqualsASCII(data, len);
+ }
+
+PRBool
+nsTAString_CharT::LowerCaseEqualsASCII( const char* data ) const
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ return AsSubstring()->LowerCaseEqualsASCII(data);
+
+ return ToSubstring().LowerCaseEqualsASCII(data);
+ }
+
+PRBool
+nsTAString_CharT::IsVoid() const
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ return AsSubstring()->IsVoid();
+
+ return AsObsoleteString()->IsVoid();
+ }
+
+void
+nsTAString_CharT::SetIsVoid( PRBool val )
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->SetIsVoid(val);
+ else
+ AsObsoleteString()->SetIsVoid(val);
+ }
+
+PRBool
+nsTAString_CharT::IsTerminated() const
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ return AsSubstring()->IsTerminated();
+
+ return AsObsoleteString()->GetFlatBufferHandle() != nsnull;
+ }
+
+CharT
+nsTAString_CharT::First() const
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ return AsSubstring()->First();
+
+ return ToSubstring().First();
+ }
+
+CharT
+nsTAString_CharT::Last() const
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ return AsSubstring()->Last();
+
+ return ToSubstring().Last();
+ }
+
+nsTAString_CharT::size_type
+nsTAString_CharT::CountChar( char_type c ) const
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ return AsSubstring()->CountChar(c);
+
+ return ToSubstring().CountChar(c);
+ }
+
+PRInt32
+nsTAString_CharT::FindChar( char_type c, index_type offset ) const
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ return AsSubstring()->FindChar(c, offset);
+
+ return ToSubstring().FindChar(c, offset);
+ }
+
+void
+nsTAString_CharT::SetCapacity( size_type size )
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->SetCapacity(size);
+ else
+ AsObsoleteString()->SetCapacity(size);
+ }
+
+void
+nsTAString_CharT::SetLength( size_type size )
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->SetLength(size);
+ else
+ AsObsoleteString()->SetLength(size);
+ }
+
+void
+nsTAString_CharT::Assign( const self_type& readable )
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->Assign(readable);
+ else
+ AsObsoleteString()->do_AssignFromReadable(readable);
+ }
+
+void
+nsTAString_CharT::Assign( const substring_tuple_type& tuple )
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->Assign(tuple);
+ else
+ AsObsoleteString()->do_AssignFromReadable(nsTAutoString_CharT(tuple));
+ }
+
+void
+nsTAString_CharT::Assign( const char_type* data )
+ {
+ // null check and SetLength(0) cases needed for backwards compat
+
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->Assign(data);
+ else if (data)
+ AsObsoleteString()->do_AssignFromElementPtr(data);
+ else
+ AsObsoleteString()->SetLength(0);
+ }
+
+void
+nsTAString_CharT::Assign( const char_type* data, size_type length )
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->Assign(data, length);
+ else
+ AsObsoleteString()->do_AssignFromElementPtrLength(data, length);
+ }
+
+void
+nsTAString_CharT::AssignASCII( const char* data )
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->AssignASCII(data);
+ else
+ {
+#ifdef CharT_is_char
+ AsObsoleteString()->do_AssignFromElementPtr(data);
+#else
+ nsTAutoString_CharT temp;
+ temp.AssignASCII(data);
+ AsObsoleteString()->do_AssignFromReadable(temp);
+#endif
+ }
+ }
+
+void
+nsTAString_CharT::AssignASCII( const char* data, size_type length )
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->AssignASCII(data, length);
+ else
+ {
+#ifdef CharT_is_char
+ AsObsoleteString()->do_AssignFromElementPtrLength(data, length);
+#else
+ nsTAutoString_CharT temp;
+ temp.AssignASCII(data, length);
+ AsObsoleteString()->do_AssignFromReadable(temp);
+#endif
+ }
+ }
+
+void
+nsTAString_CharT::Assign( char_type c )
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->Assign(c);
+ else
+ AsObsoleteString()->do_AssignFromElement(c);
+ }
+
+void
+nsTAString_CharT::Append( const self_type& readable )
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->Append(readable);
+ else
+ AsObsoleteString()->do_AppendFromReadable(readable);
+ }
+
+void
+nsTAString_CharT::Append( const substring_tuple_type& tuple )
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->Append(tuple);
+ else
+ AsObsoleteString()->do_AppendFromReadable(nsTAutoString_CharT(tuple));
+ }
+
+void
+nsTAString_CharT::Append( const char_type* data )
+ {
+ // null check case needed for backwards compat
+
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->Append(data);
+ else if (data)
+ AsObsoleteString()->do_AppendFromElementPtr(data);
+ }
+
+void
+nsTAString_CharT::Append( const char_type* data, size_type length )
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->Append(data, length);
+ else
+ AsObsoleteString()->do_AppendFromElementPtrLength(data, length);
+ }
+
+void
+nsTAString_CharT::AppendASCII( const char* data )
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->AppendASCII(data);
+ else
+ {
+#ifdef CharT_is_char
+ AsObsoleteString()->do_AppendFromElementPtr(data);
+#else
+ nsTAutoString_CharT temp;
+ temp.AssignASCII(data);
+ AsObsoleteString()->do_AppendFromReadable(temp);
+#endif
+ }
+ }
+
+void
+nsTAString_CharT::AppendASCII( const char* data, size_type length )
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->AppendASCII(data, length);
+ else
+ {
+#ifdef CharT_is_char
+ AsObsoleteString()->do_AppendFromElementPtrLength(data, length);
+#else
+ nsTAutoString_CharT temp;
+ temp.AssignASCII(data, length);
+ AsObsoleteString()->do_AppendFromReadable(temp);
+#endif
+ }
+ }
+
+void
+nsTAString_CharT::Append( char_type c )
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->Append(c);
+ else
+ AsObsoleteString()->do_AppendFromElement(c);
+ }
+
+void
+nsTAString_CharT::Insert( const self_type& readable, index_type pos )
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->Insert(readable, pos);
+ else
+ AsObsoleteString()->do_InsertFromReadable(readable, pos);
+ }
+
+void
+nsTAString_CharT::Insert( const substring_tuple_type& tuple, index_type pos )
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->Insert(tuple, pos);
+ else
+ AsObsoleteString()->do_InsertFromReadable(nsTAutoString_CharT(tuple), pos);
+ }
+
+void
+nsTAString_CharT::Insert( const char_type* data, index_type pos )
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->Insert(data, pos);
+ else
+ AsObsoleteString()->do_InsertFromElementPtr(data, pos);
+ }
+
+void
+nsTAString_CharT::Insert( const char_type* data, index_type pos, size_type length )
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->Insert(data, pos, length);
+ else
+ AsObsoleteString()->do_InsertFromElementPtrLength(data, pos, length);
+ }
+
+void
+nsTAString_CharT::Insert( char_type c, index_type pos )
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->Insert(c, pos);
+ else
+ AsObsoleteString()->do_InsertFromElement(c, pos);
+ }
+
+void
+nsTAString_CharT::Cut( index_type cutStart, size_type cutLength )
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->Cut(cutStart, cutLength);
+ else
+ AsObsoleteString()->Cut(cutStart, cutLength);
+ }
+
+void
+nsTAString_CharT::Replace( index_type cutStart, size_type cutLength, const self_type& readable )
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->Replace(cutStart, cutLength, readable);
+ else
+ AsObsoleteString()->do_ReplaceFromReadable(cutStart, cutLength, readable);
+ }
+
+void
+nsTAString_CharT::Replace( index_type cutStart, size_type cutLength, const substring_tuple_type& tuple )
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ AsSubstring()->Replace(cutStart, cutLength, tuple);
+ else
+ AsObsoleteString()->do_ReplaceFromReadable(cutStart, cutLength, nsTAutoString_CharT(tuple));
+ }
+
+nsTAString_CharT::size_type
+nsTAString_CharT::GetReadableBuffer( const char_type **data ) const
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ {
+ const substring_type* str = AsSubstring();
+ *data = str->mData;
+ return str->mLength;
+ }
+
+ obsolete_string_type::const_fragment_type frag;
+ AsObsoleteString()->GetReadableFragment(frag, obsolete_string_type::kFirstFragment, 0);
+ *data = frag.mStart;
+ return (frag.mEnd - frag.mStart);
+ }
+
+nsTAString_CharT::size_type
+nsTAString_CharT::GetWritableBuffer(char_type **data)
+ {
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ {
+ substring_type* str = AsSubstring();
+ str->BeginWriting(*data);
+ return str->Length();
+ }
+
+ obsolete_string_type::fragment_type frag;
+ AsObsoleteString()->GetWritableFragment(frag, obsolete_string_type::kFirstFragment, 0);
+ *data = frag.mStart;
+ return (frag.mEnd - frag.mStart);
+ }
+
+PRBool
+nsTAString_CharT::IsDependentOn(const char_type* start, const char_type *end) const
+ {
+ // this is an optimization...
+ if (mVTable == obsolete_string_type::sCanonicalVTable)
+ return AsSubstring()->IsDependentOn(start, end);
+
+ return ToSubstring().IsDependentOn(start, end);
+ }
+
+const nsTAString_CharT::substring_type
+nsTAString_CharT::ToSubstring() const
+ {
+ const char_type* data;
+ size_type length = GetReadableBuffer(&data);
+ return substring_type(NS_CONST_CAST(char_type*, data), length, 0);
+ }
diff --git a/src/libs/xpcom18a4/xpcom/string/src/nsTDependentSubstring.cpp b/src/libs/xpcom18a4/xpcom/string/src/nsTDependentSubstring.cpp
new file mode 100644
index 00000000..8421ecc0
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/src/nsTDependentSubstring.cpp
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+void
+nsTDependentSubstring_CharT::Rebind( const abstract_string_type& readable, PRUint32 startPos, PRUint32 length )
+ {
+ size_type strLength = readable.GetReadableBuffer((const char_type**) &mData);
+
+ if (startPos > strLength)
+ startPos = strLength;
+
+ mData += startPos;
+ mLength = NS_MIN(length, strLength - startPos);
+
+ SetDataFlags(F_NONE);
+ }
+
+void
+nsTDependentSubstring_CharT::Rebind( const substring_type& str, PRUint32 startPos, PRUint32 length )
+ {
+ size_type strLength = str.Length();
+
+ if (startPos > strLength)
+ startPos = strLength;
+
+ mData = NS_CONST_CAST(char_type*, str.Data()) + startPos;
+ mLength = NS_MIN(length, strLength - startPos);
+
+ SetDataFlags(F_NONE);
+ }
diff --git a/src/libs/xpcom18a4/xpcom/string/src/nsTObsoleteAStringThunk.cpp b/src/libs/xpcom18a4/xpcom/string/src/nsTObsoleteAStringThunk.cpp
new file mode 100644
index 00000000..3d1590a8
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/src/nsTObsoleteAStringThunk.cpp
@@ -0,0 +1,235 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+class nsTObsoleteAStringThunk_CharT : public nsTObsoleteAString_CharT
+ {
+ public:
+ typedef nsTObsoleteAStringThunk_CharT self_type;
+ typedef nsTSubstring_CharT substring_type;
+
+ public:
+
+ nsTObsoleteAStringThunk_CharT() {}
+
+
+ static const void* get_vptr()
+ {
+ const void* result;
+ new (&result) self_type();
+ return result;
+ }
+
+
+ /**
+ * we are a nsTSubstring in disguise!
+ */
+
+ substring_type* concrete_self() { return NS_REINTERPRET_CAST( substring_type*, this); }
+ const substring_type* concrete_self() const { return NS_REINTERPRET_CAST(const substring_type*, this); }
+
+
+ /**
+ * all virtual methods need to be redirected to appropriate nsString methods
+ */
+
+ virtual ~nsTObsoleteAStringThunk_CharT()
+ {
+ concrete_self()->Finalize();
+ }
+
+ virtual PRUint32 GetImplementationFlags() const
+ {
+ return 0;
+ }
+
+ virtual const buffer_handle_type* GetFlatBufferHandle() const
+ {
+ return (const buffer_handle_type*) (concrete_self()->IsTerminated() != PR_FALSE);
+ }
+
+ virtual const buffer_handle_type* GetBufferHandle() const
+ {
+ return 0;
+ }
+
+ virtual const shared_buffer_handle_type* GetSharedBufferHandle() const
+ {
+ return 0;
+ }
+
+ virtual size_type Length() const
+ {
+ return concrete_self()->Length();
+ }
+
+ virtual PRBool IsVoid() const
+ {
+ return concrete_self()->IsVoid();
+ }
+
+ virtual void SetIsVoid(PRBool val)
+ {
+ concrete_self()->SetIsVoid(val);
+ }
+
+ virtual void SetCapacity(size_type size)
+ {
+ concrete_self()->SetCapacity(size);
+ }
+
+ virtual void SetLength(size_type size)
+ {
+ concrete_self()->SetLength(size);
+ }
+
+ virtual void Cut(index_type cutStart, size_type cutLength)
+ {
+ concrete_self()->Cut(cutStart, cutLength);
+ }
+
+ virtual void do_AssignFromReadable(const abstract_string_type &s)
+ {
+ concrete_self()->Assign(s);
+ }
+
+ virtual void do_AssignFromElementPtr(const char_type *data)
+ {
+ concrete_self()->Assign(data);
+ }
+
+ virtual void do_AssignFromElementPtrLength(const char_type *data, size_type length)
+ {
+ concrete_self()->Assign(data, length);
+ }
+
+ virtual void do_AssignFromElement(char_type c)
+ {
+ concrete_self()->Assign(c);
+ }
+
+ virtual void do_AppendFromReadable(const abstract_string_type &s)
+ {
+ concrete_self()->Append(s);
+ }
+
+ virtual void do_AppendFromElementPtr(const char_type *data)
+ {
+ concrete_self()->Append(data);
+ }
+
+ virtual void do_AppendFromElementPtrLength(const char_type *data, size_type length)
+ {
+ concrete_self()->Append(data, length);
+ }
+
+ virtual void do_AppendFromElement(char_type c)
+ {
+ concrete_self()->Append(c);
+ }
+
+ virtual void do_InsertFromReadable(const abstract_string_type &s, index_type pos)
+ {
+ concrete_self()->Insert(s, pos);
+ }
+
+ virtual void do_InsertFromElementPtr(const char_type *data, index_type pos)
+ {
+ concrete_self()->Insert(data, pos);
+ }
+
+ virtual void do_InsertFromElementPtrLength(const char_type *data, index_type pos, size_type length)
+ {
+ concrete_self()->Insert(data, pos, length);
+ }
+
+ virtual void do_InsertFromElement(char_type c, index_type pos)
+ {
+ concrete_self()->Insert(c, pos);
+ }
+
+ virtual void do_ReplaceFromReadable(index_type cutStart, size_type cutLength, const abstract_string_type &s)
+ {
+ concrete_self()->Replace(cutStart, cutLength, s);
+ }
+
+ virtual const char_type *GetReadableFragment(const_fragment_type& frag, nsFragmentRequest which, PRUint32 offset) const
+ {
+ const substring_type* s = concrete_self();
+ switch (which)
+ {
+ case kFirstFragment:
+ case kLastFragment:
+ case kFragmentAt:
+ frag.mStart = s->Data();
+ frag.mEnd = frag.mStart + s->Length();
+ return frag.mStart + offset;
+ case kPrevFragment:
+ case kNextFragment:
+ default:
+ return 0;
+ }
+ }
+
+ virtual char_type *GetWritableFragment(fragment_type& frag, nsFragmentRequest which, PRUint32 offset)
+ {
+ substring_type* s = concrete_self();
+ switch (which)
+ {
+ case kFirstFragment:
+ case kLastFragment:
+ case kFragmentAt:
+ char_type* start;
+ s->BeginWriting(start);
+ frag.mStart = start;
+ frag.mEnd = start + s->Length();
+ return frag.mStart + offset;
+ case kPrevFragment:
+ case kNextFragment:
+ default:
+ return 0;
+ }
+ }
+ };
+
+
+ /**
+ * initialize the pointer to the canonical vtable...
+ */
+
+const void *nsTObsoleteAString_CharT::sCanonicalVTable = nsTObsoleteAStringThunk_CharT::get_vptr();
diff --git a/src/libs/xpcom18a4/xpcom/string/src/nsTPromiseFlatString.cpp b/src/libs/xpcom18a4/xpcom/string/src/nsTPromiseFlatString.cpp
new file mode 100644
index 00000000..bf0bfc32
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/src/nsTPromiseFlatString.cpp
@@ -0,0 +1,66 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+void
+nsTPromiseFlatString_CharT::Init(const substring_type& str)
+ {
+ // we have to manually set this here since we are being called on an
+ // unitialized object.
+ mVTable = nsTObsoleteAString_CharT::sCanonicalVTable;
+
+ if (str.IsTerminated())
+ {
+ mData = NS_CONST_CAST(char_type*, str.Data());
+ mLength = str.Length();
+ mFlags = F_TERMINATED; // does not promote F_VOIDED
+ }
+ else
+ {
+ Assign(str);
+ }
+ }
+
+ // this function is non-inline to minimize codesize
+void
+nsTPromiseFlatString_CharT::Init(const abstract_string_type& readable)
+ {
+ if (readable.mVTable == nsTObsoleteAString_CharT::sCanonicalVTable)
+ Init(*readable.AsSubstring());
+ else
+ Init(readable.ToSubstring());
+ }
diff --git a/src/libs/xpcom18a4/xpcom/string/src/nsTString.cpp b/src/libs/xpcom18a4/xpcom/string/src/nsTString.cpp
new file mode 100644
index 00000000..84911f5f
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/src/nsTString.cpp
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ * Johnny Stenback <jst@mozilla.jstenback.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+NS_COM nsTAdoptingString_CharT&
+nsTAdoptingString_CharT::operator=( const self_type& str )
+ {
+ // This'll violate the constness of this argument, that's just
+ // the nature of this class...
+ self_type* mutable_str = NS_CONST_CAST(self_type*, &str);
+
+ if (str.mFlags & F_OWNED)
+ {
+ Adopt(str.mData, str.mLength);
+
+ // Make str forget the buffer we just took ownership of.
+ new (mutable_str) self_type();
+ }
+ else
+ {
+ Assign(str);
+
+ mutable_str->Truncate();
+ }
+
+ return *this;
+ }
+
diff --git a/src/libs/xpcom18a4/xpcom/string/src/nsTStringComparator.cpp b/src/libs/xpcom18a4/xpcom/string/src/nsTStringComparator.cpp
new file mode 100644
index 00000000..6d2645a1
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/src/nsTStringComparator.cpp
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+NS_COM int
+Compare( const nsTAString_CharT& lhs, const nsTAString_CharT& rhs, const nsTStringComparator_CharT& comp )
+ {
+ typedef nsTAString_CharT::size_type size_type;
+
+ if ( &lhs == &rhs )
+ return 0;
+
+ nsTAString_CharT::const_iterator leftIter, rightIter;
+ lhs.BeginReading(leftIter);
+ rhs.BeginReading(rightIter);
+
+ size_type lLength = leftIter.size_forward();
+ size_type rLength = rightIter.size_forward();
+ size_type lengthToCompare = NS_MIN(lLength, rLength);
+
+ int result;
+ if ( (result = comp(leftIter.get(), rightIter.get(), lengthToCompare)) == 0 )
+ {
+ if ( lLength < rLength )
+ result = -1;
+ else if ( rLength < lLength )
+ result = 1;
+ else
+ result = 0;
+ }
+
+ return result;
+ }
+
+int
+nsTDefaultStringComparator_CharT::operator()( const char_type* lhs, const char_type* rhs, PRUint32 aLength ) const
+ {
+ return nsCharTraits<CharT>::compare(lhs, rhs, aLength);
+ }
+
+int
+nsTDefaultStringComparator_CharT::operator()( char_type lhs, char_type rhs) const
+ {
+ return lhs - rhs;
+ }
diff --git a/src/libs/xpcom18a4/xpcom/string/src/nsTStringObsolete.cpp b/src/libs/xpcom18a4/xpcom/string/src/nsTStringObsolete.cpp
new file mode 100644
index 00000000..5ed065ad
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/src/nsTStringObsolete.cpp
@@ -0,0 +1,518 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+
+ /**
+ * nsTString::Find
+ *
+ * aOffset specifies starting index
+ * aCount specifies number of string compares (iterations)
+ */
+
+PRInt32
+nsTString_CharT::Find( const nsCString& aString, PRBool aIgnoreCase, PRInt32 aOffset, PRInt32 aCount) const
+ {
+ // this method changes the meaning of aOffset and aCount:
+ Find_ComputeSearchRange(mLength, aString.Length(), aOffset, aCount);
+
+ PRInt32 result = FindSubstring(mData + aOffset, aCount, aString.get(), aString.Length(), aIgnoreCase);
+ if (result != kNotFound)
+ result += aOffset;
+ return result;
+ }
+
+PRInt32
+nsTString_CharT::Find( const char* aString, PRBool aIgnoreCase, PRInt32 aOffset, PRInt32 aCount) const
+ {
+ return Find(nsDependentCString(aString), aIgnoreCase, aOffset, aCount);
+ }
+
+
+ /**
+ * nsTString::RFind
+ *
+ * aOffset specifies starting index
+ * aCount specifies number of string compares (iterations)
+ */
+
+PRInt32
+nsTString_CharT::RFind( const nsCString& aString, PRBool aIgnoreCase, PRInt32 aOffset, PRInt32 aCount) const
+ {
+ // this method changes the meaning of aOffset and aCount:
+ RFind_ComputeSearchRange(mLength, aString.Length(), aOffset, aCount);
+
+ PRInt32 result = RFindSubstring(mData + aOffset, aCount, aString.get(), aString.Length(), aIgnoreCase);
+ if (result != kNotFound)
+ result += aOffset;
+ return result;
+ }
+
+PRInt32
+nsTString_CharT::RFind( const char* aString, PRBool aIgnoreCase, PRInt32 aOffset, PRInt32 aCount) const
+ {
+ return RFind(nsDependentCString(aString), aIgnoreCase, aOffset, aCount);
+ }
+
+
+ /**
+ * nsTString::RFindChar
+ */
+
+PRInt32
+nsTString_CharT::RFindChar( PRUnichar aChar, PRInt32 aOffset, PRInt32 aCount) const
+ {
+ return nsBufferRoutines<CharT>::rfind_char(mData, mLength, aOffset, aChar, aCount);
+ }
+
+
+ /**
+ * nsTString::FindCharInSet
+ */
+
+PRInt32
+nsTString_CharT::FindCharInSet( const char* aSet, PRInt32 aOffset ) const
+ {
+ if (aOffset < 0)
+ aOffset = 0;
+ else if (aOffset >= PRInt32(mLength))
+ return kNotFound;
+
+ PRInt32 result = ::FindCharInSet(mData + aOffset, mLength - aOffset, aSet);
+ if (result != kNotFound)
+ result += aOffset;
+ return result;
+ }
+
+
+ /**
+ * nsTString::RFindCharInSet
+ */
+
+PRInt32
+nsTString_CharT::RFindCharInSet( const CharT* aSet, PRInt32 aOffset ) const
+ {
+ // We want to pass a "data length" to ::RFindCharInSet
+ if (aOffset < 0 || aOffset > PRInt32(mLength))
+ aOffset = mLength;
+ else
+ ++aOffset;
+
+ return ::RFindCharInSet(mData, aOffset, aSet);
+ }
+
+
+ // it's a shame to replicate this code. it was done this way in the past
+ // to help performance. this function also gets to keep the rickg style
+ // indentation :-/
+PRInt32
+nsTString_CharT::ToInteger( PRInt32* aErrorCode, PRUint32 aRadix ) const
+{
+ CharT* cp=mData;
+ PRInt32 theRadix=10; // base 10 unless base 16 detected, or overriden (aRadix != kAutoDetect)
+ PRInt32 result=0;
+ PRBool negate=PR_FALSE;
+ CharT theChar=0;
+
+ //initial value, override if we find an integer
+ *aErrorCode=NS_ERROR_ILLEGAL_VALUE;
+
+ if(cp) {
+
+ //begin by skipping over leading chars that shouldn't be part of the number...
+
+ CharT* endcp=cp+mLength;
+ PRBool done=PR_FALSE;
+
+ while((cp<endcp) && (!done)){
+ switch(*cp++) {
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ theRadix=16;
+ done=PR_TRUE;
+ break;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ done=PR_TRUE;
+ break;
+ case '-':
+ negate=PR_TRUE; //fall through...
+ break;
+ case 'X': case 'x':
+ theRadix=16;
+ break;
+ default:
+ break;
+ } //switch
+ }
+
+ if (done) {
+
+ //integer found
+ *aErrorCode = NS_OK;
+
+ if (aRadix!=kAutoDetect) theRadix = aRadix; // override
+
+ //now iterate the numeric chars and build our result
+ CharT* first=--cp; //in case we have to back up.
+ PRBool haveValue = PR_FALSE;
+
+ while(cp<endcp){
+ theChar=*cp++;
+ if(('0'<=theChar) && (theChar<='9')){
+ result = (theRadix * result) + (theChar-'0');
+ haveValue = PR_TRUE;
+ }
+ else if((theChar>='A') && (theChar<='F')) {
+ if(10==theRadix) {
+ if(kAutoDetect==aRadix){
+ theRadix=16;
+ cp=first; //backup
+ result=0;
+ haveValue = PR_FALSE;
+ }
+ else {
+ *aErrorCode=NS_ERROR_ILLEGAL_VALUE;
+ result=0;
+ break;
+ }
+ }
+ else {
+ result = (theRadix * result) + ((theChar-'A')+10);
+ haveValue = PR_TRUE;
+ }
+ }
+ else if((theChar>='a') && (theChar<='f')) {
+ if(10==theRadix) {
+ if(kAutoDetect==aRadix){
+ theRadix=16;
+ cp=first; //backup
+ result=0;
+ haveValue = PR_FALSE;
+ }
+ else {
+ *aErrorCode=NS_ERROR_ILLEGAL_VALUE;
+ result=0;
+ break;
+ }
+ }
+ else {
+ result = (theRadix * result) + ((theChar-'a')+10);
+ haveValue = PR_TRUE;
+ }
+ }
+ else if((('X'==theChar) || ('x'==theChar)) && (!haveValue || result == 0)) {
+ continue;
+ }
+ else if((('#'==theChar) || ('+'==theChar)) && !haveValue) {
+ continue;
+ }
+ else {
+ //we've encountered a char that's not a legal number or sign
+ break;
+ }
+ } //while
+ if(negate)
+ result=-result;
+ } //if
+ }
+ return result;
+}
+
+
+ /**
+ * nsTString::Mid
+ */
+
+PRUint32
+nsTString_CharT::Mid( self_type& aResult, index_type aStartPos, size_type aLengthToCopy ) const
+ {
+ if (aStartPos == 0 && aLengthToCopy >= mLength)
+ aResult = *this;
+ else
+ aResult = Substring(*this, aStartPos, aLengthToCopy);
+
+ return aResult.mLength;
+ }
+
+
+ /**
+ * nsTString::SetCharAt
+ */
+
+PRBool
+nsTString_CharT::SetCharAt( PRUnichar aChar, PRUint32 aIndex )
+ {
+ if (aIndex >= mLength)
+ return PR_FALSE;
+
+ EnsureMutable();
+
+ mData[aIndex] = CharT(aChar);
+ return PR_TRUE;
+ }
+
+
+ /**
+ * nsTString::StripChars,StripChar,StripWhitespace
+ */
+
+void
+nsTString_CharT::StripChars( const char* aSet )
+ {
+ EnsureMutable();
+ mLength = nsBufferRoutines<CharT>::strip_chars(mData, mLength, aSet);
+ }
+
+void
+nsTString_CharT::StripChar( char_type aChar, PRInt32 aOffset )
+ {
+ if (mLength == 0 || aOffset >= PRInt32(mLength))
+ return;
+
+ EnsureMutable(); // XXX do this lazily?
+
+ // XXXdarin this code should defer writing until necessary.
+
+ char_type* to = mData + aOffset;
+ char_type* from = mData + aOffset;
+ char_type* end = mData + mLength;
+
+ while (from < end)
+ {
+ char_type theChar = *from++;
+ if (aChar != theChar)
+ *to++ = theChar;
+ }
+ *to = char_type(0); // add the null
+ mLength = to - mData;
+ }
+
+void
+nsTString_CharT::StripWhitespace()
+ {
+ StripChars(kWhitespace);
+ }
+
+
+ /**
+ * nsTString::ReplaceChar,ReplaceSubstring
+ */
+
+void
+nsTString_CharT::ReplaceChar( char_type aOldChar, char_type aNewChar )
+ {
+ EnsureMutable(); // XXX do this lazily?
+
+ for (PRUint32 i=0; i<mLength; ++i)
+ {
+ if (mData[i] == aOldChar)
+ mData[i] = aNewChar;
+ }
+ }
+
+void
+nsTString_CharT::ReplaceChar( const char* aSet, char_type aNewChar )
+ {
+ EnsureMutable(); // XXX do this lazily?
+
+ char_type* data = mData;
+ PRUint32 lenRemaining = mLength;
+
+ while (lenRemaining)
+ {
+ PRInt32 i = ::FindCharInSet(data, lenRemaining, aSet);
+ if (i == kNotFound)
+ break;
+
+ data[i++] = aNewChar;
+ data += i;
+ lenRemaining -= i;
+ }
+ }
+
+void
+nsTString_CharT::ReplaceSubstring( const char_type* aTarget, const char_type* aNewValue )
+ {
+ ReplaceSubstring(nsTDependentString_CharT(aTarget),
+ nsTDependentString_CharT(aNewValue));
+ }
+
+void
+nsTString_CharT::ReplaceSubstring( const self_type& aTarget, const self_type& aNewValue )
+ {
+ if (aTarget.Length() == 0)
+ return;
+
+ PRUint32 i = 0;
+ while (i < mLength)
+ {
+ PRInt32 r = FindSubstring(mData + i, mLength - i, aTarget.Data(), aTarget.Length(), PR_FALSE);
+ if (r == kNotFound)
+ break;
+
+ Replace(i + r, aTarget.Length(), aNewValue);
+ i += r + aNewValue.Length();
+ }
+ }
+
+
+ /**
+ * nsTString::Trim
+ */
+
+void
+nsTString_CharT::Trim( const char* aSet, PRBool aTrimLeading, PRBool aTrimTrailing, PRBool aIgnoreQuotes )
+ {
+ // the old implementation worried about aSet being null :-/
+ if (!aSet)
+ return;
+
+ char_type* start = mData;
+ char_type* end = mData + mLength;
+
+ // skip over quotes if requested
+ if (aIgnoreQuotes && mLength > 2 && mData[0] == mData[mLength - 1] &&
+ (mData[0] == '\'' || mData[0] == '"'))
+ {
+ ++start;
+ --end;
+ }
+
+ PRUint32 setLen = nsCharTraits<char>::length(aSet);
+
+ if (aTrimLeading)
+ {
+ PRUint32 cutStart = start - mData;
+ PRUint32 cutLength = 0;
+
+ // walk forward from start to end
+ for (; start != end; ++start, ++cutLength)
+ {
+ PRInt32 pos = FindChar1(aSet, setLen, 0, *start, setLen);
+ if (pos == kNotFound)
+ break;
+ }
+
+ if (cutLength)
+ {
+ Cut(cutStart, cutLength);
+
+ // reset iterators
+ start = mData + cutStart;
+ end = mData + mLength - cutStart;
+ }
+ }
+
+ if (aTrimTrailing)
+ {
+ PRUint32 cutEnd = end - mData;
+ PRUint32 cutLength = 0;
+
+ // walk backward from end to start
+ --end;
+ for (; end >= start; --end, ++cutLength)
+ {
+ PRInt32 pos = FindChar1(aSet, setLen, 0, *end, setLen);
+ if (pos == kNotFound)
+ break;
+ }
+
+ if (cutLength)
+ Cut(cutEnd - cutLength, cutLength);
+ }
+ }
+
+
+ /**
+ * nsTString::CompressWhitespace
+ */
+
+void
+nsTString_CharT::CompressWhitespace( PRBool aTrimLeading, PRBool aTrimTrailing )
+ {
+ const char* set = kWhitespace;
+
+ ReplaceChar(set, ' ');
+ Trim(set, aTrimLeading, aTrimTrailing);
+
+ // this one does some questionable fu... just copying the old code!
+ mLength = nsBufferRoutines<char_type>::compress_chars(mData, mLength, set);
+ }
+
+
+ /**
+ * nsTString::AssignWithConversion
+ */
+
+void
+nsTString_CharT::AssignWithConversion( const incompatible_char_type* aData, PRInt32 aLength )
+ {
+ // for compatibility with the old string implementation, we need to allow
+ // for a NULL input buffer :-(
+ if (!aData)
+ {
+ Truncate();
+ }
+ else
+ {
+ if (aLength < 0)
+ aLength = nsCharTraits<incompatible_char_type>::length(aData);
+
+ AssignWithConversion(Substring(aData, aData + aLength));
+ }
+ }
+
+
+ /**
+ * nsTString::AppendWithConversion
+ */
+
+void
+nsTString_CharT::AppendWithConversion( const incompatible_char_type* aData, PRInt32 aLength )
+ {
+ // for compatibility with the old string implementation, we need to allow
+ // for a NULL input buffer :-(
+ if (aData)
+ {
+ if (aLength < 0)
+ aLength = nsCharTraits<incompatible_char_type>::length(aData);
+
+ AppendWithConversion(Substring(aData, aData + aLength));
+ }
+ }
diff --git a/src/libs/xpcom18a4/xpcom/string/src/nsTSubstring.cpp b/src/libs/xpcom18a4/xpcom/string/src/nsTSubstring.cpp
new file mode 100644
index 00000000..e36b1863
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/src/nsTSubstring.cpp
@@ -0,0 +1,656 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+ /**
+ * helper function for down-casting a nsTSubstring to a nsTFixedString.
+ */
+inline const nsTFixedString_CharT*
+AsFixedString( const nsTSubstring_CharT* s )
+ {
+ return NS_STATIC_CAST(const nsTFixedString_CharT*, s);
+ }
+
+
+ /**
+ * this function is called to prepare mData for writing. the given capacity
+ * indicates the required minimum storage size for mData, in sizeof(char_type)
+ * increments. this function returns true if the operation succeeds. it also
+ * returns the old data and old flags members if mData is newly allocated.
+ * the old data must be released by the caller.
+ */
+PRBool
+nsTSubstring_CharT::MutatePrep( size_type capacity, char_type** oldData, PRUint32* oldFlags )
+ {
+ // initialize to no old data
+ *oldData = nsnull;
+ *oldFlags = 0;
+
+ size_type curCapacity = Capacity();
+
+ // |curCapacity == size_type(-1)| means that the buffer is immutable, so we
+ // need to allocate a new buffer. we cannot use the existing buffer even
+ // though it might be large enough.
+
+ if (curCapacity != size_type(-1))
+ {
+ if (capacity <= curCapacity)
+ return PR_TRUE;
+
+ if (curCapacity > 0)
+ {
+ // use doubling algorithm when forced to increase available capacity,
+ // but always start out with exactly the requested amount.
+ PRUint32 temp = curCapacity;
+ while (temp < capacity)
+ temp <<= 1;
+ capacity = temp;
+ }
+ }
+
+ //
+ // several cases:
+ //
+ // (1) we have a shared buffer (mFlags & F_SHARED)
+ // (2) we have an owned buffer (mFlags & F_OWNED)
+ // (3) we have a fixed buffer (mFlags & F_FIXED)
+ // (4) we have a readonly buffer
+ //
+ // requiring that we in some cases preserve the data before creating
+ // a new buffer complicates things just a bit ;-)
+ //
+
+ size_type storageSize = (capacity + 1) * sizeof(char_type);
+
+ // case #1
+ if (mFlags & F_SHARED)
+ {
+ nsStringHeader* hdr = nsStringHeader::FromData(mData);
+ if (!hdr->IsReadonly())
+ {
+ nsStringHeader *newHdr = nsStringHeader::Realloc(hdr, storageSize);
+ if (newHdr)
+ {
+ hdr = newHdr;
+ mData = (char_type*) hdr->Data();
+ return PR_TRUE;
+ }
+ hdr->Release();
+ // out of memory!! put us in a consistent state at least.
+ mData = NS_CONST_CAST(char_type*, char_traits::sEmptyBuffer);
+ mLength = 0;
+ SetDataFlags(F_TERMINATED);
+ return PR_FALSE;
+ }
+ }
+
+ char_type* newData;
+ PRUint32 newDataFlags;
+
+ // if we have a fixed buffer of sufficient size, then use it. this helps
+ // avoid heap allocations.
+ if ((mFlags & F_CLASS_FIXED) && (capacity < AsFixedString(this)->mFixedCapacity))
+ {
+ newData = AsFixedString(this)->mFixedBuf;
+ newDataFlags = F_TERMINATED | F_FIXED;
+ }
+ else
+ {
+ // if we reach here then, we must allocate a new buffer. we cannot
+ // make use of our F_OWNED or F_FIXED buffers because they are not
+ // large enough.
+
+ nsStringHeader* newHdr = nsStringHeader::Alloc(storageSize);
+ if (!newHdr)
+ return PR_FALSE; // we are still in a consistent state
+
+ newData = (char_type*) newHdr->Data();
+ newDataFlags = F_TERMINATED | F_SHARED;
+ }
+
+ // save old data and flags
+ *oldData = mData;
+ *oldFlags = mFlags;
+
+ mData = newData;
+ SetDataFlags(newDataFlags);
+
+ // mLength does not change
+
+ // though we are not necessarily terminated at the moment, now is probably
+ // still the best time to set F_TERMINATED.
+
+ return PR_TRUE;
+ }
+
+void
+nsTSubstring_CharT::Finalize()
+ {
+ ::ReleaseData(mData, mFlags);
+ // mData, mLength, and mFlags are purposefully left dangling
+ }
+
+void
+nsTSubstring_CharT::ReplacePrep( index_type cutStart, size_type cutLen, size_type fragLen )
+ {
+ // bound cut length
+ cutLen = NS_MIN(cutLen, mLength - cutStart);
+
+ PRUint32 newLen = mLength - cutLen + fragLen;
+
+ char_type* oldData;
+ PRUint32 oldFlags;
+ if (!MutatePrep(newLen, &oldData, &oldFlags))
+ return; // XXX out-of-memory error occured!
+
+ if (oldData)
+ {
+ // determine whether or not we need to copy part of the old string
+ // over to the new string.
+
+ if (cutStart > 0)
+ {
+ // copy prefix from old string
+ char_traits::copy(mData, oldData, cutStart);
+ }
+
+ if (cutStart + cutLen < mLength)
+ {
+ // copy suffix from old string to new offset
+ size_type from = cutStart + cutLen;
+ size_type fromLen = mLength - from;
+ PRUint32 to = cutStart + fragLen;
+ char_traits::copy(mData + to, oldData + from, fromLen);
+ }
+
+ ::ReleaseData(oldData, oldFlags);
+ }
+ else
+ {
+ // original data remains intact
+
+ // determine whether or not we need to move part of the existing string
+ // to make room for the requested hole.
+ if (fragLen != cutLen && cutStart + cutLen < mLength)
+ {
+ PRUint32 from = cutStart + cutLen;
+ PRUint32 fromLen = mLength - from;
+ PRUint32 to = cutStart + fragLen;
+ char_traits::move(mData + to, mData + from, fromLen);
+ }
+ }
+
+ // add null terminator (mutable mData always has room for the null-
+ // terminator).
+ mData[newLen] = char_type(0);
+ mLength = newLen;
+ }
+
+nsTSubstring_CharT::size_type
+nsTSubstring_CharT::Capacity() const
+ {
+ // return size_type(-1) to indicate an immutable buffer
+
+ size_type capacity;
+ if (mFlags & F_SHARED)
+ {
+ // if the string is readonly, then we pretend that it has no capacity.
+ nsStringHeader* hdr = nsStringHeader::FromData(mData);
+ if (hdr->IsReadonly())
+ capacity = size_type(-1);
+ else
+ capacity = (hdr->StorageSize() / sizeof(char_type)) - 1;
+ }
+ else if (mFlags & F_FIXED)
+ {
+ capacity = AsFixedString(this)->mFixedCapacity;
+ }
+ else if (mFlags & F_OWNED)
+ {
+ // we don't store the capacity of an adopted buffer because that would
+ // require an additional member field. the best we can do is base the
+ // capacity on our length. remains to be seen if this is the right
+ // trade-off.
+ capacity = mLength;
+ }
+ else
+ {
+ capacity = size_type(-1);
+ }
+
+ return capacity;
+ }
+
+void
+nsTSubstring_CharT::EnsureMutable()
+ {
+ if (mFlags & (F_FIXED | F_OWNED))
+ return;
+ if ((mFlags & F_SHARED) && !nsStringHeader::FromData(mData)->IsReadonly())
+ return;
+
+ // promote to a shared string buffer
+ Assign(string_type(mData, mLength));
+ }
+
+// ---------------------------------------------------------------------------
+
+void
+nsTSubstring_CharT::Assign( const char_type* data, size_type length )
+ {
+ // unfortunately, some callers pass null :-(
+ if (!data)
+ {
+ Truncate();
+ return;
+ }
+
+ if (length == size_type(-1))
+ length = char_traits::length(data);
+
+ if (IsDependentOn(data, data + length))
+ {
+ // take advantage of sharing here...
+ Assign(string_type(data, length));
+ return;
+ }
+
+ ReplacePrep(0, mLength, length);
+ char_traits::copy(mData, data, length);
+ }
+
+void
+nsTSubstring_CharT::AssignASCII( const char* data, size_type length )
+ {
+ // A Unicode string can't depend on an ASCII string buffer,
+ // so this dependence check only applies to CStrings.
+#ifdef CharT_is_char
+ if (IsDependentOn(data, data + length))
+ {
+ // take advantage of sharing here...
+ Assign(string_type(data, length));
+ return;
+ }
+#endif
+
+ ReplacePrep(0, mLength, length);
+ char_traits::copyASCII(mData, data, length);
+ }
+
+void
+nsTSubstring_CharT::AssignASCII( const char* data )
+ {
+ AssignASCII(data, strlen(data));
+ }
+
+void
+nsTSubstring_CharT::Assign( const self_type& str )
+ {
+ // |str| could be sharable. we need to check its flags to know how to
+ // deal with it.
+
+ if (&str == this)
+ return;
+
+ if (str.mFlags & F_SHARED)
+ {
+ // nice! we can avoid a string copy :-)
+
+ // |str| should be null-terminated
+ NS_ASSERTION(str.mFlags & F_TERMINATED, "shared, but not terminated");
+
+ ::ReleaseData(mData, mFlags);
+
+ mData = str.mData;
+ mLength = str.mLength;
+ SetDataFlags(F_TERMINATED | F_SHARED);
+
+ // get an owning reference to the mData
+ nsStringHeader::FromData(mData)->AddRef();
+ }
+ else if (str.mFlags & F_VOIDED)
+ {
+ // inherit the F_VOIDED attribute
+ SetIsVoid(PR_TRUE);
+ }
+ else
+ {
+ // else, treat this like an ordinary assignment.
+ Assign(str.Data(), str.Length());
+ }
+ }
+
+void
+nsTSubstring_CharT::Assign( const substring_tuple_type& tuple )
+ {
+ if (tuple.IsDependentOn(mData, mData + mLength))
+ {
+ // take advantage of sharing here...
+ Assign(string_type(tuple));
+ return;
+ }
+
+ size_type length = tuple.Length();
+
+ ReplacePrep(0, mLength, length);
+ if (length)
+ tuple.WriteTo(mData, length);
+ }
+
+ // this is non-inline to reduce codesize at the callsite
+void
+nsTSubstring_CharT::Assign( const abstract_string_type& readable )
+ {
+ // promote to string if possible to take advantage of sharing
+ if (readable.mVTable == nsTObsoleteAString_CharT::sCanonicalVTable)
+ Assign(*readable.AsSubstring());
+ else
+ Assign(readable.ToSubstring());
+ }
+
+
+void
+nsTSubstring_CharT::Adopt( char_type* data, size_type length )
+ {
+ if (data)
+ {
+ ::ReleaseData(mData, mFlags);
+
+ if (length == size_type(-1))
+ length = char_traits::length(data);
+
+ mData = data;
+ mLength = length;
+ SetDataFlags(F_TERMINATED | F_OWNED);
+
+ STRING_STAT_INCREMENT(Adopt);
+ }
+ else
+ {
+ SetIsVoid(PR_TRUE);
+ }
+ }
+
+
+void
+nsTSubstring_CharT::Replace( index_type cutStart, size_type cutLength, const char_type* data, size_type length )
+ {
+ // unfortunately, some callers pass null :-(
+ if (!data)
+ {
+ length = 0;
+ }
+ else
+ {
+ if (length == size_type(-1))
+ length = char_traits::length(data);
+
+ if (IsDependentOn(data, data + length))
+ {
+ nsTAutoString_CharT temp(data, length);
+ Replace(cutStart, cutLength, temp);
+ return;
+ }
+ }
+
+ cutStart = PR_MIN(cutStart, Length());
+
+ ReplacePrep(cutStart, cutLength, length);
+
+ if (length > 0)
+ char_traits::copy(mData + cutStart, data, length);
+ }
+
+void
+nsTSubstring_CharT::ReplaceASCII( index_type cutStart, size_type cutLength, const char* data, size_type length )
+ {
+ if (length == size_type(-1))
+ length = strlen(data);
+
+ // A Unicode string can't depend on an ASCII string buffer,
+ // so this dependence check only applies to CStrings.
+#ifdef CharT_is_char
+ if (IsDependentOn(data, data + length))
+ {
+ nsTAutoString_CharT temp(data, length);
+ Replace(cutStart, cutLength, temp);
+ return;
+ }
+#endif
+
+ cutStart = PR_MIN(cutStart, Length());
+
+ ReplacePrep(cutStart, cutLength, length);
+
+ if (length > 0)
+ char_traits::copyASCII(mData + cutStart, data, length);
+ }
+
+void
+nsTSubstring_CharT::Replace( index_type cutStart, size_type cutLength, const substring_tuple_type& tuple )
+ {
+ if (tuple.IsDependentOn(mData, mData + mLength))
+ {
+ nsTAutoString_CharT temp(tuple);
+ Replace(cutStart, cutLength, temp);
+ return;
+ }
+
+ size_type length = tuple.Length();
+
+ cutStart = PR_MIN(cutStart, Length());
+
+ ReplacePrep(cutStart, cutLength, length);
+
+ if (length > 0)
+ tuple.WriteTo(mData + cutStart, length);
+ }
+
+void
+nsTSubstring_CharT::Replace( index_type cutStart, size_type cutLength, const abstract_string_type& readable )
+ {
+ Replace(cutStart, cutLength, readable.ToSubstring());
+ }
+
+void
+nsTSubstring_CharT::SetCapacity( size_type capacity )
+ {
+ // capacity does not include room for the terminating null char
+
+ // if our capacity is reduced to zero, then free our buffer.
+ if (capacity == 0)
+ {
+ ::ReleaseData(mData, mFlags);
+ mData = NS_CONST_CAST(char_type*, char_traits::sEmptyBuffer);
+ mLength = 0;
+ SetDataFlags(F_TERMINATED);
+ }
+ else
+ {
+ char_type* oldData;
+ PRUint32 oldFlags;
+ if (!MutatePrep(capacity, &oldData, &oldFlags))
+ return; // XXX out-of-memory error occured!
+
+ // compute new string length
+ size_type newLen = NS_MIN(mLength, capacity);
+
+ if (oldData)
+ {
+ // preserve old data
+ if (mLength > 0)
+ char_traits::copy(mData, oldData, newLen);
+
+ ::ReleaseData(oldData, oldFlags);
+ }
+
+ // adjust mLength if our buffer shrunk down in size
+ if (newLen < mLength)
+ mLength = newLen;
+
+ // always null-terminate here, even if the buffer got longer. this is
+ // for backwards compat with the old string implementation.
+ mData[capacity] = char_type(0);
+ }
+ }
+
+void
+nsTSubstring_CharT::SetLength( size_type length )
+ {
+ SetCapacity(length);
+ mLength = length;
+ }
+
+void
+nsTSubstring_CharT::SetIsVoid( PRBool val )
+ {
+ if (val)
+ {
+ Truncate();
+ mFlags |= F_VOIDED;
+ }
+ else
+ {
+ mFlags &= ~F_VOIDED;
+ }
+ }
+
+PRBool
+nsTSubstring_CharT::Equals( const self_type& str ) const
+ {
+ return mLength == str.mLength && char_traits::compare(mData, str.mData, mLength) == 0;
+ }
+
+PRBool
+nsTSubstring_CharT::Equals( const self_type& str, const comparator_type& comp ) const
+ {
+ return mLength == str.mLength && comp(mData, str.mData, mLength) == 0;
+ }
+
+PRBool
+nsTSubstring_CharT::Equals( const abstract_string_type& readable ) const
+ {
+ const char_type* data;
+ size_type length = readable.GetReadableBuffer(&data);
+
+ return mLength == length && char_traits::compare(mData, data, mLength) == 0;
+ }
+
+PRBool
+nsTSubstring_CharT::Equals( const abstract_string_type& readable, const comparator_type& comp ) const
+ {
+ const char_type* data;
+ size_type length = readable.GetReadableBuffer(&data);
+
+ return mLength == length && comp(mData, data, mLength) == 0;
+ }
+
+PRBool
+nsTSubstring_CharT::Equals( const char_type* data ) const
+ {
+ // unfortunately, some callers pass null :-(
+ if (!data)
+ {
+ NS_NOTREACHED("null data pointer");
+ return mLength == 0;
+ }
+
+ // XXX avoid length calculation?
+ size_type length = char_traits::length(data);
+ return mLength == length && char_traits::compare(mData, data, mLength) == 0;
+ }
+
+PRBool
+nsTSubstring_CharT::Equals( const char_type* data, const comparator_type& comp ) const
+ {
+ // unfortunately, some callers pass null :-(
+ if (!data)
+ {
+ NS_NOTREACHED("null data pointer");
+ return mLength == 0;
+ }
+
+ // XXX avoid length calculation?
+ size_type length = char_traits::length(data);
+ return mLength == length && comp(mData, data, mLength) == 0;
+ }
+
+PRBool
+nsTSubstring_CharT::EqualsASCII( const char* data, size_type len ) const
+ {
+ return mLength == len && char_traits::compareASCII(mData, data, len) == 0;
+ }
+
+PRBool
+nsTSubstring_CharT::EqualsASCII( const char* data ) const
+ {
+ return char_traits::compareASCIINullTerminated(mData, mLength, data) == 0;
+ }
+
+PRBool
+nsTSubstring_CharT::LowerCaseEqualsASCII( const char* data, size_type len ) const
+ {
+ return mLength == len && char_traits::compareLowerCaseToASCII(mData, data, len) == 0;
+ }
+
+PRBool
+nsTSubstring_CharT::LowerCaseEqualsASCII( const char* data ) const
+ {
+ return char_traits::compareLowerCaseToASCIINullTerminated(mData, mLength, data) == 0;
+ }
+
+nsTSubstring_CharT::size_type
+nsTSubstring_CharT::CountChar( char_type c ) const
+ {
+ const char_type *start = mData;
+ const char_type *end = mData + mLength;
+
+ return NS_COUNT(start, end, c);
+ }
+
+PRInt32
+nsTSubstring_CharT::FindChar( char_type c, index_type offset ) const
+ {
+ if (offset < mLength)
+ {
+ const char_type* result = char_traits::find(mData + offset, mLength - offset, c);
+ if (result)
+ return result - mData;
+ }
+ return -1;
+ }
diff --git a/src/libs/xpcom18a4/xpcom/string/src/nsTSubstringTuple.cpp b/src/libs/xpcom18a4/xpcom/string/src/nsTSubstringTuple.cpp
new file mode 100644
index 00000000..7fff5175
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/string/src/nsTSubstringTuple.cpp
@@ -0,0 +1,127 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+ /**
+ * computes the aggregate string length
+ */
+
+nsTSubstringTuple_CharT::size_type
+nsTSubstringTuple_CharT::Length() const
+ {
+ PRUint32 len;
+ if (mHead)
+ len = mHead->Length();
+ else
+ len = TO_SUBSTRING(mFragA).Length();
+
+ return len + TO_SUBSTRING(mFragB).Length();
+ }
+
+
+ /**
+ * writes the aggregate string to the given buffer. bufLen is assumed
+ * to be equal to or greater than the value returned by the Length()
+ * method. the string written to |buf| is not null-terminated.
+ */
+
+void
+nsTSubstringTuple_CharT::WriteTo( char_type *buf, PRUint32 bufLen ) const
+ {
+ const substring_type& b = TO_SUBSTRING(mFragB);
+
+ NS_ASSERTION(bufLen >= b.Length(), "buffer too small");
+ PRUint32 headLen = bufLen - b.Length();
+ if (mHead)
+ {
+ mHead->WriteTo(buf, headLen);
+ }
+ else
+ {
+ const substring_type& a = TO_SUBSTRING(mFragA);
+
+ NS_ASSERTION(a.Length() == headLen, "buffer incorrectly sized");
+ char_traits::copy(buf, a.Data(), a.Length());
+ }
+
+ char_traits::copy(buf + headLen, b.Data(), b.Length());
+
+#if 0
+ // we need to write out data into |buf|, ending at |buf+bufLen|. so our
+ // data needs to precede |buf+bufLen| exactly. we trust that the buffer
+ // was properly sized!
+
+ const substring_type& b = TO_SUBSTRING(mFragB);
+
+ NS_ASSERTION(bufLen >= b.Length(), "buffer is too small");
+ char_traits::copy(buf + bufLen - b.Length(), b.Data(), b.Length());
+
+ bufLen -= b.Length();
+
+ if (mHead)
+ {
+ mHead->WriteTo(buf, bufLen);
+ }
+ else
+ {
+ const substring_type& a = TO_SUBSTRING(mFragA);
+ NS_ASSERTION(bufLen == a.Length(), "buffer is too small");
+ char_traits::copy(buf, a.Data(), a.Length());
+ }
+#endif
+ }
+
+
+ /**
+ * returns true if this tuple is dependent on (i.e., overlapping with)
+ * the given char sequence.
+ */
+
+PRBool
+nsTSubstringTuple_CharT::IsDependentOn( const char_type *start, const char_type *end ) const
+ {
+ // we start with the right-most fragment since it is faster to check.
+
+ if (TO_SUBSTRING(mFragB).IsDependentOn(start, end))
+ return PR_TRUE;
+
+ if (mHead)
+ return mHead->IsDependentOn(start, end);
+
+ return TO_SUBSTRING(mFragA).IsDependentOn(start, end);
+ }