summaryrefslogtreecommitdiffstats
path: root/src/libs/xpcom18a4/xpcom/string/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-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
22 files changed, 5568 insertions, 0 deletions
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);
+ }