summaryrefslogtreecommitdiffstats
path: root/src/libs/xpcom18a4/xpcom/tests
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/xpcom18a4/xpcom/tests')
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/.cvsignore31
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/CvtURL.cpp126
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/Makefile.in116
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/RegFactory.cpp162
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/SizeTest01.cpp107
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/SizeTest02.cpp93
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/SizeTest03.cpp101
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/SizeTest04.cpp72
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/SizeTest05.cpp78
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/SizeTest06.cpp231
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/Makefile.in76
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTest.Prefix4
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTest.mcpbin0 -> 245184 bytes
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestDebug.Prefix4
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestNo_wchar_t.Prefix5
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestProfileNew.Prefix3
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestProfileOld.Prefix6
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestProfileStd.Prefix7
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/ToDo.doc41
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/nsStdStringWrapper.h234
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/profile_main.cpp497
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/test_main.cpp651
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestArray.cpp230
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestAtoms.cpp132
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestAutoLock.cpp91
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestAutoPtr.cpp566
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestCOMPtr.cpp651
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestCOMPtrEq.cpp200
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestCRT.cpp112
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestCallTemplates.cpp129
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestDeque.cpp155
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestFactory.cpp160
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestFactory.h69
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestHashtables.cpp939
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestID.cpp77
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestMinStringAPI.cpp333
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestObserverService.cpp250
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestPermanentAtoms.cpp88
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestPipes.cpp655
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestServMgr.cpp173
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestShutdown.cpp78
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestStackCrawl.cpp11
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestStrings.cpp643
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestThreads.cpp280
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestVoidBTree.cpp302
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/TestXPIDLString.cpp18
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/dynamic/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/dynamic/Makefile.in61
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/dynamic/TestDynamic.cpp76
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/dynamic/win32.order1
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/nsIFileEnumerator.cpp95
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/nsIFileTest.cpp475
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/resources.h52
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/services/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/services/Makefile.in58
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/services/MyService.cpp93
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/services/MyService.h69
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/services/win32.order1
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/test.properties46
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/utils/WhatError.cpp61
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/utils/cp.js111
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/utils/dirs.js155
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/utils/ls.js64
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/windows/.cvsignore1
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/windows/Makefile.in60
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/windows/TestCOM.cpp181
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/windows/TestHelloXPLoop.cpp177
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/windows/nsStringTest.cpp33
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/windows/nsStringTest.h2277
-rw-r--r--src/libs/xpcom18a4/xpcom/tests/windows/nsStringTest2.h444
70 files changed, 13580 insertions, 0 deletions
diff --git a/src/libs/xpcom18a4/xpcom/tests/.cvsignore b/src/libs/xpcom18a4/xpcom/tests/.cvsignore
new file mode 100644
index 00000000..d01075e3
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/.cvsignore
@@ -0,0 +1,31 @@
+CvtURL
+FilesTest
+Makefile
+PropertiesTest
+RegFactory
+SizeTest01
+SizeTest02
+SizeTest03
+SizeTest04
+SizeTest05
+SizeTest06
+TestAtoms
+TestAutoLock
+TestBuffers
+TestCOMPtr
+TestCOMPtrEq
+TestArray
+TestCRT
+TestFactory
+TestID
+TestObserverService
+TestPermanentAtoms
+TestPipes
+TestThreads
+TestVoidBTree
+TestXPIDLString
+TestServMgr
+nsIFileEnumerator
+nsIFileTest
+TestCallTemplates
+TestDeque
diff --git a/src/libs/xpcom18a4/xpcom/tests/CvtURL.cpp b/src/libs/xpcom18a4/xpcom/tests/CvtURL.cpp
new file mode 100644
index 00000000..4dd052ac
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/CvtURL.cpp
@@ -0,0 +1,126 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 <stdio.h>
+#include "nscore.h"
+#include "nsIConverterInputStream.h"
+#include "nsIURL.h"
+#include "nsNetUtil.h"
+#include "nsCRT.h"
+#include "nsString.h"
+#include "prprf.h"
+#include "prtime.h"
+
+static nsString* ConvertCharacterSetName(const char* aName)
+{
+ return new nsString(NS_ConvertASCIItoUCS2(aName));
+}
+
+int main(int argc, char** argv)
+{
+ if (3 != argc) {
+ printf("usage: CvtURL url utf8\n");
+ return -1;
+ }
+
+ char* characterSetName = argv[2];
+ nsString* cset = ConvertCharacterSetName(characterSetName);
+ if (NS_PTR_TO_INT32(cset) < 0) {
+ printf("illegal character set name: '%s'\n", characterSetName);
+ return -1;
+ }
+
+ // Create url object
+ char* urlName = argv[1];
+ nsIURI* url;
+ nsresult rv;
+ rv = NS_NewURI(&url, urlName);
+ if (NS_OK != rv) {
+ printf("invalid URL: '%s'\n", urlName);
+ return -1;
+ }
+
+ // Get an input stream from the url
+ nsresult ec;
+ nsIInputStream* in;
+ ec = NS_OpenURI(&in, url);
+ if (nsnull == in) {
+ printf("open of url('%s') failed: error=%x\n", urlName, ec);
+ return -1;
+ }
+
+ // Translate the input using the argument character set id into
+ // unicode
+ nsCOMPtr<nsIConverterInputStream> uin =
+ do_CreateInstance("@mozilla.org/intl/converter-input-stream;1", &rv);
+ if (NS_SUCCEEDED(rv))
+ uin->Init(in, cset->get(), nsnull, PR_TRUE);
+ if (NS_OK != rv) {
+ printf("can't create converter input stream: %d\n", rv);
+ return -1;
+ }
+
+ // Read the input and write some output
+ PRTime start = PR_Now();
+ PRInt32 count = 0;
+ for (;;) {
+ PRUnichar buf[1000];
+ PRUint32 nb;
+ ec = uin->Read(buf, 0, 1000, &nb);
+ if (NS_FAILED(ec)) {
+ printf("i/o error: %d\n", ec);
+ break;
+ }
+ if (nb == 0) break; // EOF
+ count += nb;
+ }
+ PRTime end = PR_Now();
+ PRTime conversion, ustoms;
+ LL_I2L(ustoms, 1000);
+ LL_SUB(conversion, end, start);
+ LL_DIV(conversion, conversion, ustoms);
+ char buf[500];
+ PR_snprintf(buf, sizeof(buf),
+ "converting and discarding %d bytes took %lldms",
+ count, conversion);
+ puts(buf);
+
+ // Release the objects
+ in->Release();
+ url->Release();
+
+ return 0;
+}
diff --git a/src/libs/xpcom18a4/xpcom/tests/Makefile.in b/src/libs/xpcom18a4/xpcom/tests/Makefile.in
new file mode 100644
index 00000000..2bd730e9
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/Makefile.in
@@ -0,0 +1,116 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# 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 = xpcom
+DIRS = dynamic services
+ifeq ($(OS_ARCH),WINNT)
+DIRS += windows
+endif
+
+REQUIRES = \
+ string \
+ $(NULL)
+
+CPPSRCS = \
+ nsIFileEnumerator.cpp \
+ nsIFileTest.cpp \
+ TestArray.cpp \
+ TestAtoms.cpp \
+ TestAutoLock.cpp \
+ TestCallTemplates.cpp \
+ TestCOMPtr.cpp \
+ TestCOMPtrEq.cpp \
+ TestCRT.cpp \
+ TestFactory.cpp \
+ TestHashtables.cpp \
+ TestID.cpp \
+ TestObserverService.cpp \
+ TestPermanentAtoms.cpp \
+ TestPipes.cpp \
+ TestServMgr.cpp \
+ TestThreads.cpp \
+ TestXPIDLString.cpp \
+ TestDeque.cpp \
+ TestAutoPtr.cpp \
+ TestMinStringAPI.cpp \
+ TestStrings.cpp \
+ $(NULL)
+
+#CPPSRCS += TimerTest.cpp
+
+SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=$(BIN_SUFFIX))
+
+include $(topsrcdir)/config/config.mk
+
+LIBS += \
+ $(XPCOM_LIBS) \
+ $(NSPR_LIBS) \
+ $(NULL)
+
+# Needed to resolve __yylex (?)
+ifeq ($(OS_ARCH)$(OS_RELEASE),FreeBSD2)
+LIBS += -lpcap
+endif
+
+include $(topsrcdir)/config/rules.mk
+
+LOCAL_INCLUDES = \
+ -I$(srcdir)/../ds \
+ -I$(srcdir)/services \
+ $(NULL)
+
+ifeq ($(OS_ARCH),WINNT)
+ifdef GNU_CXX
+CXXFLAGS += -fexceptions
+else
+CXXFLAGS += -GX
+endif
+endif
+
+libs::
+ $(INSTALL) $(srcdir)/test.properties $(DIST)/bin/res
+
+install::
+ $(SYSINSTALL) $(IFLAGS1) $(srcdir)/test.properties $(DESTDIR)$(mozappdir)/res
+
diff --git a/src/libs/xpcom18a4/xpcom/tests/RegFactory.cpp b/src/libs/xpcom18a4/xpcom/tests/RegFactory.cpp
new file mode 100644
index 00000000..79e53394
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/RegFactory.cpp
@@ -0,0 +1,162 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 <iostream.h>
+#include "plstr.h"
+#include "prlink.h"
+#include "nsIComponentRegistrar.h"
+#include "nsIComponentManager.h"
+#include "nsIServiceManager.h"
+#include "nsILocalFile.h"
+#include "nsCOMPtr.h"
+#include "nsString.h"
+
+static PRBool gUnreg = PR_FALSE;
+
+void print_err(nsresult err)
+{
+ switch (err) {
+ case NS_ERROR_FACTORY_NOT_LOADED:
+ cerr << "Factory not loaded";
+ break;
+ case NS_NOINTERFACE:
+ cerr << "No Interface";
+ break;
+ case NS_ERROR_NULL_POINTER:
+ cerr << "Null pointer";
+ break;
+ case NS_ERROR_OUT_OF_MEMORY:
+ cerr << "Out of memory";
+ break;
+ default:
+ cerr << hex << err << dec;
+ }
+}
+
+nsresult Register(nsIComponentRegistrar* registrar, const char *path)
+{
+ nsCOMPtr<nsILocalFile> file;
+ nsresult rv =
+ NS_NewLocalFile(
+ NS_ConvertUTF8toUCS2(path),
+ PR_TRUE,
+ getter_AddRefs(file));
+ if (NS_FAILED(rv)) return rv;
+ rv = registrar->AutoRegister(file);
+ return rv;
+}
+
+nsresult Unregister(const char *path)
+{
+ /* NEEDS IMPLEMENTATION */
+#if 0
+ nsresult res = nsComponentManager::AutoUnregisterComponent(path);
+ return res;
+#else
+ return NS_ERROR_FAILURE;
+#endif
+}
+
+int ProcessArgs(nsIComponentRegistrar* registrar, int argc, char *argv[])
+{
+ int i = 1;
+ nsresult res;
+
+ while (i < argc) {
+ if (argv[i][0] == '-') {
+ int j;
+ for (j = 1; argv[i][j] != '\0'; j++) {
+ switch (argv[i][j]) {
+ case 'u':
+ gUnreg = PR_TRUE;
+ break;
+ default:
+ cerr << "Unknown option '" << argv[i][j] << "'\n";
+ }
+ }
+ i++;
+ } else {
+ if (gUnreg == PR_TRUE) {
+ res = Unregister(argv[i]);
+ if (NS_SUCCEEDED(res)) {
+ cout << "Successfully unregistered: " << argv[i] << "\n";
+ } else {
+ cerr << "Unregister failed (";
+ print_err(res);
+ cerr << "): " << argv[i] << "\n";
+ }
+ } else {
+ res = Register(registrar, argv[i]);
+ if (NS_SUCCEEDED(res)) {
+ cout << "Successfully registered: " << argv[i] << "\n";
+ } else {
+ cerr << "Register failed (";
+ print_err(res);
+ cerr << "): " << argv[i] << "\n";
+ }
+ }
+ i++;
+ }
+ }
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int ret = 0;
+ nsresult rv;
+ {
+ nsCOMPtr<nsIServiceManager> servMan;
+ rv = NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull);
+ if (NS_FAILED(rv)) return -1;
+ nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan);
+ NS_ASSERTION(registrar, "Null nsIComponentRegistrar");
+
+ /* With no arguments, RegFactory will autoregister */
+ if (argc <= 1)
+ {
+ rv = registrar->AutoRegister(nsnull);
+ ret = (NS_FAILED(rv)) ? -1 : 0;
+ }
+ else
+ ret = ProcessArgs(registrar, argc, argv);
+ } // this scopes the nsCOMPtrs
+ // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
+ rv = NS_ShutdownXPCOM( NULL );
+ NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");
+ return ret;
+}
diff --git a/src/libs/xpcom18a4/xpcom/tests/SizeTest01.cpp b/src/libs/xpcom18a4/xpcom/tests/SizeTest01.cpp
new file mode 100644
index 00000000..2d552a36
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/SizeTest01.cpp
@@ -0,0 +1,107 @@
+// Test01.cpp
+
+#include "nsIDOMNode.h"
+#include "nsCOMPtr.h"
+#include "nsString.h"
+
+NS_DEF_PTR(nsIDOMNode);
+
+ /*
+ This test file compares the generated code size of similar functions between raw
+ COM interface pointers (|AddRef|ing and |Release|ing by hand) and |nsCOMPtr|s.
+
+ Function size results were determined by examining dissassembly of the generated code.
+ mXXX is the size of the generated code on the Macintosh. wXXX is the size on Windows.
+ For these tests, all reasonable optimizations were enabled and exceptions were
+ disabled (just as we build for release).
+
+ The tests in this file explore only the simplest functionality: assigning a pointer
+ to be reference counted into a [raw, nsCOMPtr] object; ensuring that it is
+ |AddRef|ed and |Release|d appropriately; calling through the pointer to a function
+ supplied by the underlying COM interface.
+
+ Windows:
+ raw_optimized 31 bytes
+ raw, nsCOMPtr* 34
+ nsCOMPtr_optimized* 38
+ nsCOMPtr_optimized 42
+ nsCOMPtr 46
+
+ Macintosh:
+ raw_optimized, nsCOMPtr_optimized 112 bytes (1.0000)
+ nsCOMPtr 120 (1.0714) i.e., 7.14% bigger than raw_optimized et al
+ raw 140 (1.2500)
+
+ The overall difference in size between Windows and Macintosh is caused by the
+ the PowerPC RISC architecture where every instruction is 4 bytes.
+
+ On Macintosh, nsCOMPtr generates out-of-line destructors which are
+ not referenced, and which can be stripped by the linker.
+ */
+
+void
+Test01_raw( nsIDOMNode* aDOMNode, nsString* aResult )
+ // m140, w34
+ {
+ /*
+ This test is designed to be more like a typical large function where,
+ because you are working with several resources, you don't just return when
+ one of them is |NULL|. Similarly: |Test01_nsCOMPtr00|, and |Test01_nsIPtr00|.
+ */
+
+ nsIDOMNode* node = aDOMNode;
+ NS_IF_ADDREF(node);
+
+ if ( node )
+ node->GetNodeName(*aResult);
+
+ NS_IF_RELEASE(node);
+ }
+
+void
+Test01_raw_optimized( nsIDOMNode* aDOMNode, nsString* aResult )
+ // m112, w31
+ {
+ /*
+ This test simulates smaller functions where you _do_ just return
+ |NULL| at the first sign of trouble. Similarly: |Test01_nsCOMPtr01|,
+ and |Test01_nsIPtr01|.
+ */
+
+ /*
+ This test produces smaller code that |Test01_raw| because it avoids
+ the three tests: |NS_IF_...|, and |if ( node )|.
+ */
+
+// -- the following code is assumed, but is commented out so we compare only
+// the relevent generated code
+
+// if ( !aDOMNode )
+// return;
+
+ nsIDOMNode* node = aDOMNode;
+ NS_ADDREF(node);
+ node->GetNodeName(*aResult);
+ NS_RELEASE(node);
+ }
+
+void
+Test01_nsCOMPtr( nsIDOMNode* aDOMNode, nsString* aResult )
+ // m120, w46/34
+ {
+ nsCOMPtr<nsIDOMNode> node = aDOMNode;
+
+ if ( node )
+ node->GetNodeName(*aResult);
+ }
+
+void
+Test01_nsCOMPtr_optimized( nsIDOMNode* aDOMNode, nsString* aResult )
+ // m112, w42/38
+ {
+// if ( !aDOMNode )
+// return;
+
+ nsCOMPtr<nsIDOMNode> node = aDOMNode;
+ node->GetNodeName(*aResult);
+ }
diff --git a/src/libs/xpcom18a4/xpcom/tests/SizeTest02.cpp b/src/libs/xpcom18a4/xpcom/tests/SizeTest02.cpp
new file mode 100644
index 00000000..8515fcb1
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/SizeTest02.cpp
@@ -0,0 +1,93 @@
+// Test02.cpp
+
+#include "nsIDOMNode.h"
+#include "nsCOMPtr.h"
+#include "nsString.h"
+
+#ifdef __MWERKS__
+ #pragma exceptions off
+#endif
+
+NS_DEF_PTR(nsIDOMNode);
+
+ /*
+ This test file compares the generated code size of similar functions between raw
+ COM interface pointers (|AddRef|ing and |Release|ing by hand) and |nsCOMPtr|s.
+
+ Function size results were determined by examining dissassembly of the generated code.
+ mXXX is the size of the generated code on the Macintosh. wXXX is the size on Windows.
+ For these tests, all reasonable optimizations were enabled and exceptions were
+ disabled (just as we build for release).
+
+ The tests in this file explore more complicated functionality: assigning a pointer
+ to be reference counted into a [raw, nsCOMPtr] object using |QueryInterface|;
+ ensuring that it is |AddRef|ed and |Release|d appropriately; calling through the pointer
+ to a function supplied by the underlying COM interface. The tests in this file expand
+ on the tests in "Test01.cpp" by adding |QueryInterface|.
+
+ Windows:
+ raw01 52
+ nsCOMPtr 63
+ raw 66
+ nsCOMPtr* 68
+
+ Macintosh:
+ nsCOMPtr 120 (1.0000)
+ Raw01 128 (1.1429) i.e., 14.29% bigger than nsCOMPtr
+ Raw00 144 (1.2000)
+ */
+
+
+void // nsresult
+Test02_Raw00( nsISupports* aDOMNode, nsString* aResult )
+ // m144, w66
+ {
+// -- the following code is assumed, but is commented out so we compare only
+// the relevent generated code
+
+// if ( !aDOMNode )
+// return NS_ERROR_NULL_POINTER;
+
+ nsIDOMNode* node = 0;
+ nsresult status = aDOMNode->QueryInterface(NS_GET_IID(nsIDOMNode), (void**)&node);
+ if ( NS_SUCCEEDED(status) )
+ {
+ node->GetNodeName(*aResult);
+ }
+
+ NS_IF_RELEASE(node);
+
+// return status;
+ }
+
+void // nsresult
+Test02_Raw01( nsISupports* aDOMNode, nsString* aResult )
+ // m128, w52
+ {
+// if ( !aDOMNode )
+// return NS_ERROR_NULL_POINTER;
+
+ nsIDOMNode* node;
+ nsresult status = aDOMNode->QueryInterface(NS_GET_IID(nsIDOMNode), (void**)&node);
+ if ( NS_SUCCEEDED(status) )
+ {
+ node->GetNodeName(*aResult);
+ NS_RELEASE(node);
+ }
+
+// return status;
+ }
+
+void // nsresult
+Test02_nsCOMPtr( nsISupports* aDOMNode, nsString* aResult )
+ // m120, w63/68
+ {
+ nsresult status;
+ nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aDOMNode, &status);
+
+ if ( node )
+ node->GetNodeName(*aResult);
+
+// return status;
+ }
+
diff --git a/src/libs/xpcom18a4/xpcom/tests/SizeTest03.cpp b/src/libs/xpcom18a4/xpcom/tests/SizeTest03.cpp
new file mode 100644
index 00000000..9ca71c72
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/SizeTest03.cpp
@@ -0,0 +1,101 @@
+// Test03.cpp
+
+#include "nsIDOMNode.h"
+#include "nsCOMPtr.h"
+#include "nsString.h"
+
+#ifdef __MWERKS__
+ #pragma exceptions off
+#endif
+
+NS_DEF_PTR(nsIDOMNode);
+
+ /*
+ Windows:
+ nsCOMPtr_optimized* 45
+ raw_optimized 48
+ nsCOMPtr_optimized 50
+ nsCOMPtr 54
+ nsCOMPtr* 59
+ raw 62
+
+ Macintosh:
+ nsCOMPtr_optimized 112 (1.0000)
+ raw_optimized 124 bytes (1.1071) i.e., 10.71% bigger than nsCOMPtr_optimized
+ nsCOMPtr 144 (1.2857)
+ */
+
+void // nsresult
+Test03_raw( nsIDOMNode* aDOMNode, nsString* aResult )
+ // m140, w62
+ {
+// -- the following code is assumed, but is commented out so we compare only
+// the relevent generated code
+
+// if ( !aDOMNode || !aResult )
+// return NS_ERROR_NULL_POINTER;
+
+ nsIDOMNode* parent = 0;
+ nsresult status = aDOMNode->GetParentNode(&parent);
+
+ if ( NS_SUCCEEDED(status) )
+ {
+ parent->GetNodeName(*aResult);
+ }
+
+ NS_IF_RELEASE(parent);
+
+// return status;
+ }
+
+
+void // nsresult
+Test03_raw_optimized( nsIDOMNode* aDOMNode, nsString* aResult )
+ // m124, w48
+ {
+// if ( !aDOMNode || !aResult )
+// return NS_ERROR_NULL_POINTER;
+
+ nsIDOMNode* parent;
+ nsresult status = aDOMNode->GetParentNode(&parent);
+
+ if ( NS_SUCCEEDED(status) )
+ {
+ parent->GetNodeName(*aResult);
+ NS_RELEASE(parent);
+ }
+
+// return status;
+ }
+
+
+void // nsresult
+Test03_nsCOMPtr( nsIDOMNode* aDOMNode, nsString* aResult )
+ // m144, w54/59
+ {
+// if ( !aDOMNode || !aResult )
+// return NS_ERROR_NULL_POINTER;
+
+ nsCOMPtr<nsIDOMNode> parent;
+ nsresult status = aDOMNode->GetParentNode( getter_AddRefs(parent) );
+ if ( parent )
+ parent->GetNodeName(*aResult);
+
+// return status;
+ }
+
+void // nsresult
+Test03_nsCOMPtr_optimized( nsIDOMNode* aDOMNode, nsString* aResult )
+ // m112, w50/45
+ {
+// if ( !aDOMNode || !aResult )
+// return NS_ERROR_NULL_POINTER;
+
+ nsIDOMNode* temp;
+ nsresult status = aDOMNode->GetParentNode(&temp);
+ nsCOMPtr<nsIDOMNode> parent( dont_AddRef(temp) );
+ if ( parent )
+ parent->GetNodeName(*aResult);
+
+// return status;
+ }
diff --git a/src/libs/xpcom18a4/xpcom/tests/SizeTest04.cpp b/src/libs/xpcom18a4/xpcom/tests/SizeTest04.cpp
new file mode 100644
index 00000000..aad4ee68
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/SizeTest04.cpp
@@ -0,0 +1,72 @@
+// Test04.cpp
+
+#include "nsIDOMNode.h"
+#include "nsCOMPtr.h"
+
+#ifdef __MWERKS__
+ #pragma exceptions off
+#endif
+
+NS_DEF_PTR(nsIDOMNode);
+
+ /*
+ Windows:
+ nsCOMPtr 13
+ raw 36
+
+ Macintosh:
+ nsCOMPtr 36 bytes (1.0000)
+ raw 120 (3.3333) i.e., 333.33% bigger than nsCOMPtr
+ */
+
+class Test04_Raw
+ {
+ public:
+ Test04_Raw();
+ ~Test04_Raw();
+
+ void /*nsresult*/ SetNode( nsIDOMNode* newNode );
+
+ private:
+ nsIDOMNode* mNode;
+ };
+
+Test04_Raw::Test04_Raw()
+ : mNode(0)
+ {
+ // nothing else to do here
+ }
+
+Test04_Raw::~Test04_Raw()
+ {
+ NS_IF_RELEASE(mNode);
+ }
+
+void // nsresult
+Test04_Raw::SetNode( nsIDOMNode* newNode )
+ // m120, w36
+ {
+ NS_IF_ADDREF(newNode);
+ NS_IF_RELEASE(mNode);
+ mNode = newNode;
+
+// return NS_OK;
+ }
+
+
+
+class Test04_nsCOMPtr
+ {
+ public:
+ void /*nsresult*/ SetNode( nsIDOMNode* newNode );
+
+ private:
+ nsCOMPtr<nsIDOMNode> mNode;
+ };
+
+void // nsresult
+Test04_nsCOMPtr::SetNode( nsIDOMNode* newNode )
+ // m36, w13/13
+ {
+ mNode = newNode;
+ }
diff --git a/src/libs/xpcom18a4/xpcom/tests/SizeTest05.cpp b/src/libs/xpcom18a4/xpcom/tests/SizeTest05.cpp
new file mode 100644
index 00000000..0211610e
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/SizeTest05.cpp
@@ -0,0 +1,78 @@
+// Test05.cpp
+
+#include "nsIDOMNode.h"
+#include "nsCOMPtr.h"
+
+#ifdef __MWERKS__
+ #pragma exceptions off
+#endif
+
+NS_DEF_PTR(nsIDOMNode);
+
+ /*
+ Windows:
+ raw, nsCOMPtr 21 bytes
+
+ Macintosh:
+ Raw, nsCOMPtr 64 bytes
+ */
+
+class Test05_Raw
+ {
+ public:
+ Test05_Raw();
+ ~Test05_Raw();
+
+ void /*nsresult*/ GetNode( nsIDOMNode** aNode );
+
+ private:
+ nsIDOMNode* mNode;
+ };
+
+Test05_Raw::Test05_Raw()
+ : mNode(0)
+ {
+ // nothing else to do here
+ }
+
+Test05_Raw::~Test05_Raw()
+ {
+ NS_IF_RELEASE(mNode);
+ }
+
+void // nsresult
+Test05_Raw::GetNode( nsIDOMNode** aNode )
+ // m64, w21
+ {
+// if ( !aNode )
+// return NS_ERROR_NULL_POINTER;
+
+ *aNode = mNode;
+ NS_IF_ADDREF(*aNode);
+
+// return NS_OK;
+ }
+
+
+
+class Test05_nsCOMPtr
+ {
+ public:
+ void /*nsresult*/ GetNode( nsIDOMNode** aNode );
+
+ private:
+ nsCOMPtr<nsIDOMNode> mNode;
+ };
+
+void // nsresult
+Test05_nsCOMPtr::GetNode( nsIDOMNode** aNode )
+ // m64, w21
+ {
+// if ( !aNode )
+// return NS_ERROR_NULL_POINTER;
+
+ *aNode = mNode;
+ NS_IF_ADDREF(*aNode);
+
+// return NS_OK;
+ }
diff --git a/src/libs/xpcom18a4/xpcom/tests/SizeTest06.cpp b/src/libs/xpcom18a4/xpcom/tests/SizeTest06.cpp
new file mode 100644
index 00000000..2c28e7f3
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/SizeTest06.cpp
@@ -0,0 +1,231 @@
+// Test06.cpp
+
+#include "nsIDOMWindowInternal.h"
+#include "nsIScriptGlobalObject.h"
+#include "nsIWebShell.h"
+#include "nsIDocShell.h"
+#include "nsIWebShellWindow.h"
+#include "nsCOMPtr.h"
+
+NS_DEF_PTR(nsIScriptGlobalObject);
+NS_DEF_PTR(nsIWebShell);
+NS_DEF_PTR(nsIWebShellContainer);
+NS_DEF_PTR(nsIWebShellWindow);
+
+ /*
+ Windows:
+ nsCOMPtr_optimized 176
+ nsCOMPtr_as_found 181
+ nsCOMPtr_optimized* 182
+ nsCOMPtr02* 184
+ nsCOMPtr02 187
+ nsCOMPtr02* 188
+ nsCOMPtr03 189
+ raw_optimized, nsCOMPtr00 191
+ nsCOMPtr00* 199
+ nsCOMPtr_as_found* 201
+ raw 214
+
+ Macintosh:
+ nsCOMPtr_optimized 300 (1.0000)
+ nsCOMPtr02 320 (1.0667) i.e., 6.67% bigger than nsCOMPtr_optimized
+ nsCOMPtr00 328 (1.0933)
+ raw_optimized, nsCOMPtr03 332 (1.1067)
+ nsCOMPtr_as_found 344 (1.1467)
+ raw 388 (1.2933)
+
+ */
+
+
+void // nsresult
+Test06_raw(nsIDOMWindowInternal* aDOMWindow, nsIWebShellWindow** aWebShellWindow)
+ // m388, w214
+{
+// if (!aDOMWindow)
+// return NS_ERROR_NULL_POINTER;
+ nsIScriptGlobalObject* scriptGlobalObject = 0;
+ nsresult status = aDOMWindow->QueryInterface(NS_GET_IID(nsIScriptGlobalObject), (void**)&scriptGlobalObject);
+ nsIDocShell* docShell = 0;
+ if (scriptGlobalObject)
+ scriptGlobalObject->GetDocShell(&docShell);
+ nsIWebShell* webShell = 0;
+ if (docShell)
+ status=docShell->QueryInterface(NS_GET_IID(nsIWebShell), (void**)&webShell);
+ nsIWebShell* rootWebShell = 0;
+ if (webShell)
+ //status = webShell->GetRootWebShellEvenIfChrome(rootWebShell);
+ {}
+ nsIWebShellContainer* webShellContainer = 0;
+ if (rootWebShell)
+ status = rootWebShell->GetContainer(webShellContainer);
+ if (webShellContainer)
+ status = webShellContainer->QueryInterface(NS_GET_IID(nsIWebShellWindow), (void**)aWebShellWindow);
+ else
+ (*aWebShellWindow) = 0;
+ NS_IF_RELEASE(webShellContainer);
+ NS_IF_RELEASE(rootWebShell);
+ NS_IF_RELEASE(webShell);
+ NS_IF_RELEASE(docShell);
+ NS_IF_RELEASE(scriptGlobalObject);
+// return status;
+}
+
+void // nsresult
+Test06_raw_optimized(nsIDOMWindowInternal* aDOMWindow, nsIWebShellWindow** aWebShellWindow)
+ // m332, w191
+{
+// if (!aDOMWindow)
+// return NS_ERROR_NULL_POINTER;
+ (*aWebShellWindow) = 0;
+ nsIScriptGlobalObject* scriptGlobalObject;
+ nsresult status = aDOMWindow->QueryInterface(NS_GET_IID(nsIScriptGlobalObject), (void**)&scriptGlobalObject);
+ if (NS_SUCCEEDED(status)) {
+ nsIDocShell* docShell = 0;
+ scriptGlobalObject->GetDocShell(&docShell);
+ if (docShell) {
+ nsIWebShell* webShell = 0;
+ docShell->QueryInterface(NS_GET_IID(nsIWebShell), (void**)webShell);
+ if (webShell) {
+ nsIWebShell* rootWebShell;
+ // status = webShell->GetRootWebShellEvenIfChrome(rootWebShell);
+ if (NS_SUCCEEDED(status)) {
+ nsIWebShellContainer* webShellContainer;
+ status = rootWebShell->GetContainer(webShellContainer);
+ if (NS_SUCCEEDED(status)) {
+ status = webShellContainer->QueryInterface(NS_GET_IID(nsIWebShellWindow), (void**)aWebShellWindow);
+ NS_RELEASE(webShellContainer);
+ }
+ NS_RELEASE(rootWebShell);
+ }
+ NS_RELEASE(webShell);
+ }
+ NS_RELEASE(docShell);
+ }
+ NS_RELEASE(scriptGlobalObject);
+ }
+// return status;
+}
+
+void
+Test06_nsCOMPtr_as_found(nsIDOMWindowInternal* aDOMWindow, nsCOMPtr<nsIWebShellWindow>* aWebShellWindow)
+ // m344, w181/201
+{
+// if (!aDOMWindow)
+// return;
+ nsCOMPtr<nsIScriptGlobalObject> scriptGlobalObject = do_QueryInterface(aDOMWindow);
+ nsCOMPtr<nsIDocShell> docShell;
+ if (scriptGlobalObject)
+ scriptGlobalObject->GetDocShell(getter_AddRefs(docShell));
+ nsCOMPtr<nsIWebShell> webShell;
+ if (docShell)
+ webShell = do_QueryInterface(docShell);
+ nsCOMPtr<nsIWebShell> rootWebShell;
+ if (webShell)
+ //webShell->GetRootWebShellEvenIfChrome(*getter_AddRefs(rootWebShell));
+ {}
+ nsCOMPtr<nsIWebShellContainer> webShellContainer;
+ if (rootWebShell)
+ rootWebShell->GetContainer(*getter_AddRefs(webShellContainer));
+ (*aWebShellWindow) = do_QueryInterface(webShellContainer);
+}
+
+void // nsresult
+Test06_nsCOMPtr00(nsIDOMWindowInternal* aDOMWindow, nsIWebShellWindow** aWebShellWindow)
+ // m328, w191/199
+{
+// if (!aDOMWindow)
+// return NS_ERROR_NULL_POINTER;
+ nsresult status;
+ nsCOMPtr<nsIScriptGlobalObject> scriptGlobalObject = do_QueryInterface(aDOMWindow, &status);
+ nsIDocShell* temp0 = 0;
+ if (scriptGlobalObject)
+ scriptGlobalObject->GetDocShell(&temp0);
+ nsCOMPtr<nsIDocShell> docShell = dont_AddRef(temp0);
+ nsCOMPtr<nsIWebShell> webShell;
+ if (docShell)
+ webShell=do_QueryInterface(docShell, &status);
+ nsIWebShellContainer* temp2 = 0;
+ if (webShell)
+ status = webShell->GetContainer(temp2);
+ nsCOMPtr<nsIWebShellContainer> webShellContainer = dont_AddRef(temp2);
+ if (webShellContainer)
+ status = webShellContainer->QueryInterface(NS_GET_IID(nsIWebShellWindow), (void**)aWebShellWindow);
+ else
+ (*aWebShellWindow) = 0;
+// return status;
+}
+
+void // nsresult
+Test06_nsCOMPtr_optimized(nsIDOMWindowInternal* aDOMWindow, nsCOMPtr<nsIWebShellWindow>* aWebShellWindow)
+ // m300, w176/182
+{
+// if (!aDOMWindow)
+// return NS_ERROR_NULL_POINTER;
+ nsresult status;
+ nsCOMPtr<nsIScriptGlobalObject> scriptGlobalObject = do_QueryInterface(aDOMWindow, &status);
+ nsIDocShell* temp0 = 0;
+ if (scriptGlobalObject)
+ scriptGlobalObject->GetDocShell(&temp0);
+ nsCOMPtr<nsIWebShell> webShell = do_QueryInterface(temp0, &status);
+ nsIWebShell* temp2 = 0;
+ if (webShell)
+ // status = webShell->GetRootWebShellEvenIfChrome(temp2);
+ {}
+ nsCOMPtr<nsIWebShell> rootWebShell = dont_AddRef(temp2);
+ nsIWebShellContainer* temp3 = 0;
+ if (rootWebShell)
+ status = rootWebShell->GetContainer(temp3);
+ nsCOMPtr<nsIWebShellContainer> webShellContainer = dont_AddRef(temp3);
+ (*aWebShellWindow) = do_QueryInterface(webShellContainer, &status);
+// return status;
+}
+
+void // nsresult
+Test06_nsCOMPtr02(nsIDOMWindowInternal* aDOMWindow, nsIWebShellWindow** aWebShellWindow)
+ // m320, w187/184
+{
+// if (!aDOMWindow)
+// return NS_ERROR_NULL_POINTER;
+ (*aWebShellWindow) = 0;
+ nsresult status;
+ nsCOMPtr<nsIScriptGlobalObject> scriptGlobalObject = do_QueryInterface(aDOMWindow, &status);
+ if (scriptGlobalObject) {
+ nsIDocShell* temp0;
+ scriptGlobalObject->GetDocShell(&temp0);
+ nsCOMPtr<nsIWebShell> webShell = do_QueryInterface(temp0);
+ if (webShell) {
+ nsIWebShellContainer* temp2;
+ status = webShell->GetContainer(temp2);
+ nsCOMPtr<nsIWebShellContainer> webShellContainer = dont_AddRef(temp2);
+ if (webShellContainer)
+ status = webShellContainer->QueryInterface(NS_GET_IID(nsIWebShellWindow), (void**)aWebShellWindow);
+ }
+ }
+// return status;
+}
+
+void // nsresult
+Test06_nsCOMPtr03(nsIDOMWindowInternal* aDOMWindow, nsCOMPtr<nsIWebShellWindow>* aWebShellWindow)
+ // m332, w189/188
+{
+// if (!aDOMWindow)
+// return NS_ERROR_NULL_POINTER;
+ (*aWebShellWindow) = 0;
+ nsresult status;
+ nsCOMPtr<nsIScriptGlobalObject> scriptGlobalObject = do_QueryInterface(aDOMWindow, &status);
+ if (scriptGlobalObject) {
+ nsIDocShell* temp0;
+ scriptGlobalObject->GetDocShell(&temp0);
+ nsCOMPtr<nsIDocShell> docShell = dont_AddRef(temp0);
+ if (docShell) {
+ nsCOMPtr<nsIWebShell> webShell = do_QueryInterface(docShell, &status);
+ if (webShell) {
+ nsIWebShellContainer* temp2;
+ status = webShell->GetContainer(temp2);
+ nsCOMPtr<nsIWebShellContainer> webShellContainer = dont_AddRef(temp2);
+ (*aWebShellWindow) = do_QueryInterface(webShellContainer, &status);
+ }
+ }
+ }
+// return status;
+}
diff --git a/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/Makefile.in b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/Makefile.in
new file mode 100644
index 00000000..1ced5d3e
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/Makefile.in
@@ -0,0 +1,76 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# 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 = xpcom
+PROGRAM = profile_strings
+#PROGRAM = test_main
+
+CPPSRCS = \
+ $(topsrcdir)/xpcom/ds/nsString2.cpp \
+ $(topsrcdir)/xpcom/ds/nsStr.cpp \
+ $(topsrcdir)/xpcom/ds/nsString.cpp \
+ $(topsrcdir)/xpcom/ds/nsCRT.cpp \
+ $(topsrcdir)/xpcom/base/nsAllocator.cpp \
+ $(topsrcdir)/xpcom/ds/nsDeque.cpp \
+ profile_main.cpp \
+ $(NULL)
+# test_main.cpp \
+
+
+LIBS += \
+ $(NSPR_LIBS) \
+ $(NULL)
+
+include $(topsrcdir)/config/rules.mk
+
+DEFINES += -DNEW_STRING_APIS -DSTANDALONE_STRING_TESTS -UDEBUG -DNDEBUG
+#DEFINES += -DSTANDALONE_STRING_TESTS -UDEBUG -DNDEBUG
+INCLUDES += -I$(srcdir)/../public -I$(srcdir)/services
+
+libs::
+ $(INSTALL) $(srcdir)/test.properties $(DIST)/bin/res
+
+install::
+ $(SYSINSTALL) $(IFLAGS1) $(srcdir)/test.properties $(DESTDIR)$(mozappdir)/res
+
diff --git a/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTest.Prefix b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTest.Prefix
new file mode 100644
index 00000000..b9580e49
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTest.Prefix
@@ -0,0 +1,4 @@
+// StringTest.Prefix
+
+#define STANDALONE_STRING_TESTS
+#define HAVE_CPP_2BYTE_WCHAR_T
diff --git a/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTest.mcp b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTest.mcp
new file mode 100644
index 00000000..12b125ed
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTest.mcp
Binary files differ
diff --git a/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestDebug.Prefix b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestDebug.Prefix
new file mode 100644
index 00000000..3724af94
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestDebug.Prefix
@@ -0,0 +1,4 @@
+#include "StringTest.Prefix"
+
+#define DEBUG 1
+#undef NDEBUG
diff --git a/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestNo_wchar_t.Prefix b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestNo_wchar_t.Prefix
new file mode 100644
index 00000000..dddf8450
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestNo_wchar_t.Prefix
@@ -0,0 +1,5 @@
+// StringTestNo_wchar_t.Prefix
+
+#include "StringTest.Prefix"
+
+#undef HAVE_CPP_2BYTE_WCHAR_T
diff --git a/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestProfileNew.Prefix b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestProfileNew.Prefix
new file mode 100644
index 00000000..b6ca50d3
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestProfileNew.Prefix
@@ -0,0 +1,3 @@
+// StringTestProfileNew.Prefix
+
+#include "StringTest.Prefix"
diff --git a/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestProfileOld.Prefix b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestProfileOld.Prefix
new file mode 100644
index 00000000..d23e3ea9
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestProfileOld.Prefix
@@ -0,0 +1,6 @@
+// StringTestProfileOld.Prefix
+
+#include "StringTest.Prefix"
+
+#define OLD_STRING_APIS
+#undef HAVE_CPP_2BYTE_WCHAR_T \ No newline at end of file
diff --git a/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestProfileStd.Prefix b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestProfileStd.Prefix
new file mode 100644
index 00000000..eb8a7a85
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTestProfileStd.Prefix
@@ -0,0 +1,7 @@
+// StringTestProfileOld.Prefix
+
+#include "StringTest.Prefix"
+
+#define OLD_STRING_APIS
+#define TEST_STD_STRING
+#undef HAVE_CPP_2BYTE_WCHAR_T \ No newline at end of file
diff --git a/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/ToDo.doc b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/ToDo.doc
new file mode 100644
index 00000000..da114471
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/ToDo.doc
@@ -0,0 +1,41 @@
+// To Do...
+
+ - Decide: do I really want to define |Equals| (i.e., so many extra signatures)
+
+ . Make |ns[C]String| rename its converting operations to, e.g., |EqualsWithConversion|,
+ |AssignWithConversion|, |CompareWithConversion|, |AppendWithConversion|, etc.
+
+ . Bring |Equals| and |Compare| into scope
+
+ . Implement chunky iterators
+
+ . Get "nsAReadableString.h" and "nsAWritableString.h" to added to the MANIFEST, etc.
+
+ - Get "nsAReadableString.h" and "nsAWritableString.h" to compile everywhere
+
+ - Add test for |Replace|...
+
+ - Add tests for Find and RFind
+
+ - Implement the Find and RFind signatures
+
+ . Fix Truncate / SetLength confusion (make SetLength the real function in |nsString|)
+
+ . Chop out conflicting |ns[C]String| operators
+
+ . Figure out how if we can make PRUnichar be wchar_t, so we get the cheap constructors,
+ ...and ensure the cheap constructors can be made to work everywhere
+
+ x Try the |static const unsigned long kLeftString = 1 - 1; /* because VC++ doesn't like =0 */| hack
+
+ . Add tests for |nsShared[C]String|
+
+ . Implement |nsShared[C]String|
+
+ - Add tests for the shared string smart pointer
+
+ . Implement the shared string smart pointer
+
+ . Figure out why StdStringWrapper isn't as good as raw std::string
+
+ - Implement a smart allocator for StdStringWrapper
diff --git a/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/nsStdStringWrapper.h b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/nsStdStringWrapper.h
new file mode 100644
index 00000000..6e43b528
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/nsStdStringWrapper.h
@@ -0,0 +1,234 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Scott Collins <scc@mozilla.org>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsStdStringWrapper_h___
+#define nsStdStringWrapper_h___
+
+#include <string>
+
+#ifndef nsAString_h___
+#include "nsAString.h"
+#endif
+
+
+template <class T>
+class nsStringAllocator
+ : public std::allocator<T> // temporarily
+ {
+ // ...
+ };
+
+
+template < class CharT, class TraitsT = nsCharTraits<CharT>, class AllocatorT = nsStringAllocator<CharT> >
+class basic_nsStdStringWrapper
+ : public basic_nsAString<CharT>
+ /*
+ ...
+ */
+ {
+ protected:
+ std::basic_string<CharT, TraitsT, AllocatorT> mRawString;
+
+ typedef std::basic_string<CharT, TraitsT, AllocatorT> basic_string_t;
+
+ using typename basic_string_t::traits_type;
+ using typename basic_string_t::value_type;
+ using typename basic_string_t::allocator_type;
+ using typename basic_string_t::size_type;
+ using typename basic_string_t::difference_type;
+ using typename basic_string_t::reference;
+ using typename basic_string_t::const_reference;
+ using typename basic_string_t::pointer;
+ using typename basic_string_t::const_pointer;
+ using typename basic_string_t::iterator;
+ using typename basic_string_t::const_iterator;
+ using typename basic_string_t::reverse_iterator;
+ using typename basic_string_t::const_reverse_iterator;
+
+ static const size_type npos = size_type(-1);
+
+ protected:
+ virtual const void* Implementation() const;
+
+ virtual const CharT* GetReadableFragment( nsReadableFragment<CharT>&, nsFragmentRequest, PRUint32 ) const;
+ virtual CharT* GetWritableFragment( nsWritableFragment<CharT>&, nsFragmentRequest, PRUint32 );
+
+ public:
+ basic_nsStdStringWrapper() { }
+
+#if 0
+ explicit
+ basic_nsStdStringWrapper( const AllocatorT& a = AllocatorT() )
+ : mRawString(a)
+ {
+ }
+#endif
+
+ explicit
+ basic_nsStdStringWrapper( const basic_nsAString<CharT>& str )
+ {
+ Assign(str);
+ }
+
+#if 0
+ explicit
+ basic_nsStdStringWrapper( const basic_string_t& str, size_type pos = 0, size_type n = npos )
+ : mRawString(str, pos, n)
+ {
+ }
+
+ basic_nsStdStringWrapper( const basic_string_t& str, size_type pos, size_type n, const AllocatorT& a )
+ : mRawString(str, pos, n, a)
+ {
+ }
+#endif
+
+ basic_nsStdStringWrapper( const CharT* s, size_type n, const AllocatorT& a = AllocatorT() )
+ : mRawString(s, n, a)
+ {
+ }
+
+ explicit
+ basic_nsStdStringWrapper( const CharT* s, const AllocatorT& a = AllocatorT() )
+ : mRawString(s, a)
+ {
+ }
+
+#if 0
+ basic_nsStdStringWrapper( size_type n, CharT c, const AllocatorT& a = AllocatorT() )
+ : mRawString(n, c, a)
+ {
+ }
+#endif
+
+ virtual
+ PRUint32
+ Length() const
+ {
+ return mRawString.length();
+ }
+
+ virtual
+ void
+ SetCapacity( PRUint32 aNewCapacity )
+ {
+ mRawString.reserve(aNewCapacity);
+ }
+
+ virtual
+ void
+ SetLength( PRUint32 aNewLength )
+ {
+ mRawString.resize(aNewLength);
+ }
+
+ protected:
+ virtual void do_AssignFromReadable( const basic_nsAString<CharT>& );
+
+ // ...
+ };
+
+NS_DEF_TEMPLATE_STRING_COMPARISON_OPERATORS(basic_nsStdStringWrapper<CharT>, CharT)
+
+
+
+template <class CharT, class TraitsT, class AllocatorT>
+const void*
+basic_nsStdStringWrapper<CharT, TraitsT, AllocatorT>::Implementation() const
+ {
+ static const char* implementation = "nsStdStringWrapper";
+ return implementation;
+ }
+
+
+template <class CharT, class TraitsT, class AllocatorT>
+const CharT*
+basic_nsStdStringWrapper<CharT, TraitsT, AllocatorT>::GetReadableFragment( nsReadableFragment<CharT>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset ) const
+ {
+ switch ( aRequest )
+ {
+ case kFirstFragment:
+ case kLastFragment:
+ case kFragmentAt:
+ aFragment.mEnd = (aFragment.mStart = mRawString.data()) + mRawString.length();
+ return aFragment.mStart + aOffset;
+
+ case kPrevFragment:
+ case kNextFragment:
+ default:
+ return 0;
+ }
+ }
+
+template <class CharT, class TraitsT, class AllocatorT>
+CharT*
+basic_nsStdStringWrapper<CharT, TraitsT, AllocatorT>::GetWritableFragment( nsWritableFragment<CharT>& aFragment, nsFragmentRequest aRequest, PRUint32 aOffset )
+ {
+ switch ( aRequest )
+ {
+ case kFirstFragment:
+ case kLastFragment:
+ case kFragmentAt:
+ aFragment.mEnd = (aFragment.mStart = NS_CONST_CAST(CharT*, mRawString.data())) + mRawString.length();
+ return aFragment.mStart + aOffset;
+
+ case kPrevFragment:
+ case kNextFragment:
+ default:
+ return 0;
+ }
+ }
+
+template <class CharT, class TraitsT, class AllocatorT>
+void
+basic_nsStdStringWrapper<CharT, TraitsT, AllocatorT>::do_AssignFromReadable( const basic_nsAString<CharT>& rhs )
+ {
+ typedef basic_nsStdStringWrapper<CharT, TraitsT, AllocatorT> this_t;
+
+ if ( SameImplementation(*this, rhs) )
+ mRawString = NS_STATIC_CAST(this_t, rhs).mRawString;
+ else
+ basic_nsAString<CharT>::do_AssignFromReadable(rhs);
+ }
+
+
+typedef basic_nsStdStringWrapper<PRUnichar> nsStdString;
+typedef basic_nsStdStringWrapper<char> nsStdCString;
+
+
+#endif // !defined(nsStdStringWrapper_h___)
diff --git a/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/profile_main.cpp b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/profile_main.cpp
new file mode 100644
index 00000000..d7c14621
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/profile_main.cpp
@@ -0,0 +1,497 @@
+// profile_main.cpp
+
+#include "nscore.h"
+#include <iostream.h>
+#include <string>
+#include <iomanip>
+
+#include "nsInt64.h"
+
+#ifdef XP_MAC
+#include <Timer.h>
+#include "Profiler.h"
+#else
+#include "prtime.h"
+#endif
+
+#ifndef TEST_STD_STRING
+#include "nsString.h"
+#else
+#include "nsStdStringWrapper.h"
+typedef nsStdCString nsCString;
+#endif
+
+static const int kTestSucceeded = 0;
+static const int kTestFailed = 1;
+
+static const size_t N = 100000;
+
+
+template <class T>
+inline
+PRUint32
+TotalLength( const T& s )
+ {
+ return s.Length();
+ }
+
+NS_SPECIALIZE_TEMPLATE
+inline
+PRUint32
+TotalLength( const string& s )
+ {
+ return s.length();
+ }
+
+template <class T>
+inline
+PRUint32
+Find( const T& text, const T& pattern )
+ {
+ return text.Find(pattern);
+ }
+
+NS_SPECIALIZE_TEMPLATE
+inline
+PRUint32
+Find( const string& text, const string& pattern )
+ {
+ return text.find(pattern);
+ }
+
+inline
+nsInt64
+GetTime()
+ {
+#ifdef XP_MAC
+ UnsignedWide time;
+ Microseconds(&time);
+ return nsInt64( *reinterpret_cast<PRInt64*>(&time) );
+#else
+ return nsInt64( PR_Now() );
+#endif
+ }
+
+class TestTimer
+ {
+ public:
+ TestTimer() : mStartTime(GetTime()) { }
+
+ ~TestTimer()
+ {
+ nsInt64 stopTime = GetTime();
+ nsInt64 totalTime = stopTime - mStartTime;
+#ifdef HAVE_LONG_LONG
+ cout << setw(10) << NS_STATIC_CAST(PRInt64, totalTime) << " µs : ";
+#else
+ cout << setw(10) << NS_STATIC_CAST(PRInt32, totalTime) << "µs : ";
+#endif
+ }
+
+ private:
+ nsInt64 mStartTime;
+ };
+
+inline
+int
+foo( const nsCString& )
+ {
+ return 1;
+ }
+
+static
+int
+test_construction()
+ {
+ cout << endl;
+
+ {
+ nsCString someCString;
+ int total = 0;
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ {
+ total += foo( someCString );
+ }
+ }
+ cout << "null loop time for constructor" << endl;
+
+
+ {
+ int total = 0;
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ {
+ total += foo( nsCString() );
+ }
+ }
+ cout << "nsCString()" << endl;
+
+
+ {
+ int total = 0;
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ {
+ total += foo( nsCString("This is a reasonable length string with some text in it and it is good.") );
+ }
+ }
+ cout << "nsCString(\"abc\")" << endl;
+
+ return kTestSucceeded;
+ }
+
+static
+int
+test_concat()
+ {
+ cout << endl;
+
+ //---------|---------|---------|---------|---------|---------|---------|
+ nsCString s1("This is a reasonable length string with some text in it and it is good.");
+ nsCString s2("This is another string that I will use in the concatenation test.");
+ nsCString s3("This is yet a third string that I will use in the concatenation test.");
+
+ PRUint32 len = TotalLength( s1 + s2 + s3 + s1 + s2 + s3 );
+ if ( len != (71 + 65 + 69 + 71 + 65 + 69) )
+ {
+ cout << "|test_concat()| FAILED" << endl;
+ return kTestFailed;
+ }
+
+
+ {
+ nsCString anEmptyCString;
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ {
+ len += TotalLength( anEmptyCString );
+ }
+ }
+ cout << "null loop time for concat" << endl;
+
+
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ len += TotalLength( s1 + s2 + s3 + s1 + s2 + s3 );
+ }
+ cout << "TotalLength( s1 + s2 + s3 + s1 + s2 + s3 )" << endl;
+
+
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ len += TotalLength( s1 + s2 );
+ }
+ cout << "TotalLength( s1 + s2 )" << endl;
+
+ return kTestSucceeded;
+ }
+
+static
+int
+test_concat_and_assign()
+ {
+ //---------|---------|---------|---------|---------|---------|---------|
+ nsCString s1("This is a reasonable length string with some text in it and it is good.");
+ nsCString s2("This is another string that I will use in the concatenation test.");
+ nsCString s3("This is yet a third string that I will use in the concatenation test.");
+
+ nsCString s4( s1 + s2 + s3 + s1 + s2 + s3 );
+ if ( TotalLength(s4) != (71 + 65 + 69 + 71 + 65 + 69) )
+ {
+ cout << "|test_concat()| FAILED" << endl;
+ return kTestFailed;
+ }
+
+
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ s4 = s1 + s2 + s3 + s1 + s2 + s3;
+ }
+ cout << "s4 = s1 + s2 + s3 + s1 + s2 + s3" << endl;
+
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ s4 = s1 + s2;
+ }
+ cout << "s4 = s1 + s2" << endl;
+
+ return kTestSucceeded;
+ }
+
+static
+int
+test_compare()
+ {
+ nsCString s1("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxThis is a reasonable length string with some text in it and it is good.");
+ nsCString s2("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxThis is a reasonable length string with some text in it and it is bad.");
+
+ int count = 0;
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ if ( s1 > s2 )
+ ++count;
+ }
+ cout << "s1 > s2" << endl;
+
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ if ( s1 == s1 )
+ ++count;
+ }
+ cout << "s1 == s1" << endl;
+
+ return kTestSucceeded;
+ }
+
+static
+int
+test_countchar()
+ {
+ nsCString s1("This is a reasonable length string with some text in it and it is good.");
+
+ if ( s1.CountChar('e') != 5 )
+ {
+ cout << "|test_countchar()| FAILED: found a count of " << s1.CountChar('e') << endl;
+ return kTestFailed;
+ }
+
+ PRUint32 total = 0;
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ total += s1.CountChar('e');
+ }
+ cout << "s1.CountChar('e')" << endl;
+
+ return kTestSucceeded;
+ }
+
+static
+int
+test_append_string()
+ {
+ nsCString s1("This is a reasonable length string with some text in it and it is good.");
+ nsCString s2("This is another string that I will use in the concatenation test.");
+
+ PRUint32 len = 0;
+
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ {
+ nsCString s3;
+ s3.Append(s1);
+ s3.Append(s2);
+ len += TotalLength(s3);
+ }
+ }
+ cout << "s3.Append(s1); s3.Append(s2)" << endl;
+
+ return kTestSucceeded;
+ }
+
+static
+int
+test_repeated_append_string()
+ {
+ nsCString s1("This is a reasonable length string with some text in it and it is good.");
+ nsCString s2("This is another string that I will use in the concatenation test.");
+
+ PRUint32 len = 0;
+
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ {
+ nsCString s3;
+ for ( int j=0; j<100; ++j )
+ {
+ s3.Append(s1);
+ s3.Append(s2);
+ len += TotalLength(s3);
+ }
+ }
+ }
+ cout << "repeated s3.Append(s1); s3.Append(s2)" << endl;
+
+ return kTestSucceeded;
+ }
+
+static
+int
+test_append_char()
+ {
+ cout << endl;
+
+ PRUint32 len = 0;
+
+ nsCString s1("hello");
+ PRUint32 oldLength = s1.Length();
+
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ {
+ s1.SetLength(oldLength);
+ }
+ }
+ cout << "null loop time for append char" << endl;
+
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ {
+ s1.Append('e');
+ s1.SetLength(oldLength);
+ }
+ }
+ cout << "s1.Append('e')" << endl;
+
+ return kTestSucceeded;
+ }
+
+static
+int
+test_repeated_append_char()
+ {
+ PRUint32 len = 0;
+
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ {
+ nsCString s1;
+ for ( int j=0; j<1000; ++j )
+ {
+ s1.Append('e');
+ len += TotalLength(s1);
+ }
+ }
+ }
+ cout << "repeated s1.Append('e')" << endl;
+
+ return kTestSucceeded;
+ }
+
+static
+int
+test_insert_string()
+ {
+ nsCString s1("This is a reasonable length string with some text in it and it is good.");
+
+ PRUint32 len = 0;
+
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ {
+ nsCString s2("This is another string that I will use in the concatenation test.");
+ s2.Insert(s1, 3);
+ len += TotalLength(s2);
+ }
+ }
+ cout << "s2.Insert(s1, 3)" << endl;
+
+ return kTestSucceeded;
+ }
+
+#ifndef TEST_STD_STRING
+static
+int
+test_find_string()
+ {
+ nsCString text("aaaaaaaaaab");
+ nsCString pattern("aab");
+
+ PRUint32 position = 0;
+ {
+ TestTimer timer;
+ for ( int i=0; i<N; ++i )
+ position = Find(text, pattern);
+ }
+ cout << "text.Find(pattern)" << endl;
+
+ return kTestSucceeded;
+ }
+#endif
+
+class Profiler
+ {
+ public:
+ Profiler()
+ {
+#if 0
+ ProfilerInit(collectDetailed, bestTimeBase, 100, 32);
+#endif
+ }
+
+ void
+ Dump( const char* output_name )
+ {
+ }
+
+ void
+ Dump( const unsigned char* output_name )
+ {
+#if 0
+ ProfilerDump(output_name);
+#endif
+ }
+
+ ~Profiler()
+ {
+#if 0
+ ProfilerDump(mOutputName);
+ ProfilerTerm();
+#endif
+ }
+ };
+
+int
+main()
+ {
+
+ cout << "String performance profiling. Compiled " __DATE__ " " __TIME__ << endl;
+#ifdef TEST_STD_STRING
+ cout << "Testing std::string." << endl;
+#else
+ cout << "Testing factored nsString." << endl;
+#endif
+
+ int tests_failed = 0;
+
+ Profiler profiler;
+
+ tests_failed += test_construction();
+ tests_failed += test_concat();
+ tests_failed += test_concat_and_assign();
+ tests_failed += test_compare();
+ tests_failed += test_countchar();
+ tests_failed += test_append_string();
+ tests_failed += test_repeated_append_string();
+ tests_failed += test_append_char();
+ tests_failed += test_repeated_append_char();
+ tests_failed += test_insert_string();
+#ifndef TEST_STD_STRING
+ tests_failed += test_find_string();
+#endif
+
+#ifdef TEST_STD_STRING
+ profiler.Dump("\pStandard String.prof");
+#else
+ profiler.Dump("\pFactored String.prof");
+#endif
+
+ if ( tests_failed )
+ cout << "One or more tests FAILED. Measurements may be invalid." << endl;
+
+ cout << "End of string performance profiling." << endl;
+ return 0;
+ }
diff --git a/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/test_main.cpp b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/test_main.cpp
new file mode 100644
index 00000000..b8365dac
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/test_main.cpp
@@ -0,0 +1,651 @@
+#include <iostream.h>
+#include "nsStringIO.h"
+
+//#define TEST_STD_STRING
+
+
+#include "nsString.h"
+#include "nsFragmentedString.h"
+#include "nsReadableUtils.h"
+#include "nsSlidingString.h"
+
+#ifdef TEST_STD_STRING
+#include "nsStdStringWrapper.h"
+#else
+ typedef nsString nsStdString;
+ typedef nsCString nsStdCString;
+#endif
+
+template <class CharT>
+basic_nsLiteralString<CharT>
+literal_hello( CharT* )
+ {
+ }
+
+NS_SPECIALIZE_TEMPLATE
+basic_nsLiteralString<char>
+literal_hello( char* )
+ {
+ return basic_nsLiteralString<char>("Hello");
+ }
+
+NS_SPECIALIZE_TEMPLATE
+basic_nsLiteralString<PRUnichar>
+literal_hello( PRUnichar* )
+ {
+#ifdef HAVE_CPP_2BYTE_WCHAR_T
+ return basic_nsLiteralString<PRUnichar>(L"Hello");
+#else
+ static PRUnichar constant_unicode[] = { 'H', 'e', 'l', 'l', 'o', PRUnichar() };
+ return basic_nsLiteralString<PRUnichar>(constant_unicode);
+#endif
+ }
+
+template <class T>
+struct string_class_traits
+ {
+ };
+
+NS_SPECIALIZE_TEMPLATE
+struct string_class_traits<PRUnichar>
+ {
+ typedef PRUnichar* pointer;
+ typedef nsString implementation_t;
+
+ static basic_nsLiteralString<PRUnichar> literal_hello() { return ::literal_hello(pointer()); }
+ };
+
+NS_SPECIALIZE_TEMPLATE
+struct string_class_traits<char>
+ {
+ typedef char* pointer;
+ typedef nsCString implementation_t;
+
+ static basic_nsLiteralString<char> literal_hello() { return ::literal_hello(pointer()); }
+ };
+
+
+static
+void
+CallCMid( nsACString& aResult, const nsACString& aSource, PRUint32 aStartPos, PRUint32 aLengthToCopy )
+ {
+ aSource.Mid(aResult, aStartPos, aLengthToCopy);
+ }
+
+
+
+template <class CharT>
+int
+test_multifragment_iterators( const basic_nsAString<CharT>& aString )
+ /*
+ ...this tests a problem that was present in |nsPromiseConcatenation| where,
+ because it originally stored some iteration state in the object itself, rather than
+ in the fragment, the iterators could get confused if used out of sequence.
+
+ This test should be run on any multi-fragment implementation to verify that it
+ does not have the same bug. Make sure the first fragment is only one character long.
+ */
+ {
+ typedef typename basic_nsAString<CharT>::const_iterator ConstIterator;
+
+ int tests_failed = 0;
+
+ ConstIterator iter1 = aString.BeginReading();
+ ConstIterator iter2 = aString.BeginReading();
+ ++iter2; ++iter2;
+
+ ConstIterator iter3 = aString.EndReading();
+ --iter3;
+ ++iter1; ++iter1;
+ if ( iter1 != iter2 )
+ {
+ cout << "FAILED in |test_multifragment_iterators|" << endl;
+ ++tests_failed;
+ }
+
+ return tests_failed;
+ }
+
+template <class CharT>
+int
+test_Vidur_functions( const basic_nsAString<CharT>& aString )
+ {
+ char* char_copy = ToNewCString(aString);
+ PRUnichar* PRUnichar_copy = ToNewUnicode(aString);
+
+ nsMemory::Free(PRUnichar_copy);
+ nsMemory::Free(char_copy);
+
+ return 0;
+ }
+
+template <class CharT>
+int
+test_readable_hello( const basic_nsAString<CharT>& aReadable )
+ {
+ int tests_failed = 0;
+
+ if ( aReadable.Length() != 5 )
+ {
+ cout << "FAILED |test_readable_hello|: |Length()| --> " << aReadable.Length() << endl;
+ ++tests_failed;
+ }
+
+ if ( aReadable.First() != CharT('H') )
+ {
+ cout << "FAILED |test_readable_hello|: |First()| --> '" << aReadable.First() << "'" << endl;
+ ++tests_failed;
+ }
+
+ if ( aReadable.Last() != CharT('o') )
+ {
+ cout << "FAILED |test_readable_hello|: |Last()| --> '" << aReadable.Last() << "'" << endl;
+ ++tests_failed;
+ }
+
+ if ( aReadable[3] != CharT('l') )
+ {
+ cout << "FAILED |test_readable_hello|: |operator[]| --> '" << aReadable[3] << "'" << endl;
+ ++tests_failed;
+ }
+
+ if ( aReadable.CountChar( CharT('l') ) != 2 )
+ {
+ cout << "FAILED |test_readable_hello|: |CountChar('l')| --> " << aReadable.CountChar(CharT('l')) << endl;
+ ++tests_failed;
+ }
+
+ basic_nsAString<CharT>::const_iterator iter = aReadable.BeginReading();
+ if ( *iter != CharT('H') )
+ {
+ cout << "FAILED |test_readable_hello|: didn't start out pointing to the right thing, or else couldn't be dereferenced. --> '" << *iter << "'" << endl;
+ ++tests_failed;
+ }
+
+ ++iter;
+
+ if ( *iter != CharT('e') )
+ {
+ cout << "FAILED |test_readable_hello|: iterator couldn't be incremented, or else couldn't be dereferenced. --> '" << *iter << "'" << endl;
+ ++tests_failed;
+ }
+
+ iter = aReadable.EndReading();
+ --iter;
+ if ( *iter != CharT('o') )
+ {
+ cout << "FAILED |test_readable_hello|: iterator couldn't be set to |EndReading()|, or else couldn't be decremented, or else couldn't be dereferenced. --> '" << *iter << "'" << endl;
+ ++tests_failed;
+ }
+
+ basic_nsAString<CharT>::const_iterator iter1 = aReadable.BeginReading().advance(3);
+ if ( *iter1 != CharT('l') )
+ {
+ cout << "FAILED |test_readable_hello|: iterator couldn't be set to |BeginReading()+=n|, or else couldn't be dereferenced. --> '" << *iter1 << "'" << endl;
+ ++tests_failed;
+ }
+
+ basic_nsAString<CharT>::const_iterator iter2 = aReadable.EndReading().advance(-2);
+ if ( *iter2 != CharT('l') )
+ {
+ cout << "FAILED |test_readable_hello|: iterator couldn't be set to |EndReading()-=n|, or else couldn't be dereferenced. --> '" << *iter2 << "'" << endl;
+ ++tests_failed;
+ }
+
+ if ( iter1 != iter2 )
+ {
+ cout << "FAILED |test_readable_hello|: iterator comparison with !=." << endl;
+ ++tests_failed;
+ }
+
+ if ( !(iter1 == iter2) )
+ {
+ cout << "FAILED |test_readable_hello|: iterator comparison with ==." << endl;
+ ++tests_failed;
+ }
+
+ typedef CharT* CharT_ptr;
+ if ( aReadable != literal_hello(CharT_ptr()) )
+ {
+ cout << "FAILED |test_readable_hello|: comparison with \"Hello\"" << endl;
+ ++tests_failed;
+ }
+
+ tests_failed += test_multifragment_iterators(aReadable);
+ // tests_failed += test_deprecated_GetBufferGetUnicode(aReadable);
+
+ test_Vidur_functions(aReadable);
+
+ return tests_failed;
+ }
+
+
+template <class CharT>
+int
+test_SetLength( basic_nsAString<CharT>& aWritable )
+ {
+ int tests_failed = 0;
+
+ string_class_traits<CharT>::implementation_t oldValue(aWritable);
+
+
+ size_t oldLength = aWritable.Length();
+
+ if ( oldValue != Substring(aWritable, 0, oldLength) )
+ {
+ cout << "FAILED growing a string in |test_SetLength|, saving the value didn't work." << endl;
+ ++tests_failed;
+ }
+
+ size_t newLength = 2*(oldLength+1);
+
+ aWritable.SetLength(newLength);
+ if ( aWritable.Length() != newLength )
+ {
+ cout << "FAILED growing a string in |test_SetLength|, length is wrong." << endl;
+ ++tests_failed;
+ }
+
+ if ( oldValue != Substring(aWritable, 0, oldLength) )
+ {
+ cout << "FAILED growing a string in |test_SetLength|, contents damaged after growing." << endl;
+ ++tests_failed;
+ }
+
+ aWritable.SetLength(oldLength);
+ if ( aWritable.Length() != oldLength )
+ {
+ cout << "FAILED shrinking a string in |test_SetLength|." << endl;
+ ++tests_failed;
+ }
+
+ if ( oldValue != Substring(aWritable, 0, oldLength) )
+ {
+ cout << "FAILED growing a string in |test_SetLength|, contents damaged after shrinking." << endl;
+ ++tests_failed;
+ }
+
+ return tests_failed;
+ }
+
+
+template <class CharT>
+int
+test_insert( basic_nsAString<CharT>& aWritable )
+ {
+ int tests_failed = 0;
+
+ string_class_traits<CharT>::implementation_t oldValue(aWritable);
+
+ if ( oldValue != aWritable )
+ {
+ cout << "FAILED saving the old string value in |test_insert|." << endl;
+ ++tests_failed;
+ }
+
+ string_class_traits<CharT>::implementation_t insertable( string_class_traits<CharT>::literal_hello() );
+
+ insertable.SetLength(1);
+ aWritable.Insert(insertable, 0);
+
+ if ( aWritable != (insertable + oldValue) )
+ {
+ cout << "FAILED in |test_insert|." << endl;
+ ++tests_failed;
+ }
+
+ aWritable = oldValue;
+
+ return tests_failed;
+ }
+
+
+template <class CharT>
+int
+test_cut( basic_nsAString<CharT>& aWritable )
+ {
+ int tests_failed = 0;
+
+ aWritable.Cut(0, aWritable.Length()+5);
+
+ return tests_failed;
+ }
+
+template <class CharT>
+int
+test_self_assign( basic_nsAString<CharT>& aWritable )
+ {
+ int tests_failed = 0;
+ string_class_traits<CharT>::implementation_t oldValue(aWritable);
+
+ aWritable = aWritable;
+ if ( aWritable != oldValue )
+ {
+ cout << "FAILED self assignment." << endl;
+ ++tests_failed;
+ }
+
+ aWritable = oldValue;
+ return tests_failed;
+ }
+
+template <class CharT>
+int
+test_self_append( basic_nsAString<CharT>& aWritable )
+ {
+ int tests_failed = 0;
+ string_class_traits<CharT>::implementation_t oldValue(aWritable);
+
+ aWritable += aWritable;
+ if ( aWritable != oldValue + oldValue )
+ {
+ cout << "FAILED self append." << endl;
+ ++tests_failed;
+ }
+
+ aWritable = oldValue;
+ return tests_failed;
+ }
+
+template <class CharT>
+int
+test_self_insert( basic_nsAString<CharT>& aWritable )
+ {
+ int tests_failed = 0;
+ string_class_traits<CharT>::implementation_t oldValue(aWritable);
+
+ aWritable.Insert(aWritable, 0);
+ if ( aWritable != oldValue + oldValue )
+ {
+ cout << "FAILED self insert." << endl;
+ ++tests_failed;
+ }
+
+ aWritable = oldValue;
+ return tests_failed;
+ }
+
+template <class CharT>
+int
+test_self_replace( basic_nsAString<CharT>& aWritable )
+ {
+ int tests_failed = 0;
+ string_class_traits<CharT>::implementation_t oldValue(aWritable);
+
+ aWritable.Replace(0, 0, aWritable);
+ if ( aWritable != oldValue + oldValue )
+ {
+ cout << "FAILED self insert." << endl;
+ ++tests_failed;
+ }
+
+ aWritable = oldValue;
+ return tests_failed;
+ }
+
+
+
+template <class CharT>
+int
+test_writable( basic_nsAString<CharT>& aWritable )
+ {
+ int tests_failed = 0;
+ // ...
+
+
+ {
+ typedef CharT* CharT_ptr;
+ aWritable = literal_hello(CharT_ptr());
+
+ if ( aWritable != literal_hello(CharT_ptr()) )
+ {
+ cout << "FAILED assignment and/or comparison in |test_writable|." << endl;
+ ++tests_failed;
+ }
+
+ tests_failed += test_readable_hello(aWritable);
+ }
+
+ tests_failed += test_SetLength(aWritable);
+ tests_failed += test_insert(aWritable);
+ tests_failed += test_cut(aWritable);
+ tests_failed += test_self_assign(aWritable);
+ tests_failed += test_self_append(aWritable);
+ tests_failed += test_self_insert(aWritable);
+ tests_failed += test_self_replace(aWritable);
+
+ return tests_failed;
+ }
+
+
+
+typedef void* void_ptr;
+
+int
+main()
+ {
+ int tests_failed = 0;
+ cout << "String unit tests. Compiled " __DATE__ " " __TIME__ << endl;
+
+#if 0
+ {
+ nsFragmentedCString fs0;
+ fs0.Append("Hello");
+ tests_failed += test_readable_hello(fs0);
+ tests_failed += test_writable(fs0);
+ }
+#endif
+
+ {
+ NS_NAMED_LITERAL_STRING(literal, "Hello");
+ PRUnichar* buffer = ToNewUnicode(literal);
+
+ nsSlidingString ss0(buffer, buffer+5, buffer+6);
+// ss0.AppendBuffer(buffer, buffer+5, buffer+6);
+ nsReadingIterator<PRUnichar> ri0;
+ ss0.BeginReading(ri0);
+
+ tests_failed += test_readable_hello(ss0);
+
+ nsSlidingSubstring ss1(ss0);
+ tests_failed += test_readable_hello(ss1);
+
+ buffer = ToNewUnicode(literal);
+ ss0.AppendBuffer(buffer, buffer+5, buffer+6);
+
+ ri0.advance(5);
+ ss0.DiscardPrefix(ri0);
+
+ tests_failed += test_readable_hello(ss0);
+ tests_failed += test_readable_hello(ss1);
+
+ nsReadingIterator<PRUnichar> ri1;
+ ss0.EndReading(ri1);
+
+ nsSlidingSubstring ss2(ss0, ri0, ri1);
+ tests_failed += test_readable_hello(ss2);
+ }
+
+
+ {
+ nsLiteralCString s0("Patrick Beard made me write this: \"This is just a test\"\n");
+ print_string(s0);
+
+ const char* raw_string = "He also made me write this.\n";
+ nsFileCharSink<char> output(stdout);
+ copy_string(raw_string, raw_string+nsCharTraits<char>::length(raw_string), output);
+
+ nsLiteralCString s1("This ", 5), s2("is ", 3), s3("a ", 2), s4("test\n", 5);
+ print_string(s1+s2+s3+s4);
+
+ nsLiteralCString s5( "This is " "a " "test" );
+ print_string(s5+NS_LITERAL_CSTRING("\n"));
+
+ print_string(nsLiteralCString("The value of the string |x| is \"") + Substring(s0, 0, s0.Length()-1) + NS_LITERAL_CSTRING("\". Hope you liked it."));
+ }
+
+
+ {
+ tests_failed += test_readable_hello(NS_LITERAL_STRING("Hello"));
+
+ nsLiteralCString s1("Hello");
+ tests_failed += test_readable_hello(s1);
+ }
+
+ {
+
+ nsString s3( NS_LITERAL_STRING("Hello") );
+
+ tests_failed += test_readable_hello(s3);
+ tests_failed += test_writable(s3);
+
+ nsCString s4("Hello");
+ tests_failed += test_readable_hello(s4);
+ tests_failed += test_writable(s4);
+ }
+
+ {
+ nsStdString s5( NS_LITERAL_STRING("Hello") );
+
+ tests_failed += test_readable_hello(s5);
+ tests_failed += test_writable(s5);
+
+ nsStdCString s6("Hello");
+ tests_failed += test_readable_hello(s6);
+ tests_failed += test_writable(s6);
+ }
+
+ {
+ nsLiteralString s7(NS_LITERAL_STRING("He"));
+ nsString s8(NS_LITERAL_STRING("l"));
+ nsStdString s9(NS_LITERAL_STRING("lo"));
+
+ tests_failed += test_readable_hello(s7+s8+s9);
+
+ nsString s13( s7 + s8 + s9 );
+ tests_failed += test_readable_hello(s13);
+
+ nsStdString s14( s7 + s8 + s9 );
+ tests_failed += test_readable_hello(s14);
+
+ nsCString s10("He");
+ nsLiteralCString s11("l");
+ nsStdCString s12("lo");
+
+ tests_failed += test_readable_hello(s10+s11+s12);
+
+
+ }
+
+ {
+ const char *foo = "this is a really long string";
+ nsCString origString;
+ nsCString string2;
+ nsCString string3;
+
+ origString = foo;
+
+ string2 = Substring(origString, 0, 5);
+ string3 = Substring(origString, 6, origString.Length() - 6);
+ }
+
+ {
+ nsLiteralCString s13("He");
+ nsCAutoString s14("l");
+ nsLiteralCString s15("lo");
+
+ s14.Assign(s13 + s14 + s15);
+
+ if ( int failures = test_readable_hello(s14) )
+ {
+ tests_failed += failures;
+ cout << "FAILED to keep a promise." << endl;
+ }
+ }
+
+
+ {
+ nsLiteralCString str1("Hello");
+ nsStdCString str2("Hello");
+
+ nsLiteralCString str3("Hello there");
+
+ if ( str1 != str2 )
+ {
+ cout << "string comparison using != failed" << endl;
+ ++tests_failed;
+ }
+
+ if ( !(str3 > str2) )
+ {
+ cout << "string comparison using > failed" << endl;
+ ++tests_failed;
+ }
+
+ if ( !(str2 < str3) )
+ {
+ cout << "string comparison using < failed" << endl;
+ ++tests_failed;
+ }
+
+ if ( str1 != "Hello" )
+ {
+ cout << "string comparison using == failed" << endl;
+ ++tests_failed;
+ }
+ }
+
+#if 0
+ nsStdCString extracted_middle("XXXXXXXXXX");
+ CallCMid(extracted_middle, part1+part2a+part2b, 1, 3);
+
+ cout << "The result of mid was \"" << extracted_middle << "\"" << endl;
+
+ nsLiteralCString middle_answer("ell");
+ if ( middle_answer != extracted_middle )
+ {
+ cout << "mid FAILED on nsConcatString" << endl;
+ ++tests_failed;
+ }
+
+
+
+ //
+ // |nsStdStringWrapper|, i.e., |nsStdCString|
+ //
+
+ {
+ nsStdCString extracted_middle;
+ CallCMid(extracted_middle, part1+part2a+part2b, 1, 3);
+
+ cout << "The result of mid was \"" << extracted_middle << "\"" << endl;
+
+ nsLiteralCString middle_answer("ell");
+ if ( middle_answer != extracted_middle )
+ {
+ cout << "mid FAILED on nsStdCString" << endl;
+ ++tests_failed;
+ }
+ }
+
+
+
+ nsStdCString leftString;
+ source.Left(leftString, 9);
+ // cout << static_cast<const nsACString>(leftString) << endl;
+
+
+
+ tests_failed += test_multifragment_iterators(part1+part2a+part2b);
+#endif
+
+
+
+ cout << "End of string unit tests." << endl;
+ if ( !tests_failed )
+ cout << "OK, all tests passed." << endl;
+ else
+ cout << "FAILED one or more tests." << endl;
+
+ return tests_failed;
+ }
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestArray.cpp b/src/libs/xpcom18a4/xpcom/tests/TestArray.cpp
new file mode 100644
index 00000000..852938fe
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/TestArray.cpp
@@ -0,0 +1,230 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Pierre Phaneuf <pp@ludusdesign.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "nsISupportsArray.h"
+
+// {9e70a320-be02-11d1-8031-006008159b5a}
+#define NS_IFOO_IID \
+ {0x9e70a320, 0xbe02, 0x11d1, \
+ {0x80, 0x31, 0x00, 0x60, 0x08, 0x15, 0x9b, 0x5a}}
+
+static const PRBool kExitOnError = PR_TRUE;
+
+class IFoo : public nsISupports {
+public:
+
+ NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFOO_IID)
+
+ NS_IMETHOD_(nsrefcnt) RefCnt() = 0;
+ NS_IMETHOD_(PRInt32) ID() = 0;
+};
+
+class Foo : public IFoo {
+public:
+
+ Foo(PRInt32 aID);
+
+ // nsISupports implementation
+ NS_DECL_ISUPPORTS
+
+ // IFoo implementation
+ NS_IMETHOD_(nsrefcnt) RefCnt() { return mRefCnt; }
+ NS_IMETHOD_(PRInt32) ID() { return mID; }
+
+ static PRInt32 gCount;
+
+ PRInt32 mID;
+
+private:
+ ~Foo();
+};
+
+PRInt32 Foo::gCount;
+
+Foo::Foo(PRInt32 aID)
+{
+ mID = aID;
+ ++gCount;
+ fprintf(stdout, "init: %d (%p), %d total)\n", mID, this, gCount);
+}
+
+Foo::~Foo()
+{
+ --gCount;
+ fprintf(stdout, "destruct: %d (%p), %d remain)\n", mID, this, gCount);
+}
+
+NS_IMPL_ISUPPORTS1(Foo, IFoo)
+
+const char* AssertEqual(PRInt32 aValue1, PRInt32 aValue2)
+{
+ if (aValue1 == aValue2) {
+ return "OK";
+ }
+ if (kExitOnError) {
+ exit(1);
+ }
+ return "ERROR";
+}
+
+void DumpArray(nsISupportsArray* aArray, PRInt32 aExpectedCount, PRInt32 aElementIDs[], PRInt32 aExpectedTotal)
+{
+ PRUint32 cnt = 0;
+ nsresult rv = aArray->Count(&cnt);
+ NS_ASSERTION(NS_SUCCEEDED(rv), "Count failed");
+ PRInt32 count = cnt;
+ PRInt32 index;
+
+ fprintf(stdout, "object count %d = %d %s\n", Foo::gCount, aExpectedTotal,
+ AssertEqual(Foo::gCount, aExpectedTotal));
+ fprintf(stdout, "array count %d = %d %s\n", count, aExpectedCount,
+ AssertEqual(count, aExpectedCount));
+
+ for (index = 0; (index < count) && (index < aExpectedCount); index++) {
+ IFoo* foo = (IFoo*)(aArray->ElementAt(index));
+ fprintf(stdout, "%2d: %d=%d (%p) c: %d %s\n",
+ index, aElementIDs[index], foo->ID(), foo, foo->RefCnt() - 1,
+ AssertEqual(foo->ID(), aElementIDs[index]));
+ foo->Release();
+ }
+}
+
+void FillArray(nsISupportsArray* aArray, PRInt32 aCount)
+{
+ PRInt32 index;
+ for (index = 0; index < aCount; index++) {
+ nsCOMPtr<IFoo> foo = new Foo(index);
+ aArray->AppendElement(foo);
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ nsISupportsArray* array;
+ nsresult rv;
+
+ if (NS_OK == (rv = NS_NewISupportsArray(&array))) {
+ FillArray(array, 10);
+ fprintf(stdout, "Array created:\n");
+ PRInt32 fillResult[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
+ DumpArray(array, 10, fillResult, 10);
+
+ // test insert
+ IFoo* foo = (IFoo*)array->ElementAt(3);
+ foo->Release(); // pre-release to fix ref count for dumps
+ array->InsertElementAt(foo, 5);
+ fprintf(stdout, "insert 3 at 5:\n");
+ PRInt32 insertResult[11] = {0, 1, 2, 3, 4, 3, 5, 6, 7, 8, 9};
+ DumpArray(array, 11, insertResult, 10);
+ fprintf(stdout, "insert 3 at 0:\n");
+ array->InsertElementAt(foo, 0);
+ PRInt32 insertResult2[12] = {3, 0, 1, 2, 3, 4, 3, 5, 6, 7, 8, 9};
+ DumpArray(array, 12, insertResult2, 10);
+ fprintf(stdout, "append 3:\n");
+ array->AppendElement(foo);
+ PRInt32 appendResult[13] = {3, 0, 1, 2, 3, 4, 3, 5, 6, 7, 8, 9, 3};
+ DumpArray(array, 13, appendResult, 10);
+
+
+ // test IndexOf && LastIndexOf
+ PRInt32 expectedIndex[5] = {0, 4, 6, 12, -1};
+ PRInt32 count = 0;
+ PRInt32 index = array->IndexOf(foo);
+ fprintf(stdout, "IndexOf(foo): %d=%d %s\n", index, expectedIndex[count],
+ AssertEqual(index, expectedIndex[count]));
+ while (-1 != index) {
+ count++;
+ index = array->IndexOfStartingAt(foo, index + 1);
+ if (-1 != index)
+ fprintf(stdout, "IndexOf(foo): %d=%d %s\n", index, expectedIndex[count],
+ AssertEqual(index, expectedIndex[count]));
+ }
+ index = array->LastIndexOf(foo);
+ count--;
+ fprintf(stdout, "LastIndexOf(foo): %d=%d %s\n", index, expectedIndex[count],
+ AssertEqual(index, expectedIndex[count]));
+
+ // test ReplaceElementAt
+ fprintf(stdout, "ReplaceElementAt(8):\n");
+ array->ReplaceElementAt(foo, 8);
+ PRInt32 replaceResult[13] = {3, 0, 1, 2, 3, 4, 3, 5, 3, 7, 8, 9, 3};
+ DumpArray(array, 13, replaceResult, 9);
+
+ // test RemoveElementAt, RemoveElement RemoveLastElement
+ fprintf(stdout, "RemoveElementAt(0):\n");
+ array->RemoveElementAt(0);
+ PRInt32 removeResult[12] = {0, 1, 2, 3, 4, 3, 5, 3, 7, 8, 9, 3};
+ DumpArray(array, 12, removeResult, 9);
+ fprintf(stdout, "RemoveElementAt(7):\n");
+ array->RemoveElementAt(7);
+ PRInt32 removeResult2[11] = {0, 1, 2, 3, 4, 3, 5, 7, 8, 9, 3};
+ DumpArray(array, 11, removeResult2, 9);
+ fprintf(stdout, "RemoveElement(foo):\n");
+ array->RemoveElement(foo);
+ PRInt32 removeResult3[10] = {0, 1, 2, 4, 3, 5, 7, 8, 9, 3};
+ DumpArray(array, 10, removeResult3, 9);
+ fprintf(stdout, "RemoveLastElement(foo):\n");
+ array->RemoveLastElement(foo);
+ PRInt32 removeResult4[9] = {0, 1, 2, 4, 3, 5, 7, 8, 9};
+ DumpArray(array, 9, removeResult4, 9);
+
+ // test clear
+ fprintf(stdout, "clear array:\n");
+ array->Clear();
+ DumpArray(array, 0, 0, 0);
+ fprintf(stdout, "add 4 new:\n");
+ FillArray(array, 4);
+ DumpArray(array, 4, fillResult, 4);
+
+ // test compact
+ fprintf(stdout, "compact array:\n");
+ array->Compact();
+ DumpArray(array, 4, fillResult, 4);
+
+ // test delete
+ fprintf(stdout, "release array:\n");
+ NS_RELEASE(array);
+ }
+ else {
+ fprintf(stdout, "error can't create array: %x\n", rv);
+ }
+
+ return 0;
+}
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestAtoms.cpp b/src/libs/xpcom18a4/xpcom/tests/TestAtoms.cpp
new file mode 100644
index 00000000..48b2f603
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/TestAtoms.cpp
@@ -0,0 +1,132 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 "nsIAtom.h"
+#include "nsString.h"
+#include "nsReadableUtils.h"
+#include "prprf.h"
+#include "prtime.h"
+#include <stdio.h>
+
+extern "C" int _CrtSetDbgFlag(int);
+
+int main(int argc, char** argv)
+{
+ FILE* fp = fopen("words.txt", "r");
+ if (nsnull == fp) {
+ printf("can't open words.txt\n");
+ return -1;
+ }
+
+ PRInt32 count = 0;
+ PRUnichar** strings = new PRUnichar*[60000];
+ nsIAtom** ids = new nsIAtom*[60000];
+ nsAutoString s1, s2;
+ PRTime start = PR_Now();
+ PRInt32 i;
+ for (i = 0; i < 30000; i++) {
+ char buf[1000];
+ char* s = fgets(buf, sizeof(buf), fp);
+ if (nsnull == s) {
+ break;
+ }
+ nsCAutoString sb;
+ sb.Assign(buf);
+ strings[count++] = ToNewUnicode(sb);
+ ToUpperCase(sb);
+ strings[count++] = ToNewUnicode(sb);
+ }
+ PRTime end0 = PR_Now();
+
+ // Find and create idents
+ for (i = 0; i < count; i++) {
+ ids[i] = NS_NewAtom(strings[i]);
+ }
+ PRUnichar qqs[1]; qqs[0] = 0;
+ nsIAtom* qq = NS_NewAtom(qqs);
+ PRTime end1 = PR_Now();
+
+ // Now make sure we can find all the idents we just made
+ for (i = 0; i < count; i++) {
+ const char *utf8String;
+ ids[i]->GetUTF8String(&utf8String);
+ nsIAtom* id = NS_NewAtom(utf8String);
+ if (id != ids[i]) {
+ id->ToString(s1);
+ ids[i]->ToString(s2);
+ printf("find failed: id='%s' ids[%d]='%s'\n",
+ NS_LossyConvertUCS2toASCII(s1).get(), i, NS_LossyConvertUCS2toASCII(s2).get());
+ return -1;
+ }
+ NS_RELEASE(id);
+ }
+ PRTime end2 = PR_Now();
+
+ // Destroy all the atoms we just made
+ NS_RELEASE(qq);
+ for (i = 0; i < count; i++) {
+ NS_RELEASE(ids[i]);
+ }
+
+ // Print out timings
+ PRTime end3 = PR_Now();
+ PRTime creates, finds, lookups, dtor, ustoms;
+ LL_I2L(ustoms, 1000);
+ LL_SUB(creates, end0, start);
+ LL_DIV(creates, creates, ustoms);
+ LL_SUB(finds, end1, end0);
+ LL_DIV(finds, finds, ustoms);
+ LL_SUB(lookups, end2, end1);
+ LL_DIV(lookups, lookups, ustoms);
+ LL_SUB(dtor, end3, end2);
+ char buf[500];
+ PR_snprintf(buf, sizeof(buf), "making %d ident strings took %lldms",
+ count, creates);
+ puts(buf);
+ PR_snprintf(buf, sizeof(buf), "%d new idents took %lldms",
+ count, finds);
+ puts(buf);
+ PR_snprintf(buf, sizeof(buf), "%d ident lookups took %lldms",
+ count, lookups);
+ puts(buf);
+ PR_snprintf(buf, sizeof(buf), "dtor took %lldusec", dtor);
+ puts(buf);
+
+ printf("%d live atoms\n", NS_GetNumberOfAtoms());
+ NS_POSTCONDITION(0 == NS_GetNumberOfAtoms(), "dangling atoms");
+
+ return 0;
+}
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestAutoLock.cpp b/src/libs/xpcom18a4/xpcom/tests/TestAutoLock.cpp
new file mode 100644
index 00000000..4537044f
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/TestAutoLock.cpp
@@ -0,0 +1,91 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 ***** */
+
+/*
+
+ Some tests for nsAutoLock.
+
+ */
+
+#include "nsAutoLock.h"
+#include "prthread.h"
+
+PRLock* gLock;
+int gCount;
+
+static void PR_CALLBACK run(void* arg)
+{
+ for (int i = 0; i < 1000000; ++i) {
+ nsAutoLock guard(gLock);
+ ++gCount;
+ PR_ASSERT(gCount == 1);
+ --gCount;
+ }
+}
+
+
+int main(int argc, char** argv)
+{
+ gLock = PR_NewLock();
+ gCount = 0;
+
+ // This shouldn't compile
+ //nsAutoLock* l1 = new nsAutoLock(theLock);
+ //delete l1;
+
+ // Create a block-scoped lock. This should compile.
+ {
+ nsAutoLock l2(gLock);
+ }
+
+ // Fork a thread to access the shared variable in a tight loop
+ PRThread* t1 =
+ PR_CreateThread(PR_SYSTEM_THREAD,
+ run,
+ nsnull,
+ PR_PRIORITY_NORMAL,
+ PR_GLOBAL_THREAD,
+ PR_JOINABLE_THREAD,
+ 0);
+
+ // ...and now do the same thing ourselves
+ run(nsnull);
+
+ // Wait for the background thread to finish, if necessary.
+ PR_JoinThread(t1);
+ return 0;
+}
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestAutoPtr.cpp b/src/libs/xpcom18a4/xpcom/tests/TestAutoPtr.cpp
new file mode 100644
index 00000000..c48134a4
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/TestAutoPtr.cpp
@@ -0,0 +1,566 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// vim:cindent:ts=4:et:sw=4:
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is TestCOMPtrEq.cpp.
+ *
+ * The Initial Developer of the Original Code is
+ * L. David Baron.
+ * Portions created by the Initial Developer are Copyright (C) 2001
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * L. David Baron <dbaron@dbaron.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 "nsAutoPtr.h"
+#include <stdio.h>
+#include "nscore.h"
+
+class TestObjectBaseA {
+ public:
+ // Virtual dtor for deleting through base class pointer
+ virtual ~TestObjectBaseA() { };
+ int fooA;
+};
+
+class TestObjectBaseB {
+ public:
+ // Virtual dtor for deleting through base class pointer
+ virtual ~TestObjectBaseB() { };
+ int fooB;
+};
+
+class TestObject : public TestObjectBaseA, public TestObjectBaseB {
+ public:
+ TestObject()
+ {
+ printf(" Creating TestObject %p.\n",
+ NS_STATIC_CAST(void*, this));
+ }
+
+ // Virtual dtor for deleting through base class pointer
+ virtual ~TestObject()
+ {
+ printf(" Destroying TestObject %p.\n",
+ NS_STATIC_CAST(void*, this));
+ }
+};
+
+class TestRefObjectBaseA {
+ public:
+ int fooA;
+ // Must return |nsrefcnt| to keep |nsDerivedSafe| happy.
+ virtual nsrefcnt AddRef() = 0;
+ virtual nsrefcnt Release() = 0;
+};
+
+class TestRefObjectBaseB {
+ public:
+ int fooB;
+ virtual nsrefcnt AddRef() = 0;
+ virtual nsrefcnt Release() = 0;
+};
+
+class TestRefObject : public TestRefObjectBaseA, public TestRefObjectBaseB {
+ public:
+ TestRefObject()
+ : mRefCount(0)
+ {
+ printf(" Creating TestRefObject %p.\n",
+ NS_STATIC_CAST(void*, this));
+ }
+
+ ~TestRefObject()
+ {
+ printf(" Destroying TestRefObject %p.\n",
+ NS_STATIC_CAST(void*, this));
+ }
+
+ nsrefcnt AddRef()
+ {
+ ++mRefCount;
+ printf(" AddRef to %d on TestRefObject %p.\n",
+ mRefCount, NS_STATIC_CAST(void*, this));
+ return mRefCount;
+ }
+
+ nsrefcnt Release()
+ {
+ --mRefCount;
+ printf(" Release to %d on TestRefObject %p.\n",
+ mRefCount, NS_STATIC_CAST(void*, this));
+ if (mRefCount == 0) {
+ delete NS_CONST_CAST(TestRefObject*, this);
+ return 0;
+ }
+ return mRefCount;
+ }
+
+ protected:
+ PRUint32 mRefCount;
+
+};
+
+static void CreateTestObject(TestObject **aResult)
+{
+ *aResult = new TestObject();
+}
+
+static void CreateTestRefObject(TestRefObject **aResult)
+{
+ (*aResult = new TestRefObject())->AddRef();
+}
+
+static void DoSomethingWithTestObject(TestObject *aIn)
+{
+ printf(" Doing something with |TestObject| %p.\n",
+ NS_STATIC_CAST(void*, aIn));
+}
+
+static void DoSomethingWithConstTestObject(const TestObject *aIn)
+{
+ printf(" Doing something with |const TestObject| %p.\n",
+ NS_STATIC_CAST(const void*, aIn));
+}
+
+static void DoSomethingWithTestRefObject(TestRefObject *aIn)
+{
+ printf(" Doing something with |TestRefObject| %p.\n",
+ NS_STATIC_CAST(void*, aIn));
+}
+
+static void DoSomethingWithConstTestRefObject(const TestRefObject *aIn)
+{
+ printf(" Doing something with |const TestRefObject| %p.\n",
+ NS_STATIC_CAST(const void*, aIn));
+}
+
+static void DoSomethingWithTestObjectBaseB(TestObjectBaseB *aIn)
+{
+ printf(" Doing something with |TestObjectBaseB| %p.\n",
+ NS_STATIC_CAST(void*, aIn));
+}
+
+static void DoSomethingWithConstTestObjectBaseB(const TestObjectBaseB *aIn)
+{
+ printf(" Doing something with |const TestObjectBaseB| %p.\n",
+ NS_STATIC_CAST(const void*, aIn));
+}
+
+static void DoSomethingWithTestRefObjectBaseB(TestRefObjectBaseB *aIn)
+{
+ printf(" Doing something with |TestRefObjectBaseB| %p.\n",
+ NS_STATIC_CAST(void*, aIn));
+}
+
+static void DoSomethingWithConstTestRefObjectBaseB(const TestRefObjectBaseB *aIn)
+{
+ printf(" Doing something with |const TestRefObjectBaseB| %p.\n",
+ NS_STATIC_CAST(const void*, aIn));
+}
+
+int main()
+{
+ {
+ printf("Should create one |TestObject|:\n");
+ nsAutoPtr<TestObject> pobj( new TestObject() );
+ printf("Should destroy one |TestObject|:\n");
+ }
+
+ {
+ printf("Should create one |TestObject|:\n");
+ nsAutoPtr<TestObject> pobj( new TestObject() );
+ printf("Should create one |TestObject| and then destroy one:\n");
+ pobj = new TestObject();
+ printf("Should destroy one |TestObject|:\n");
+ }
+
+ {
+ printf("Should create 3 |TestObject|s:\n");
+ nsAutoArrayPtr<TestObject> pobj( new TestObject[3] );
+ printf("Should create 5 |TestObject|s and then destroy 3:\n");
+ pobj = new TestObject[5];
+ printf("Should destroy 5 |TestObject|s:\n");
+ }
+
+ {
+ printf("Should create and AddRef one |TestRefObject|:\n");
+ nsRefPtr<TestRefObject> pobj( new TestRefObject() );
+ printf("Should Release and destroy one |TestRefObject|:\n");
+ }
+
+ {
+ printf("Should create and AddRef one |TestRefObject|:\n");
+ nsRefPtr<TestRefObject> pobj( new TestRefObject() );
+ printf("Should create and AddRef one |TestRefObject| and then Release and destroy one:\n");
+ pobj = new TestRefObject();
+ printf("Should Release and destroy one |TestRefObject|:\n");
+ }
+
+ {
+ printf("Should create and AddRef one |TestRefObject|:\n");
+ nsRefPtr<TestRefObject> p1( new TestRefObject() );
+ printf("Should AddRef one |TestRefObject|:\n");
+ nsRefPtr<TestRefObject> p2( p1 );
+ printf("Should Release twice and destroy one |TestRefObject|:\n");
+ }
+
+ printf("\nTesting equality (with all const-ness combinations):\n");
+
+ {
+ nsRefPtr<TestRefObject> p1( new TestRefObject() );
+ nsRefPtr<TestRefObject> p2( p1 );
+ printf("equality %s.\n",
+ ((p1 == p2) && !(p1 != p2)) ? "OK" : "broken");
+ }
+
+ {
+ const nsRefPtr<TestRefObject> p1( new TestRefObject() );
+ nsRefPtr<TestRefObject> p2( p1 );
+ printf("equality %s.\n",
+ ((p1 == p2) && !(p1 != p2)) ? "OK" : "broken");
+ }
+
+ {
+ nsRefPtr<TestRefObject> p1( new TestRefObject() );
+ const nsRefPtr<TestRefObject> p2( p1 );
+ printf("equality %s.\n",
+ ((p1 == p2) && !(p1 != p2)) ? "OK" : "broken");
+ }
+
+ {
+ const nsRefPtr<TestRefObject> p1( new TestRefObject() );
+ const nsRefPtr<TestRefObject> p2( p1 );
+ printf("equality %s.\n",
+ ((p1 == p2) && !(p1 != p2)) ? "OK" : "broken");
+ }
+
+ {
+ nsRefPtr<TestRefObject> p1( new TestRefObject() );
+ TestRefObject * p2 = p1;
+ printf("equality %s.\n",
+ ((p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1)) ? "OK" : "broken");
+ }
+
+ {
+ const nsRefPtr<TestRefObject> p1( new TestRefObject() );
+ TestRefObject * p2 = p1;
+ printf("equality %s.\n",
+ ((p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1)) ? "OK" : "broken");
+ }
+
+#if 0 /* MSVC++ 6.0 can't be coaxed to accept this */
+ {
+ nsRefPtr<TestRefObject> p1( new TestRefObject() );
+ TestRefObject * const p2 = p1;
+ printf("equality %s.\n",
+ ((p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1)) ? "OK" : "broken");
+ }
+
+ {
+ const nsRefPtr<TestRefObject> p1( new TestRefObject() );
+ TestRefObject * const p2 = p1;
+ printf("equality %s.\n",
+ ((p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1)) ? "OK" : "broken");
+ }
+#endif /* Things that MSVC++ 6.0 can't be coaxed to accept */
+
+ {
+ nsRefPtr<TestRefObject> p1( new TestRefObject() );
+ const TestRefObject * p2 = p1;
+ printf("equality %s.\n",
+ ((p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1)) ? "OK" : "broken");
+ }
+
+ {
+ const nsRefPtr<TestRefObject> p1( new TestRefObject() );
+ const TestRefObject * p2 = p1;
+ printf("equality %s.\n",
+ ((p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1)) ? "OK" : "broken");
+ }
+
+ {
+ nsRefPtr<TestRefObject> p1( new TestRefObject() );
+ const TestRefObject * const p2 = p1;
+ printf("equality %s.\n",
+ ((p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1)) ? "OK" : "broken");
+ }
+
+ {
+ const nsRefPtr<TestRefObject> p1( new TestRefObject() );
+ const TestRefObject * const p2 = p1;
+ printf("equality %s.\n",
+ ((p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1)) ? "OK" : "broken");
+ }
+
+ printf("\nTesting getter_Transfers and getter_AddRefs.\n");
+
+ {
+ nsAutoPtr<TestObject> ptr;
+ printf("Should create one |TestObject|:\n");
+ CreateTestObject(getter_Transfers(ptr));
+ printf("Should destroy one |TestObject|:\n");
+ }
+
+ {
+ nsRefPtr<TestRefObject> ptr;
+ printf("Should create and AddRef one |TestRefObject|:\n");
+ CreateTestRefObject(getter_AddRefs(ptr));
+ printf("Should Release and destroy one |TestRefObject|:\n");
+ }
+
+ printf("\nTesting casts and equality tests.\n");
+
+ if ((void*)(TestObject*)0x1000 ==
+ (void*)(TestObjectBaseB*)(TestObject*)0x1000)
+ printf("\n\nAll these tests are meaningless!\n\n\n");
+
+ {
+ nsAutoPtr<TestObject> p1(new TestObject());
+ TestObjectBaseB *p2 = p1;
+ printf("equality %s.\n",
+ ((NS_STATIC_CAST(void*, p1) != NS_STATIC_CAST(void*, p2)) &&
+ (p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1))
+ ? "OK" : "broken");
+ }
+
+ {
+ TestObject *p1 = new TestObject();
+ nsAutoPtr<TestObjectBaseB> p2(p1);
+ printf("equality %s.\n",
+ ((NS_STATIC_CAST(void*, p1) != NS_STATIC_CAST(void*, p2)) &&
+ (p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1))
+ ? "OK" : "broken");
+ }
+
+ {
+ nsRefPtr<TestRefObject> p1 = new TestRefObject();
+ // nsCOMPtr requires a |get| for something like this as well
+ nsRefPtr<TestRefObjectBaseB> p2 = p1.get();
+ printf("equality %s.\n",
+ ((NS_STATIC_CAST(void*, p1) != NS_STATIC_CAST(void*, p2)) &&
+ (p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1))
+ ? "OK" : "broken");
+ }
+
+ {
+ nsRefPtr<TestRefObject> p1 = new TestRefObject();
+ TestRefObjectBaseB *p2 = p1;
+ printf("equality %s.\n",
+ ((NS_STATIC_CAST(void*, p1) != NS_STATIC_CAST(void*, p2)) &&
+ (p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1))
+ ? "OK" : "broken");
+ }
+
+ {
+ TestRefObject *p1 = new TestRefObject();
+ nsRefPtr<TestRefObjectBaseB> p2 = p1;
+ printf("equality %s.\n",
+ ((NS_STATIC_CAST(void*, p1) != NS_STATIC_CAST(void*, p2)) &&
+ (p1 == p2) && !(p1 != p2) && (p2 == p1) && !(p2 != p1))
+ ? "OK" : "broken");
+ }
+
+ printf("\nTesting |forget()|.\n");
+
+ {
+ printf("Should create one |TestObject|:\n");
+ nsAutoPtr<TestObject> pobj( new TestObject() );
+ printf("Should do nothing:\n");
+ nsAutoPtr<TestObject> pobj2( pobj.forget() );
+ printf("Should destroy one |TestObject|:\n");
+ }
+
+ {
+ printf("Should create 3 |TestObject|s:\n");
+ nsAutoArrayPtr<TestObject> pobj( new TestObject[3] );
+ printf("Should do nothing:\n");
+ nsAutoArrayPtr<TestObject> pobj2( pobj.forget() );
+ printf("Should destroy 3 |TestObject|s:\n");
+ }
+
+ printf("\nTesting construction.\n");
+
+ {
+ printf("Should create one |TestObject|:\n");
+ nsAutoPtr<TestObject> pobj(new TestObject());
+ printf("Should destroy one |TestObject|:\n");
+ }
+
+ {
+ printf("Should create 3 |TestObject|s:\n");
+ nsAutoArrayPtr<TestObject> pobj(new TestObject[3]);
+ printf("Should destroy 3 |TestObject|s:\n");
+ }
+
+ {
+ printf("Should create and AddRef one |TestRefObject|:\n");
+ nsRefPtr<TestRefObject> pobj = new TestRefObject();
+ printf("Should Release and destroy one |TestRefObject|:\n");
+ }
+
+ printf("\nTesting calling of functions (including array access and casts).\n");
+
+ {
+ printf("Should create one |TestObject|:\n");
+ nsAutoPtr<TestObject> pobj(new TestObject());
+ printf("Should do something with one |TestObject|:\n");
+ DoSomethingWithTestObject(pobj);
+ printf("Should do something with one |TestObject|:\n");
+ DoSomethingWithConstTestObject(pobj);
+ printf("Should destroy one |TestObject|:\n");
+ }
+
+ {
+ printf("Should create 3 |TestObject|s:\n");
+ nsAutoArrayPtr<TestObject> pobj(new TestObject[3]);
+ printf("Should do something with one |TestObject|:\n");
+ DoSomethingWithTestObject(&pobj[2]);
+ printf("Should do something with one |TestObject|:\n");
+ DoSomethingWithConstTestObject(&pobj[1]);
+ printf("Should do something with one |TestObject|:\n");
+ DoSomethingWithTestObject(pobj + 2);
+ printf("Should do something with one |TestObject|:\n");
+ DoSomethingWithConstTestObject(pobj + 1);
+ printf("Should destroy 3 |TestObject|s:\n");
+ }
+
+ {
+ printf("Should create and AddRef one |TestRefObject|:\n");
+ nsRefPtr<TestRefObject> pobj = new TestRefObject();
+ printf("Should do something with one |TestRefObject|:\n");
+ DoSomethingWithTestRefObject(pobj);
+ printf("Should do something with one |TestRefObject|:\n");
+ DoSomethingWithConstTestRefObject(pobj);
+ printf("Should Release and destroy one |TestRefObject|:\n");
+ }
+
+ {
+ printf("Should create one |TestObject|:\n");
+ nsAutoPtr<TestObject> pobj(new TestObject());
+ printf("Should do something with one |TestObject|:\n");
+ DoSomethingWithTestObjectBaseB(pobj);
+ printf("Should do something with one |TestObject|:\n");
+ DoSomethingWithConstTestObjectBaseB(pobj);
+ printf("Should destroy one |TestObject|:\n");
+ }
+
+ {
+ printf("Should create 3 |TestObject|s:\n");
+ nsAutoArrayPtr<TestObject> pobj(new TestObject[3]);
+ printf("Should do something with one |TestObject|:\n");
+ DoSomethingWithTestObjectBaseB(&pobj[2]);
+ printf("Should do something with one |TestObject|:\n");
+ DoSomethingWithConstTestObjectBaseB(&pobj[1]);
+ printf("Should do something with one |TestObject|:\n");
+ DoSomethingWithTestObjectBaseB(pobj + 2);
+ printf("Should do something with one |TestObject|:\n");
+ DoSomethingWithConstTestObjectBaseB(pobj + 1);
+ printf("Should destroy 3 |TestObject|s:\n");
+ }
+
+ {
+ printf("Should create and AddRef one |TestRefObject|:\n");
+ nsRefPtr<TestRefObject> pobj = new TestRefObject();
+ printf("Should do something with one |TestRefObject|:\n");
+ DoSomethingWithTestRefObjectBaseB(pobj);
+ printf("Should do something with one |TestRefObject|:\n");
+ DoSomethingWithConstTestRefObjectBaseB(pobj);
+ printf("Should Release and destroy one |TestRefObject|:\n");
+ }
+
+ {
+ printf("Should create one |TestObject|:\n");
+ const nsAutoPtr<TestObject> pobj(new TestObject());
+ printf("Should do something with one |TestObject|:\n");
+ DoSomethingWithTestObject(pobj);
+ printf("Should do something with one |TestObject|:\n");
+ DoSomethingWithConstTestObject(pobj);
+ printf("Should destroy one |TestObject|:\n");
+ }
+
+ {
+ printf("Should create 3 |TestObject|s:\n");
+ const nsAutoArrayPtr<TestObject> pobj(new TestObject[3]);
+ printf("Should do something with one |TestObject|:\n");
+ DoSomethingWithTestObject(&pobj[2]);
+ printf("Should do something with one |TestObject|:\n");
+ DoSomethingWithConstTestObject(&pobj[1]);
+ printf("Should do something with one |TestObject|:\n");
+ DoSomethingWithTestObject(pobj + 2);
+ printf("Should do something with one |TestObject|:\n");
+ DoSomethingWithConstTestObject(pobj + 1);
+ printf("Should destroy 3 |TestObject|s:\n");
+ }
+
+ {
+ printf("Should create and AddRef one |TestRefObject|:\n");
+ const nsRefPtr<TestRefObject> pobj = new TestRefObject();
+ printf("Should do something with one |TestRefObject|:\n");
+ DoSomethingWithTestRefObject(pobj);
+ printf("Should do something with one |TestRefObject|:\n");
+ DoSomethingWithConstTestRefObject(pobj);
+ printf("Should Release and destroy one |TestRefObject|:\n");
+ }
+
+ {
+ printf("Should create one |TestObject|:\n");
+ const nsAutoPtr<TestObject> pobj(new TestObject());
+ printf("Should do something with one |TestObject|:\n");
+ DoSomethingWithTestObjectBaseB(pobj);
+ printf("Should do something with one |TestObject|:\n");
+ DoSomethingWithConstTestObjectBaseB(pobj);
+ printf("Should destroy one |TestObject|:\n");
+ }
+
+ {
+ printf("Should create 3 |TestObject|s:\n");
+ const nsAutoArrayPtr<TestObject> pobj(new TestObject[3]);
+ printf("Should do something with one |TestObject|:\n");
+ DoSomethingWithTestObjectBaseB(&pobj[2]);
+ printf("Should do something with one |TestObject|:\n");
+ DoSomethingWithConstTestObjectBaseB(&pobj[1]);
+ printf("Should do something with one |TestObject|:\n");
+ DoSomethingWithTestObjectBaseB(pobj + 2);
+ printf("Should do something with one |TestObject|:\n");
+ DoSomethingWithConstTestObjectBaseB(pobj + 1);
+ printf("Should destroy 3 |TestObject|s:\n");
+ }
+
+ {
+ printf("Should create and AddRef one |TestRefObject|:\n");
+ const nsRefPtr<TestRefObject> pobj = new TestRefObject();
+ printf("Should do something with one |TestRefObject|:\n");
+ DoSomethingWithTestRefObjectBaseB(pobj);
+ printf("Should do something with one |TestRefObject|:\n");
+ DoSomethingWithConstTestRefObjectBaseB(pobj);
+ printf("Should Release and destroy one |TestRefObject|:\n");
+ }
+
+ return 0;
+}
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestCOMPtr.cpp b/src/libs/xpcom18a4/xpcom/tests/TestCOMPtr.cpp
new file mode 100644
index 00000000..c48219e2
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/TestCOMPtr.cpp
@@ -0,0 +1,651 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Pierre Phaneuf <pp@ludusdesign.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <assert.h>
+#include <stdio.h>
+#include "nsCOMPtr.h"
+#include "nsISupports.h"
+
+#ifdef HAVE_CPP_NEW_CASTS
+ #define STATIC_CAST(T,x) static_cast<T>(x)
+ #define REINTERPRET_CAST(T,x) reinterpret_cast<T>(x)
+#else
+ #define STATIC_CAST(T,x) ((T)(x))
+ #define REINTERPRET_CAST(T,x) ((T)(x))
+#endif
+
+
+#define NS_IFOO_IID \
+{ 0x6f7652e0, 0xee43, 0x11d1, \
+ { 0x9c, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
+
+class IFoo : public nsISupports
+ {
+ public:
+ NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFOO_IID)
+
+ public:
+ IFoo();
+ // virtual dtor because IBar uses our Release()
+ virtual ~IFoo();
+
+ NS_IMETHOD_(nsrefcnt) AddRef();
+ NS_IMETHOD_(nsrefcnt) Release();
+ NS_IMETHOD QueryInterface( const nsIID&, void** );
+
+ static void print_totals();
+
+ private:
+ unsigned int refcount_;
+
+ static unsigned int total_constructions_;
+ static unsigned int total_destructions_;
+ };
+
+class IBar;
+
+ // some types I'll need
+typedef unsigned long NS_RESULT;
+
+ // some functions I'll need (and define below)
+ nsresult CreateIFoo( void** );
+ nsresult CreateIBar( void** result );
+ void AnIFooPtrPtrContext( IFoo** );
+ void AnISupportsPtrPtrContext( nsISupports** );
+ void AVoidPtrPtrContext( void** );
+ void set_a_IFoo( nsCOMPtr<IFoo>* result );
+nsCOMPtr<IFoo> return_a_IFoo();
+
+
+
+
+unsigned int IFoo::total_constructions_;
+unsigned int IFoo::total_destructions_;
+
+class test_message
+ {
+ public:
+ test_message()
+ {
+ printf("BEGIN unit tests for |nsCOMPtr|, compiled " __DATE__ "\n");
+ }
+
+ ~test_message()
+ {
+ IFoo::print_totals();
+ printf("END unit tests for |nsCOMPtr|.\n");
+ }
+ };
+
+test_message gTestMessage;
+
+
+ /*
+ ...
+ */
+
+void
+IFoo::print_totals()
+ {
+ printf("total constructions/destructions --> %d/%d\n",
+ total_constructions_, total_destructions_);
+ }
+
+IFoo::IFoo()
+ : refcount_(0)
+ {
+ ++total_constructions_;
+ printf(" new IFoo@%p [#%d]\n",
+ STATIC_CAST(void*, this), total_constructions_);
+ }
+
+IFoo::~IFoo()
+ {
+ ++total_destructions_;
+ printf("IFoo@%p::~IFoo() [#%d]\n",
+ STATIC_CAST(void*, this), total_destructions_);
+ }
+
+nsrefcnt
+IFoo::AddRef()
+ {
+ ++refcount_;
+ printf("IFoo@%p::AddRef(), refcount --> %d\n",
+ STATIC_CAST(void*, this), refcount_);
+ return refcount_;
+ }
+
+nsrefcnt
+IFoo::Release()
+ {
+ int wrap_message = (refcount_ == 1);
+ if ( wrap_message )
+ printf(">>");
+
+ nsrefcnt const newcount = --refcount_;
+ printf("IFoo@%p::Release(), refcount --> %d\n",
+ STATIC_CAST(void*, this), newcount);
+
+ if ( !newcount )
+ {
+ printf(" delete IFoo@%p\n", STATIC_CAST(void*, this));
+ delete this;
+ }
+
+ if ( wrap_message )
+ printf("<<IFoo@%p::Release()\n", STATIC_CAST(void*, this));
+
+ return newcount;
+ }
+
+nsresult
+IFoo::QueryInterface( const nsIID& aIID, void** aResult )
+ {
+ printf("IFoo@%p::QueryInterface()\n", STATIC_CAST(void*, this));
+ nsISupports* rawPtr = 0;
+ nsresult status = NS_OK;
+
+ if ( aIID.Equals(GetIID()) )
+ rawPtr = this;
+ else
+ {
+ nsID iid_of_ISupports = NS_ISUPPORTS_IID;
+ if ( aIID.Equals(iid_of_ISupports) )
+ rawPtr = STATIC_CAST(nsISupports*, this);
+ else
+ status = NS_ERROR_NO_INTERFACE;
+ }
+
+ NS_IF_ADDREF(rawPtr);
+ *aResult = rawPtr;
+
+ return status;
+ }
+
+nsresult
+CreateIFoo( void** result )
+ // a typical factory function (that calls AddRef)
+ {
+ printf(">>CreateIFoo() --> ");
+ IFoo* foop = new IFoo;
+ printf("IFoo@%p\n", STATIC_CAST(void*, foop));
+
+ foop->AddRef();
+ *result = foop;
+
+ printf("<<CreateIFoo()\n");
+ return 0;
+ }
+
+void
+set_a_IFoo( nsCOMPtr<IFoo>* result )
+ {
+ printf(">>set_a_IFoo()\n");
+ assert(result);
+
+ nsCOMPtr<IFoo> foop( do_QueryInterface(new IFoo) );
+ *result = foop;
+ printf("<<set_a_IFoo()\n");
+ }
+
+nsCOMPtr<IFoo>
+return_a_IFoo()
+ {
+ printf(">>return_a_IFoo()\n");
+ nsCOMPtr<IFoo> foop( do_QueryInterface(new IFoo) );
+ printf("<<return_a_IFoo()\n");
+ return foop;
+ }
+
+
+
+
+#define NS_IBAR_IID \
+{ 0x6f7652e1, 0xee43, 0x11d1, \
+ { 0x9c, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
+
+class IBar : public IFoo
+ {
+ public:
+ NS_DEFINE_STATIC_IID_ACCESSOR(NS_IBAR_IID)
+
+ public:
+ IBar();
+ virtual ~IBar();
+
+ NS_IMETHOD QueryInterface( const nsIID&, void** );
+ };
+
+IBar::IBar()
+ {
+ printf(" new IBar@%p\n", STATIC_CAST(void*, this));
+ }
+
+IBar::~IBar()
+ {
+ printf("IBar@%p::~IBar()\n", STATIC_CAST(void*, this));
+ }
+
+nsresult
+IBar::QueryInterface( const nsID& aIID, void** aResult )
+ {
+ printf("IBar@%p::QueryInterface()\n", STATIC_CAST(void*, this));
+ nsISupports* rawPtr = 0;
+ nsresult status = NS_OK;
+
+ if ( aIID.Equals(GetIID()) )
+ rawPtr = this;
+ else if ( aIID.Equals(NS_GET_IID(IFoo)) )
+ rawPtr = STATIC_CAST(IFoo*, this);
+ else
+ {
+ nsID iid_of_ISupports = NS_ISUPPORTS_IID;
+ if ( aIID.Equals(iid_of_ISupports) )
+ rawPtr = STATIC_CAST(nsISupports*, this);
+ else
+ status = NS_ERROR_NO_INTERFACE;
+ }
+
+ NS_IF_ADDREF(rawPtr);
+ *aResult = rawPtr;
+
+ return status;
+ }
+
+
+
+nsresult
+CreateIBar( void** result )
+ // a typical factory function (that calls AddRef)
+ {
+ printf(">>CreateIBar() --> ");
+ IBar* barp = new IBar;
+ printf("IBar@%p\n", STATIC_CAST(void*, barp));
+
+ barp->AddRef();
+ *result = barp;
+
+ printf("<<CreateIBar()\n");
+ return 0;
+ }
+
+void
+AnIFooPtrPtrContext( IFoo** )
+ {
+ }
+
+void
+AVoidPtrPtrContext( void** )
+ {
+ }
+
+void
+AnISupportsPtrPtrContext( nsISupports** )
+ {
+ }
+
+
+// Optimism
+#define TEST_EXCEPTIONS 1
+
+// HAVE_CPP_EXCEPTIONS is defined automagically on unix
+#if defined(XP_UNIX) || defined(XP_BEOS) || defined(XP_OS2)
+#if !defined(HAVE_CPP_EXCEPTIONS)
+#undef TEST_EXCEPTIONS
+#endif
+#endif
+
+#ifdef TEST_EXCEPTIONS
+static
+nsresult
+TestBloat_Raw()
+ {
+ IBar* barP = 0;
+ nsresult result = CreateIBar(REINTERPRET_CAST(void**, &barP));
+
+ if ( barP )
+ {
+ try
+ {
+ IFoo* fooP = 0;
+ if ( NS_SUCCEEDED( result = barP->QueryInterface(NS_GET_IID(IFoo), REINTERPRET_CAST(void**, &fooP)) ) )
+ {
+ try
+ {
+ fooP->print_totals();
+ }
+ catch( ... )
+ {
+ NS_RELEASE(fooP);
+ throw;
+ }
+
+ NS_RELEASE(fooP);
+ }
+ }
+ catch( ... )
+ {
+ NS_RELEASE(barP);
+ throw;
+ }
+
+ NS_RELEASE(barP);
+ }
+
+ return result;
+ }
+#endif // TEST_EXCEPTIONS
+
+static
+nsresult
+TestBloat_Raw_Unsafe()
+ {
+ IBar* barP = 0;
+ nsresult result = CreateIBar(REINTERPRET_CAST(void**, &barP));
+
+ if ( barP )
+ {
+ IFoo* fooP = 0;
+ if ( NS_SUCCEEDED( result = barP->QueryInterface(NS_GET_IID(IFoo), REINTERPRET_CAST(void**, &fooP)) ) )
+ {
+ fooP->print_totals();
+ NS_RELEASE(fooP);
+ }
+
+ NS_RELEASE(barP);
+ }
+
+ return result;
+ }
+
+
+static
+nsresult
+TestBloat_Smart()
+ {
+ nsCOMPtr<IBar> barP;
+ nsresult result = CreateIBar( getter_AddRefs(barP) );
+
+ nsCOMPtr<IFoo> fooP( do_QueryInterface(barP, &result) );
+
+ if ( fooP )
+ fooP->print_totals();
+
+ return result;
+ }
+
+
+
+
+nsCOMPtr<IFoo> gFoop;
+
+int
+main()
+ {
+ printf(">>main()\n");
+
+ printf("sizeof(nsCOMPtr<IFoo>) --> %zd\n", sizeof(nsCOMPtr<IFoo>));
+
+#ifdef TEST_EXCEPTIONS
+ TestBloat_Raw();
+#endif // TEST_EXCEPTIONS
+ TestBloat_Raw_Unsafe();
+ TestBloat_Smart();
+
+
+ {
+ printf("\n### Test 1: will a |nsCOMPtr| call |AddRef| on a pointer assigned into it?\n");
+ nsCOMPtr<IFoo> foop( do_QueryInterface(new IFoo) );
+
+ printf("\n### Test 2: will a |nsCOMPtr| |Release| its old pointer when a new one is assigned in?\n");
+ foop = do_QueryInterface(new IFoo);
+
+ // [Shouldn't compile] Is it a compile time error to try to |AddRef| by hand?
+ //foop->AddRef();
+
+ // [Shouldn't compile] Is it a compile time error to try to |Release| be hand?
+ //foop->Release();
+
+ // [Shouldn't compile] Is it a compile time error to try to |delete| an |nsCOMPtr|?
+ //delete foop;
+
+ printf("\n### Test 3: can you |AddRef| if you must?\n");
+ STATIC_CAST(IFoo*, foop)->AddRef();
+
+ printf("\n### Test 4: can you |Release| if you must?\n");
+ STATIC_CAST(IFoo*, foop)->Release();
+
+ printf("\n### Test 5: will a |nsCOMPtr| |Release| when it goes out of scope?\n");
+ }
+
+ {
+ printf("\n### Test 6: will a |nsCOMPtr| call the correct destructor?\n");
+ nsCOMPtr<IFoo> foop( do_QueryInterface(new IBar) );
+ }
+
+ {
+ printf("\n### Test 7: can you compare one |nsCOMPtr| with another [!=]?\n");
+
+ nsCOMPtr<IFoo> foo1p( do_QueryInterface(new IFoo) );
+
+ // [Shouldn't compile] Is it a compile time error to omit |getter_[doesnt_]AddRef[s]|?
+ //AnIFooPtrPtrContext(&foo1p);
+
+ // [Shouldn't compile] Is it a compile time error to omit |getter_[doesnt_]AddRef[s]|?
+ //AVoidPtrPtrContext(&foo1p);
+
+ nsCOMPtr<IFoo> foo2p( do_QueryInterface(new IFoo) );
+
+ if ( foo1p != foo2p )
+ printf("foo1p != foo2p\n");
+ else
+ printf("foo1p == foo2p\n");
+
+ printf("\n### Test 7.5: can you compare a |nsCOMPtr| with NULL, 0, nsnull [!=]?\n");
+ if ( foo1p != 0 )
+ printf("foo1p != 0\n");
+ if ( 0 != foo1p )
+ printf("0 != foo1p\n");
+ if ( foo1p == 0 )
+ printf("foo1p == 0\n");
+ if ( 0 == foo1p )
+ printf("0 == foo1p\n");
+
+
+ IFoo* raw_foo2p = foo2p.get();
+
+ printf("\n### Test 8: can you compare a |nsCOMPtr| with a raw interface pointer [!=]?\n");
+ if ( foo1p.get() != raw_foo2p )
+ printf("foo1p != raw_foo2p\n");
+ else
+ printf("foo1p == raw_foo2p\n");
+
+
+ printf("\n### Test 9: can you assign one |nsCOMPtr| into another?\n");
+ foo1p = foo2p;
+
+ printf("\n### Test 10: can you compare one |nsCOMPtr| with another [==]?\n");
+ if ( foo1p == foo2p )
+ printf("foo1p == foo2p\n");
+ else
+ printf("foo1p != foo2p\n");
+
+ printf("\n### Test 11: can you compare a |nsCOMPtr| with a raw interface pointer [==]?\n");
+ if ( raw_foo2p == foo2p.get() )
+ printf("raw_foo2p == foo2p\n");
+ else
+ printf("raw_foo2p != foo2p\n");
+
+#if 1
+ printf("\n### Test 11.5: can you compare a |nsCOMPtr| with a raw interface pointer [==]?\n");
+ if ( nsCOMPtr<IFoo>( raw_foo2p ) == foo2p )
+ printf("raw_foo2p == foo2p\n");
+ else
+ printf("raw_foo2p != foo2p\n");
+#endif
+
+ printf("\n### Test 12: bare pointer test?\n");
+ if ( foo1p )
+ printf("foo1p is not NULL\n");
+ else
+ printf("foo1p is NULL\n");
+
+ printf("\n### Test 13: numeric pointer test?\n");
+ if ( foo1p == 0 )
+ printf("foo1p is NULL\n");
+ else
+ printf("foo1p is not NULL\n");
+
+#if 0
+ if ( foo1p == 1 )
+ printf("foo1p allowed compare with in\n");
+#endif
+
+ printf("\n### Test 14: how about when two |nsCOMPtr|s referring to the same object go out of scope?\n");
+ }
+
+ {
+ printf("\n### Test 15,16 ...setup...\n");
+ IFoo* raw_foo1p = new IFoo;
+ raw_foo1p->AddRef();
+
+ IFoo* raw_foo2p = new IFoo;
+ raw_foo2p->AddRef();
+
+ printf("\n### Test 15: what if I don't want to |AddRef| when I construct?\n");
+ nsCOMPtr<IFoo> foo1p( dont_AddRef(raw_foo1p) );
+ //nsCOMPtr<IFoo> foo1p = dont_AddRef(raw_foo1p);
+
+ printf("\n### Test 16: what if I don't want to |AddRef| when I assign in?\n");
+ nsCOMPtr<IFoo> foo2p;
+ foo2p = dont_AddRef(raw_foo2p);
+ }
+
+
+
+
+
+
+
+ {
+ printf("\n### setup for Test 17\n");
+ nsCOMPtr<IFoo> foop;
+ printf("### Test 17: basic parameter behavior?\n");
+ CreateIFoo( nsGetterAddRefs<IFoo>(foop) );
+ }
+ printf("### End Test 17\n");
+
+
+ {
+ printf("\n### setup for Test 18\n");
+ nsCOMPtr<IFoo> foop;
+ printf("### Test 18: basic parameter behavior, using the short form?\n");
+ CreateIFoo( getter_AddRefs(foop) );
+ }
+ printf("### End Test 18\n");
+
+
+ {
+ printf("\n### setup for Test 19, 20\n");
+ nsCOMPtr<IFoo> foop;
+ printf("### Test 19: reference parameter behavior?\n");
+ set_a_IFoo(address_of(foop));
+
+ printf("### Test 20: return value behavior?\n");
+ foop = return_a_IFoo();
+ }
+ printf("### End Test 19, 20\n");
+
+ {
+ printf("\n### setup for Test 21\n");
+ nsCOMPtr<IFoo> fooP;
+
+ printf("### Test 21: is |QueryInterface| called on assigning in a raw pointer?\n");
+ fooP = do_QueryInterface(new IFoo);
+ }
+ printf("### End Test 21\n");
+
+ {
+ printf("\n### setup for Test 22\n");
+ nsCOMPtr<IFoo> fooP;
+ fooP = do_QueryInterface(new IFoo);
+
+ nsCOMPtr<IFoo> foo2P;
+
+ printf("### Test 22: is |QueryInterface| _not_ called when assigning in a smart-pointer of the same type?\n");
+ foo2P = fooP;
+ }
+ printf("### End Test 22\n");
+
+ {
+ printf("\n### setup for Test 23\n");
+ nsCOMPtr<IBar> barP( do_QueryInterface(new IBar) );
+
+ printf("### Test 23: is |QueryInterface| called when assigning in a smart-pointer of a different type?\n");
+
+ nsCOMPtr<IFoo> fooP( do_QueryInterface(barP) );
+ if ( fooP )
+ printf("an IBar* is an IFoo*\n");
+ }
+ printf("### End Test 23\n");
+
+
+ {
+ nsCOMPtr<IFoo> fooP;
+
+ AnIFooPtrPtrContext( getter_AddRefs(fooP) );
+ AVoidPtrPtrContext( getter_AddRefs(fooP) );
+ AnISupportsPtrPtrContext( getter_AddRefs(fooP) );
+ }
+
+
+ {
+ nsCOMPtr<nsISupports> supportsP;
+
+ AVoidPtrPtrContext( getter_AddRefs(supportsP) );
+ AnISupportsPtrPtrContext( getter_AddRefs(supportsP) );
+ }
+
+
+ printf("\n### Test 24: will a static |nsCOMPtr| |Release| before program termination?\n");
+ gFoop = do_QueryInterface(new IFoo);
+
+ printf("<<main()\n");
+ return 0;
+ }
+
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestCOMPtrEq.cpp b/src/libs/xpcom18a4/xpcom/tests/TestCOMPtrEq.cpp
new file mode 100644
index 00000000..916a0775
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/TestCOMPtrEq.cpp
@@ -0,0 +1,200 @@
+/* -*- 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 TestCOMPtrEq.cpp.
+ *
+ * The Initial Developer of the Original Code is
+ * L. David Baron.
+ * Portions created by the Initial Developer are Copyright (C) 2001
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * L. David Baron <dbaron@dbaron.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 ***** */
+
+ /**
+ * This attempts to test all the possible variations of |operator==|
+ * used with |nsCOMPtr|s. Currently only the tests where pointers
+ * are to the same class are enabled. It's not clear whether we
+ * should be supporting other tests, and some of them won't work
+ * on at least some platforms. If we add separate comparisons
+ * for nsCOMPtr<nsISupports> we'll need to add more tests for
+ * those cases.
+ */
+
+#include "nsCOMPtr.h"
+
+ // Don't test these now, since some of them won't work and it's
+ // not clear whether they should (see above).
+#undef NSCAP_EQTEST_TEST_ACROSS_TYPES
+
+#define NS_ICOMPTREQTESTFOO_IID \
+ {0x8eb5bbef, 0xd1a3, 0x4659, \
+ {0x9c, 0xf6, 0xfd, 0xf3, 0xe4, 0xd2, 0x00, 0x0e}}
+
+class nsICOMPtrEqTestFoo : public nsISupports {
+ public:
+ NS_DEFINE_STATIC_IID_ACCESSOR(NS_ICOMPTREQTESTFOO_IID)
+};
+
+#ifdef NSCAP_EQTEST_TEST_ACROSS_TYPES
+
+#define NS_ICOMPTREQTESTFOO2_IID \
+ {0x6516387b, 0x36c5, 0x4036, \
+ {0x82, 0xc9, 0xa7, 0x4d, 0xd9, 0xe5, 0x92, 0x2f}}
+
+class nsICOMPtrEqTestFoo2 : public nsISupports {
+ public:
+ NS_DEFINE_STATIC_IID_ACCESSOR(NS_ICOMPTREQTESTFOO2_IID)
+};
+
+#endif
+
+int
+main()
+ {
+ nsCOMPtr<nsICOMPtrEqTestFoo> s;
+ nsICOMPtrEqTestFoo* r = 0;
+ const nsCOMPtr<nsICOMPtrEqTestFoo> sc;
+ const nsICOMPtrEqTestFoo* rc = 0;
+ nsICOMPtrEqTestFoo* const rk = 0;
+ const nsICOMPtrEqTestFoo* const rkc = 0;
+ nsDerivedSafe<nsICOMPtrEqTestFoo>* d = s.get();
+
+#ifdef NSCAP_EQTEST_TEST_ACROSS_TYPES
+ nsCOMPtr<nsICOMPtrEqTestFoo2> s2;
+ nsICOMPtrEqTestFoo2* r2 = 0;
+ const nsCOMPtr<nsICOMPtrEqTestFoo2> sc2;
+ const nsICOMPtrEqTestFoo2* rc2 = 0;
+ nsICOMPtrEqTestFoo2* const rk2 = 0;
+ const nsICOMPtrEqTestFoo2* const rkc2 = 0;
+ nsDerivedSafe<nsICOMPtrEqTestFoo2>* d2 = s2.get();
+#endif
+
+ return (!(PR_TRUE &&
+ (s == s) &&
+ (s == r) &&
+ (s == sc) &&
+ (s == rc) &&
+ (s == rk) &&
+ (s == rkc) &&
+ (s == d) &&
+ (r == s) &&
+ (r == r) &&
+ (r == sc) &&
+ (r == rc) &&
+ (r == rk) &&
+ (r == rkc) &&
+ (r == d) &&
+ (sc == s) &&
+ (sc == r) &&
+ (sc == sc) &&
+ (sc == rc) &&
+ (sc == rk) &&
+ (sc == rkc) &&
+ (sc == d) &&
+ (rc == s) &&
+ (rc == r) &&
+ (rc == sc) &&
+ (rc == rc) &&
+ (rc == rk) &&
+ (rc == rkc) &&
+ (rc == d) &&
+ (rk == s) &&
+ (rk == r) &&
+ (rk == sc) &&
+ (rk == rc) &&
+ (rk == rk) &&
+ (rk == rkc) &&
+ (rk == d) &&
+ (rkc == s) &&
+ (rkc == r) &&
+ (rkc == sc) &&
+ (rkc == rc) &&
+ (rkc == rk) &&
+ (rkc == rkc) &&
+ (rkc == d) &&
+ (d == s) &&
+ (d == r) &&
+ (d == sc) &&
+ (d == rc) &&
+ (d == rk) &&
+ (d == rkc) &&
+ (d == d) &&
+#ifdef NSCAP_EQTEST_TEST_ACROSS_TYPES
+ (s == s2) &&
+ (s == r2) &&
+ (s == sc2) &&
+ (s == rc2) &&
+ (s == rk2) &&
+ (s == rkc2) &&
+ (s == d2) &&
+ (r == s2) &&
+ (r == r2) &&
+ (r == sc2) &&
+ (r == rc2) &&
+ (r == rk2) &&
+ (r == rkc2) &&
+ (r == d2) &&
+ (sc == s2) &&
+ (sc == r2) &&
+ (sc == sc2) &&
+ (sc == rc2) &&
+ (sc == rk2) &&
+ (sc == rkc2) &&
+ (sc == d2) &&
+ (rc == s2) &&
+ (rc == r2) &&
+ (rc == sc2) &&
+ (rc == rc2) &&
+ (rc == rk2) &&
+ (rc == rkc2) &&
+ (rc == d2) &&
+ (rk == s2) &&
+ (rk == r2) &&
+ (rk == sc2) &&
+ (rk == rc2) &&
+ (rk == rk2) &&
+ (rk == rkc2) &&
+ (rk == d2) &&
+ (rkc == s2) &&
+ (rkc == r2) &&
+ (rkc == sc2) &&
+ (rkc == rc2) &&
+ (rkc == rk2) &&
+ (rkc == rkc2) &&
+ (rkc == d2) &&
+ (d == s2) &&
+ (d == r2) &&
+ (d == sc2) &&
+ (d == rc2) &&
+ (d == rk2) &&
+ (d == rkc2) &&
+ (d == d2) &&
+#endif
+ PR_TRUE));
+ }
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestCRT.cpp b/src/libs/xpcom18a4/xpcom/tests/TestCRT.cpp
new file mode 100644
index 00000000..11bdd512
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/TestCRT.cpp
@@ -0,0 +1,112 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 "nsCRT.h"
+#include "nsString.h"
+#include "plstr.h"
+#include <stdlib.h>
+
+// The return from strcmp etc is only defined to be postive, zero or
+// negative. The magnitude of a non-zero return is irrelevant.
+PRIntn sign(PRIntn val) {
+ if (val == 0)
+ return 0;
+ else {
+ if (val > 0)
+ return 1;
+ else
+ return -1;
+ }
+}
+
+
+// Verify that nsCRT versions of string comparison routines get the
+// same answers as the native non-unicode versions. We only pass in
+// iso-latin-1 strings, so the comparison must be valid.
+static void Check(const char* s1, const char* s2, PRIntn n)
+{
+ PRIntn clib = PL_strcmp(s1, s2);
+ PRIntn clib_n = PL_strncmp(s1, s2, n);
+ PRIntn clib_case = PL_strcasecmp(s1, s2);
+ PRIntn clib_case_n = PL_strncasecmp(s1, s2, n);
+
+ nsAutoString t1,t2;
+ t1.AssignWithConversion(s1);
+ t2.AssignWithConversion(s2);
+ const PRUnichar* us1 = t1.get();
+ const PRUnichar* us2 = t2.get();
+
+ PRIntn u2 = nsCRT::strcmp(us1, us2);
+ PRIntn u2_n = nsCRT::strncmp(us1, us2, n);
+
+ NS_ASSERTION(sign(clib) == sign(u2), "strcmp");
+ NS_ASSERTION(sign(clib_n) == sign(u2_n), "strncmp");
+}
+
+struct Test {
+ const char* s1;
+ const char* s2;
+ PRIntn n;
+};
+
+static Test tests[] = {
+ { "foo", "foo", 3 },
+ { "foo", "fo", 3 },
+
+ { "foo", "bar", 3 },
+ { "foo", "ba", 3 },
+
+ { "foo", "zap", 3 },
+ { "foo", "za", 3 },
+
+ { "bar", "foo", 3 },
+ { "bar", "fo", 3 },
+
+ { "bar", "foo", 3 },
+ { "bar", "fo", 3 },
+};
+#define NUM_TESTS int((sizeof(tests) / sizeof(tests[0])))
+
+int main()
+{
+ Test* tp = tests;
+ for (int i = 0; i < NUM_TESTS; i++, tp++) {
+ Check(tp->s1, tp->s2, tp->n);
+ }
+
+ return 0;
+}
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestCallTemplates.cpp b/src/libs/xpcom18a4/xpcom/tests/TestCallTemplates.cpp
new file mode 100644
index 00000000..3ec9c29a
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/TestCallTemplates.cpp
@@ -0,0 +1,129 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * vim:cindent:ts=8:et:sw=4:
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is 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):
+ * L. David Baron <dbaron@dbaron.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 ***** */
+
+/*
+ * This test is NOT intended to be run. It's a test to make sure
+ * a group of functions BUILD correctly.
+ */
+
+#include "nsISupportsUtils.h"
+#include "nsIWeakReference.h"
+#include "nsIComponentManager.h"
+#include "nsIServiceManager.h"
+#include "nsWeakReference.h"
+#include "nsIInterfaceRequestor.h"
+#include "nsIInterfaceRequestorUtils.h"
+
+#define NS_ITESTSERVICE_IID \
+ {0x127b5253, 0x37b1, 0x43c7, \
+ { 0x96, 0x2b, 0xab, 0xf1, 0x2d, 0x22, 0x56, 0xae }}
+
+class NS_NO_VTABLE nsITestService : public nsISupports {
+ public:
+ NS_DEFINE_STATIC_IID_ACCESSOR(NS_ITESTSERVICE_IID)
+};
+
+class nsTestService : public nsITestService, public nsSupportsWeakReference
+{
+ public:
+ NS_DECL_ISUPPORTS
+};
+
+NS_IMPL_ISUPPORTS2(nsTestService, nsITestService, nsISupportsWeakReference)
+
+#define NS_TEST_SERVICE_CONTRACTID "@mozilla.org/test/testservice;1"
+#define NS_TEST_SERVICE_CID \
+ {0xa00c1406, 0x283a, 0x45c9, \
+ {0xae, 0xd2, 0x1a, 0xb6, 0xdd, 0xba, 0xfe, 0x53}}
+static NS_DEFINE_CID(kTestServiceCID, NS_TEST_SERVICE_CID);
+
+int main()
+{
+ /*
+ * NOTE: This does NOT demonstrate how these functions are
+ * intended to be used. They are intended for filling in out
+ * parameters that need to be |AddRef|ed. I'm just too lazy
+ * to write lots of little getter functions for a test program
+ * when I don't need to.
+ */
+
+ NS_NOTREACHED("This test is not intended to run, only to compile!");
+
+ /* Test CallQueryInterface */
+
+ nsISupports *mySupportsPtr = NS_REINTERPRET_CAST(nsISupports*, 0x1000);
+
+ nsITestService *myITestService = nsnull;
+ CallQueryInterface(mySupportsPtr, &myITestService);
+
+ nsTestService *myTestService =
+ NS_REINTERPRET_CAST(nsTestService*, mySupportsPtr);
+ nsISupportsWeakReference *mySupportsWeakRef;
+ CallQueryInterface(myTestService, &mySupportsWeakRef);
+
+ /* Test CallQueryReferent */
+
+ nsIWeakReference *myWeakRef =
+ NS_STATIC_CAST(nsIWeakReference*, mySupportsPtr);
+ CallQueryReferent(myWeakRef, &myITestService);
+
+ /* Test CallCreateInstance */
+
+ CallCreateInstance(kTestServiceCID, mySupportsPtr, &myITestService);
+ CallCreateInstance(kTestServiceCID, &myITestService);
+ CallCreateInstance(NS_TEST_SERVICE_CONTRACTID, mySupportsPtr,
+ &myITestService);
+ CallCreateInstance(NS_TEST_SERVICE_CONTRACTID, &myITestService);
+
+ /* Test CallGetService */
+ nsIShutdownListener *myShutdownListener = nsnull;
+ CallGetService(kTestServiceCID, &myITestService);
+ CallGetService(kTestServiceCID, myShutdownListener, &myITestService);
+ CallGetService(NS_TEST_SERVICE_CONTRACTID, &myITestService);
+ CallGetService(NS_TEST_SERVICE_CONTRACTID, myShutdownListener,
+ &myITestService);
+
+ /* Test CallGetInterface */
+ nsIInterfaceRequestor *myInterfaceRequestor =
+ NS_STATIC_CAST(nsIInterfaceRequestor*, mySupportsPtr);
+ CallGetInterface(myInterfaceRequestor, &myITestService);
+
+ return 0;
+}
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestDeque.cpp b/src/libs/xpcom18a4/xpcom/tests/TestDeque.cpp
new file mode 100644
index 00000000..4b00c7fb
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/TestDeque.cpp
@@ -0,0 +1,155 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 "nsDeque.h"
+#include "nsCRT.h"
+#include <stdio.h>
+
+/**************************************************************
+ Now define the token deallocator class...
+ **************************************************************/
+class _TestDeque {
+public:
+ _TestDeque() {
+ SelfTest();
+ }
+ int SelfTest();
+ nsresult OriginalTest();
+ nsresult OriginalFlaw();
+ nsresult AssignFlaw();
+};
+static _TestDeque sTestDeque;
+
+class _Dealloc: public nsDequeFunctor {
+ virtual void* operator()(void* aObject) {
+ return 0;
+ }
+};
+
+/**
+ * conduct automated self test for this class
+ *
+ * @param
+ * @return
+ */
+int _TestDeque::SelfTest() {
+ /* the old deque should have failed a bunch of these tests */
+ int results=0;
+ results+=OriginalTest();
+ results+=OriginalFlaw();
+ results+=AssignFlaw();
+ return results;
+}
+
+nsresult _TestDeque::OriginalTest() {
+ int ints[200];
+ int count=sizeof(ints)/sizeof(int);
+ int i=0;
+ int* temp;
+ nsDeque theDeque(new _Dealloc); //construct a simple one...
+
+ for (i=0;i<count;i++) { //initialize'em
+ ints[i]=10*(1+i);
+ }
+ for (i=0;i<70;i++) {
+ theDeque.Push(&ints[i]);
+ }
+ for (i=0;i<56;i++) {
+ temp=(int*)theDeque.Pop();
+ }
+ for (i=0;i<55;i++) {
+ theDeque.Push(&ints[i]);
+ }
+ for (i=0;i<35;i++) {
+ temp=(int*)theDeque.Pop();
+ }
+ for (i=0;i<35;i++) {
+ theDeque.Push(&ints[i]);
+ }
+ for (i=0;i<38;i++) {
+ temp=(int*)theDeque.Pop();
+ }
+ return NS_OK;
+}
+
+nsresult _TestDeque::OriginalFlaw() {
+ int ints[200];
+ int i=0;
+ int* temp;
+ nsDeque secondDeque(new _Dealloc);
+ /**
+ * Test 1. Origin near end, semi full, call Peek().
+ * you start, mCapacity is 8
+ */
+ printf("fill array\n");
+ for (i=32; i; --i)
+ ints[i]=i*3+10;
+ printf("push 6 times\n");
+ for (i=0; i<6; i++)
+ secondDeque.Push(&ints[i]);
+ printf("popfront 4 times:\n");
+ for (i=4; i; --i) {
+ temp=(int*)secondDeque.PopFront();
+ printf("%d\t",*temp);
+ }
+ printf("push 4 times\n");
+ for (int j=4; j; --j)
+ secondDeque.Push(&ints[++i]);
+ printf("origin should now be about 4\n");
+ printf("and size should be 6\n");
+ printf("origin+size>capacity\n");
+
+ /*<akk> Oh, I see ... it's a circular buffer */
+ printf("but the old code wasn't behaving accordingly.\n");
+
+ /*right*/
+ printf("we shouldn't crash or anything interesting, ");
+
+ temp=(int*)secondDeque.Peek();
+ printf("peek: %d\n",*temp);
+ return NS_OK;
+}
+
+nsresult _TestDeque::AssignFlaw() {
+ nsDeque src(new _Dealloc),dest(new _Dealloc);
+ return NS_OK;
+}
+
+int main (void) {
+ _TestDeque test;
+ return 0;
+}
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestFactory.cpp b/src/libs/xpcom18a4/xpcom/tests/TestFactory.cpp
new file mode 100644
index 00000000..f0d5f777
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/TestFactory.cpp
@@ -0,0 +1,160 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Pierre Phaneuf <pp@ludusdesign.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <stdio.h>
+#include "TestFactory.h"
+#include "nsISupports.h"
+#include "nsIComponentManager.h"
+#include "nsIComponentRegistrar.h"
+#include "nsIServiceManager.h"
+
+NS_DEFINE_CID(kTestFactoryCID, NS_TESTFACTORY_CID);
+NS_DEFINE_CID(kTestLoadedFactoryCID, NS_TESTLOADEDFACTORY_CID);
+
+
+/**
+ * ITestClass implementation
+ */
+
+class TestClassImpl: public ITestClass {
+ NS_DECL_ISUPPORTS
+public:
+ TestClassImpl() {
+ }
+
+ void Test();
+};
+
+NS_IMPL_ISUPPORTS1(TestClassImpl, ITestClass)
+
+void TestClassImpl::Test() {
+ printf("hello, world!\n");
+}
+
+/**
+ * TestFactory implementation
+ */
+
+class TestFactory: public nsIFactory {
+ NS_DECL_ISUPPORTS
+
+public:
+ TestFactory() {
+ }
+
+ NS_IMETHOD CreateInstance(nsISupports *aDelegate,
+ const nsIID &aIID,
+ void **aResult);
+
+ NS_IMETHOD LockFactory(PRBool aLock) { return NS_OK; }
+};
+
+NS_IMPL_ISUPPORTS1(TestFactory, nsIFactory)
+
+nsresult TestFactory::CreateInstance(nsISupports *aDelegate,
+ const nsIID &aIID,
+ void **aResult) {
+ if (aDelegate != NULL) {
+ return NS_ERROR_NO_AGGREGATION;
+ }
+
+ TestClassImpl *t = new TestClassImpl();
+
+ if (t == NULL) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ nsresult res = t->QueryInterface(aIID, aResult);
+
+ if (NS_FAILED(res)) {
+ *aResult = NULL;
+ delete t;
+ }
+
+ return res;
+}
+
+
+int main(int argc, char **argv) {
+ nsresult rv;
+
+ {
+ nsCOMPtr<nsIServiceManager> servMan;
+ rv = NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull);
+ if (NS_FAILED(rv)) return -1;
+ nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan);
+ NS_ASSERTION(registrar, "Null nsIComponentRegistrar");
+ if (registrar)
+ registrar->RegisterFactory(kTestFactoryCID,
+ nsnull,
+ nsnull,
+ new TestFactory());
+
+ ITestClass *t = NULL;
+ nsComponentManager::CreateInstance(kTestFactoryCID,
+ NULL,
+ NS_GET_IID(ITestClass),
+ (void **) &t);
+
+ if (t != NULL) {
+ t->Test();
+ t->Release();
+ } else {
+ printf("CreateInstance failed\n");
+ }
+
+ t = NULL;
+
+ nsComponentManager::CreateInstance(kTestLoadedFactoryCID,
+ NULL,
+ NS_GET_IID(ITestClass),
+ (void **) &t);
+
+ if (t != NULL) {
+ t->Test();
+ t->Release();
+ } else {
+ printf("Dynamic CreateInstance failed\n");
+ }
+ } // this scopes the nsCOMPtrs
+ // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
+ rv = NS_ShutdownXPCOM(nsnull);
+ NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");
+ return 0;
+}
+
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestFactory.h b/src/libs/xpcom18a4/xpcom/tests/TestFactory.h
new file mode 100644
index 00000000..d81cefc7
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/TestFactory.h
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Suresh Duddi <dp@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __TestFactory_h
+#define __TestFactory_h
+
+#include "nsIFactory.h"
+
+// {8B330F20-A24A-11d1-A961-00805F8A7AC4}
+#define NS_TESTFACTORY_CID \
+{ 0x8b330f20, 0xa24a, 0x11d1, \
+ { 0xa9, 0x61, 0x0, 0x80, 0x5f, 0x8a, 0x7a, 0xc4 } }
+
+// {8B330F21-A24A-11d1-A961-00805F8A7AC4}
+#define NS_ITESTCLASS_IID \
+{ 0x8b330f21, 0xa24a, 0x11d1, \
+ { 0xa9, 0x61, 0x0, 0x80, 0x5f, 0x8a, 0x7a, 0xc4 } }
+
+// {8B330F22-A24A-11d1-A961-00805F8A7AC4}
+#define NS_TESTLOADEDFACTORY_CID \
+{ 0x8b330f22, 0xa24a, 0x11d1, \
+ { 0xa9, 0x61, 0x0, 0x80, 0x5f, 0x8a, 0x7a, 0xc4 } }
+
+#define NS_TESTLOADEDFACTORY_CONTRACTID "@mozilla.org/xpcom/dynamic-test;1"
+
+class ITestClass: public nsISupports {
+public:
+ NS_DEFINE_STATIC_IID_ACCESSOR(NS_ITESTCLASS_IID)
+ virtual void Test() = 0;
+};
+
+extern "C" void RegisterTestFactories();
+
+#endif
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestHashtables.cpp b/src/libs/xpcom18a4/xpcom/tests/TestHashtables.cpp
new file mode 100644
index 00000000..1b2d3671
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/TestHashtables.cpp
@@ -0,0 +1,939 @@
+/* -*- 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 C++ hashtable templates.
+ *
+ * The Initial Developer of the Original Code is
+ * Benjamin Smedberg.
+ * Portions created by the Initial Developer are Copyright (C) 2002
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 "nsTHashtable.h"
+#include "nsBaseHashtable.h"
+#include "nsDataHashtable.h"
+#include "nsInterfaceHashtable.h"
+#include "nsClassHashtable.h"
+
+#include "nsCOMPtr.h"
+#include "nsISupports.h"
+#include "nsCRT.h"
+#include "nsCOMArray.h"
+
+class TestUniChar // for nsClassHashtable
+{
+public:
+ TestUniChar(PRUint32 aWord)
+ {
+ printf(" TestUniChar::TestUniChar() %u\n", aWord);
+ mWord = aWord;
+ }
+
+ ~TestUniChar()
+ {
+ printf(" TestUniChar::~TestUniChar() %u\n", mWord);
+ }
+
+ PRUint32 GetChar() const { return mWord; }
+
+private:
+ PRUint32 mWord;
+};
+
+struct EntityNode {
+ const char* mStr; // never owns buffer
+ PRUint32 mUnicode;
+};
+
+EntityNode gEntities[] = {
+ {"nbsp",160},
+ {"iexcl",161},
+ {"cent",162},
+ {"pound",163},
+ {"curren",164},
+ {"yen",165},
+ {"brvbar",166},
+ {"sect",167},
+ {"uml",168},
+ {"copy",169},
+ {"ordf",170},
+ {"laquo",171},
+ {"not",172},
+ {"shy",173},
+ {"reg",174},
+ {"macr",175}
+};
+
+#define ENTITY_COUNT (sizeof(gEntities)/sizeof(EntityNode))
+
+class EntityToUnicodeEntry : public PLDHashEntryHdr
+{
+public:
+ typedef const char* KeyType;
+ typedef const char* KeyTypePointer;
+
+ EntityToUnicodeEntry(const char* aKey) { mNode = nsnull; }
+ EntityToUnicodeEntry(const EntityToUnicodeEntry& aEntry) { mNode = aEntry.mNode; }
+ ~EntityToUnicodeEntry() { };
+
+ const char* GetKeyPointer() const { return mNode->mStr; }
+ PRBool KeyEquals(const char* aEntity) const { return !strcmp(mNode->mStr, aEntity); }
+ static const char* KeyToPointer(const char* aEntity) { return aEntity; }
+ static PLDHashNumber HashKey(const char* aEntity) { return nsCRT::HashCode(aEntity); }
+ enum { ALLOW_MEMMOVE = PR_TRUE };
+
+ const EntityNode* mNode;
+};
+
+PLDHashOperator
+nsTEnumGo(EntityToUnicodeEntry* aEntry, void* userArg) {
+ printf(" enumerated \"%s\" = %u\n",
+ aEntry->mNode->mStr, aEntry->mNode->mUnicode);
+
+ return PL_DHASH_NEXT;
+}
+
+PLDHashOperator
+nsTEnumStop(EntityToUnicodeEntry* aEntry, void* userArg) {
+ printf(" enumerated \"%s\" = %u\n",
+ aEntry->mNode->mStr, aEntry->mNode->mUnicode);
+
+ return PL_DHASH_REMOVE;
+}
+
+void
+testTHashtable(nsTHashtable<EntityToUnicodeEntry>& hash, PRUint32 numEntries) {
+ printf("Filling hash with %d entries.\n", numEntries);
+
+ PRUint32 i;
+ for (i = 0; i < numEntries; ++i) {
+ printf(" Putting entry \"%s\"...", gEntities[i].mStr);
+ EntityToUnicodeEntry* entry =
+ hash.PutEntry(gEntities[i].mStr);
+
+ if (!entry) {
+ printf("FAILED\n");
+ exit (2);
+ }
+ printf("OK...");
+
+ if (entry->mNode) {
+ printf("entry already exists!\n");
+ exit (3);
+ }
+ printf("\n");
+
+ entry->mNode = &gEntities[i];
+ }
+
+ printf("Testing Get:\n");
+
+ for (i = 0; i < numEntries; ++i) {
+ printf(" Getting entry \"%s\"...", gEntities[i].mStr);
+ EntityToUnicodeEntry* entry =
+ hash.GetEntry(gEntities[i].mStr);
+
+ if (!entry) {
+ printf("FAILED\n");
+ exit (4);
+ }
+
+ printf("Found %u\n", entry->mNode->mUnicode);
+ }
+
+ printf("Testing non-existent entries...");
+
+ EntityToUnicodeEntry* entry =
+ hash.GetEntry("xxxy");
+
+ if (entry) {
+ printf("FOUND! BAD!\n");
+ exit (5);
+ }
+
+ printf("not found; good.\n");
+
+ printf("Enumerating:\n");
+ PRUint32 count = hash.EnumerateEntries(nsTEnumGo, nsnull);
+ if (count != numEntries) {
+ printf(" Bad count!\n");
+ exit (6);
+ }
+}
+
+PLDHashOperator
+nsDEnumRead(const PRUint32& aKey, const char* aData, void* userArg) {
+ printf(" enumerated %u = \"%s\"\n", aKey, aData);
+ return PL_DHASH_NEXT;
+}
+
+PLDHashOperator
+nsDEnum(const PRUint32& aKey, const char*& aData, void* userArg) {
+ printf(" enumerated %u = \"%s\"\n", aKey, aData);
+ return PL_DHASH_NEXT;
+}
+
+PLDHashOperator
+nsCEnumRead(const nsACString& aKey, TestUniChar* aData, void* userArg) {
+ printf(" enumerated \"%s\" = %c\n",
+ PromiseFlatCString(aKey).get(), aData->GetChar());
+ return PL_DHASH_NEXT;
+}
+
+PLDHashOperator
+nsCEnum(const nsACString& aKey, nsAutoPtr<TestUniChar>& aData, void* userArg) {
+ printf(" enumerated \"%s\" = %c\n",
+ PromiseFlatCString(aKey).get(), aData->GetChar());
+ return PL_DHASH_NEXT;
+}
+
+//
+// all this nsIFoo stuff was copied wholesale from TestCOMPTr.cpp
+//
+
+#define NS_IFOO_IID \
+{ 0x6f7652e0, 0xee43, 0x11d1, \
+ { 0x9c, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
+
+class IFoo : public nsISupports
+ {
+ public:
+ NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFOO_IID)
+
+ public:
+ IFoo();
+
+ NS_IMETHOD_(nsrefcnt) AddRef();
+ NS_IMETHOD_(nsrefcnt) Release();
+ NS_IMETHOD QueryInterface( const nsIID&, void** );
+
+ NS_IMETHOD SetString(const nsACString& /*in*/ aString);
+ NS_IMETHOD GetString(nsACString& /*out*/ aString);
+
+ static void print_totals();
+
+ private:
+ ~IFoo();
+
+ unsigned int refcount_;
+
+ static unsigned int total_constructions_;
+ static unsigned int total_destructions_;
+ nsCString mString;
+ };
+
+unsigned int IFoo::total_constructions_;
+unsigned int IFoo::total_destructions_;
+
+void
+IFoo::print_totals()
+ {
+ printf("total constructions/destructions --> %d/%d\n",
+ total_constructions_, total_destructions_);
+ }
+
+IFoo::IFoo()
+ : refcount_(0)
+ {
+ ++total_constructions_;
+ printf(" new IFoo@%p [#%d]\n",
+ NS_STATIC_CAST(void*, this), total_constructions_);
+ }
+
+IFoo::~IFoo()
+ {
+ ++total_destructions_;
+ printf("IFoo@%p::~IFoo() [#%d]\n",
+ NS_STATIC_CAST(void*, this), total_destructions_);
+ }
+
+nsrefcnt
+IFoo::AddRef()
+ {
+ ++refcount_;
+ printf("IFoo@%p::AddRef(), refcount --> %d\n",
+ NS_STATIC_CAST(void*, this), refcount_);
+ return refcount_;
+ }
+
+nsrefcnt
+IFoo::Release()
+ {
+ int wrap_message = (refcount_ == 1);
+ if ( wrap_message )
+ printf(">>");
+
+ nsrefcnt newrefcount = --refcount_;
+ printf("IFoo@%p::Release(), refcount --> %d\n",
+ NS_STATIC_CAST(void*, this), newrefcount);
+
+ if ( !newrefcount )
+ {
+ printf(" delete IFoo@%p\n", NS_STATIC_CAST(void*, this));
+ delete this;
+ }
+
+ if ( wrap_message )
+ printf(" delete IFoo@%p\n", NS_STATIC_CAST(void*, this));
+
+ return newrefcount;
+ }
+
+nsresult
+IFoo::QueryInterface( const nsIID& aIID, void** aResult )
+ {
+ printf("IFoo@%p::QueryInterface()\n", NS_STATIC_CAST(void*, this));
+ nsISupports* rawPtr = 0;
+ nsresult status = NS_OK;
+
+ if ( aIID.Equals(GetIID()) )
+ rawPtr = this;
+ else
+ {
+ nsID iid_of_ISupports = NS_ISUPPORTS_IID;
+ if ( aIID.Equals(iid_of_ISupports) )
+ rawPtr = NS_STATIC_CAST(nsISupports*, this);
+ else
+ status = NS_ERROR_NO_INTERFACE;
+ }
+
+ NS_IF_ADDREF(rawPtr);
+ *aResult = rawPtr;
+
+ return status;
+ }
+
+nsresult
+IFoo::SetString(const nsACString& aString)
+{
+ mString = aString;
+ return NS_OK;
+}
+
+nsresult
+IFoo::GetString(nsACString& aString)
+{
+ aString = mString;
+ return NS_OK;
+}
+
+nsresult
+CreateIFoo( IFoo** result )
+ // a typical factory function (that calls AddRef)
+ {
+ printf(" >>CreateIFoo() --> ");
+ IFoo* foop = new IFoo();
+ printf("IFoo@%p\n", NS_STATIC_CAST(void*, foop));
+
+ foop->AddRef();
+ *result = foop;
+
+ printf("<<CreateIFoo()\n");
+ return 0;
+ }
+
+PLDHashOperator
+nsIEnumRead(const PRUint32& aKey, IFoo* aFoo, void* userArg) {
+ nsCAutoString str;
+ aFoo->GetString(str);
+
+ printf(" enumerated %u = \"%s\"\n", aKey, str.get());
+ return PL_DHASH_NEXT;
+}
+
+PLDHashOperator
+nsIEnum(const PRUint32& aKey, nsCOMPtr<IFoo>& aData, void* userArg) {
+ nsCAutoString str;
+ aData->GetString(str);
+
+ printf(" enumerated %u = \"%s\"\n", aKey, str.get());
+ return PL_DHASH_NEXT;
+}
+
+PLDHashOperator
+nsIEnum2Read(nsISupports* aKey, PRUint32 aData, void* userArg) {
+ nsCAutoString str;
+ nsCOMPtr<IFoo> foo = do_QueryInterface(aKey);
+ foo->GetString(str);
+
+
+ printf(" enumerated \"%s\" = %u\n", str.get(), aData);
+ return PL_DHASH_NEXT;
+}
+
+PLDHashOperator
+nsIEnum2(nsISupports* aKey, PRUint32& aData, void* userArg) {
+ nsCAutoString str;
+ nsCOMPtr<IFoo> foo = do_QueryInterface(aKey);
+ foo->GetString(str);
+
+ printf(" enumerated \"%s\" = %u\n", str.get(), aData);
+ return PL_DHASH_NEXT;
+}
+
+int
+main(void) {
+ // check an nsTHashtable
+ nsTHashtable<EntityToUnicodeEntry> EntityToUnicode;
+
+ printf("Initializing nsTHashtable...");
+ if (!EntityToUnicode.Init(ENTITY_COUNT)) {
+ printf("FAILED\n");
+ exit (1);
+ }
+ printf("OK\n");
+
+ printf("Partially filling nsTHashtable:\n");
+ testTHashtable(EntityToUnicode, 5);
+
+ printf("Enumerate-removing...\n");
+ PRUint32 count = EntityToUnicode.EnumerateEntries(nsTEnumStop, nsnull);
+ if (count != 5) {
+ printf("wrong count\n");
+ exit (7);
+ }
+ printf("OK\n");
+
+ printf("Check enumeration...");
+ count = EntityToUnicode.EnumerateEntries(nsTEnumGo, nsnull);
+ if (count) {
+ printf("entries remain in table!\n");
+ exit (8);
+ }
+ printf("OK\n");
+
+ printf("Filling nsTHashtable:\n");
+ testTHashtable(EntityToUnicode, ENTITY_COUNT);
+
+ printf("Clearing...");
+ EntityToUnicode.Clear();
+ printf("OK\n");
+
+ printf("Check enumeration...");
+ count = EntityToUnicode.EnumerateEntries(nsTEnumGo, nsnull);
+ if (count) {
+ printf("entries remain in table!\n");
+ exit (9);
+ }
+ printf("OK\n");
+
+ //
+ // now check a data-hashtable
+ //
+
+ nsDataHashtable<nsUint32HashKey,const char*> UniToEntity;
+
+ printf("Initializing nsDataHashtable...");
+ if (!UniToEntity.Init(ENTITY_COUNT)) {
+ printf("FAILED\n");
+ exit (10);
+ }
+ printf("OK\n");
+
+ printf("Filling hash with %zd entries.\n", ENTITY_COUNT);
+
+ PRUint32 i;
+ for (i = 0; i < ENTITY_COUNT; ++i) {
+ printf(" Putting entry %u...", gEntities[i].mUnicode);
+ if (!UniToEntity.Put(gEntities[i].mUnicode, gEntities[i].mStr)) {
+ printf("FAILED\n");
+ exit (11);
+ }
+ printf("OK...\n");
+ }
+
+ printf("Testing Get:\n");
+ const char* str;
+
+ for (i = 0; i < ENTITY_COUNT; ++i) {
+ printf(" Getting entry %u...", gEntities[i].mUnicode);
+ if (!UniToEntity.Get(gEntities[i].mUnicode, &str)) {
+ printf("FAILED\n");
+ exit (12);
+ }
+
+ printf("Found %s\n", str);
+ }
+
+ printf("Testing non-existent entries...");
+ if (UniToEntity.Get(99446, &str)) {
+ printf("FOUND! BAD!\n");
+ exit (13);
+ }
+
+ printf("not found; good.\n");
+
+ printf("Enumerating:\n");
+
+ count = UniToEntity.EnumerateRead(nsDEnumRead, nsnull);
+ if (count != ENTITY_COUNT) {
+ printf(" Bad count!\n");
+ exit (14);
+ }
+
+ printf("Clearing...");
+ UniToEntity.Clear();
+ printf("OK\n");
+
+ printf("Checking count...");
+ count = UniToEntity.Enumerate(nsDEnum, nsnull);
+ if (count) {
+ printf(" Clear did not remove all entries.\n");
+ exit (15);
+ }
+
+ printf("OK\n");
+
+ //
+ // now check a thread-safe data-hashtable
+ //
+
+ nsDataHashtableMT<nsUint32HashKey,const char*> UniToEntityL;
+
+ printf("Initializing nsDataHashtableMT...");
+ if (!UniToEntityL.Init(ENTITY_COUNT)) {
+ printf("FAILED\n");
+ exit (10);
+ }
+ printf("OK\n");
+
+ printf("Filling hash with %zd entries.\n", ENTITY_COUNT);
+
+ for (i = 0; i < ENTITY_COUNT; ++i) {
+ printf(" Putting entry %u...", gEntities[i].mUnicode);
+ if (!UniToEntityL.Put(gEntities[i].mUnicode, gEntities[i].mStr)) {
+ printf("FAILED\n");
+ exit (11);
+ }
+ printf("OK...\n");
+ }
+
+ printf("Testing Get:\n");
+
+ for (i = 0; i < ENTITY_COUNT; ++i) {
+ printf(" Getting entry %u...", gEntities[i].mUnicode);
+ if (!UniToEntityL.Get(gEntities[i].mUnicode, &str)) {
+ printf("FAILED\n");
+ exit (12);
+ }
+
+ printf("Found %s\n", str);
+ }
+
+ printf("Testing non-existent entries...");
+ if (UniToEntityL.Get(99446, &str)) {
+ printf("FOUND! BAD!\n");
+ exit (13);
+ }
+
+ printf("not found; good.\n");
+
+ printf("Enumerating:\n");
+
+ count = UniToEntityL.EnumerateRead(nsDEnumRead, nsnull);
+ if (count != ENTITY_COUNT) {
+ printf(" Bad count!\n");
+ exit (14);
+ }
+
+ printf("Clearing...");
+ UniToEntityL.Clear();
+ printf("OK\n");
+
+ printf("Checking count...");
+ count = UniToEntityL.Enumerate(nsDEnum, nsnull);
+ if (count) {
+ printf(" Clear did not remove all entries.\n");
+ exit (15);
+ }
+
+ printf("OK\n");
+
+ //
+ // now check a class-hashtable
+ //
+
+ nsClassHashtable<nsCStringHashKey,TestUniChar> EntToUniClass;
+
+ printf("Initializing nsClassHashtable...");
+ if (!EntToUniClass.Init(ENTITY_COUNT)) {
+ printf("FAILED\n");
+ exit (16);
+ }
+ printf("OK\n");
+
+ printf("Filling hash with %zd entries.\n", ENTITY_COUNT);
+
+ for (i = 0; i < ENTITY_COUNT; ++i) {
+ printf(" Putting entry %u...", gEntities[i].mUnicode);
+ TestUniChar* temp = new TestUniChar(gEntities[i].mUnicode);
+
+ if (!EntToUniClass.Put(nsDependentCString(gEntities[i].mStr), temp)) {
+ printf("FAILED\n");
+ delete temp;
+ exit (17);
+ }
+ printf("OK...\n");
+ }
+
+ printf("Testing Get:\n");
+ TestUniChar* myChar;
+
+ for (i = 0; i < ENTITY_COUNT; ++i) {
+ printf(" Getting entry %s...", gEntities[i].mStr);
+ if (!EntToUniClass.Get(nsDependentCString(gEntities[i].mStr), &myChar)) {
+ printf("FAILED\n");
+ exit (18);
+ }
+
+ printf("Found %c\n", myChar->GetChar());
+ }
+
+ printf("Testing non-existent entries...");
+ if (EntToUniClass.Get(NS_LITERAL_CSTRING("xxxx"), &myChar)) {
+ printf("FOUND! BAD!\n");
+ exit (19);
+ }
+
+ printf("not found; good.\n");
+
+ printf("Enumerating:\n");
+
+ count = EntToUniClass.EnumerateRead(nsCEnumRead, nsnull);
+ if (count != ENTITY_COUNT) {
+ printf(" Bad count!\n");
+ exit (20);
+ }
+
+ printf("Clearing...\n");
+ EntToUniClass.Clear();
+ printf(" Clearing OK\n");
+
+ printf("Checking count...");
+ count = EntToUniClass.Enumerate(nsCEnum, nsnull);
+ if (count) {
+ printf(" Clear did not remove all entries.\n");
+ exit (21);
+ }
+
+ printf("OK\n");
+
+ //
+ // now check a thread-safe class-hashtable
+ //
+
+ nsClassHashtableMT<nsCStringHashKey,TestUniChar> EntToUniClassL;
+
+ printf("Initializing nsClassHashtableMT...");
+ if (!EntToUniClassL.Init(ENTITY_COUNT)) {
+ printf("FAILED\n");
+ exit (16);
+ }
+ printf("OK\n");
+
+ printf("Filling hash with %zd entries.\n", ENTITY_COUNT);
+
+ for (i = 0; i < ENTITY_COUNT; ++i) {
+ printf(" Putting entry %u...", gEntities[i].mUnicode);
+ TestUniChar* temp = new TestUniChar(gEntities[i].mUnicode);
+
+ if (!EntToUniClassL.Put(nsDependentCString(gEntities[i].mStr), temp)) {
+ printf("FAILED\n");
+ delete temp;
+ exit (17);
+ }
+ printf("OK...\n");
+ }
+
+ printf("Testing Get:\n");
+
+ for (i = 0; i < ENTITY_COUNT; ++i) {
+ printf(" Getting entry %s...", gEntities[i].mStr);
+ if (!EntToUniClassL.Get(nsDependentCString(gEntities[i].mStr), &myChar)) {
+ printf("FAILED\n");
+ exit (18);
+ }
+
+ printf("Found %c\n", myChar->GetChar());
+ }
+
+ printf("Testing non-existent entries...");
+ if (EntToUniClassL.Get(NS_LITERAL_CSTRING("xxxx"), &myChar)) {
+ printf("FOUND! BAD!\n");
+ exit (19);
+ }
+
+ printf("not found; good.\n");
+
+ printf("Enumerating:\n");
+
+ count = EntToUniClassL.EnumerateRead(nsCEnumRead, nsnull);
+ if (count != ENTITY_COUNT) {
+ printf(" Bad count!\n");
+ exit (20);
+ }
+
+ printf("Clearing...\n");
+ EntToUniClassL.Clear();
+ printf(" Clearing OK\n");
+
+ printf("Checking count...");
+ count = EntToUniClassL.Enumerate(nsCEnum, nsnull);
+ if (count) {
+ printf(" Clear did not remove all entries.\n");
+ exit (21);
+ }
+
+ printf("OK\n");
+
+ //
+ // now check a data-hashtable with an interface key
+ //
+
+ nsDataHashtable<nsISupportsHashKey,PRUint32> EntToUniClass2;
+
+ printf("Initializing nsDataHashtable with interface key...");
+ if (!EntToUniClass2.Init(ENTITY_COUNT)) {
+ printf("FAILED\n");
+ exit (22);
+ }
+ printf("OK\n");
+
+ printf("Filling hash with %zd entries.\n", ENTITY_COUNT);
+
+ nsCOMArray<IFoo> fooArray;
+
+ for (i = 0; i < ENTITY_COUNT; ++i) {
+ printf(" Putting entry %u...", gEntities[i].mUnicode);
+ nsCOMPtr<IFoo> foo;
+ CreateIFoo(getter_AddRefs(foo));
+ foo->SetString(nsDependentCString(gEntities[i].mStr));
+
+
+ fooArray.InsertObjectAt(foo, i);
+
+ if (!EntToUniClass2.Put(foo, gEntities[i].mUnicode)) {
+ printf("FAILED\n");
+ exit (23);
+ }
+ printf("OK...\n");
+ }
+
+ printf("Testing Get:\n");
+ PRUint32 myChar2;
+
+ for (i = 0; i < ENTITY_COUNT; ++i) {
+ printf(" Getting entry %s...", gEntities[i].mStr);
+
+ if (!EntToUniClass2.Get(fooArray[i], &myChar2)) {
+ printf("FAILED\n");
+ exit (24);
+ }
+
+ printf("Found %c\n", myChar2);
+ }
+
+ printf("Testing non-existent entries...");
+ if (EntToUniClass2.Get((nsISupports*) 0x55443316, &myChar2)) {
+ printf("FOUND! BAD!\n");
+ exit (25);
+ }
+
+ printf("not found; good.\n");
+
+ printf("Enumerating:\n");
+
+ count = EntToUniClass2.EnumerateRead(nsIEnum2Read, nsnull);
+ if (count != ENTITY_COUNT) {
+ printf(" Bad count!\n");
+ exit (26);
+ }
+
+ printf("Clearing...\n");
+ EntToUniClass2.Clear();
+ printf(" Clearing OK\n");
+
+ printf("Checking count...");
+ count = EntToUniClass2.Enumerate(nsIEnum2, nsnull);
+ if (count) {
+ printf(" Clear did not remove all entries.\n");
+ exit (27);
+ }
+
+ printf("OK\n");
+
+ //
+ // now check an interface-hashtable with an PRUint32 key
+ //
+
+ nsInterfaceHashtable<nsUint32HashKey,IFoo> UniToEntClass2;
+
+ printf("Initializing nsInterfaceHashtable...");
+ if (!UniToEntClass2.Init(ENTITY_COUNT)) {
+ printf("FAILED\n");
+ exit (28);
+ }
+ printf("OK\n");
+
+ printf("Filling hash with %zd entries.\n", ENTITY_COUNT);
+
+ for (i = 0; i < ENTITY_COUNT; ++i) {
+ printf(" Putting entry %u...", gEntities[i].mUnicode);
+ nsCOMPtr<IFoo> foo;
+ CreateIFoo(getter_AddRefs(foo));
+ foo->SetString(nsDependentCString(gEntities[i].mStr));
+
+ if (!UniToEntClass2.Put(gEntities[i].mUnicode, foo)) {
+ printf("FAILED\n");
+ exit (29);
+ }
+ printf("OK...\n");
+ }
+
+ printf("Testing Get:\n");
+
+ for (i = 0; i < ENTITY_COUNT; ++i) {
+ printf(" Getting entry %s...", gEntities[i].mStr);
+
+ nsCOMPtr<IFoo> myEnt;
+ if (!UniToEntClass2.Get(gEntities[i].mUnicode, getter_AddRefs(myEnt))) {
+ printf("FAILED\n");
+ exit (30);
+ }
+
+ nsCAutoString str;
+ myEnt->GetString(str);
+ printf("Found %s\n", str.get());
+ }
+
+ printf("Testing non-existent entries...");
+ nsCOMPtr<IFoo> myEnt;
+ if (UniToEntClass2.Get(9462, getter_AddRefs(myEnt))) {
+ printf("FOUND! BAD!\n");
+ exit (31);
+ }
+
+ printf("not found; good.\n");
+
+ printf("Enumerating:\n");
+
+ count = UniToEntClass2.EnumerateRead(nsIEnumRead, nsnull);
+ if (count != ENTITY_COUNT) {
+ printf(" Bad count!\n");
+ exit (32);
+ }
+
+ printf("Clearing...\n");
+ UniToEntClass2.Clear();
+ printf(" Clearing OK\n");
+
+ printf("Checking count...");
+ count = UniToEntClass2.Enumerate(nsIEnum, nsnull);
+ if (count) {
+ printf(" Clear did not remove all entries.\n");
+ exit (33);
+ }
+
+ printf("OK\n");
+
+ //
+ // now check a thread-safe interface hashtable
+ //
+
+ nsInterfaceHashtableMT<nsUint32HashKey,IFoo> UniToEntClass2L;
+
+ printf("Initializing nsInterfaceHashtableMT...");
+ if (!UniToEntClass2L.Init(ENTITY_COUNT)) {
+ printf("FAILED\n");
+ exit (28);
+ }
+ printf("OK\n");
+
+ printf("Filling hash with %zd entries.\n", ENTITY_COUNT);
+
+ for (i = 0; i < ENTITY_COUNT; ++i) {
+ printf(" Putting entry %u...", gEntities[i].mUnicode);
+ nsCOMPtr<IFoo> foo;
+ CreateIFoo(getter_AddRefs(foo));
+ foo->SetString(nsDependentCString(gEntities[i].mStr));
+
+ if (!UniToEntClass2L.Put(gEntities[i].mUnicode, foo)) {
+ printf("FAILED\n");
+ exit (29);
+ }
+ printf("OK...\n");
+ }
+
+ printf("Testing Get:\n");
+
+ for (i = 0; i < ENTITY_COUNT; ++i) {
+ printf(" Getting entry %s...", gEntities[i].mStr);
+
+ nsCOMPtr<IFoo> myEnt;
+ if (!UniToEntClass2L.Get(gEntities[i].mUnicode, getter_AddRefs(myEnt))) {
+ printf("FAILED\n");
+ exit (30);
+ }
+
+ nsCAutoString str;
+ myEnt->GetString(str);
+ printf("Found %s\n", str.get());
+ }
+
+ printf("Testing non-existent entries...");
+ if (UniToEntClass2L.Get(9462, getter_AddRefs(myEnt))) {
+ printf("FOUND! BAD!\n");
+ exit (31);
+ }
+
+ printf("not found; good.\n");
+
+ printf("Enumerating:\n");
+
+ count = UniToEntClass2L.EnumerateRead(nsIEnumRead, nsnull);
+ if (count != ENTITY_COUNT) {
+ printf(" Bad count!\n");
+ exit (32);
+ }
+
+ printf("Clearing...\n");
+ UniToEntClass2L.Clear();
+ printf(" Clearing OK\n");
+
+ printf("Checking count...");
+ count = UniToEntClass2L.Enumerate(nsIEnum, nsnull);
+ if (count) {
+ printf(" Clear did not remove all entries.\n");
+ exit (33);
+ }
+
+ printf("OK\n");
+
+ return 0;
+}
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestID.cpp b/src/libs/xpcom18a4/xpcom/tests/TestID.cpp
new file mode 100644
index 00000000..f91fda9f
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/TestID.cpp
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 <stdio.h>
+#include "plstr.h"
+#include "nsID.h"
+#include "prmem.h"
+
+static const char* const ids[] = {
+ "5C347B10-D55C-11D1-89B7-006008911B81",
+ "{5C347B10-D55C-11D1-89B7-006008911B81}",
+ "5c347b10-d55c-11d1-89b7-006008911b81",
+ "{5c347b10-d55c-11d1-89b7-006008911b81}",
+
+ "FC347B10-D55C-F1D1-F9B7-006008911B81",
+ "{FC347B10-D55C-F1D1-F9B7-006008911B81}",
+ "fc347b10-d55c-f1d1-f9b7-006008911b81",
+ "{fc347b10-d55c-f1d1-f9b7-006008911b81}",
+};
+#define NUM_IDS ((int) (sizeof(ids) / sizeof(ids[0])))
+
+int main(int argc, char** argv)
+{
+ nsID id;
+ for (int i = 0; i < NUM_IDS; i++) {
+ const char* idstr = ids[i];
+ if (!id.Parse(idstr)) {
+ fprintf(stderr, "TestID: Parse failed on test #%d\n", i);
+ return -1;
+ }
+ char* cp = id.ToString();
+ if (NULL == cp) {
+ fprintf(stderr, "TestID: ToString failed on test #%d\n", i);
+ return -1;
+ }
+ if (0 != PL_strcmp(cp, ids[4*(i/4) + 3])) {
+ fprintf(stderr, "TestID: compare of ToString failed on test #%d\n", i);
+ return -1;
+ }
+ PR_Free(cp);
+ }
+
+ return 0;
+}
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestMinStringAPI.cpp b/src/libs/xpcom18a4/xpcom/tests/TestMinStringAPI.cpp
new file mode 100644
index 00000000..811df138
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/TestMinStringAPI.cpp
@@ -0,0 +1,333 @@
+/* vim:set ts=2 sw=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <stdio.h>
+#include "nsStringAPI.h"
+#include "nsCRT.h"
+
+static const char kAsciiData[] = "hello world";
+
+static const PRUnichar kUnicodeData[] =
+ {'h','e','l','l','o',' ','w','o','r','l','d','\0'};
+
+static PRBool test_basic_1()
+ {
+ nsCStringContainer s;
+ NS_CStringContainerInit(s);
+
+ const char *ptr;
+ PRUint32 len;
+ char *clone;
+
+ NS_CStringGetData(s, &ptr);
+ if (ptr == nsnull || *ptr != '\0')
+ {
+ NS_ERROR("unexpected result");
+ return PR_FALSE;
+ }
+
+ NS_CStringSetData(s, kAsciiData, PR_UINT32_MAX);
+ len = NS_CStringGetData(s, &ptr);
+ if (ptr == nsnull || strcmp(ptr, kAsciiData) != 0)
+ {
+ NS_ERROR("unexpected result");
+ return PR_FALSE;
+ }
+ if (len != sizeof(kAsciiData)-1)
+ {
+ NS_ERROR("unexpected result");
+ return PR_FALSE;
+ }
+
+ clone = NS_CStringCloneData(s);
+ if (ptr == nsnull || strcmp(ptr, kAsciiData) != 0)
+ {
+ NS_ERROR("unexpected result");
+ return PR_FALSE;
+ }
+ nsMemory::Free(clone);
+
+ nsCStringContainer temp;
+ NS_CStringContainerInit(temp);
+ NS_CStringCopy(temp, s);
+
+ len = NS_CStringGetData(temp, &ptr);
+ if (ptr == nsnull || strcmp(ptr, kAsciiData) != 0)
+ {
+ NS_ERROR("unexpected result");
+ return PR_FALSE;
+ }
+ if (len != sizeof(kAsciiData)-1)
+ {
+ NS_ERROR("unexpected result");
+ return PR_FALSE;
+ }
+
+ NS_CStringContainerFinish(temp);
+
+ NS_CStringContainerFinish(s);
+ return PR_TRUE;
+ }
+
+static PRBool test_basic_2()
+ {
+ nsStringContainer s;
+ NS_StringContainerInit(s);
+
+ const PRUnichar *ptr;
+ PRUint32 len;
+ PRUnichar *clone;
+
+ NS_StringGetData(s, &ptr);
+ if (ptr == nsnull || *ptr != '\0')
+ {
+ NS_ERROR("unexpected result");
+ return PR_FALSE;
+ }
+
+ NS_StringSetData(s, kUnicodeData, PR_UINT32_MAX);
+ len = NS_StringGetData(s, &ptr);
+ if (ptr == nsnull || nsCRT::strcmp(ptr, kUnicodeData) != 0)
+ {
+ NS_ERROR("unexpected result");
+ return PR_FALSE;
+ }
+ if (len != sizeof(kUnicodeData)/2 - 1)
+ {
+ NS_ERROR("unexpected result");
+ return PR_FALSE;
+ }
+
+ clone = NS_StringCloneData(s);
+ if (ptr == nsnull || nsCRT::strcmp(ptr, kUnicodeData) != 0)
+ {
+ NS_ERROR("unexpected result");
+ return PR_FALSE;
+ }
+ nsMemory::Free(clone);
+
+ nsStringContainer temp;
+ NS_StringContainerInit(temp);
+ NS_StringCopy(temp, s);
+
+ len = NS_StringGetData(temp, &ptr);
+ if (ptr == nsnull || nsCRT::strcmp(ptr, kUnicodeData) != 0)
+ {
+ NS_ERROR("unexpected result");
+ return PR_FALSE;
+ }
+ if (len != sizeof(kUnicodeData)/2 - 1)
+ {
+ NS_ERROR("unexpected result");
+ return PR_FALSE;
+ }
+
+ NS_StringContainerFinish(temp);
+
+ NS_StringContainerFinish(s);
+
+ return PR_TRUE;
+ }
+
+static PRBool test_convert()
+ {
+ nsStringContainer s;
+ NS_StringContainerInit(s);
+ NS_StringSetData(s, kUnicodeData, sizeof(kUnicodeData)/2 - 1);
+
+ nsCStringContainer temp;
+ NS_CStringContainerInit(temp);
+
+ const char *data;
+
+ NS_UTF16ToCString(s, NS_CSTRING_ENCODING_ASCII, temp);
+ NS_CStringGetData(temp, &data);
+ if (strcmp(data, kAsciiData) != 0)
+ return PR_FALSE;
+
+ NS_UTF16ToCString(s, NS_CSTRING_ENCODING_UTF8, temp);
+ NS_CStringGetData(temp, &data);
+ if (strcmp(data, kAsciiData) != 0)
+ return PR_FALSE;
+
+ NS_CStringContainerFinish(temp);
+
+ NS_StringContainerFinish(s);
+ return PR_TRUE;
+ }
+
+static PRBool test_append()
+ {
+ nsCStringContainer s;
+ NS_CStringContainerInit(s);
+
+ NS_CStringSetData(s, "foo");
+ NS_CStringAppendData(s, "bar");
+
+ NS_CStringContainerFinish(s);
+ return PR_TRUE;
+ }
+
+// Replace all occurances of |matchVal| with |newVal|
+static void ReplaceSubstring( nsACString& str,
+ const nsACString& matchVal,
+ const nsACString& newVal )
+ {
+ const char* sp, *mp, *np;
+ PRUint32 sl, ml, nl;
+
+ sl = NS_CStringGetData(str, &sp);
+ ml = NS_CStringGetData(matchVal, &mp);
+ nl = NS_CStringGetData(newVal, &np);
+
+ for (const char* iter = sp; iter <= sp + sl - ml; ++iter)
+ {
+ if (memcmp(iter, mp, ml) == 0)
+ {
+ PRUint32 offset = iter - sp;
+
+ NS_CStringSetDataRange(str, offset, ml, np, nl);
+
+ sl = NS_CStringGetData(str, &sp);
+
+ iter = sp + offset + nl - 1;
+ }
+ }
+ }
+
+static PRBool test_replace_driver(const char *strVal,
+ const char *matchVal,
+ const char *newVal,
+ const char *finalVal)
+ {
+ nsCStringContainer a;
+ NS_CStringContainerInit(a);
+ NS_CStringSetData(a, strVal);
+
+ nsCStringContainer b;
+ NS_CStringContainerInit(b);
+ NS_CStringSetData(b, matchVal);
+
+ nsCStringContainer c;
+ NS_CStringContainerInit(c);
+ NS_CStringSetData(c, newVal);
+
+ ReplaceSubstring(a, b, c);
+
+ const char *data;
+ NS_CStringGetData(a, &data);
+ if (strcmp(data, finalVal) != 0)
+ return PR_FALSE;
+
+ NS_CStringContainerFinish(c);
+ NS_CStringContainerFinish(b);
+ NS_CStringContainerFinish(a);
+ return PR_TRUE;
+ }
+
+static PRBool test_replace()
+ {
+ PRBool rv;
+
+ rv = test_replace_driver("hello world, hello again!",
+ "hello",
+ "goodbye",
+ "goodbye world, goodbye again!");
+ if (!rv)
+ return rv;
+
+ rv = test_replace_driver("foofoofoofoo!",
+ "foo",
+ "bar",
+ "barbarbarbar!");
+ if (!rv)
+ return rv;
+
+ rv = test_replace_driver("foo bar systems",
+ "xyz",
+ "crazy",
+ "foo bar systems");
+ if (!rv)
+ return rv;
+
+ rv = test_replace_driver("oh",
+ "xyz",
+ "crazy",
+ "oh");
+ if (!rv)
+ return rv;
+
+ return PR_TRUE;
+ }
+
+//----
+
+typedef PRBool (*TestFunc)();
+
+static const struct Test
+ {
+ const char* name;
+ TestFunc func;
+ }
+tests[] =
+ {
+ { "test_basic_1", test_basic_1 },
+ { "test_basic_2", test_basic_2 },
+ { "test_convert", test_convert },
+ { "test_append", test_append },
+ { "test_replace", test_replace },
+ { nsnull, nsnull }
+ };
+
+//----
+
+int main(int argc, char **argv)
+ {
+ int count = 1;
+ if (argc > 1)
+ count = atoi(argv[1]);
+
+ while (count--)
+ {
+ for (const Test* t = tests; t->name != nsnull; ++t)
+ {
+ printf("%25s : %s\n", t->name, t->func() ? "SUCCESS" : "FAILURE");
+ }
+ }
+
+ return 0;
+ }
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestObserverService.cpp b/src/libs/xpcom18a4/xpcom/tests/TestObserverService.cpp
new file mode 100644
index 00000000..148400e2
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/TestObserverService.cpp
@@ -0,0 +1,250 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Pierre Phaneuf <pp@ludusdesign.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsISupports.h"
+#include "nsIComponentManager.h"
+#include "nsIObserverService.h"
+#include "nsIObserver.h"
+#include "nsIEnumerator.h"
+#include "nsString.h"
+#include "nsReadableUtils.h"
+#include "prprf.h"
+#include "nsWeakReference.h"
+
+static nsIObserverService *anObserverService = NULL;
+
+#ifdef VBOX
+static bool testResult( nsresult rv ) {
+ if ( NS_SUCCEEDED( rv ) ) {
+ printf("...ok\n");
+ return true;
+ }
+ printf("...failed, rv=0x%x\n", (int)rv);
+ return false;
+}
+#else
+static void testResult( nsresult rv ) {
+ if ( NS_SUCCEEDED( rv ) ) {
+ printf("...ok\n");
+ } else {
+ printf("...failed, rv=0x%x\n", (int)rv);
+ }
+ return;
+}
+#endif
+
+void printString(nsString &str) {
+#ifdef VBOX /* asan complains about mixing different allocators */
+ char *cstr = ToNewCString(str);
+ printf("%s", cstr);
+ nsMemory::Free(cstr);
+#else
+ const char *cstr = ToNewCString(str);
+ printf("%s", cstr);
+ delete [] (char*)cstr;
+#endif
+}
+
+class TestObserver : public nsIObserver, public nsSupportsWeakReference {
+public:
+ TestObserver( const nsAString &name )
+ : mName( name ) {
+ }
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIOBSERVER
+
+ nsString mName;
+
+private:
+ ~TestObserver() {}
+};
+
+NS_IMPL_ISUPPORTS2( TestObserver, nsIObserver, nsISupportsWeakReference )
+
+NS_IMETHODIMP
+TestObserver::Observe( nsISupports *aSubject,
+ const char *aTopic,
+ const PRUnichar *someData ) {
+ nsCString topic( aTopic );
+ nsString data( someData );
+ /*
+ The annoying double-cast below is to work around an annoying bug in
+ the compiler currently used on wensleydale. This is a test.
+ */
+ printString(mName);
+ printf(" has observed something: subject@%p", (void*)aSubject);
+ printf(" name=");
+ printString(NS_REINTERPRET_CAST(TestObserver*, NS_REINTERPRET_CAST(void*, aSubject))->mName);
+ printf(" aTopic=%s", topic.get());
+ printf(" someData=");
+ printString(data);
+ printf("\n");
+ return NS_OK;
+}
+
+int main(int argc, char *argv[])
+{
+ nsCString topicA; topicA.Assign( "topic-A" );
+ nsCString topicB; topicB.Assign( "topic-B" );
+ nsresult rv;
+
+ nsresult res = nsComponentManager::CreateInstance("@mozilla.org/observer-service;1",
+ NULL,
+ NS_GET_IID(nsIObserverService),
+ (void **) &anObserverService);
+#ifdef VBOX
+ bool fSuccess = res == NS_OK;
+#endif
+
+ if (res == NS_OK) {
+
+ nsIObserver *aObserver = new TestObserver(NS_LITERAL_STRING("Observer-A"));
+ aObserver->AddRef();
+ nsIObserver *bObserver = new TestObserver(NS_LITERAL_STRING("Observer-B"));
+ bObserver->AddRef();
+
+ printf("Adding Observer-A as observer of topic-A...\n");
+ rv = anObserverService->AddObserver(aObserver, topicA.get(), PR_FALSE);
+#ifdef VBOX
+ fSuccess = fSuccess &&
+#endif
+ testResult(rv);
+
+ printf("Adding Observer-B as observer of topic-A...\n");
+ rv = anObserverService->AddObserver(bObserver, topicA.get(), PR_FALSE);
+#ifdef VBOX
+ fSuccess = fSuccess &&
+#endif
+ testResult(rv);
+
+ printf("Adding Observer-B as observer of topic-B...\n");
+ rv = anObserverService->AddObserver(bObserver, topicB.get(), PR_FALSE);
+#ifdef VBOX
+ fSuccess = fSuccess &&
+#endif
+ testResult(rv);
+
+ printf("Testing Notify(observer-A, topic-A)...\n");
+ rv = anObserverService->NotifyObservers( aObserver,
+ topicA.get(),
+ NS_LITERAL_STRING("Testing Notify(observer-A, topic-A)").get() );
+#ifdef VBOX
+ fSuccess = fSuccess &&
+#endif
+ testResult(rv);
+
+ printf("Testing Notify(observer-B, topic-B)...\n");
+ rv = anObserverService->NotifyObservers( bObserver,
+ topicB.get(),
+ NS_LITERAL_STRING("Testing Notify(observer-B, topic-B)").get() );
+#ifdef VBOX
+ fSuccess = fSuccess &&
+#endif
+ testResult(rv);
+
+ printf("Testing EnumerateObserverList (for topic-A)...\n");
+ nsCOMPtr<nsISimpleEnumerator> e;
+ rv = anObserverService->EnumerateObservers(topicA.get(), getter_AddRefs(e));
+
+#ifdef VBOX
+ fSuccess = fSuccess &&
+#endif
+ testResult(rv);
+
+ printf("Enumerating observers of topic-A...\n");
+ if ( e ) {
+ nsCOMPtr<nsIObserver> observer;
+ PRBool loop = PR_TRUE;
+ while( NS_SUCCEEDED(e->HasMoreElements(&loop)) && loop)
+ {
+ e->GetNext(getter_AddRefs(observer));
+ printf("Calling observe on enumerated observer ");
+ printString(NS_REINTERPRET_CAST(TestObserver*,
+ NS_REINTERPRET_CAST(void*, observer.get()))->mName);
+ printf("...\n");
+ rv = observer->Observe( observer,
+ topicA.get(),
+ NS_LITERAL_STRING("during enumeration").get() );
+#ifdef VBOX
+ fSuccess = fSuccess &&
+#endif
+ testResult(rv);
+ }
+ }
+ printf("...done enumerating observers of topic-A\n");
+
+ printf("Removing Observer-A...\n");
+ rv = anObserverService->RemoveObserver(aObserver, topicA.get());
+#ifdef VBOX
+ fSuccess = fSuccess &&
+#endif
+ testResult(rv);
+
+
+ printf("Removing Observer-B (topic-A)...\n");
+ rv = anObserverService->RemoveObserver(bObserver, topicB.get());
+#ifdef VBOX
+ fSuccess = fSuccess &&
+#endif
+ testResult(rv);
+ printf("Removing Observer-B (topic-B)...\n");
+ rv = anObserverService->RemoveObserver(bObserver, topicA.get());
+#ifdef VBOX
+ fSuccess = fSuccess &&
+#endif
+ testResult(rv);
+
+#ifdef VBOX
+ /* Cleanup: */
+ nsrefcnt refs = bObserver->Release();
+ fSuccess = fSuccess && refs == 0;
+ if (refs != 0)
+ printf("bObserver->Release() -> %d, expected 0\n", (int)refs);
+
+ refs = aObserver->Release();
+ fSuccess = fSuccess && refs == 0;
+ if (refs != 0)
+ printf("aObserver->Release() -> %d, expected 0\n", (int)refs);
+#endif
+ }
+#ifdef VBOX
+ return fSuccess ? 0 : 1;
+#else
+ return NS_OK;
+#endif
+}
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestPermanentAtoms.cpp b/src/libs/xpcom18a4/xpcom/tests/TestPermanentAtoms.cpp
new file mode 100644
index 00000000..09b0b2e9
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/TestPermanentAtoms.cpp
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+// vim:cindent:ts=8:et:sw=4:
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is TestPermanentAtoms.cpp.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2001
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * L. David Baron <dbaron@dbaron.org> (original author)
+ *
+ * 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 "nsIAtom.h"
+#include "nsAtomTable.h"
+#include "nsCOMPtr.h"
+#include <stdio.h>
+#include "nsString.h"
+#include "nsReadableUtils.h"
+
+static void Assert(PRBool aCondition, const char* aStatement)
+{
+ printf("%s: %s\n", aCondition?"PASS":"FAIL", aStatement);
+}
+
+static void AssertString(nsIAtom *aAtom, const nsACString& aString)
+{
+ const char *str;
+ NS_STATIC_CAST(AtomImpl*,aAtom)->GetUTF8String(&str);
+ Assert(nsDependentCString(str) == aString, "string is correct");
+}
+
+static void AssertPermanence(nsIAtom *aAtom, PRBool aPermanence)
+{
+ Assert(NS_STATIC_CAST(AtomImpl*,aAtom)->IsPermanent() == aPermanence,
+ aPermanence ? "atom is permanent" : "atom is not permanent");
+}
+
+int main()
+{
+ nsCOMPtr<nsIAtom> foo = do_GetAtom("foo");
+ AssertString(foo, NS_LITERAL_CSTRING("foo"));
+ AssertPermanence(foo, PR_FALSE);
+
+ nsCOMPtr<nsIAtom> foop = do_GetPermanentAtom("foo");
+ AssertString(foop, NS_LITERAL_CSTRING("foo"));
+ AssertPermanence(foop, PR_TRUE);
+
+ Assert(foo == foop, "atoms are equal");
+
+ nsCOMPtr<nsIAtom> barp = do_GetPermanentAtom("bar");
+ AssertString(barp, NS_LITERAL_CSTRING("bar"));
+ AssertPermanence(barp, PR_TRUE);
+
+ nsCOMPtr<nsIAtom> bar = do_GetAtom("bar");
+ AssertString(bar, NS_LITERAL_CSTRING("bar"));
+ AssertPermanence(bar, PR_TRUE);
+
+ Assert(bar == barp, "atoms are equal");
+
+ return 0;
+}
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestPipes.cpp b/src/libs/xpcom18a4/xpcom/tests/TestPipes.cpp
new file mode 100644
index 00000000..2d798a5b
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/TestPipes.cpp
@@ -0,0 +1,655 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Pierre Phaneuf <pp@ludusdesign.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsIThread.h"
+#include "nsIRunnable.h"
+#include "nsIInputStream.h"
+#include "nsIOutputStream.h"
+#include "nsIServiceManager.h"
+#include "prprf.h"
+#include "prinrval.h"
+#include "plstr.h"
+#include "nsCRT.h"
+#include "nsCOMPtr.h"
+#include <stdio.h>
+#include "nsIPipe.h" // new implementation
+#include "nsAutoLock.h"
+#include <stdlib.h> // for rand
+
+#define KEY 0xa7
+#define ITERATIONS 33333
+char kTestPattern[] = "My hovercraft is full of eels.\n";
+
+PRBool gTrace = PR_FALSE;
+
+static nsresult
+WriteAll(nsIOutputStream *os, const char *buf, PRUint32 bufLen, PRUint32 *lenWritten)
+{
+ const char *p = buf;
+ *lenWritten = 0;
+ while (bufLen) {
+ PRUint32 n;
+ nsresult rv = os->Write(p, bufLen, &n);
+ if (NS_FAILED(rv)) return rv;
+ p += n;
+ bufLen -= n;
+ *lenWritten += n;
+ }
+ return NS_OK;
+}
+
+class nsReceiver : public nsIRunnable {
+public:
+ NS_DECL_ISUPPORTS
+
+ NS_IMETHOD Run() {
+ nsresult rv;
+ char buf[101];
+ PRUint32 count;
+ PRIntervalTime start = PR_IntervalNow();
+ while (PR_TRUE) {
+ rv = mIn->Read(buf, 100, &count);
+ if (NS_FAILED(rv)) {
+ printf("read failed\n");
+ break;
+ }
+ if (count == 0) {
+// printf("EOF count = %d\n", mCount);
+ break;
+ }
+
+ if (gTrace) {
+ printf("read: ");
+ buf[count] = '\0';
+ printf(buf);
+ printf("\n");
+ }
+ mCount += count;
+ }
+ PRIntervalTime end = PR_IntervalNow();
+ printf("read %d bytes, time = %dms\n", mCount,
+ PR_IntervalToMilliseconds(end - start));
+ return rv;
+ }
+
+ nsReceiver(nsIInputStream* in) : mIn(in), mCount(0) {
+ NS_ADDREF(in);
+ }
+
+ PRUint32 GetBytesRead() { return mCount; }
+
+private:
+ ~nsReceiver() {
+ NS_RELEASE(mIn);
+ }
+
+protected:
+ nsIInputStream* mIn;
+ PRUint32 mCount;
+};
+
+NS_IMPL_THREADSAFE_ISUPPORTS1(nsReceiver, nsIRunnable)
+
+nsresult
+TestPipe(nsIInputStream* in, nsIOutputStream* out)
+{
+ nsresult rv;
+ nsIThread* thread;
+ nsReceiver* receiver = new nsReceiver(in);
+ if (receiver == nsnull) return NS_ERROR_OUT_OF_MEMORY;
+ NS_ADDREF(receiver);
+
+ rv = NS_NewThread(&thread, receiver, 0, PR_JOINABLE_THREAD);
+ if (NS_FAILED(rv)) return rv;
+
+ PRUint32 total = 0;
+ PRIntervalTime start = PR_IntervalNow();
+ for (PRUint32 i = 0; i < ITERATIONS; i++) {
+ PRUint32 writeCount;
+ char *buf = PR_smprintf("%d %s", i, kTestPattern);
+ PRUint32 len = strlen(buf);
+ rv = WriteAll(out, buf, len, &writeCount);
+ if (gTrace) {
+ printf("wrote: ");
+ for (PRUint32 j = 0; j < writeCount; j++) {
+ putc(buf[j], stdout);
+ }
+ printf("\n");
+ }
+ PR_smprintf_free(buf);
+ if (NS_FAILED(rv)) return rv;
+ total += writeCount;
+ }
+ rv = out->Close();
+ if (NS_FAILED(rv)) return rv;
+
+ PRIntervalTime end = PR_IntervalNow();
+
+ thread->Join();
+
+ printf("wrote %d bytes, time = %dms\n", total,
+ PR_IntervalToMilliseconds(end - start));
+ NS_ASSERTION(receiver->GetBytesRead() == total, "didn't read everything");
+
+ NS_RELEASE(thread);
+ NS_RELEASE(receiver);
+
+ return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+class nsShortReader : public nsIRunnable {
+public:
+ NS_DECL_ISUPPORTS
+
+ NS_IMETHOD Run() {
+ nsresult rv;
+ char buf[101];
+ PRUint32 count;
+ PRUint32 total = 0;
+ while (PR_TRUE) {
+ //if (gTrace)
+ // printf("calling Read\n");
+ rv = mIn->Read(buf, 100, &count);
+ if (NS_FAILED(rv)) {
+ printf("read failed\n");
+ break;
+ }
+ if (count == 0) {
+ break;
+ }
+ buf[count] = '\0';
+ if (gTrace)
+ printf("read %d bytes: %s\n", count, buf);
+ Received(count);
+ total += count;
+ }
+ printf("read %d bytes\n", total);
+ return rv;
+ }
+
+ nsShortReader(nsIInputStream* in) : mIn(in), mReceived(0) {
+ NS_ADDREF(in);
+ }
+
+ void Received(PRUint32 count) {
+ nsAutoCMonitor mon(this);
+ mReceived += count;
+ mon.Notify();
+ }
+
+ PRUint32 WaitForReceipt() {
+ nsAutoCMonitor mon(this);
+ PRUint32 result = mReceived;
+ while (result == 0) {
+ mon.Wait();
+ NS_ASSERTION(mReceived >= 0, "failed to receive");
+ result = mReceived;
+ }
+ mReceived = 0;
+ return result;
+ }
+
+private:
+ ~nsShortReader() {
+ NS_RELEASE(mIn);
+ }
+
+protected:
+ nsIInputStream* mIn;
+ PRUint32 mReceived;
+};
+
+NS_IMPL_THREADSAFE_ISUPPORTS1(nsShortReader, nsIRunnable)
+
+nsresult
+TestShortWrites(nsIInputStream* in, nsIOutputStream* out)
+{
+ nsresult rv;
+ nsIThread* thread;
+ nsShortReader* receiver = new nsShortReader(in);
+ if (receiver == nsnull) return NS_ERROR_OUT_OF_MEMORY;
+ NS_ADDREF(receiver);
+
+ rv = NS_NewThread(&thread, receiver, 0, PR_JOINABLE_THREAD);
+ if (NS_FAILED(rv)) return rv;
+
+ PRUint32 total = 0;
+ for (PRUint32 i = 0; i < ITERATIONS; i++) {
+ PRUint32 writeCount;
+ char* buf = PR_smprintf("%d %s", i, kTestPattern);
+ PRUint32 len = strlen(buf);
+ len = len * rand() / RAND_MAX;
+ len = PR_MAX(1, len);
+ rv = WriteAll(out, buf, len, &writeCount);
+ if (NS_FAILED(rv)) return rv;
+ NS_ASSERTION(writeCount == len, "didn't write enough");
+ total += writeCount;
+
+ if (gTrace)
+ printf("wrote %d bytes: %s\n", writeCount, buf);
+ PR_smprintf_free(buf);
+ //printf("calling Flush\n");
+ out->Flush();
+ //printf("calling WaitForReceipt\n");
+ PRUint32 received = receiver->WaitForReceipt();
+ NS_ASSERTION(received == writeCount, "received wrong amount");
+ }
+ rv = out->Close();
+ if (NS_FAILED(rv)) return rv;
+
+ thread->Join();
+ printf("wrote %d bytes\n", total);
+
+ NS_RELEASE(thread);
+ NS_RELEASE(receiver);
+
+ return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#if 0
+
+class nsPipeObserver : public nsIInputStreamObserver,
+ public nsIOutputStreamObserver
+{
+public:
+ NS_DECL_ISUPPORTS
+
+ NS_IMETHOD OnFull(nsIOutputStream *outStr) {
+ printf("OnFull outStr=%p\n", outStr);
+ return NS_OK;
+ }
+
+ NS_IMETHOD OnWrite(nsIOutputStream *outStr, PRUint32 amount) {
+ printf("OnWrite outStr=%p amount=%d\n", outStr, amount);
+ return NS_OK;
+ }
+
+ NS_IMETHOD OnEmpty(nsIInputStream* inStr) {
+ printf("OnEmpty inStr=%p\n", inStr);
+ return NS_OK;
+ }
+
+ NS_IMETHOD OnClose(nsIInputStream* inStr) {
+ printf("OnClose inStr=%p\n", inStr);
+ return NS_OK;
+ }
+
+ nsPipeObserver() { }
+
+private:
+ ~nsPipeObserver() {}
+};
+
+NS_IMPL_ISUPPORTS2(nsPipeObserver, nsIInputStreamObserver, nsIOutputStreamObserver)
+
+nsresult
+TestPipeObserver()
+{
+ nsresult rv;
+ nsPipeObserver* obs = new nsPipeObserver();
+ if (obs == nsnull) return NS_ERROR_OUT_OF_MEMORY;
+ NS_ADDREF(obs);
+
+ printf("TestPipeObserver: OnWrite and OnFull should be called once, OnEmpty should be called twice.\n");
+ nsIInputStream* in;
+ nsIOutputStream* out;
+ rv = NS_NewPipe(&in, &out, 18, 36, PR_TRUE, PR_TRUE);
+ if (NS_FAILED(rv)) return rv;
+
+ nsCOMPtr<nsIObservableInputStream> observableIn(do_QueryInterface(in, &rv));
+ if (NS_FAILED(rv)) return rv;
+ nsCOMPtr<nsIObservableInputStream> observableOut(do_QueryInterface(out, &rv));
+ if (NS_FAILED(rv)) return rv;
+
+ rv = observableIn->SetObserver(obs);
+ if (NS_FAILED(rv)) return rv;
+ rv = observableOut->SetObserver(obs);
+ if (NS_FAILED(rv)) return rv;
+
+ char buf[] = "puirt a beul: a style of Gaelic vocal music intended for dancing.";
+ PRUint32 cnt;
+ printf("> should see OnWrite message:\n");
+ rv = out->Write(buf, 20, &cnt);
+ if (NS_FAILED(rv)) return rv;
+ NS_ASSERTION(cnt == 20, "Write failed");
+
+ printf("> should see OnWrite message followed by OnFull message:\n");
+ rv = out->Write(buf + 20, 20, &cnt);
+ if (NS_FAILED(rv)) return rv;
+ NS_ASSERTION(cnt == 16, "Write failed");
+
+ rv = in->Available(&cnt);
+ if (NS_FAILED(rv)) return rv;
+ printf("available = %u\n", cnt);
+ NS_ASSERTION(cnt == 36, "Available failed");
+
+ char buf2[40];
+ printf("> should see OnEmpty message:\n");
+ rv = in->Read(buf2, 40, &cnt);
+ if (NS_FAILED(rv)) return rv;
+ printf("cnt = %u\n", cnt);
+ NS_ASSERTION(cnt == 36, "Read failed");
+ NS_ASSERTION(nsCRT::strncmp(buf, buf2, 36) == 0, "Read wrong stuff");
+
+ rv = in->Available(&cnt);
+ if (NS_FAILED(rv)) return rv;
+ printf("available = %u\n", cnt);
+ NS_ASSERTION(cnt == 0, "Available failed");
+
+ printf("> should see OnEmpty message:\n");
+ rv = in->Read(buf2, 2, &cnt);
+ if (NS_FAILED(rv) && rv != NS_BASE_STREAM_WOULD_BLOCK) return rv;
+ NS_ASSERTION(cnt == 0 && rv == NS_BASE_STREAM_WOULD_BLOCK, "Read failed");
+
+ printf("> should see OnWrite message:\n");
+ rv = out->Write(buf, 20, &cnt);
+ if (NS_FAILED(rv)) return rv;
+ NS_ASSERTION(cnt == 20, "Write failed");
+
+ rv = in->Available(&cnt);
+ if (NS_FAILED(rv)) return rv;
+ printf("available = %u\n", cnt);
+ NS_ASSERTION(cnt == 20, "Available failed");
+
+ printf("> should see OnEmpty message:\n");
+ rv = in->Read(buf2, 20, &cnt);
+ if (NS_FAILED(rv)) return rv;
+ NS_ASSERTION(cnt == 20, "Read failed");
+
+ printf("> should see OnClose message:\n");
+ NS_RELEASE(obs);
+ NS_RELEASE(in);
+ NS_RELEASE(out);
+ return NS_OK;
+}
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+
+class nsPump : public nsIRunnable
+{
+public:
+ NS_DECL_ISUPPORTS
+
+ NS_IMETHOD Run() {
+ nsresult rv;
+ PRUint32 count;
+ while (PR_TRUE) {
+ nsAutoCMonitor mon(this);
+ rv = mOut->WriteFrom(mIn, ~0U, &count);
+ if (NS_FAILED(rv)) {
+ printf("Write failed\n");
+ break;
+ }
+ if (count == 0) {
+ printf("EOF count = %d\n", mCount);
+ break;
+ }
+
+ if (gTrace) {
+ printf("Wrote: %d\n", count);
+ }
+ mCount += count;
+ }
+ mOut->Close();
+ return rv;
+ }
+
+ nsPump(nsIInputStream* in,
+ nsIOutputStream* out)
+ : mIn(in), mOut(out), mCount(0) {
+ }
+
+private:
+ ~nsPump() {}
+
+protected:
+ nsCOMPtr<nsIInputStream> mIn;
+ nsCOMPtr<nsIOutputStream> mOut;
+ PRUint32 mCount;
+};
+
+NS_IMPL_THREADSAFE_ISUPPORTS1(nsPump,
+ nsIRunnable)
+
+nsresult
+TestChainedPipes()
+{
+ nsresult rv;
+ printf("TestChainedPipes\n");
+
+ nsIInputStream* in1;
+ nsIOutputStream* out1;
+ rv = NS_NewPipe(&in1, &out1, 20, 1999);
+ if (NS_FAILED(rv)) return rv;
+
+ nsIInputStream* in2;
+ nsIOutputStream* out2;
+ rv = NS_NewPipe(&in2, &out2, 200, 401);
+ if (NS_FAILED(rv)) return rv;
+
+ nsIThread* thread;
+ nsPump* pump = new nsPump(in1, out2);
+ if (pump == nsnull) return NS_ERROR_OUT_OF_MEMORY;
+ NS_ADDREF(pump);
+
+ rv = NS_NewThread(&thread, pump, 0, PR_JOINABLE_THREAD);
+ if (NS_FAILED(rv)) return rv;
+
+ nsIThread* receiverThread;
+ nsReceiver* receiver = new nsReceiver(in2);
+ if (receiver == nsnull) return NS_ERROR_OUT_OF_MEMORY;
+ NS_ADDREF(receiver);
+
+ rv = NS_NewThread(&receiverThread, receiver, 0, PR_JOINABLE_THREAD);
+ if (NS_FAILED(rv)) return rv;
+
+ PRUint32 total = 0;
+ for (PRUint32 i = 0; i < ITERATIONS; i++) {
+ PRUint32 writeCount;
+ char* buf = PR_smprintf("%d %s", i, kTestPattern);
+ PRUint32 len = strlen(buf);
+ len = len * rand() / RAND_MAX;
+ len = PR_MAX(1, len);
+ rv = WriteAll(out1, buf, len, &writeCount);
+ if (NS_FAILED(rv)) return rv;
+ NS_ASSERTION(writeCount == len, "didn't write enough");
+ total += writeCount;
+
+ if (gTrace)
+ printf("wrote %d bytes: %s\n", writeCount, buf);
+
+ PR_smprintf_free(buf);
+ }
+ printf("wrote total of %d bytes\n", total);
+ rv = out1->Close();
+ if (NS_FAILED(rv)) return rv;
+
+ thread->Join();
+ receiverThread->Join();
+
+ NS_RELEASE(thread);
+ NS_RELEASE(pump);
+ NS_RELEASE(receiverThread);
+ NS_RELEASE(receiver);
+ NS_RELEASE(out2);
+ NS_RELEASE(in2);
+ NS_RELEASE(in1);
+ NS_RELEASE(out1);
+ return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void
+RunTests(PRUint32 segSize, PRUint32 segCount)
+{
+ nsresult rv;
+ nsIInputStream* in = 0; /* bird: initialize to quiet gcc. */
+ nsIOutputStream* out = 0; /* ditto */
+ PRUint32 bufSize;
+
+ bufSize = segSize * segCount;
+ printf("Testing New Pipes: segment size %d buffer size %d\n", segSize, bufSize);
+
+ printf("Testing long writes...\n");
+ rv = NS_NewPipe(&in, &out, segSize, bufSize);
+ NS_ASSERTION(NS_SUCCEEDED(rv), "NS_NewPipe failed");
+ rv = TestPipe(in, out);
+ NS_RELEASE(in);
+ NS_RELEASE(out);
+ NS_ASSERTION(NS_SUCCEEDED(rv), "TestPipe failed");
+
+ printf("Testing short writes...\n");
+ rv = NS_NewPipe(&in, &out, segSize, bufSize);
+ NS_ASSERTION(NS_SUCCEEDED(rv), "NS_NewPipe failed");
+ rv = TestShortWrites(in, out);
+ NS_RELEASE(in);
+ NS_RELEASE(out);
+ NS_ASSERTION(NS_SUCCEEDED(rv), "TestPipe failed");
+}
+
+////////////////////////////////////////////////////////////////////////////////
+#if 0
+void
+TestSearch(const char* delim, PRUint32 segSize)
+{
+ nsresult rv;
+ // need at least 2 segments to test boundary conditions:
+ PRUint32 bufDataSize = segSize * 2;
+ PRUint32 bufSize = segSize * 2;
+ nsIInputStream* in;
+ nsIOutputStream* out;
+ rv = NS_NewPipe(&in, &out, segSize, bufSize);
+ NS_ASSERTION(NS_SUCCEEDED(rv), "NS_NewPipe failed");
+ out->SetNonBlocking(PR_TRUE);
+
+ PRUint32 i, j, amt;
+ PRUint32 delimLen = nsCRT::strlen(delim);
+ for (i = 0; i < bufDataSize; i++) {
+ // first fill the buffer
+ for (j = 0; j < i; j++) {
+ rv = out->Write("-", 1, &amt);
+ NS_ASSERTION(NS_SUCCEEDED(rv) && amt == 1, "Write failed");
+ }
+ rv = out->Write(delim, delimLen, &amt);
+ NS_ASSERTION(NS_SUCCEEDED(rv), "Write failed");
+ if (i + amt < bufDataSize) {
+ for (j = i + amt; j < bufDataSize; j++) {
+ rv = out->Write("+", 1, &amt);
+ NS_ASSERTION(NS_SUCCEEDED(rv) && amt == 1, "Write failed");
+ }
+ }
+
+ // now search for the delimiter
+ PRBool found;
+ PRUint32 offset;
+ rv = in->Search(delim, PR_FALSE, &found, &offset);
+ NS_ASSERTION(NS_SUCCEEDED(rv), "Search failed");
+
+ // print the results
+ char* bufferContents = new char[bufDataSize + 1];
+ rv = in->Read(bufferContents, bufDataSize, &amt);
+ NS_ASSERTION(NS_SUCCEEDED(rv) && amt == bufDataSize, "Read failed");
+ bufferContents[bufDataSize] = '\0';
+ printf("Buffer: %s\nDelim: %s %s offset: %d\n", bufferContents,
+ delim, (found ? "found" : "not found"), offset);
+ }
+ NS_RELEASE(in);
+ NS_RELEASE(out);
+}
+#endif
+////////////////////////////////////////////////////////////////////////////////
+
+#ifdef DEBUG
+extern NS_COM void
+TestSegmentedBuffer();
+#endif
+
+int
+main(int argc, char* argv[])
+{
+ nsresult rv;
+ nsIServiceManager* servMgr;
+
+ rv = NS_InitXPCOM2(&servMgr, NULL, NULL);
+ if (NS_FAILED(rv)) return rv;
+
+ if (argc > 1 && nsCRT::strcmp(argv[1], "-trace") == 0)
+ gTrace = PR_TRUE;
+
+#ifdef DEBUG
+ TestSegmentedBuffer();
+#endif
+
+#if 0 // obsolete old implementation
+ rv = NS_NewPipe(&in, &out, 4096 * 4);
+ if (NS_FAILED(rv)) {
+ printf("NewPipe failed\n");
+ return -1;
+ }
+
+ rv = TestPipe(in, out);
+ NS_RELEASE(in);
+ NS_RELEASE(out);
+ if (NS_FAILED(rv)) {
+ printf("TestPipe failed\n");
+ return -1;
+ }
+#endif
+#if 0
+ TestSearch("foo", 8);
+ TestSearch("bar", 6);
+ TestSearch("baz", 2);
+#endif
+
+ rv = TestChainedPipes();
+ NS_ASSERTION(NS_SUCCEEDED(rv), "TestChainedPipes failed");
+ RunTests(16, 1);
+ RunTests(4096, 16);
+ NS_RELEASE(servMgr);
+ rv = NS_ShutdownXPCOM( NULL );
+ NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");
+ return 0;
+}
+
+////////////////////////////////////////////////////////////////////////////////
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestServMgr.cpp b/src/libs/xpcom18a4/xpcom/tests/TestServMgr.cpp
new file mode 100644
index 00000000..8eaaaa77
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/TestServMgr.cpp
@@ -0,0 +1,173 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Pierre Phaneuf <pp@ludusdesign.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "MyService.h"
+#include "nsXPCOM.h"
+#include "nsIServiceManager.h"
+#include "nsIComponentManager.h"
+#include <stdio.h>
+
+static NS_DEFINE_CID(kIMyServiceCID, NS_IMYSERVICE_CID);
+
+////////////////////////////////////////////////////////////////////////////////
+
+IMyService* myServ = NULL;
+
+nsresult
+BeginTest(int testNumber)
+{
+ nsresult err;
+ NS_ASSERTION(myServ == NULL, "myServ not reset");
+ err = nsServiceManager::GetService(kIMyServiceCID, NS_GET_IID(IMyService),
+ (nsISupports**)&myServ);
+ return err;
+}
+
+nsresult
+EndTest(int testNumber)
+{
+ nsresult err = NS_OK;
+
+ if (myServ) {
+ err = myServ->Doit();
+ if (err != NS_OK) return err;
+
+ err = nsServiceManager::ReleaseService(kIMyServiceCID, myServ);
+ if (err != NS_OK) return err;
+ myServ = NULL;
+ }
+
+ printf("test %d succeeded\n", testNumber);
+ return NS_OK;
+}
+
+nsresult
+SimpleTest(int testNumber)
+{
+ // This test just gets a service, uses it and releases it.
+
+ nsresult err;
+ err = BeginTest(testNumber);
+ if (err != NS_OK) return err;
+ err = EndTest(testNumber);
+ return err;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+nsresult
+AsyncShutdown(int testNumber)
+{
+ nsresult err;
+
+ // If the AsyncShutdown was truly asynchronous and happened on another
+ // thread, we'd have to protect all accesses to myServ throughout this
+ // code with a monitor.
+
+ err = nsServiceManager::UnregisterService(kIMyServiceCID);
+ if (err == NS_ERROR_SERVICE_NOT_AVAILABLE) {
+ printf("async shutdown -- service not found\n");
+ return NS_OK;
+ }
+ return err;
+}
+
+nsresult
+AsyncNoShutdownTest(int testNumber)
+{
+ // This test gets a service, and also gets an async request for shutdown,
+ // but the service doesn't get shut down because some other client (who's
+ // not participating in the async shutdown game as he should) is
+ // continuing to hang onto the service. This causes myServ variable to
+ // get set to NULL, but the service doesn't get unloaded right away as
+ // it should.
+
+ nsresult err;
+
+ err = BeginTest(testNumber);
+ if (err != NS_OK) return err;
+
+ // Create some other user of kIMyServiceCID, preventing it from
+ // really going away:
+ IMyService* otherClient;
+ err = nsServiceManager::GetService(kIMyServiceCID, NS_GET_IID(IMyService),
+ (nsISupports**)&otherClient);
+ if (err != NS_OK) return err;
+
+ err = AsyncShutdown(testNumber);
+ if (err != NS_OK) return err;
+ err = EndTest(testNumber);
+
+ // Finally, release the other client.
+ err = nsServiceManager::ReleaseService(kIMyServiceCID, otherClient);
+
+ return err;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+int
+main(void)
+{
+ nsresult err;
+ int testNumber = 0;
+
+ err = NS_InitXPCOM2(nsnull, nsnull, nsnull);
+ if (NS_FAILED(err)) {
+ printf("NS_InitXPCOM2 failed\n");
+ return -1;
+ }
+
+ err = SimpleTest(++testNumber);
+ if (err != NS_OK)
+ goto error;
+
+ err = AsyncNoShutdownTest(++testNumber);
+ if (err != NS_OK)
+ goto error;
+
+ AsyncShutdown(++testNumber);
+
+ printf("there was great success\n");
+ return 0;
+
+ error:
+ printf("test %d failed\n", testNumber);
+ return -1;
+}
+
+////////////////////////////////////////////////////////////////////////////////
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestShutdown.cpp b/src/libs/xpcom18a4/xpcom/tests/TestShutdown.cpp
new file mode 100644
index 00000000..259a7b31
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/TestShutdown.cpp
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Pierre Phaneuf <pp@ludusdesign.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsIServiceManager.h"
+
+// Gee this seems simple! It's for testing for memory leaks with Purify.
+
+void main(int argc, char* argv[])
+{
+ nsresult rv;
+ nsIServiceManager* servMgr;
+ rv = NS_InitXPCOM2(&servMgr, NULL, NULL);
+ NS_ASSERTION(NS_SUCCEEDED(rv), "NS_InitXPCOM failed");
+
+ // try loading a component and releasing it to see if it leaks
+ if (argc > 1 && argv[1] != nsnull) {
+ char* cidStr = argv[1];
+ nsISupports* obj = nsnull;
+ if (cidStr[0] == '{') {
+ nsCID cid;
+ cid.Parse(cidStr);
+ rv = nsComponentManager::CreateInstance(cid, nsnull,
+ NS_GET_IID(nsISupports),
+ (void**)&obj);
+ }
+ else {
+ // contractID case:
+ rv = nsComponentManager::CreateInstance(cidStr, nsnull,
+ NS_GET_IID(nsISupports),
+ (void**)&obj);
+ }
+ if (NS_SUCCEEDED(rv)) {
+ printf("Successfully created %s\n", cidStr);
+ NS_RELEASE(obj);
+ }
+ else {
+ printf("Failed to create %s (%x)\n", cidStr, rv);
+ }
+ }
+
+ rv = NS_ShutdownXPCOM(servMgr);
+ NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");
+}
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestStackCrawl.cpp b/src/libs/xpcom18a4/xpcom/tests/TestStackCrawl.cpp
new file mode 100644
index 00000000..76187edd
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/TestStackCrawl.cpp
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+#include "nsISupportsUtils.h"
+#include "nsTraceRefCntImpl.h"
+
+int main(int argc, char* argv[])
+{
+ nsTraceRefcntImpl::WalkTheStack(stdout);
+ return 0;
+}
+
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestStrings.cpp b/src/libs/xpcom18a4/xpcom/tests/TestStrings.cpp
new file mode 100644
index 00000000..b1b725a4
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/TestStrings.cpp
@@ -0,0 +1,643 @@
+/* vim:set ts=2 sw=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <stdio.h>
+#include "nsString.h"
+#include "nsReadableUtils.h"
+#include "nsCRT.h"
+
+void test_assign_helper(const nsACString& in, nsACString &_retval)
+ {
+ _retval = in;
+ }
+
+PRBool test_assign()
+ {
+ nsCString result;
+ test_assign_helper(NS_LITERAL_CSTRING("a") + NS_LITERAL_CSTRING("b"), result);
+ PRBool r = strcmp(result.get(), "ab") == 0;
+ if (!r)
+ printf("[result=%s]\n", result.get());
+ return r;
+ }
+
+PRBool test_assign_c()
+ {
+ nsCString c; c.Assign('c');
+ PRBool r = strcmp(c.get(), "c") == 0;
+ if (!r)
+ printf("[result=%s]\n", c.get());
+ return r;
+ }
+
+PRBool test1()
+ {
+ NS_NAMED_LITERAL_STRING(empty, "");
+ const nsAString& aStr = empty;
+
+ nsAutoString buf(aStr);
+
+ PRInt32 n = buf.FindChar(',');
+
+ n = buf.Length();
+
+ buf.Cut(0, n + 1);
+ n = buf.FindChar(',');
+
+ if (n != kNotFound)
+ printf("n=%d\n", n);
+
+ return n == kNotFound;
+ }
+
+PRBool test2()
+ {
+ nsCString data("hello world");
+ const nsACString& aStr = data;
+
+ nsCString temp(aStr);
+ temp.Cut(0, 6);
+
+ PRBool r = strcmp(temp.get(), "world") == 0;
+ if (!r)
+ printf("[temp=%s]\n", temp.get());
+ return r;
+ }
+
+PRBool test_find()
+ {
+ nsCString src("<!DOCTYPE blah blah blah>");
+
+ PRInt32 i = src.Find("DOCTYPE", PR_TRUE, 2, 1);
+ if (i == 2)
+ return PR_TRUE;
+
+ printf("i=%d\n", i);
+ return PR_FALSE;
+ }
+
+PRBool test_rfind()
+ {
+ const char text[] = "<!DOCTYPE blah blah blah>";
+ const char term[] = "bLaH";
+ nsCString src(text);
+ PRInt32 i;
+
+ i = src.RFind(term, PR_TRUE, 3, -1);
+ if (i != kNotFound)
+ {
+ printf("unexpected result searching from offset=3, i=%d\n", i);
+ return PR_FALSE;
+ }
+
+ i = src.RFind(term, PR_TRUE, -1, -1);
+ if (i != 20)
+ {
+ printf("unexpected result searching from offset=-1, i=%d\n", i);
+ return PR_FALSE;
+ }
+
+ i = src.RFind(term, PR_TRUE, 13, -1);
+ if (i != 10)
+ {
+ printf("unexpected result searching from offset=13, i=%d\n", i);
+ return PR_FALSE;
+ }
+
+ i = src.RFind(term, PR_TRUE, 22, 3);
+ if (i != 20)
+ {
+ printf("unexpected result searching from offset=22, i=%d\n", i);
+ return PR_FALSE;
+ }
+
+ return PR_TRUE;
+ }
+
+PRBool test_rfind_2()
+ {
+ const char text[] = "<!DOCTYPE blah blah blah>";
+ nsCString src(text);
+ PRInt32 i = src.RFind("TYPE", PR_FALSE, 5, -1);
+ if (i == 5)
+ return PR_TRUE;
+
+ printf("i=%d\n", i);
+ return PR_FALSE;
+ }
+
+PRBool test_rfind_3()
+ {
+ const char text[] = "urn:mozilla:locale:en-US:necko";
+ nsCAutoString value(text);
+ PRInt32 i = value.RFind(":");
+ if (i == 24)
+ return PR_TRUE;
+
+ printf("i=%d\n", i);
+ return PR_FALSE;
+ }
+
+PRBool test_rfind_4()
+ {
+ nsCString value("a.msf");
+ PRInt32 i = value.RFind(".msf");
+ if (i != 1)
+ {
+ printf("i=%d\n", i);
+ return PR_FALSE;
+ }
+
+ return PR_TRUE;
+ }
+
+PRBool test_distance()
+ {
+ const char text[] = "abc-xyz";
+ nsCString s(text);
+ nsCString::const_iterator begin, end;
+ s.BeginReading(begin);
+ s.EndReading(end);
+ size_t d = Distance(begin, end);
+ PRBool r = (d == sizeof(text)-1);
+ if (!r)
+ printf("d=%zu\n", d);
+ return r;
+ }
+
+PRBool test_length()
+ {
+ const char text[] = "abc-xyz";
+ nsCString s(text);
+ size_t d = s.Length();
+ PRBool r = (d == sizeof(text)-1);
+ if (!r)
+ printf("d=%zu\n", d);
+ return r;
+ }
+
+PRBool test_trim()
+ {
+ const char text[] = " a\t $ ";
+ const char set[] = " \t$";
+
+ nsCString s(text);
+ s.Trim(set);
+ PRBool r = strcmp(s.get(), "a") == 0;
+ if (!r)
+ printf("[s=%s]\n", s.get());
+ return r;
+ }
+
+PRBool test_replace_substr()
+ {
+ const char text[] = "abc-ppp-qqq-ppp-xyz";
+ nsCString s(text);
+ s.ReplaceSubstring("ppp", "www");
+ PRBool r = strcmp(s.get(), "abc-www-qqq-www-xyz") == 0;
+ if (!r)
+ {
+ printf("[s=%s]\n", s.get());
+ return PR_FALSE;
+ }
+
+ s.Assign("foobar");
+ s.ReplaceSubstring("foo", "bar");
+ s.ReplaceSubstring("bar", "");
+ r = strcmp(s.get(), "") == 0;
+ if (!r)
+ {
+ printf("[s=%s]\n", s.get());
+ return PR_FALSE;
+ }
+
+ s.Assign("foofoofoo");
+ s.ReplaceSubstring("foo", "foo");
+ r = strcmp(s.get(), "foofoofoo") == 0;
+ if (!r)
+ {
+ printf("[s=%s]\n", s.get());
+ return PR_FALSE;
+ }
+
+ s.Assign("foofoofoo");
+ s.ReplaceSubstring("of", "fo");
+ r = strcmp(s.get(), "fofoofooo") == 0;
+ if (!r)
+ {
+ printf("[s=%s]\n", s.get());
+ return PR_FALSE;
+ }
+
+ return PR_TRUE;
+ }
+
+PRBool test_replace_substr_2()
+ {
+ const char *oldName = nsnull;
+ const char *newName = "user";
+ nsString acctName; acctName.AssignLiteral("forums.foo.com");
+ nsAutoString newAcctName, oldVal, newVal;
+ oldVal.AssignWithConversion(oldName);
+ newVal.AssignWithConversion(newName);
+ newAcctName.Assign(acctName);
+
+ // here, oldVal is empty. we are testing that this function
+ // does not hang. see bug 235355.
+ newAcctName.ReplaceSubstring(oldVal, newVal);
+
+ // we expect that newAcctName will be unchanged.
+ if (!newAcctName.Equals(acctName))
+ return PR_FALSE;
+
+ return PR_TRUE;
+ }
+
+PRBool test_strip_ws()
+ {
+ const char text[] = " a $ ";
+ nsCString s(text);
+ s.StripWhitespace();
+ PRBool r = strcmp(s.get(), "a$") == 0;
+ if (!r)
+ printf("[s=%s]\n", s.get());
+ return r;
+ }
+
+PRBool test_equals_ic()
+ {
+ nsCString s;
+ PRBool r = s.LowerCaseEqualsLiteral("view-source");
+ if (r)
+ printf("[r=%d]\n", r);
+ return !r;
+ }
+
+PRBool test_fixed_string()
+ {
+ char buf[256] = "hello world";
+
+ nsFixedCString s(buf, sizeof(buf));
+
+ if (s.Length() != strlen(buf))
+ return PR_FALSE;
+
+ if (strcmp(s.get(), buf) != 0)
+ return PR_FALSE;
+
+ s.Assign("foopy doopy doo");
+ if (s.get() != buf)
+ return PR_FALSE;
+
+ return PR_TRUE;
+ }
+
+PRBool test_concat()
+ {
+ nsCString bar("bar");
+ const nsACString& barRef = bar;
+
+ const nsPromiseFlatCString& result =
+ PromiseFlatCString(NS_LITERAL_CSTRING("foo") +
+ NS_LITERAL_CSTRING(",") +
+ barRef);
+ if (strcmp(result.get(), "foo,bar") == 0)
+ return PR_TRUE;
+
+ printf("[result=%s]\n", result.get());
+ return PR_FALSE;
+ }
+
+PRBool test_concat_2()
+ {
+ nsCString fieldTextStr("xyz");
+ nsCString text("text");
+ const nsACString& aText = text;
+
+ nsCAutoString result( fieldTextStr + aText );
+
+ if (strcmp(result.get(), "xyztext") == 0)
+ return PR_TRUE;
+
+ printf("[result=%s]\n", result.get());
+ return PR_FALSE;
+ }
+
+#if 0
+PRBool test_concat_3()
+ {
+ nsCString a("a"), b("b");
+
+ // THIS DOES NOT COMPILE
+ const nsACString& r = a + b;
+
+ return PR_TRUE;
+ }
+#endif
+
+PRBool test_xpidl_string()
+ {
+ nsXPIDLCString a, b;
+ a = b;
+ if (a != b)
+ return PR_FALSE;
+
+ a.Adopt(0);
+ if (a != b)
+ return PR_FALSE;
+
+ a.Append("foopy");
+ a.Assign(b);
+ if (a != b)
+ return PR_FALSE;
+
+ a.Insert("", 0);
+ a.Assign(b);
+ if (a != b)
+ return PR_FALSE;
+
+ const char text[] = "hello world";
+ *getter_Copies(a) = nsCRT::strdup(text);
+ if (strcmp(a, text) != 0)
+ return PR_FALSE;
+
+ b = a;
+ if (strcmp(a, b) != 0)
+ return PR_FALSE;
+
+ a.Adopt(0);
+ nsACString::const_iterator begin, end;
+ a.BeginReading(begin);
+ a.EndReading(end);
+ char *r = ToNewCString(Substring(begin, end));
+ if (strcmp(r, "") != 0)
+ return PR_FALSE;
+ nsMemory::Free(r);
+
+ a.Adopt(0);
+ if (a != (const char*) 0)
+ return PR_FALSE;
+
+ /*
+ PRInt32 index = a.FindCharInSet("xyz");
+ if (index != kNotFound)
+ return PR_FALSE;
+ */
+
+ return PR_TRUE;
+ }
+
+PRBool test_empty_assign()
+ {
+ nsCString a;
+ a.AssignLiteral("");
+
+ a.AppendLiteral("");
+
+ nsCString b;
+ b.SetCapacity(0);
+ return PR_TRUE;
+ }
+
+PRBool test_set_length()
+ {
+ const char kText[] = "Default Plugin";
+ nsCString buf;
+ buf.SetCapacity(sizeof(kText)-1);
+ buf.Assign(kText);
+ buf.SetLength(sizeof(kText)-1);
+ if (strcmp(buf.get(), kText) != 0)
+ return PR_FALSE;
+ return PR_TRUE;
+ }
+
+PRBool test_substring()
+ {
+ nsCString super("hello world"), sub("hello");
+
+ // this tests that |super| starts with |sub|,
+
+ PRBool r = sub.Equals(StringHead(super, sub.Length()));
+ if (!r)
+ return PR_FALSE;
+
+ // and verifies that |sub| does not start with |super|.
+
+ r = super.Equals(StringHead(sub, super.Length()));
+ if (r)
+ return PR_FALSE;
+
+ return PR_TRUE;
+ }
+
+PRBool test_appendint64()
+ {
+ nsCString str;
+
+ PRInt64 max = LL_MaxInt();
+ static const char max_expected[] = "9223372036854775807";
+ PRInt64 min = LL_MinInt();
+ static const char min_expected[] = "-9223372036854775808";
+ static const char min_expected_oct[] = "1000000000000000000000";
+ PRInt64 maxint_plus1 = LL_INIT(1, 0);
+ static const char maxint_plus1_expected[] = "4294967296";
+ static const char maxint_plus1_expected_x[] = "100000000";
+
+ str.AppendInt(max);
+
+ if (!str.Equals(max_expected)) {
+ fprintf(stderr, "Error appending LL_MaxInt(): Got %s\n", str.get());
+ return PR_FALSE;
+ }
+
+ str.Truncate();
+ str.AppendInt(min);
+ if (!str.Equals(min_expected)) {
+ fprintf(stderr, "Error appending LL_MinInt(): Got %s\n", str.get());
+ return PR_FALSE;
+ }
+ str.Truncate();
+ str.AppendInt(min, 8);
+ if (!str.Equals(min_expected_oct)) {
+ fprintf(stderr, "Error appending LL_MinInt() (oct): Got %s\n", str.get());
+ return PR_FALSE;
+ }
+
+
+ str.Truncate();
+ str.AppendInt(maxint_plus1);
+ if (!str.Equals(maxint_plus1_expected)) {
+ fprintf(stderr, "Error appending PR_UINT32_MAX + 1: Got %s\n", str.get());
+ return PR_FALSE;
+ }
+ str.Truncate();
+ str.AppendInt(maxint_plus1, 16);
+ if (!str.Equals(maxint_plus1_expected_x)) {
+ fprintf(stderr, "Error appending PR_UINT32_MAX + 1 (hex): Got %s\n", str.get());
+ return PR_FALSE;
+ }
+
+
+ return PR_TRUE;
+ }
+
+PRBool test_findcharinset()
+ {
+ nsCString buf("hello, how are you?");
+
+ PRInt32 index = buf.FindCharInSet(",?", 5);
+ if (index != 5)
+ return PR_FALSE;
+
+ index = buf.FindCharInSet("helo", 0);
+ if (index != 0)
+ return PR_FALSE;
+
+ index = buf.FindCharInSet("z?", 6);
+ if (index != (PRInt32) buf.Length()-1)
+ return PR_FALSE;
+
+ return PR_TRUE;
+ }
+
+PRBool test_rfindcharinset()
+ {
+ nsCString buf("hello, how are you?");
+
+ PRInt32 index = buf.RFindCharInSet(",?", 5);
+ if (index != 5)
+ return PR_FALSE;
+
+ index = buf.RFindCharInSet("helo", 0);
+ if (index != 0)
+ return PR_FALSE;
+
+ index = buf.RFindCharInSet("z?", 6);
+ if (index != kNotFound)
+ return PR_FALSE;
+
+ index = buf.RFindCharInSet("l", 5);
+ if (index != 3)
+ return PR_FALSE;
+
+ buf.Assign("abcdefghijkabc");
+
+ index = buf.RFindCharInSet("ab");
+ if (index != 12)
+ return PR_FALSE;
+
+ index = buf.RFindCharInSet("ab", 11);
+ if (index != 11)
+ return PR_FALSE;
+
+ index = buf.RFindCharInSet("ab", 10);
+ if (index != 1)
+ return PR_FALSE;
+
+ index = buf.RFindCharInSet("ab", 0);
+ if (index != 0)
+ return PR_FALSE;
+
+ index = buf.RFindCharInSet("cd", 1);
+ if (index != kNotFound)
+ return PR_FALSE;
+
+ index = buf.RFindCharInSet("h");
+ if (index != 7)
+ return PR_FALSE;
+
+ return PR_TRUE;
+ }
+
+//----
+
+typedef PRBool (*TestFunc)();
+
+static const struct Test
+ {
+ const char* name;
+ TestFunc func;
+ }
+tests[] =
+ {
+ { "test_assign", test_assign },
+ { "test_assign_c", test_assign_c },
+ { "test1", test1 },
+ { "test2", test2 },
+ { "test_find", test_find },
+ { "test_rfind", test_rfind },
+ { "test_rfind_2", test_rfind_2 },
+ { "test_rfind_3", test_rfind_3 },
+ { "test_rfind_4", test_rfind_4 },
+ { "test_distance", test_distance },
+ { "test_length", test_length },
+ { "test_trim", test_trim },
+ { "test_replace_substr", test_replace_substr },
+ { "test_replace_substr_2", test_replace_substr_2 },
+ { "test_strip_ws", test_strip_ws },
+ { "test_equals_ic", test_equals_ic },
+ { "test_fixed_string", test_fixed_string },
+ { "test_concat", test_concat },
+ { "test_concat_2", test_concat_2 },
+ { "test_xpidl_string", test_xpidl_string },
+ { "test_empty_assign", test_empty_assign },
+ { "test_set_length", test_set_length },
+ { "test_substring", test_substring },
+ { "test_appendint64", test_appendint64 },
+ { "test_findcharinset", test_findcharinset },
+ { "test_rfindcharinset", test_rfindcharinset },
+ { nsnull, nsnull }
+ };
+
+//----
+
+int main(int argc, char **argv)
+ {
+ int count = 1;
+ if (argc > 1)
+ count = atoi(argv[1]);
+
+ while (count--)
+ {
+ for (const Test* t = tests; t->name != nsnull; ++t)
+ {
+ printf("%25s : %s\n", t->name, t->func() ? "SUCCESS" : "FAILURE <--");
+ }
+ }
+
+ return 0;
+ }
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestThreads.cpp b/src/libs/xpcom18a4/xpcom/tests/TestThreads.cpp
new file mode 100644
index 00000000..10025a05
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/TestThreads.cpp
@@ -0,0 +1,280 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Pierre Phaneuf <pp@ludusdesign.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsIThread.h"
+#include "nsIRunnable.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "nspr.h"
+#include "nsCOMPtr.h"
+#include "nsIServiceManager.h"
+
+class nsRunner : public nsIRunnable {
+public:
+ NS_DECL_ISUPPORTS
+
+ NS_IMETHOD Run() {
+ nsCOMPtr<nsIThread> thread;
+ nsresult rv = nsIThread::GetCurrent(getter_AddRefs(thread));
+ if (NS_FAILED(rv)) {
+ printf("failed to get current thread\n");
+ return rv;
+ }
+ printf("running %d on thread %p\n", mNum, (void *)thread.get());
+
+ // if we don't do something slow, we'll never see the other
+ // worker threads run
+ PR_Sleep(PR_MillisecondsToInterval(100));
+
+ return rv;
+ }
+
+ nsRunner(int num) : mNum(num) {
+ }
+
+protected:
+ int mNum;
+};
+
+NS_IMPL_THREADSAFE_ISUPPORTS1(nsRunner, nsIRunnable)
+
+nsresult
+TestThreads()
+{
+ nsresult rv;
+
+ nsCOMPtr<nsIThread> runner;
+ rv = NS_NewThread(getter_AddRefs(runner), new nsRunner(0), 0, PR_JOINABLE_THREAD);
+ if (NS_FAILED(rv)) {
+ printf("failed to create thread\n");
+ return rv;
+ }
+
+ nsCOMPtr<nsIThread> thread;
+ rv = nsIThread::GetCurrent(getter_AddRefs(thread));
+ if (NS_FAILED(rv)) {
+ printf("failed to get current thread\n");
+ return rv;
+ }
+
+ PRThreadScope scope;
+ rv = runner->GetScope(&scope);
+ if (NS_FAILED(rv)) {
+ printf("runner already exited\n");
+ }
+
+ rv = runner->Join(); // wait for the runner to die before quitting
+ if (NS_FAILED(rv)) {
+ printf("join failed\n");
+ }
+
+ rv = runner->GetScope(&scope); // this should fail after Join
+ if (NS_SUCCEEDED(rv)) {
+ printf("get scope failed\n");
+ }
+
+ rv = runner->Interrupt(); // this should fail after Join
+ if (NS_SUCCEEDED(rv)) {
+ printf("interrupt failed\n");
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // try an unjoinable thread
+ rv = NS_NewThread(getter_AddRefs(runner), new nsRunner(1));
+ if (NS_FAILED(rv)) {
+ printf("failed to create thread\n");
+ return rv;
+ }
+
+ rv = runner->Join(); // wait for the runner to die before quitting
+ if (NS_SUCCEEDED(rv)) {
+ printf("shouldn't have been able to join an unjoinable thread\n");
+ }
+
+ PR_Sleep(PR_MillisecondsToInterval(100)); // hopefully the runner will quit here
+
+ return NS_OK;
+}
+
+class nsStressRunner : public nsIRunnable {
+public:
+ NS_DECL_ISUPPORTS
+
+ NS_IMETHOD Run() {
+ NS_ASSERTION(!mWasRun, "run twice!");
+ mWasRun = PR_TRUE;
+ PR_Sleep(1);
+ if (!PR_AtomicDecrement(&gNum)) {
+ printf(" last thread was %d\n", mNum);
+ }
+ return NS_OK;
+ }
+
+ nsStressRunner(int num) : mNum(num), mWasRun(PR_FALSE) {
+ PR_AtomicIncrement(&gNum);
+ }
+
+ static PRInt32 GetGlobalCount() {return gNum;}
+
+private:
+ ~nsStressRunner() {
+ NS_ASSERTION(mWasRun, "never run!");
+ }
+
+protected:
+ static PRInt32 gNum;
+ PRInt32 mNum;
+ PRBool mWasRun;
+};
+
+PRInt32 nsStressRunner::gNum = 0;
+
+NS_IMPL_THREADSAFE_ISUPPORTS1(nsStressRunner, nsIRunnable)
+
+static int Stress(int loops, int threads)
+{
+
+ for (int i = 0; i < loops; i++) {
+ printf("Loop %d of %d\n", i+1, loops);
+
+ int k;
+ nsIThread** array = new nsIThread*[threads];
+ NS_ASSERTION(array, "out of memory");
+
+ NS_ASSERTION(!nsStressRunner::GetGlobalCount(), "bad count of runnables");
+
+ for (k = 0; k < threads; k++) {
+ nsCOMPtr<nsIThread> t;
+ nsresult rv = NS_NewThread(getter_AddRefs(t),
+ new nsStressRunner(k),
+ 0, PR_JOINABLE_THREAD);
+ NS_ASSERTION(NS_SUCCEEDED(rv), "can't create thread");
+ NS_ADDREF(array[k] = t);
+ }
+
+ for (k = threads-1; k >= 0; k--) {
+ array[k]->Join();
+ NS_RELEASE(array[k]);
+ }
+ delete [] array;
+ }
+ return 0;
+}
+
+PR_STATIC_CALLBACK(void) threadProc(void *arg)
+{
+ // printf(" running thread %d\n", (int) arg);
+ PR_Sleep(1);
+ PR_ASSERT(PR_JOINABLE_THREAD == PR_GetThreadState(PR_GetCurrentThread()));
+}
+
+static int StressNSPR(int loops, int threads)
+{
+
+ for (int i = 0; i < loops; i++) {
+ printf("Loop %d of %d\n", i+1, loops);
+
+ int k;
+ PRThread** array = new PRThread*[threads];
+ PR_ASSERT(array);
+
+ for (k = 0; k < threads; k++) {
+ array[k] = PR_CreateThread(PR_USER_THREAD,
+ threadProc, (void*)(uintptr_t)k,
+ PR_PRIORITY_NORMAL,
+ PR_GLOBAL_THREAD,
+ PR_JOINABLE_THREAD,
+ 0);
+ PR_ASSERT(array[k]);
+ }
+
+ for (k = 0; k < threads; k++) {
+ PR_ASSERT(PR_JOINABLE_THREAD == PR_GetThreadState(array[k]));
+ }
+
+ for (k = threads-1; k >= 0; k--) {
+ PR_JoinThread(array[k]);
+ }
+ delete [] array;
+ }
+ return 0;
+}
+
+
+int
+main(int argc, char** argv)
+{
+ int retval = 0;
+ nsresult rv;
+
+ rv = NS_InitXPCOM2(nsnull, nsnull, nsnull);
+ if (NS_FAILED(rv)) return -1;
+
+ if (argc > 1 && !strcmp(argv[1], "-stress")) {
+ int loops;
+ int threads;
+ if (argc != 4 || *argv[2] != '-' || *argv[3] != '-' ||
+ !(loops = atoi(argv[2]+1)) || !(threads = atoi(argv[3]+1))) {
+ printf("To use -stress you must pass loop count and thread count...\n"
+ " TestThreads -stress -1000 -50\n");
+ } else {
+ printf("Running stress test with %d loops of %d threads each\n",
+ loops, threads);
+ retval = Stress(loops, threads);
+ }
+ } else if (argc > 1 && !strcmp(argv[1], "-stress-nspr")) {
+ int loops;
+ int threads;
+ if (argc != 4 || *argv[2] != '-' || *argv[3] != '-' ||
+ !(loops = atoi(argv[2]+1)) || !(threads = atoi(argv[3]+1))) {
+ printf("To use -stress-nspr you must pass loop count and thread count...\n"
+ " TestThreads -stress -1000 -50\n");
+ } else {
+ printf("Running stress test with %d loops of %d threads each\n",
+ loops, threads);
+ retval = StressNSPR(loops, threads);
+ }
+ } else {
+ rv = TestThreads();
+ if (NS_FAILED(rv)) return -1;
+ }
+
+ rv = NS_ShutdownXPCOM(nsnull);
+ if (NS_FAILED(rv)) return -1;
+ return retval;
+}
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestVoidBTree.cpp b/src/libs/xpcom18a4/xpcom/tests/TestVoidBTree.cpp
new file mode 100644
index 00000000..956f179f
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/TestVoidBTree.cpp
@@ -0,0 +1,302 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org Code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include "nsVoidBTree.h"
+#include "nsVoidArray.h"
+
+#define COUNT 1024
+#define POINTER(i) NS_REINTERPRET_CAST(void*, 4 + 4 * (i))
+
+static PRBool
+Equal(const nsVoidArray& aControl, const nsVoidBTree& aTest)
+{
+ if (aControl.Count() != aTest.Count()) {
+ printf("counts not equal; ");
+ return PR_FALSE;
+ }
+
+ for (PRInt32 i = aControl.Count() - 1; i >= 0; --i) {
+ if (aControl[i] != aTest[i]) {
+ printf("element %d differs; ", i);
+ return PR_FALSE;
+ }
+ }
+
+ return PR_TRUE;
+}
+
+
+static void
+CheckForwardEnumeration(const nsVoidArray& aControl, const nsVoidBTree& aTest)
+{
+ PRInt32 index = 0;
+
+ nsVoidBTree::ConstIterator last = aTest.Last();
+ for (nsVoidBTree::ConstIterator element = aTest.First(); element != last; ++element, ++index) {
+ if (*element != aControl[index]) {
+ printf("failed forward enumeration\n");
+ exit(-1);
+ }
+ }
+
+ if (index != aControl.Count()) {
+ printf("erratic termination during forward enumeration\n");
+ exit(-1);
+ }
+}
+
+static void
+CheckBackwardEnumeration(const nsVoidArray& aControl, const nsVoidBTree& aTest)
+{
+ PRInt32 index = aControl.Count();
+ nsVoidBTree::ConstIterator first = aTest.First();
+ nsVoidBTree::ConstIterator element = aTest.Last();
+
+ if (first != element) {
+ do {
+ if (*--element != aControl[--index]) {
+ printf("failed backward enumeration\n");
+ exit(-1);
+ }
+ } while (element != first);
+ }
+
+ if (index != 0) {
+ printf("erratic termination during backward enumeration\n");
+ exit(-1);
+ }
+}
+
+int main(int argc, char* argv[])
+{
+ nsVoidBTree btree;
+
+ PRInt32 i;
+
+ //----------------------------------------
+ // Tail fill
+ for (i = 0; i < COUNT; ++i)
+ btree.InsertElementAt(NS_REINTERPRET_CAST(void*, POINTER(i)), i);
+
+ for (i = 0; i < COUNT; ++i) {
+ if (btree[i] != POINTER(i)) {
+ printf("tail fill failed\n");
+ return -1;
+ }
+ }
+
+ printf("tail fill succeeded\n");
+
+ //----------------------------------------
+ // Tail empty
+ for (i = COUNT - 1; i >= 0; --i)
+ btree.RemoveElementAt(i);
+
+ if (btree.Count() != 0) {
+ printf("tail empty failed\n");
+ return -1;
+ }
+
+ printf("tail empty succeeded\n");
+
+ // N.B. no intervening Clear() to verify that we handle the re-use
+ // case.
+
+ //----------------------------------------
+ // Front fill
+ for (i = 0; i < COUNT; ++i)
+ btree.InsertElementAt(POINTER(i), 0);
+
+ for (i = 0; i < COUNT; ++i) {
+ if (btree[COUNT - (i + 1)] != POINTER(i)) {
+ printf("simple front fill failed\n");
+ return -1;
+ }
+ }
+
+ printf("front fill succeeded\n");
+
+ //----------------------------------------
+ // Front empty
+ for (i = COUNT - 1; i >= 0; --i)
+ btree.RemoveElementAt(0);
+
+ if (btree.Count() != 0) {
+ printf("front empty failed\n");
+ return -1;
+ }
+
+ printf("front empty succeeded\n");
+ fflush(stdout);
+
+ //----------------------------------------
+ // Test boundary conditions with small btree
+
+ {
+ printf("small btree boundary conditions ");
+ fflush(stdout);
+
+ nsVoidArray control;
+ btree.Clear();
+
+ CheckBackwardEnumeration(control, btree);
+ CheckForwardEnumeration(control, btree);
+
+ btree.AppendElement(POINTER(0));
+ control.AppendElement(POINTER(0));
+
+ CheckBackwardEnumeration(control, btree);
+ CheckForwardEnumeration(control, btree);
+
+ btree.AppendElement(POINTER(1));
+ control.AppendElement(POINTER(1));
+
+ CheckBackwardEnumeration(control, btree);
+ CheckForwardEnumeration(control, btree);
+
+ btree.RemoveElementAt(0);
+ btree.RemoveElementAt(0);
+ control.RemoveElementAt(0);
+ control.RemoveElementAt(0);
+
+ CheckBackwardEnumeration(control, btree);
+ CheckForwardEnumeration(control, btree);
+
+ printf("succeeded\n");
+ }
+
+ //----------------------------------------
+ // Iterator
+ {
+ nsVoidArray control;
+ btree.Clear();
+
+ // Fill
+ for (i = 0; i < COUNT; ++i) {
+ PRInt32 slot = i ? rand() % i : 0;
+
+ btree.InsertElementAt(POINTER(i), slot);
+ control.InsertElementAt(POINTER(i), slot);
+
+ if (! Equal(control, btree)) {
+ printf("failed\n");
+ return -1;
+ }
+ }
+
+ for (nsVoidBTree::Iterator m = btree.First(); m != btree.Last(); ++m) {
+ nsVoidBTree::Iterator n;
+ for (n = m, ++n; n != btree.Last(); ++n) {
+ if (*m > *n) {
+ void* tmp = *m;
+ *m = *n;
+ *n = tmp;
+ }
+ }
+ }
+
+ nsVoidBTree::Iterator el;
+ for (el = btree.First(), i = 0; el != btree.Last(); ++el, ++i) {
+ if (*el != POINTER(i)) {
+ printf("bubble sort failed\n");
+ return -1;
+ }
+ }
+
+ printf("iteration succeeded\n");
+ }
+
+ //----------------------------------------
+ // Random hammering
+
+ printf("random fill/empty: ");
+
+ for (PRInt32 iter = 10; iter >= 1; --iter) {
+ printf("%d ", iter);
+ fflush(stdout);
+
+ nsVoidArray control;
+ btree.Clear();
+
+ // Fill
+ for (i = 0; i < COUNT; ++i) {
+ PRInt32 slot = i ? rand() % i : 0;
+
+ btree.InsertElementAt(POINTER(i), slot);
+ control.InsertElementAt(POINTER(i), slot);
+
+ if (! Equal(control, btree)) {
+ printf("failed\n");
+ return -1;
+ }
+ }
+
+ // IndexOf
+ for (i = 0; i < COUNT; ++i) {
+ void* element = control[i];
+ if (btree.IndexOf(element) != i) {
+ printf("failed IndexOf at %d\n", i);
+ return -1;
+ }
+ }
+
+ // Backward enumeration
+ CheckBackwardEnumeration(control, btree);
+
+ // Forward enumeration
+ CheckForwardEnumeration(control, btree);
+
+ // Empty
+ for (i = COUNT - 1; i >= 0; --i) {
+ PRInt32 slot = i ? rand() % i : 0;
+
+ btree.RemoveElementAt(slot);
+ control.RemoveElementAt(slot);
+
+ if (! Equal(control, btree)) {
+ printf("failed\n");
+ return -1;
+ }
+ }
+ }
+
+ printf("succeeded\n");
+
+ return 0;
+}
diff --git a/src/libs/xpcom18a4/xpcom/tests/TestXPIDLString.cpp b/src/libs/xpcom18a4/xpcom/tests/TestXPIDLString.cpp
new file mode 100644
index 00000000..f2802e1f
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/TestXPIDLString.cpp
@@ -0,0 +1,18 @@
+#include "nsString.h"
+#include "nsReadableUtils.h"
+#include "nsXPIDLString.h"
+
+static void
+nsXPIDLStringTest_Value(PRUnichar** aResult)
+{
+ *aResult = ToNewUnicode(NS_LITERAL_STRING("Hello, World"));
+}
+
+int
+main(int argc, char* argv[])
+{
+ nsXPIDLString s1;
+ nsXPIDLStringTest_Value(getter_Copies(s1));
+ return 0;
+}
+
diff --git a/src/libs/xpcom18a4/xpcom/tests/dynamic/.cvsignore b/src/libs/xpcom18a4/xpcom/tests/dynamic/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/dynamic/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/xpcom/tests/dynamic/Makefile.in b/src/libs/xpcom18a4/xpcom/tests/dynamic/Makefile.in
new file mode 100644
index 00000000..c17318c0
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/dynamic/Makefile.in
@@ -0,0 +1,61 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# 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
+
+IS_COMPONENT = 1
+MODULE_NAME = nsTestDynamicModule
+MODULE = xpcom
+LIBRARY_NAME = testdynamic
+SHORT_LIBNAME = tdynamic
+
+CPPSRCS = TestDynamic.cpp
+
+include $(topsrcdir)/config/config.mk
+
+LOCAL_INCLUDES = -I$(srcdir)/.. -I$(srcdir)/../../public
+
+include $(topsrcdir)/config/rules.mk
+
+EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS)
+
+
diff --git a/src/libs/xpcom18a4/xpcom/tests/dynamic/TestDynamic.cpp b/src/libs/xpcom18a4/xpcom/tests/dynamic/TestDynamic.cpp
new file mode 100644
index 00000000..a27d8ea9
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/dynamic/TestDynamic.cpp
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Suresh Duddi <dp@netscape.com>
+ * Christopher Blizzard <blizzard@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 ***** */
+
+#include <stdio.h>
+#include "TestFactory.h"
+#include "nsIGenericFactory.h"
+
+/**
+ * ITestClass implementation
+ */
+
+class TestDynamicClassImpl: public ITestClass {
+ NS_DECL_ISUPPORTS
+
+ TestDynamicClassImpl() {
+ }
+ void Test();
+};
+
+NS_IMPL_ISUPPORTS1(TestDynamicClassImpl, ITestClass)
+
+void TestDynamicClassImpl::Test() {
+ printf("hello, dynamic world!\n");
+}
+
+/**
+ * Generic Module
+ */
+
+NS_GENERIC_FACTORY_CONSTRUCTOR(TestDynamicClassImpl)
+
+static const nsModuleComponentInfo components[] =
+{
+ { "Test Dynamic", NS_TESTLOADEDFACTORY_CID, NS_TESTLOADEDFACTORY_CONTRACTID,
+ TestDynamicClassImplConstructor
+ }
+};
+
+NS_IMPL_NSGETMODULE(nsTestDynamicModule, components)
+
diff --git a/src/libs/xpcom18a4/xpcom/tests/dynamic/win32.order b/src/libs/xpcom18a4/xpcom/tests/dynamic/win32.order
new file mode 100644
index 00000000..bf181a81
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/dynamic/win32.order
@@ -0,0 +1 @@
+_NSGetModule ; 1
diff --git a/src/libs/xpcom18a4/xpcom/tests/nsIFileEnumerator.cpp b/src/libs/xpcom18a4/xpcom/tests/nsIFileEnumerator.cpp
new file mode 100644
index 00000000..a5f3551d
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/nsIFileEnumerator.cpp
@@ -0,0 +1,95 @@
+#include "nsILocalFile.h"
+#include "nsDependentString.h"
+#include "nsString.h"
+
+#include <stdio.h>
+#include "nsIComponentRegistrar.h"
+#include "nsIComponentManager.h"
+#include "nsIServiceManager.h"
+#include "nsMemory.h"
+#include "nsXPIDLString.h"
+#include "nsISimpleEnumerator.h"
+
+
+PRBool LoopInDir(nsILocalFile* file)
+{
+ nsresult rv;
+ nsCOMPtr<nsISimpleEnumerator> entries;
+ rv = file->GetDirectoryEntries(getter_AddRefs(entries));
+ if(NS_FAILED(rv) || !entries)
+ return PR_FALSE;
+
+ PRBool hasMore;
+ while(NS_SUCCEEDED(entries->HasMoreElements(&hasMore)) && hasMore)
+ {
+ nsCOMPtr<nsISupports> sup;
+ entries->GetNext(getter_AddRefs(sup));
+ if(!sup)
+ return PR_FALSE;
+
+ nsCOMPtr<nsILocalFile> file = do_QueryInterface(sup);
+ if(!file)
+ return PR_FALSE;
+
+ nsCAutoString name;
+ if(NS_FAILED(file->GetNativeLeafName(name)))
+ return PR_FALSE;
+
+ PRBool isDir;
+ printf("%s\n", name.get());
+ rv = file->IsDirectory(&isDir);
+ if (NS_FAILED(rv))
+ {
+ printf("IsDirectory Failed!!!\n");
+ return PR_FALSE;
+ }
+
+ if (isDir == PR_TRUE)
+ {
+ nsCOMPtr<nsILocalFile> lfile = do_QueryInterface(file);
+ LoopInDir(lfile);
+ }
+ }
+ return PR_TRUE;
+}
+
+
+int
+main(int argc, char* argv[])
+{
+ nsresult rv;
+ {
+ nsCOMPtr<nsILocalFile> topDir;
+
+ nsCOMPtr<nsIServiceManager> servMan;
+ rv = NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull);
+ if (NS_FAILED(rv)) return -1;
+ nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan);
+ NS_ASSERTION(registrar, "Null nsIComponentRegistrar");
+ if (registrar)
+ registrar->AutoRegister(nsnull);
+
+ if (argc > 1 && argv[1] != nsnull)
+ {
+ char* pathStr = argv[1];
+ NS_NewNativeLocalFile(nsDependentCString(pathStr), PR_FALSE, getter_AddRefs(topDir));
+ }
+
+ if (!topDir)
+ {
+ printf("No Top Dir\n");
+ return -1;
+ }
+ PRInt32 startTime = PR_IntervalNow();
+
+ LoopInDir(topDir);
+
+ PRInt32 endTime = PR_IntervalNow();
+
+ printf("\nTime: %d\n", PR_IntervalToMilliseconds(endTime - startTime));
+ } // this scopes the nsCOMPtrs
+ // no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
+ rv = NS_ShutdownXPCOM(nsnull);
+ NS_ASSERTION(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");
+ return 0;
+}
diff --git a/src/libs/xpcom18a4/xpcom/tests/nsIFileTest.cpp b/src/libs/xpcom18a4/xpcom/tests/nsIFileTest.cpp
new file mode 100644
index 00000000..1dd2cd54
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/nsIFileTest.cpp
@@ -0,0 +1,475 @@
+#include "nsILocalFile.h"
+#if 0 /* too new */
+#include "nsStringGlue.h"
+#else
+#include "nsString.h"
+#endif
+
+#include <stdio.h>
+#include "nsXPCOM.h"
+#include "nsIComponentManager.h"
+#include "nsIComponentRegistrar.h"
+#include "nsIServiceManager.h"
+#include "nsIMemory.h"
+
+#include "nsComponentManagerUtils.h"
+#include "nsCOMPtr.h"
+
+void Passed();
+void Failed(const char* explanation = nsnull);
+void Inspect();
+void Banner(const char* bannerString);
+
+void VerifyResult(nsresult rv)
+{
+ if (NS_FAILED(rv))
+ {
+ Failed("rv failed");
+ printf("rv = %d\n", rv);
+ }
+}
+//----------------------------------------------------------------------------
+void Banner(const char* bannerString)
+//----------------------------------------------------------------------------
+{
+ printf("---------------------------\n");
+ printf("%s\n", bannerString);
+ printf("---------------------------\n");
+}
+
+//----------------------------------------------------------------------------
+void Passed()
+//----------------------------------------------------------------------------
+{
+ printf("Test passed.");
+}
+
+//----------------------------------------------------------------------------
+void Failed(const char* explanation)
+//----------------------------------------------------------------------------
+{
+ printf("ERROR : Test failed.\n");
+ printf("REASON: %s.\n", explanation);
+}
+
+//----------------------------------------------------------------------------
+void Inspect()
+//----------------------------------------------------------------------------
+{
+ printf("^^^^^^^^^^ PLEASE INSPECT OUTPUT FOR ERRORS\n");
+}
+
+void GetPaths(nsILocalFile* file)
+{
+ nsresult rv;
+ nsCAutoString pathName;
+
+ printf("Getting Path\n");
+
+ rv = file->GetNativePath(pathName);
+ VerifyResult(rv);
+
+ printf("filepath: %s\n", pathName.get());
+}
+
+void InitTest(const char* creationPath, const char* appendPath)
+{
+ nsILocalFile* file = nsnull;
+ nsresult rv = CallCreateInstance(NS_LOCAL_FILE_CONTRACTID, &file);
+
+
+ if (NS_FAILED(rv) || (!file))
+ {
+ printf("create nsILocalFile failed\n");
+ return;
+ }
+
+ nsCAutoString leafName;
+
+ Banner("InitWithPath");
+ printf("creationPath == %s\nappendPath == %s\n", creationPath, appendPath);
+
+ rv = file->InitWithNativePath(nsDependentCString(creationPath));
+ VerifyResult(rv);
+
+ printf("Getting Filename\n");
+ rv = file->GetNativeLeafName(leafName);
+ printf(" %s\n", leafName.get());
+ VerifyResult(rv);
+
+ printf("Appending %s \n", appendPath);
+ rv = file->AppendNative(nsDependentCString(appendPath));
+ VerifyResult(rv);
+
+ printf("Getting Filename\n");
+ rv = file->GetNativeLeafName(leafName);
+ printf(" %s\n", leafName.get());
+ VerifyResult(rv);
+
+ GetPaths(file);
+
+
+ printf("Check For Existence\n");
+
+ PRBool exists;
+ file->Exists(&exists);
+
+ NS_RELEASE(file);
+
+ if (exists)
+ printf("Yup!\n");
+ else
+ printf("no.\n");
+}
+
+
+void CreationTest(const char* creationPath, const char* appendPath,
+ PRInt32 whatToCreate, PRInt32 perm)
+{
+ nsresult rv;
+ nsCOMPtr<nsILocalFile> file =
+ do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
+
+ if (NS_FAILED(rv) || (!file))
+ {
+ printf("create nsILocalFile failed\n");
+ return;
+ }
+
+ Banner("Creation Test");
+ printf("creationPath == %s\nappendPath == %s\n", creationPath, appendPath);
+
+ rv = file->InitWithNativePath(nsDependentCString(creationPath));
+ VerifyResult(rv);
+
+ printf("Appending %s\n", appendPath);
+ rv = file->AppendRelativeNativePath(nsDependentCString(appendPath));
+ VerifyResult(rv);
+
+ printf("Check For Existence\n");
+
+ PRBool exists;
+ file->Exists(&exists);
+
+ if (exists)
+ printf("Yup!\n");
+ else
+ printf("no.\n");
+
+
+ rv = file->Create(whatToCreate, perm);
+ VerifyResult(rv);
+
+ rv = file->Exists(&exists);
+ VerifyResult(rv);
+
+
+ if (!exists)
+ {
+ Failed("Did not create file system object!");
+ return;
+ }
+
+}
+
+void CreateUniqueTest(const char* creationPath, const char* appendPath,
+ PRInt32 whatToCreate, PRInt32 perm)
+{
+ nsresult rv;
+ nsCOMPtr<nsILocalFile> file =
+ do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
+
+ if (NS_FAILED(rv) || (!file))
+ {
+ printf("create nsILocalFile failed\n");
+ return;
+ }
+
+ Banner("Creation Test");
+ printf("creationPath == %s\nappendPath == %s\n", creationPath, appendPath);
+
+ rv = file->InitWithNativePath(nsDependentCString(creationPath));
+ VerifyResult(rv);
+
+ printf("Appending %s\n", appendPath);
+ rv = file->AppendNative(nsDependentCString(appendPath));
+ VerifyResult(rv);
+
+ printf("Check For Existence\n");
+
+ PRBool exists;
+ file->Exists(&exists);
+
+ if (exists)
+ printf("Yup!\n");
+ else
+ printf("no.\n");
+
+
+ rv = file->CreateUnique(whatToCreate, perm);
+ VerifyResult(rv);
+
+ rv = file->Exists(&exists);
+ VerifyResult(rv);
+
+
+ if (!exists)
+ {
+ Failed("Did not create file system object!");
+ return;
+ }
+
+}
+
+
+void
+CopyTest(const char *testFile, const char *targetDir)
+{
+ printf("start copy test\n");
+
+ nsresult rv;
+ nsCOMPtr<nsILocalFile> file =
+ do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
+
+ if (NS_FAILED(rv) || (!file))
+ {
+ printf("create nsILocalFile failed\n");
+ return;
+ }
+
+ rv = file->InitWithNativePath(nsDependentCString(testFile));
+ VerifyResult(rv);
+
+ nsCOMPtr<nsILocalFile> dir =
+ do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
+
+ if (NS_FAILED(rv) || (!dir))
+ {
+ printf("create nsILocalFile failed\n");
+ return;
+ }
+
+ rv = dir->InitWithNativePath(nsDependentCString(targetDir));
+ VerifyResult(rv);
+
+ rv = file->CopyTo(dir, EmptyString());
+ VerifyResult(rv);
+
+ printf("end copy test\n");
+}
+
+void
+DeletionTest(const char* creationPath, const char* appendPath, PRBool recursive)
+{
+ nsresult rv;
+ nsCOMPtr<nsILocalFile> file =
+ do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
+
+ if (NS_FAILED(rv) || (!file))
+ {
+ printf("create nsILocalFile failed\n");
+ return;
+ }
+
+ Banner("Deletion Test");
+ printf("creationPath == %s\nappendPath == %s\n", creationPath, appendPath);
+
+ rv = file->InitWithNativePath(nsDependentCString(creationPath));
+ VerifyResult(rv);
+
+ printf("Appending %s\n", appendPath);
+ rv = file->AppendNative(nsDependentCString(appendPath));
+ VerifyResult(rv);
+
+ printf("Check For Existance\n");
+
+ PRBool exists;
+ file->Exists(&exists);
+
+ if (exists)
+ printf("Yup!\n");
+ else
+ printf("no.\n");
+
+ rv = file->Remove(recursive);
+ VerifyResult(rv);
+
+ rv = file->Exists(&exists);
+ VerifyResult(rv);
+
+ if (exists)
+ {
+ Failed("Did not create delete system object!");
+ return;
+ }
+
+}
+
+void
+MoveTest(const char *testFile, const char *targetDir)
+{
+ Banner("Move Test");
+
+ printf("start move test\n");
+
+ nsresult rv;
+ nsCOMPtr<nsILocalFile> file(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
+
+ if (!file)
+ {
+ printf("create nsILocalFile failed\n");
+ return;
+ }
+
+ rv = file->InitWithNativePath(nsDependentCString(testFile));
+ VerifyResult(rv);
+
+ nsCOMPtr<nsILocalFile> dir(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
+
+ if (!dir)
+ {
+ printf("create nsILocalFile failed\n");
+ return;
+ }
+
+ rv = dir->InitWithNativePath(nsDependentCString(targetDir));
+ VerifyResult(rv);
+
+ rv = file->MoveToNative(dir, NS_LITERAL_CSTRING("newtemp"));
+ VerifyResult(rv);
+ if (NS_FAILED(rv))
+ {
+ printf("MoveToNative() test Failed.\n");
+ }
+ printf("end move test\n");
+}
+
+// move up the number of directories in moveUpCount, then append "foo/bar"
+void
+NormalizeTest(const char *testPath, int moveUpCount,
+ const char *expected)
+{
+ Banner("Normalize Test");
+
+ nsresult rv;
+ nsCOMPtr<nsILocalFile> file(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
+
+ if (!file)
+ {
+ printf("create nsILocalFile failed\n");
+ return;
+ }
+
+ rv = file->InitWithNativePath(nsDependentCString(testPath));
+ VerifyResult(rv);
+
+ nsCOMPtr<nsIFile> parent;
+ nsAutoString path;
+ for (int i=0; i < moveUpCount; i++)
+ {
+ rv = file->GetParent(getter_AddRefs(parent));
+ VerifyResult(rv);
+ rv = parent->GetPath(path);
+ VerifyResult(rv);
+ rv = file->InitWithPath(path);
+ VerifyResult(rv);
+ }
+
+ if (!parent) {
+ printf("Getting parent failed!\n");
+ return;
+ }
+
+ rv = parent->Append(NS_LITERAL_STRING("foo"));
+ VerifyResult(rv);
+ rv = parent->Append(NS_LITERAL_STRING("bar"));
+ VerifyResult(rv);
+
+ rv = parent->Normalize();
+ VerifyResult(rv);
+
+ nsCAutoString newPath;
+ rv = parent->GetNativePath(newPath);
+ VerifyResult(rv);
+
+ nsCOMPtr<nsILocalFile>
+ expectedFile(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
+
+ if (!expectedFile)
+ {
+ printf("create nsILocalFile failed\n");
+ return;
+ }
+ rv = expectedFile->InitWithNativePath(nsDependentCString(expected));
+ VerifyResult(rv);
+
+ rv = expectedFile->Normalize();
+ VerifyResult(rv);
+
+ nsCAutoString expectedPath;
+ rv = expectedFile->GetNativePath(expectedPath);
+ VerifyResult(rv);
+
+ if (!newPath.Equals(expectedPath)) {
+ printf("ERROR: Normalize() test Failed!\n");
+ printf(" Got: %s\n", newPath.get());
+ printf("Expected: %s\n", expectedPath.get());
+ }
+
+ printf("end normalize test.\n");
+}
+
+int main(void)
+{
+ nsCOMPtr<nsIServiceManager> servMan;
+ NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull);
+ nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan);
+ NS_ASSERTION(registrar, "Null nsIComponentRegistrar");
+ registrar->AutoRegister(nsnull);
+
+#if defined(XP_WIN) || defined(XP_OS2)
+ InitTest("c:\\temp\\", "sub1/sub2/"); // expect failure
+ InitTest("d:\\temp\\", "sub1\\sub2\\"); // expect failure
+
+ CreationTest("c:\\temp\\", "file.txt", nsIFile::NORMAL_FILE_TYPE, 0644);
+ DeletionTest("c:\\temp\\", "file.txt", PR_FALSE);
+
+ MoveTest("c:\\newtemp\\", "d:");
+
+ CreationTest("c:\\temp\\", "mumble\\a\\b\\c\\d\\e\\f\\g\\h\\i\\j\\k\\", nsIFile::DIRECTORY_TYPE, 0644);
+ DeletionTest("c:\\temp\\", "mumble", PR_TRUE);
+
+ CreateUniqueTest("c:\\temp\\", "foo", nsIFile::NORMAL_FILE_TYPE, 0644);
+ CreateUniqueTest("c:\\temp\\", "foo", nsIFile::NORMAL_FILE_TYPE, 0644);
+ CreateUniqueTest("c:\\temp\\", "bar.xx", nsIFile::DIRECTORY_TYPE, 0644);
+ CreateUniqueTest("c:\\temp\\", "bar.xx", nsIFile::DIRECTORY_TYPE, 0644);
+ DeletionTest("c:\\temp\\", "foo", PR_TRUE);
+ DeletionTest("c:\\temp\\", "foo-1", PR_TRUE);
+ DeletionTest("c:\\temp\\", "bar.xx", PR_TRUE);
+ DeletionTest("c:\\temp\\", "bar-1.xx", PR_TRUE);
+
+#else
+#ifdef XP_UNIX
+ InitTest("/tmp/", "sub1/sub2/"); // expect failure
+
+ CreationTest("/tmp", "file.txt", nsIFile::NORMAL_FILE_TYPE, 0644);
+ DeletionTest("/tmp/", "file.txt", PR_FALSE);
+
+ CreationTest("/tmp", "mumble/a/b/c/d/e/f/g/h/i/j/k/", nsIFile::DIRECTORY_TYPE, 0644);
+ DeletionTest("/tmp", "mumble", PR_TRUE);
+
+ CreationTest("/tmp", "file", nsIFile::NORMAL_FILE_TYPE, 0644);
+ CopyTest("/tmp/file", "/tmp/newDir");
+ MoveTest("/tmp/file", "/tmp/newDir/anotherNewDir");
+ DeletionTest("/tmp", "newDir", PR_TRUE);
+
+ CreationTest("/tmp", "qux/quux", nsIFile::NORMAL_FILE_TYPE, 0644);
+ CreationTest("/tmp", "foo/bar", nsIFile::NORMAL_FILE_TYPE, 0644);
+ NormalizeTest("/tmp/qux/quux/..", 1, "/tmp/foo/bar");
+ DeletionTest("/tmp", "qux", PR_TRUE);
+ DeletionTest("/tmp", "foo", PR_TRUE);
+
+#endif /* XP_UNIX */
+#endif /* XP_WIN || XP_OS2 */
+ return 0;
+}
diff --git a/src/libs/xpcom18a4/xpcom/tests/resources.h b/src/libs/xpcom18a4/xpcom/tests/resources.h
new file mode 100644
index 00000000..b82df25e
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/resources.h
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Chris Waterson <waterson@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#ifndef resources_h___
+#define resources_h___
+
+#define TIMER_1SECOND 40000
+#define TIMER_5SECOND 40001
+#define TIMER_10SECOND 40002
+
+#define TIMER_1REPEAT 40003
+#define TIMER_5REPEAT 40004
+#define TIMER_10REPEAT 40005
+
+#define TIMER_CANCEL 40006
+#define TIMER_EXIT 40010
+
+#endif /* resources_h___ */
diff --git a/src/libs/xpcom18a4/xpcom/tests/services/.cvsignore b/src/libs/xpcom18a4/xpcom/tests/services/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/services/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/xpcom/tests/services/Makefile.in b/src/libs/xpcom18a4/xpcom/tests/services/Makefile.in
new file mode 100644
index 00000000..84cd3c84
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/services/Makefile.in
@@ -0,0 +1,58 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# 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 = xpcom
+IS_COMPONENT = 1
+MODULE_NAME = MyService
+LIBRARY_NAME = MyService
+SHORT_LIBNAME = MyServce
+
+CPPSRCS = MyService.cpp
+
+LOCAL_INCLUDES = -I$(srcdir)/..
+
+EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS)
+
+include $(topsrcdir)/config/rules.mk
+
diff --git a/src/libs/xpcom18a4/xpcom/tests/services/MyService.cpp b/src/libs/xpcom18a4/xpcom/tests/services/MyService.cpp
new file mode 100644
index 00000000..aec78449
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/services/MyService.cpp
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Pierre Phaneuf <pp@ludusdesign.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "MyService.h"
+#include "nsIServiceManager.h"
+#include "nsIGenericFactory.h"
+#include <stdio.h>
+
+////////////////////////////////////////////////////////////////////////////////
+
+class MyService : public IMyService {
+public:
+
+ NS_IMETHOD
+ Doit(void);
+
+ MyService();
+ NS_DECL_ISUPPORTS
+
+private:
+ ~MyService();
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// MyService Implementation
+
+NS_IMPL_ISUPPORTS1(MyService, IMyService)
+
+MyService::MyService()
+{
+ printf(" creating my service\n");
+}
+
+MyService::~MyService()
+{
+ printf(" destroying my service\n");
+}
+
+nsresult
+MyService::Doit(void)
+{
+ printf(" invoking my service\n");
+ return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// MyServiceFactory Implementation
+
+NS_GENERIC_FACTORY_CONSTRUCTOR(MyService)
+
+static const nsModuleComponentInfo myService_components[] = {
+ { "MyService", NS_IMYSERVICE_CID, nsnull, MyServiceConstructor },
+};
+
+NS_IMPL_NSGETMODULE(MyService, myService_components)
+
+
+
diff --git a/src/libs/xpcom18a4/xpcom/tests/services/MyService.h b/src/libs/xpcom18a4/xpcom/tests/services/MyService.h
new file mode 100644
index 00000000..30b0e30a
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/services/MyService.h
@@ -0,0 +1,69 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Pierre Phaneuf <pp@ludusdesign.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef MyService_h__
+#define MyService_h__
+
+#include "nsISupports.h"
+
+#define NS_IMYSERVICE_IID \
+{ /* fedc3380-3648-11d2-8163-006008119d7a */ \
+ 0xfedc3380, \
+ 0x3648, \
+ 0x11d2, \
+ {0x81, 0x63, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
+}
+
+class IMyService : public nsISupports {
+public:
+ NS_DEFINE_STATIC_IID_ACCESSOR(NS_IMYSERVICE_IID)
+
+ NS_IMETHOD
+ Doit(void) = 0;
+
+};
+
+#define NS_IMYSERVICE_CID \
+{ /* 34876550-364b-11d2-8163-006008119d7a */ \
+ 0x34876550, \
+ 0x364b, \
+ 0x11d2, \
+ {0x81, 0x63, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \
+}
+
+#endif // MyService_h__
diff --git a/src/libs/xpcom18a4/xpcom/tests/services/win32.order b/src/libs/xpcom18a4/xpcom/tests/services/win32.order
new file mode 100644
index 00000000..132a4357
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/services/win32.order
@@ -0,0 +1 @@
+_NSCanUnload ; 1
diff --git a/src/libs/xpcom18a4/xpcom/tests/test.properties b/src/libs/xpcom18a4/xpcom/tests/test.properties
new file mode 100644
index 00000000..4ed37783
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/test.properties
@@ -0,0 +1,46 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# 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 *****
+1=1
+ 2=2
+3 =3
+ 4 =4
+5=5
+6= 6
+7=7
+8= 8
+# this is a comment
+9=this is the first part of a continued line \
+ and here is the 2nd part
diff --git a/src/libs/xpcom18a4/xpcom/tests/utils/WhatError.cpp b/src/libs/xpcom18a4/xpcom/tests/utils/WhatError.cpp
new file mode 100644
index 00000000..13942f3b
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/utils/WhatError.cpp
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 "nsError.h"
+#include <stdlib.h>
+#include <stdio.h>
+
+int
+main(int argc, char **argv)
+{
+ int errorCode = 0;
+ char buffer[100];
+
+ if (argc != 2)
+ return -1;
+
+ sscanf( argv[1], "0x%x", &errorCode);
+ sprintf(buffer, "%d", errorCode);
+ sscanf( buffer, "%d", &errorCode);
+
+ printf( "Code: %d, Module: %d, Severity: %d\n",
+ NS_ERROR_GET_CODE(errorCode),
+ NS_ERROR_GET_MODULE(errorCode),
+ NS_ERROR_GET_SEVERITY(errorCode));
+
+ return 0;
+}
diff --git a/src/libs/xpcom18a4/xpcom/tests/utils/cp.js b/src/libs/xpcom18a4/xpcom/tests/utils/cp.js
new file mode 100644
index 00000000..a38c120b
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/utils/cp.js
@@ -0,0 +1,111 @@
+const nsILocalFile = Components.interfaces.nsILocalFile;
+var prefix = "";
+
+function rename(source, newName)
+{
+ try {
+ var sourceFile = Components.classes["@mozilla.org/file/local;1"].
+ createInstance(nsILocalFile);
+ sourceFile.initWithPath(source);
+
+ }
+ catch (e) {
+ dump("Could not create nsILocalFile\n");
+ }
+
+
+ try {
+ sourceFile.copyTo(null, newName);
+ }
+ catch (e) {
+ dump("error coping" + e + "\n");
+ }
+}
+
+
+function cp(source, dest, followLinks, newName)
+{
+ try {
+ var sourceFile = Components.classes["@mozilla.org/file/local;1"].
+ createInstance(nsILocalFile);
+ sourceFile.initWithPath(source);
+
+ var destFile = Components.classes["@mozilla.org/file/local;1"].
+ createInstance(nsILocalFile);
+ destFile.initWithPath(dest);
+
+ }
+ catch (e) {
+ dump("Could not create nsILocalFile\n");
+ }
+
+ try {
+
+ if (! destFile.isDirectory())
+ {
+ dump("destination not a directory!\n");
+ return;
+ }
+ }
+ catch (e) {
+ dump("error accessing dest");
+ }
+
+ try {
+ if (followLinks)
+ {
+ sourceFile.copyToFollowingLinks(destFile, newName);
+ }
+ else
+ {
+ sourceFile.copyTo(destFile, newName);
+ }
+ }
+ catch (e) {
+ dump("error coping" + e + "\n");
+ }
+}
+
+
+function mv(source, dest, followLinks, newName)
+{
+ try {
+ var sourceFile = Components.classes["@mozilla.org/file/local;1"].
+ createInstance(nsILocalFile);
+ sourceFile.initWithPath(source);
+
+ var destFile = Components.classes["@mozilla.org/file/local;1"].
+ createInstance(nsILocalFile);
+ destFile.initWithPath(dest);
+
+ }
+ catch (e) {
+ dump("Could not create nsILocalFile\n");
+ }
+
+ try {
+
+ if (! destFile.isDirectory())
+ {
+ dump("destination not a directory!\n");
+ return;
+ }
+ }
+ catch (e) {
+ dump("error accessing dest");
+ }
+
+ try {
+ if (followLinks)
+ {
+ sourceFile.moveToFollowingLinks(destFile, newName);
+ }
+ else
+ {
+ sourceFile.moveTo(destFile, newName);
+ }
+ }
+ catch (e) {
+ dump("error coping" + e + "\n");
+ }
+}
diff --git a/src/libs/xpcom18a4/xpcom/tests/utils/dirs.js b/src/libs/xpcom18a4/xpcom/tests/utils/dirs.js
new file mode 100644
index 00000000..c3fc2479
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/utils/dirs.js
@@ -0,0 +1,155 @@
+function dumpPathOfProperty(prop)
+{
+ dump(prop +' = ');
+
+ try
+ {
+ var file = dsprops.get(prop, Components.interfaces.nsIFile);
+ dump(file.path + '\n');
+ }
+ catch (ar)
+ {
+ dump('undefined or error \n');
+ }
+}
+
+var dscontractid = "@mozilla.org/file/directory_service;1"; // XXX old-style
+var ds = Components.classes[dscontractid].getService();
+var dsprops = ds.QueryInterface(Components.interfaces.nsIProperties);
+
+dump("xpcom locations::\n");
+// XPCOM Locations:
+ dumpPathOfProperty ("xpcom.currentProcess");
+ dumpPathOfProperty ("xpcom.currentProcess.componentRegistry");
+ dumpPathOfProperty ("xpcom.currentProcess.componentDirectory");
+ dumpPathOfProperty ("system.OS_DriveDirectory");
+ dumpPathOfProperty ("system.OS_TemporaryDirectory");
+ dumpPathOfProperty ("system.OS_CurrentProcessDirectory");
+ dumpPathOfProperty ("system.OS_CurrentWorkingDirectory");
+
+dump("Mac locations::\n");
+// Mac
+ dumpPathOfProperty ("system.SystemDirectory");
+ dumpPathOfProperty ("system.DesktopDirectory");
+ dumpPathOfProperty ("system.TrashDirectory");
+ dumpPathOfProperty ("system.StartupDirectory");
+ dumpPathOfProperty ("system.ShutdownDirectory");
+ dumpPathOfProperty ("system.AppleMenuDirectory");
+ dumpPathOfProperty ("system.ControlPanelDirectory");
+ dumpPathOfProperty ("system.ExtensionDirectory");
+ dumpPathOfProperty ("system.FontsDirectory");
+ dumpPathOfProperty ("system.PreferencesDirectory");
+ dumpPathOfProperty ("system.DocumentsDirectory");
+ dumpPathOfProperty ("system.InternetSearchDirectory");
+
+dump("PC locations::\n");
+// PC
+ dumpPathOfProperty ("system.SystemDirectory");
+ dumpPathOfProperty ("system.WindowsDirectory");
+ dumpPathOfProperty ("system.HomeDirectory");
+ dumpPathOfProperty ("system.Desktop");
+ dumpPathOfProperty ("system.Programs");
+ dumpPathOfProperty ("system.Controls");
+ dumpPathOfProperty ("system.Printers");
+ dumpPathOfProperty ("system.Personal");
+ dumpPathOfProperty ("system.Favorites");
+ dumpPathOfProperty ("system.Startup");
+ dumpPathOfProperty ("system.Recent");
+ dumpPathOfProperty ("system.Sendto");
+ dumpPathOfProperty ("system.Bitbucket");
+ dumpPathOfProperty ("system.Startmenu");
+ dumpPathOfProperty ("system.Desktopdirectory");
+ dumpPathOfProperty ("system.Drives");
+ dumpPathOfProperty ("system.Network");
+ dumpPathOfProperty ("system.Nethood");
+ dumpPathOfProperty ("system.Fonts");
+ dumpPathOfProperty ("system.Templates");
+ dumpPathOfProperty ("system.Common_Startmenu");
+ dumpPathOfProperty ("system.Common_Programs");
+ dumpPathOfProperty ("system.Common_Startup");
+ dumpPathOfProperty ("system.Common_Desktopdirectory");
+ dumpPathOfProperty ("system.Appdata");
+ dumpPathOfProperty ("system.Printhood");
+
+dump("Unix locations::\n");
+// Unix
+
+ dumpPathOfProperty ("system.LocalDirectory");
+ dumpPathOfProperty ("system.LibDirectory");
+ dumpPathOfProperty ("system.HomeDirectory");
+
+dump("Beos locations::\n");
+// Beos
+
+ dumpPathOfProperty ("system.SettingsDirectory");
+ dumpPathOfProperty ("system.HomeDirectory");
+ dumpPathOfProperty ("system.DesktopDirectory");
+ dumpPathOfProperty ("system.SystemDirectory");
+
+dump("OS2 locations::\n");
+// OS2
+ dumpPathOfProperty ("system.SystemDirectory");
+ dumpPathOfProperty ("system.OS2Directory");
+ dumpPathOfProperty ("system.DesktopDirectory");
+
+
+// XPFE locations:
+
+
+// application Directories:
+ dumpPathOfProperty ("app.res.directory");
+ dumpPathOfProperty ("app.defaults.directory");
+ dumpPathOfProperty ("app.chrome.directory");
+ dumpPathOfProperty ("app.chrome.user.directory");
+ dumpPathOfProperty ("app.plugins.directory");
+
+// application Files:
+
+ dumpPathOfProperty ("app.registry.file.4");
+ dumpPathOfProperty ("app.registry.file.5");
+ dumpPathOfProperty ("app.local.store.file.5");
+ dumpPathOfProperty ("app.history.file.5");
+ dumpPathOfProperty ("app.user.panels.5");
+
+// Preferences:
+
+// dumpPathOfProperty ("app.prefs.directory.3");
+// dumpPathOfProperty ("app.prefs.directory.4");
+ dumpPathOfProperty ("app.prefs.directory.5");
+ dumpPathOfProperty ("app.pref.default.directory.5");
+
+// dumpPathOfProperty ("app.prefs.file.3");
+// dumpPathOfProperty ("app.prefs.file.4");
+ dumpPathOfProperty ("app.prefs.file.5");
+
+// Profile:
+
+// dumpPathOfProperty ("app.profile.user.directory.3");
+// dumpPathOfProperty ("app.profile.user.directory.4");
+ dumpPathOfProperty ("app.profile.user.directory.5");
+// dumpPathOfProperty ("app.profile.default.user.directory.3");
+// dumpPathOfProperty ("app.profile.default.user.directory.4");
+ dumpPathOfProperty ("app.profile.default.user.directory.5");
+// dumpPathOfProperty ("app.profile.defaults.directory.3");
+// dumpPathOfProperty ("app.profile.defaults.directory.4");
+ dumpPathOfProperty ("app.profile.defaults.directory.5");
+
+
+
+// Bookmarks:
+
+// dumpPathOfProperty ("app.bookmark.file.3");
+// dumpPathOfProperty ("app.bookmark.file.4");
+ dumpPathOfProperty ("app.bookmark.file.5");
+
+// Search
+ dumpPathOfProperty ("app.search.file.5");
+ dumpPathOfProperty ("app.search.directory.5");
+
+
+// MailNews:
+
+ dumpPathOfProperty ("app.mail.directory.5");
+ dumpPathOfProperty ("app.mail.imap.directory.5");
+ dumpPathOfProperty ("app.mail.news.directory.5");
+ dumpPathOfProperty ("app.mail.messenger.cache.directory.5");
diff --git a/src/libs/xpcom18a4/xpcom/tests/utils/ls.js b/src/libs/xpcom18a4/xpcom/tests/utils/ls.js
new file mode 100644
index 00000000..8ae62f06
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/utils/ls.js
@@ -0,0 +1,64 @@
+const nsILocalFile = Components.interfaces.nsILocalFile;
+var prefix = "";
+
+function ls(path, recur)
+{
+ var file = Components.classes["@mozilla.org/file/local;1"].
+ createInstance(nsILocalFile);
+ try {
+ file.initWithPath( path );
+
+ if (file.isDirectory() && arguments.length == 1)
+ ls_dir(file, recur);
+ else
+ ls_file(file, recur);
+ }
+ catch (e) {
+ dump("Error Returned " + e + "\n");
+ }
+}
+function ls_file(file, recur)
+{
+ dump(prefix);
+
+ try {
+ if (file.isDirectory()) {
+ dump("directory " + file.leafName + "\n");
+ if(recur)
+ ls_dir(file, true);
+ return;
+ }
+
+ dump(file.leafName + " " + file.fileSize);
+ if (file.isSymlink())
+ dump(" -> " + file.target);
+ dump("\n");
+ }
+
+ catch (e) {
+ dump(file.leafName + " (error accessing)\n");
+ }
+}
+
+function ls_dir(file, recur)
+{
+ var leafName = file.leafName;
+
+ var old = prefix;
+ prefix = prefix + " ";
+
+ iter = file.directoryEntries;
+ dump(iter + "\n");
+
+ foreach_iter(iter,
+ function (file) { ls_file(file, recur); });
+ prefix = old;
+}
+
+function foreach_iter(iter, fun)
+{
+ while (iter.hasMoreElements()) {
+ var item = iter.getNext().QueryInterface(nsILocalFile);
+ fun(item);
+ }
+}
diff --git a/src/libs/xpcom18a4/xpcom/tests/windows/.cvsignore b/src/libs/xpcom18a4/xpcom/tests/windows/.cvsignore
new file mode 100644
index 00000000..f3c7a7c5
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/windows/.cvsignore
@@ -0,0 +1 @@
+Makefile
diff --git a/src/libs/xpcom18a4/xpcom/tests/windows/Makefile.in b/src/libs/xpcom18a4/xpcom/tests/windows/Makefile.in
new file mode 100644
index 00000000..8bd782c8
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/windows/Makefile.in
@@ -0,0 +1,60 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2001
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# 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 = xpcom
+
+REQUIRES = string
+
+CPPSRCS = TestCOM.cpp
+#TestHelloXPLoop.cpp nsStringTest.cpp
+
+SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=$(BIN_SUFFIX))
+
+include $(topsrcdir)/config/config.mk
+
+include $(topsrcdir)/config/rules.mk
+
+OS_LIBS = $(call EXPAND_LIBNAME,rpcrt4 uuid)
+
+LIBS = $(XPCOM_LIBS) $(NSPR_LIBS)
diff --git a/src/libs/xpcom18a4/xpcom/tests/windows/TestCOM.cpp b/src/libs/xpcom18a4/xpcom/tests/windows/TestCOM.cpp
new file mode 100644
index 00000000..b76eccb4
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/windows/TestCOM.cpp
@@ -0,0 +1,181 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Pierre Phaneuf <pp@ludusdesign.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <windows.h>
+#include <unknwn.h>
+#include <stdio.h>
+#include "nsISupports.h"
+#include "nsIFactory.h"
+
+// unknwn.h is needed to build with WIN32_LEAN_AND_MEAN
+#include <unknwn.h>
+
+// {5846BA30-B856-11d1-A98A-00805F8A7AC4}
+#define NS_ITEST_COM_IID \
+{ 0x5846ba30, 0xb856, 0x11d1, \
+ { 0xa9, 0x8a, 0x0, 0x80, 0x5f, 0x8a, 0x7a, 0xc4 } }
+
+class nsITestCom: public nsISupports
+{
+public:
+ NS_DEFINE_STATIC_IID_ACCESSOR(NS_ITEST_COM_IID)
+ NS_IMETHOD Test() = 0;
+};
+
+/*
+ * nsTestCom
+ */
+
+class nsTestCom: public nsITestCom {
+ NS_DECL_ISUPPORTS
+
+public:
+ nsTestCom() {
+ }
+
+ NS_IMETHOD Test() {
+ printf("Accessed nsITestCom::Test() from COM\n");
+ return NS_OK;
+ }
+
+private:
+ ~nsTestCom() {
+ printf("nsTestCom instance successfully deleted\n");
+ }
+};
+
+NS_IMPL_QUERY_INTERFACE1(nsTestCom, nsITestCom)
+
+nsrefcnt nsTestCom::AddRef()
+{
+ nsrefcnt res = ++mRefCnt;
+ NS_LOG_ADDREF(this, mRefCnt, "nsTestCom", sizeof(*this));
+ printf("nsTestCom: Adding ref = %d\n", res);
+ return res;
+}
+
+nsrefcnt nsTestCom::Release()
+{
+ nsrefcnt res = --mRefCnt;
+ NS_LOG_RELEASE(this, mRefCnt, "nsTestCom");
+ printf("nsTestCom: Releasing = %d\n", res);
+ if (res == 0) {
+ delete this;
+ }
+ return res;
+}
+
+class nsTestComFactory: public nsIFactory {
+ NS_DECL_ISUPPORTS
+public:
+ nsTestComFactory() {
+ }
+
+ NS_IMETHOD CreateInstance(nsISupports *aOuter,
+ const nsIID &aIID,
+ void **aResult);
+
+ NS_IMETHOD LockFactory(PRBool aLock) {
+ printf("nsTestComFactory: ");
+ printf("%s", (aLock == PR_TRUE ? "Locking server" : "Unlocking server"));
+ printf("\n");
+ return S_OK;
+ }
+};
+
+NS_IMPL_ISUPPORTS1(nsTestComFactory, nsIFactory)
+
+nsresult nsTestComFactory::CreateInstance(nsISupports *aOuter,
+ const nsIID &aIID,
+ void **aResult)
+{
+ if (aOuter != NULL) {
+ return NS_ERROR_NO_AGGREGATION;
+ }
+
+ nsTestCom *t = new nsTestCom();
+
+ if (t == NULL) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ NS_ADDREF(t);
+ nsresult res = t->QueryInterface(aIID, aResult);
+ NS_RELEASE(t);
+
+ if (NS_SUCCEEDED(res)) {
+ printf("nsTestComFactory: successfully created nsTestCom instance\n");
+ }
+
+ return res;
+}
+
+/*
+ * main
+ */
+
+int main(int argc, char *argv[])
+{
+ nsTestComFactory *inst = new nsTestComFactory();
+ IClassFactory *iFactory;
+ inst->QueryInterface(NS_GET_IID(nsIFactory), (void **) &iFactory);
+
+ IUnknown *iUnknown;
+ nsITestCom *iTestCom;
+
+ nsresult res;
+ iFactory->LockServer(TRUE);
+ res = iFactory->CreateInstance(NULL,
+ IID_IUnknown,
+ (void **) &iUnknown);
+ iFactory->LockServer(FALSE);
+
+ GUID testGUID = NS_ITEST_COM_IID;
+ HRESULT hres;
+ hres= iUnknown->QueryInterface(testGUID,
+ (void **) &iTestCom);
+
+ iTestCom->Test();
+
+ iUnknown->Release();
+ iTestCom->Release();
+ iFactory->Release();
+
+ return 0;
+}
+
diff --git a/src/libs/xpcom18a4/xpcom/tests/windows/TestHelloXPLoop.cpp b/src/libs/xpcom18a4/xpcom/tests/windows/TestHelloXPLoop.cpp
new file mode 100644
index 00000000..fdfa1218
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/windows/TestHelloXPLoop.cpp
@@ -0,0 +1,177 @@
+/* -*- Mode: C++; tab-width: 4; 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 the Mozilla browser.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications, Inc.
+ * Portions created by the Initial Developer are Copyright (C) 1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Travis Bogard <travis@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsIServiceManager.h"
+#include "nsCOMPtr.h"
+#include "nsCNativeApp.h"
+#include "nsIEventLoop.h"
+#include <windows.h>
+
+static NS_DEFINE_CID(kNativeAppCID, NS_NATIVE_APP_CID);
+
+LRESULT CALLBACK WndProc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+void ErrorBox(LPSTR text)
+{
+ MessageBox(NULL, text, "XP Event Loop", MB_OK | MB_ICONSTOP);
+}
+
+void InfoBox(LPSTR text)
+{
+ MessageBox(NULL, text, "XP Event Loop", MB_OK | MB_ICONINFORMATION);
+}
+
+int WINAPI WinMain(HINSTANCE inst,
+ HINSTANCE prevInstance,
+ LPSTR lpszCmdLine,
+ int nShowCmd)
+{
+ char* lpszAppName = "HelloWorld";
+ HWND wnd;
+ WNDCLASSEX wndclass;
+ int retCode;
+
+ { // Needed to scope all nsCOMPtr within XPCOM Init and Shutdown
+ nsresult rv;
+ nsCOMPtr<nsIServiceManager> servMan;
+ rv = NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull);
+ if(NS_FAILED(rv))
+ {
+ ErrorBox("Failed to initalize xpcom.");
+ return -1;
+ }
+
+ nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan);
+ NS_ASSERTION(registrar, "Null nsIComponentRegistrar");
+ registrar->AutoRegister(nsnull);
+
+ nsCOMPtr<nsINativeApp> nativeAppService(do_GetService(kNativeAppCID, &rv));
+
+ if(NS_FAILED(rv))
+ {
+ ErrorBox("Failed to get nativeAppService");
+ return -1;
+ }
+ wndclass.cbSize = sizeof(wndclass);
+ wndclass.style = CS_HREDRAW | CS_VREDRAW;
+ wndclass.lpfnWndProc = WndProc;
+ wndclass.cbClsExtra = 0;
+ wndclass.cbWndExtra = 0;
+ wndclass.hInstance = inst;
+ wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
+ wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
+ wndclass.lpszMenuName = NULL;
+ wndclass.lpszClassName = lpszAppName;
+ wndclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
+
+ RegisterClassEx(&wndclass) ;
+
+ wnd = CreateWindow(lpszAppName, "The Hello World",
+ WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ CW_USEDEFAULT, CW_USEDEFAULT,
+ NULL, NULL, inst, NULL);
+
+ ShowWindow(wnd, nShowCmd);
+ UpdateWindow(wnd);
+
+ nsCOMPtr<nsIEventLoop> eventLoop;
+
+ if(NS_FAILED(nativeAppService->CreateEventLoop(L"_MainLoop",
+ nsEventLoopTypes::MainAppLoop, getter_AddRefs(eventLoop))))
+ {
+ ErrorBox("Failed to create event Loop");
+ return 0;
+ }
+
+ eventLoop->Run(nsnull, nsnull, nsnull, &retCode);
+ eventLoop = nsnull; // Clear out before Shutting down XPCOM
+
+ InfoBox("Hello World app is out of loop");
+ }
+ NS_ShutdownXPCOM(nsnull);
+ InfoBox("Hello World app is exiting");
+ return retCode;
+}
+
+LRESULT CALLBACK WndProc(HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ HDC hdc;
+ PAINTSTRUCT ps;
+ RECT rect;
+
+ switch(msg)
+ {
+ case WM_PAINT:
+ hdc = BeginPaint(wnd, &ps);
+
+ GetClientRect(wnd, &rect);
+
+ DrawText(hdc, "Hello, XP Event Loop!", -1, &rect,
+ DT_SINGLELINE | DT_CENTER | DT_VCENTER);
+
+ EndPaint(wnd, &ps);
+ return 0;
+
+ case WM_DESTROY:
+ {
+ nsresult rv;
+ nsCOMPtr<nsINativeApp> nativeAppService =
+ do_GetService(kNativeAppCID, &rv);
+ if(NS_FAILED(rv))
+ {
+ ErrorBox("Could not get NativeAppService");
+ return 0;
+ }
+ nsCOMPtr<nsIEventLoop> eventLoop;
+
+ if(NS_FAILED(nativeAppService->FindEventLoop(L"_MainLoop",
+ getter_AddRefs(eventLoop))))
+ {
+ ErrorBox("Failed to find event Loop");
+ return 0;
+ }
+ eventLoop->Exit(0);
+ }
+ return 0;
+ }
+
+ return DefWindowProc(wnd, msg, wParam, lParam);
+}
diff --git a/src/libs/xpcom18a4/xpcom/tests/windows/nsStringTest.cpp b/src/libs/xpcom18a4/xpcom/tests/windows/nsStringTest.cpp
new file mode 100644
index 00000000..6719ed38
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/windows/nsStringTest.cpp
@@ -0,0 +1,33 @@
+
+#include <iostream.h>
+#include "nsStr.h"
+#include "nsStringTest2.h"
+#include "nsString.h"
+#include "nsReadableUtils.h"
+
+int main(){
+
+ nsString temp("\t\t\n\r\n\r25,* \t \n\n \t");
+ temp.CompressWhitespace();
+
+ nsString temp1("\t\t\n\r\n\r25,* \t \n\n \t");
+ temp1.CompressSet("\t\n\r ",' ',false,false);
+
+ nsString temp3("");
+ char* s = ToNewCString(temp3);
+ delete s;
+
+ char* f = ToNewCString(nsAutoString(""));
+ char* f1 = ToNewCString(nsCAutoString(""));
+ delete f;
+ delete f1;
+
+
+ CStringTester gStringTester;
+
+ gStringTester.TestI18nString();
+
+ return 0;
+}
+
+
diff --git a/src/libs/xpcom18a4/xpcom/tests/windows/nsStringTest.h b/src/libs/xpcom18a4/xpcom/tests/windows/nsStringTest.h
new file mode 100644
index 00000000..8244a5a1
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/windows/nsStringTest.h
@@ -0,0 +1,2277 @@
+/********************************************************************************************
+ *
+ * MODULES NOTES:
+ *
+ * This file is designed to help test the new nsString classes.
+ *
+ * Contributor(s):
+ * Rick Gessner <rickg@netscape.com>
+ *
+ * History:
+ *
+ * 02.29.2000: Original files (rickg)
+ * 03.02.2000: Flesh out the interface to be compatible with old library (rickg)
+ *
+ ********************************************************************************************/
+
+#ifndef _STRINGTEST
+#define _STRINGTEST
+
+
+#include "nsString.h"
+#include "nsReadableUtils.h"
+#include <time.h>
+
+#define USE_STL
+
+#ifdef USE_STL
+#include <string>
+using namespace std;
+#endif
+
+#define USE_WIDE 1
+#ifdef USE_WIDE
+ #define stringtype nsString
+ #define astringtype nsAutoString
+ #define chartype PRUnichar
+#else
+ #define stringtype nsCString
+ #define astringtype nsCAutoString
+ #define chartype char
+#endif
+
+
+#include <stdio.h>
+
+
+
+static const char* kConstructorError = "constructor error";
+static const char* kComparisonError = "Comparision error!";
+static const char* kEqualsError = "Equals error!";
+
+static char* kNumbers[]={"0123456789","0\01\02\03\04\05\06\07\08\09\0\0\0"};
+static char* kLetters[]={"abcdefghij","a\0b\0c\0d\0e\0f\0g\0h\0i\0j\0\0\0"};
+static char* kAAA[]={"AAA","A\0A\0A\0\0\0"};
+static char* kBBB[]={"BBB","B\0B\0B\0\0\0"};
+static char* kHello[]={"hello","h\0e\0l\0l\0o\0\0\0"};
+static char* kWSHello[]={" hello "," \0 \0h\0e\0l\0l\0o\0 \0 \0\0\0"};
+
+
+
+/********************************************************
+
+ This class's only purpose in life is to test the
+ netscape string library. We exercise the string
+ API's here, and do a bit of performance testing
+ against the standard c++ library string (from STL).
+
+ ********************************************************/
+class CStringTester {
+public:
+ CStringTester() {
+ TestConstructors();
+ TestAutoStrings();
+ TestAppend();
+ TestAssignAndAdd();
+ TestInsert();
+ TestDelete();
+ TestTruncate();
+ TestLogical();
+ TestLexomorphic();
+ TestCreators();
+ TestNumerics();
+ TestExtractors();
+ TestSearching();
+ TestSubsumables();
+ TestRandomOps();
+ TestReplace();
+ TestRegressions();
+ TestStringPerformance();
+ TestWideStringPerformance();
+ }
+protected:
+ int TestConstructors();
+ int TestLogical();
+ int TestAutoStrings();
+ int TestAppend();
+ int TestAssignAndAdd();
+ int TestInsert();
+ int TestDelete();
+ int TestTruncate();
+ int TestLexomorphic();
+ int TestCreators();
+ int TestNumerics();
+ int TestExtractors();
+ int TestSearching();
+ int TestSubsumables();
+ int TestRandomOps();
+ int TestReplace();
+ int TestStringPerformance();
+ int TestWideStringPerformance();
+ int TestRegressions();
+};
+
+
+class Stopwatch {
+public:
+ Stopwatch() {
+ start=clock();
+ }
+
+ void Stop() {
+ stop=clock();
+ }
+
+ double Elapsed() {
+ return (double)(stop - start) / CLOCKS_PER_SEC;
+ }
+
+ void Print(const char* msg= "") {
+ printf("%s %f\n",msg,Elapsed());
+ }
+
+ clock_t start,stop;
+};
+
+/**
+ *
+ * @update gess10/30/98
+ * @param
+ * @return
+ */
+int CStringTester::TestSearching(){
+ int result=0;
+
+
+
+ PRUnichar pbuf[10]={'e','f','g',0};
+ PRUnichar pbuf2[10]={'a','b','c',0};
+
+
+ //Since there is so much ground to cover with searching, we use a typedef to
+ //allow you to vary the string type being searched...
+
+
+ stringtype theDest("abcdefghijkabc");
+ nsString s1("ijk");
+ nsCString c1("ijk");
+
+ PRInt32 pos=theDest.Find(pbuf);
+ NS_ASSERTION(pos==4,"Error: Find routine");
+
+ pos=theDest.Find(pbuf2,PR_FALSE,-1);
+ NS_ASSERTION(pos==0,"Error: Find routine");
+
+ pos=theDest.Find(pbuf2,PR_FALSE,pos+1);
+ NS_ASSERTION(pos==11,"Error: Find routine");
+
+ pos=theDest.FindChar('a');
+ NS_ASSERTION(pos==0,"Error: Find routine");
+
+ pos=theDest.FindChar('a',PR_FALSE,pos+1);
+ NS_ASSERTION(pos==11,"Error: Find routine");
+
+ pos=theDest.Find("efg");
+ NS_ASSERTION(pos==4,"Error: Find routine");
+
+ pos=theDest.Find("EFG",PR_TRUE);
+ NS_ASSERTION(pos==4,"Error: Find routine");
+
+ pos=theDest.FindChar('d');
+ NS_ASSERTION(pos==3,"Error: Find char routine");
+
+ pos=theDest.Find(s1);
+ NS_ASSERTION(pos==8,"Error: Find char routine");
+
+ pos=theDest.FindCharInSet("12k");
+ NS_ASSERTION(pos==10,"Error: Findcharinset routine");
+
+ pos=theDest.FindCharInSet(pbuf);
+ NS_ASSERTION(pos==4,"Error: Findcharinset routine");
+
+ pos=theDest.FindCharInSet(s1);
+ NS_ASSERTION(pos==8,"Error: Findcharinset routine");
+
+ pos=theDest.Find("efg",PR_FALSE,2);
+ NS_ASSERTION(pos==4,"Error: Find routine");
+
+ pos=theDest.RFindCharInSet("12k");
+ NS_ASSERTION(pos==10,"Error: RFindcharinset routine");
+
+ pos=theDest.RFindCharInSet("xyz");
+ NS_ASSERTION(pos==-1,"Error: RFindcharinset routine");
+
+ pos=theDest.RFindCharInSet(pbuf);
+ NS_ASSERTION(pos==6,"Error: RFindcharinset routine");
+
+ pos=theDest.RFindCharInSet(s1);
+ NS_ASSERTION(pos==10,"Error: RFindcharinset routine");
+
+ pos=theDest.RFind("efg");
+ NS_ASSERTION(pos==4,"Error: RFind routine");
+
+ pos=theDest.RFind("xxx");
+ NS_ASSERTION(pos==-1,"Error: RFind routine"); //this should fail
+
+ pos=theDest.RFind("");
+ NS_ASSERTION(pos==-1,"Error: RFind routine"); //this too should fail.
+
+ pos=theDest.RFindChar('a',PR_FALSE,4);
+ NS_ASSERTION(pos==-1,"Error: RFind routine");
+
+
+ //now try searching with FindChar using offset and count...
+ {
+ stringtype s1("hello there rick");
+
+ PRInt32 pos=s1.FindChar('r'); //this will search from the beginning, and for the length of the string.
+ NS_ASSERTION(pos==9,"Error: FindChar() with offset and count");
+
+ pos=s1.FindChar('r',PR_FALSE,0,5); //this will search from the front using count. THIS WILL FAIL!
+ NS_ASSERTION(pos==-1,"Error: FindChar() with offset and count");
+
+ pos=s1.FindChar('r',PR_FALSE,0,10); //this will search from the front using count. THIS WILL SUCCEED!
+ NS_ASSERTION(pos==9,"Error: FindChar() with offset and count");
+
+ pos=s1.FindChar('i',PR_FALSE,5,5); //this will search from the middle using count. THIS WILL FAIL!
+ NS_ASSERTION(pos==-1,"Error: FindChar() with offset and count");
+
+ pos=s1.FindChar('i',PR_FALSE,5,10); //this will search from the middle using count. THIS WILL SUCCEED!
+ NS_ASSERTION(pos==13,"Error: FindChar() with offset and count");
+
+ pos=s1.FindChar('k',PR_FALSE,10,2); //this will search from near the end using count. THIS WILL FAIL!
+ NS_ASSERTION(pos==-1,"Error: FindChar() with offset and count");
+
+ pos=s1.FindChar('k',PR_FALSE,10,7); //this will search from near the end using count. THIS WILL SUCCEED!
+ NS_ASSERTION(pos==15,"Error: FindChar() with offset and count");
+
+ //now let's try a few with bad data...
+
+ pos=s1.FindChar('k',PR_FALSE,100,2); //this will search from a bad offset. THIS WILL FAIL!
+ NS_ASSERTION(pos==-1,"Error: FindChar() with offset and count");
+
+ pos=s1.FindChar('k',PR_FALSE,10,0); //this will search for a bad count. THIS WILL FAIL!
+ NS_ASSERTION(pos==-1,"Error: FindChar() with offset and count");
+
+ pos=s1.FindChar('k',PR_FALSE,10,20); //this will search for a bad count. THIS WILL SUCCEED!
+ NS_ASSERTION(pos==15,"Error: FindChar() with offset and count");
+
+ pos=s1.FindChar('k',PR_FALSE,10,4); //this will search for a bad count. THIS WILL FAIL!
+ NS_ASSERTION(pos==-1,"Error: FindChar() with offset and count");
+
+ pos=10;
+ }
+
+ //now try searching with RFindChar using offset and count...
+ {
+ stringtype s1("hello there rick");
+
+ PRInt32 pos=s1.RFindChar('o'); //this will search from the end, and for the length of the string.
+ NS_ASSERTION(pos==4,"Error: RFindChar() with offset and count");
+
+ pos=s1.RFindChar('i'); //this will search from the end, and for the length of the string.
+ NS_ASSERTION(pos==13,"Error: RFindChar() with offset and count");
+
+ pos=s1.RFindChar(' ',PR_FALSE,-1,4); //this will search from the end, and for the length of the string.
+ NS_ASSERTION(pos==-1,"Error: RFindChar() with offset and count"); //THIS WILL FAIL
+
+ pos=s1.RFindChar(' ',PR_FALSE,12,1); //this will search from the middle, and for the length of 1.
+ NS_ASSERTION(pos==-1,"Error: RFindChar() with offset and count"); //THIS WILL FAIL
+
+ pos=s1.RFindChar(' ',PR_FALSE,12,2); //this will search from the middle, and for the length of 2.
+ NS_ASSERTION(pos==11,"Error: RFindChar() with offset and count"); //THIS WILL SUCCEED
+
+ pos=s1.RFindChar('o',PR_FALSE,-1,5); //this will search from the end using count. THIS WILL FAIL!
+ NS_ASSERTION(pos==-1,"Error: RFindChar() with offset and count");
+
+ pos=s1.RFindChar('o',PR_FALSE,-1,12); //this will search from the front using count. THIS WILL SUCCEED!
+ NS_ASSERTION(pos==4,"Error: RFindChar() with offset and count");
+
+ pos=s1.RFindChar('l',PR_FALSE,8,2); //this will search from the middle using count. THIS WILL FAIL!
+ NS_ASSERTION(pos==-1,"Error: RFindChar() with offset and count");
+
+ pos=s1.RFindChar('l',PR_FALSE,8,7); //this will search from the middle using count. THIS WILL SUCCEED!
+ NS_ASSERTION(pos==3,"Error: RFindChar() with offset and count");
+
+//***
+
+ pos=s1.RFindChar('h',PR_FALSE,3,2); //this will search from near the end using count. THIS WILL FAIL!
+ NS_ASSERTION(pos==-1,"Error: RFindChar() with offset and count");
+
+ pos=s1.RFindChar('h',PR_FALSE,3,7); //this will search from near the end using count. THIS WILL SUCCEED!
+ NS_ASSERTION(pos==0,"Error: RFindChar() with offset and count");
+
+ //now let's try a few with bad data...
+
+ pos=s1.RFindChar('k',PR_FALSE,100,2); //this will search from a bad offset. THIS WILL FAIL!
+ NS_ASSERTION(pos==-1,"Error: RFindChar() with offset and count");
+
+ pos=s1.RFindChar('k',PR_FALSE,10,0); //this will search for a bad count. THIS WILL FAIL!
+ NS_ASSERTION(pos==-1,"Error: RFindChar() with offset and count");
+
+ pos=10;
+ }
+
+ //now try searching with Find() using offset and count...
+ {
+ stringtype s1("hello there rick");
+
+ PRInt32 pos= s1.Find("there",PR_FALSE,0,4); //first search from front using offset
+ NS_ASSERTION(pos==-1,"Error: Find() with offset and count"); //THIS WILL FAIL
+
+ pos= s1.Find("there",PR_FALSE,0,8); //first search from front using count
+ NS_ASSERTION(pos==6,"Error: Find) with offset and count"); //THIS WILL SUCCEED
+
+ pos= s1.Find("there",PR_FALSE,4,1); //first search from front using count
+ NS_ASSERTION(pos==-1,"Error: Find() with offset and count"); //THIS WILL FAIL
+
+ pos= s1.Find("there",PR_FALSE,5,2); //first search from front using count
+ NS_ASSERTION(pos==6,"Error: Find() with offset and count"); //THIS WILL SUCCEED
+
+ pos= s1.Find("there",PR_FALSE,6,1); //first search from front using count
+ NS_ASSERTION(pos==6,"Error: Find() with offset and count"); //THIS WILL SUCCEED
+
+ pos= s1.Find("there",PR_FALSE,6,0); //first search from front using a bogus count
+ NS_ASSERTION(pos==-1,"Error: Find() with offset and count"); //THIS WILL FAIL
+
+ pos= s1.Find("k",PR_FALSE,15,1); //first search from end using a count
+ NS_ASSERTION(pos==15,"Error: Find() with offset and count"); //THIS WILL SUCCEED
+
+ pos= s1.Find("k",PR_FALSE,15,10); //first search from end using a LARGE count
+ NS_ASSERTION(pos==15,"Error: Find() with offset and count"); //THIS WILL SUCCEED
+
+ pos= s1.Find("k",PR_FALSE,25,10); //first search from bogus offset using a LARGE count
+ NS_ASSERTION(pos==-1,"Error: Find() with offset and count"); //THIS WILL FAIL
+
+ pos=10;
+ }
+
+ //now try substringsearching with RFind() using offset and count...
+ {
+ nsString s1("abcdefghijklmnopqrstuvwxyz");
+
+ PRInt32 pos= s1.RFind("ghi"); //first search from end using count
+ NS_ASSERTION(pos==6,"Error: RFind() with offset and count"); //THIS WILL SUCCEED!
+
+ pos= s1.RFind("nop",PR_FALSE,-1,4); //first search from end using count
+ NS_ASSERTION(pos==-1,"Error: RFind() with offset and count"); //THIS WILL FAIL
+
+ pos= s1.RFind("nop",PR_FALSE,-1,15); //first search from end using count
+ NS_ASSERTION(pos==13,"Error: RFind() with offset and count"); //THIS WILL SUCCEED
+
+ pos= s1.RFind("nop",PR_FALSE,16,3); //first search from middle using count
+ NS_ASSERTION(pos==-1,"Error: RFind() with offset and count"); //THIS WILL FAIL
+
+ pos= s1.RFind("nop",PR_FALSE,16,7); //first search from middle using count
+ NS_ASSERTION(pos==13,"Error: RFind() with offset and count"); //THIS WILL SUCCEED
+
+ pos= s1.RFind("nop",PR_FALSE,0,1); //first search from front using count
+ NS_ASSERTION(pos==-1,"Error: RFind() with offset and count"); //THIS WILL FAIL
+
+ pos= s1.RFind("abc",PR_FALSE,0,1); //first search from middle using count
+ NS_ASSERTION(pos==0,"Error: RFind() with offset and count"); //THIS WILL SUCCEED
+
+ pos= s1.RFind("foo",PR_FALSE,10,100); //first search from front using bogus count
+ NS_ASSERTION(pos==-1,"Error: RFind() with offset and count"); //THIS WILL FAIL
+
+ pos= s1.RFind("ghi",PR_FALSE,30,1); //first search from middle using bogus offset
+ NS_ASSERTION(pos==-1,"Error: RFind() with offset and count"); //THIS WILL FAIL
+
+ pos=10;
+ }
+
+ //Various UNICODE tests...
+ {
+ //do some searching against chinese unicode chars...
+
+ PRUnichar chinese[] = {0x4e41,0x4e42, 0x4e43, 0x0000}; // 3 chinese unicode
+
+ nsString T2(chinese);
+ nsString T2copy(chinese);
+
+ pos = T2.FindCharInSet("A");
+ NS_ASSERTION(kNotFound==pos,"Error in FindCharInSet");
+
+ pos=T2.RFindCharInSet("A",2);
+ NS_ASSERTION(kNotFound==pos,"Error in RFindCharInSet");
+
+ pos=T2.Find("A", PR_FALSE, 0, 1);
+ NS_ASSERTION(kNotFound==pos,"Error in Find");
+
+ pos=T2.RFind("A", PR_FALSE, 2, 1);
+ NS_ASSERTION(kNotFound==pos,"Error in RFind");
+
+ T2.ReplaceChar("A",' ');
+ NS_ASSERTION(T2==T2copy,"Error in ReplaceChar");
+
+ //Here's the 3rd FTang unicode test...
+
+ static char test4[]="ABCDEF";
+ static char test4b[]=" BCDEF";
+
+ PRUnichar test5[]={0x4e41, 0x0000};
+ PRUnichar test6[]={0x0041, 0x0000};
+
+ nsCString T4(test4);
+ nsCString T4copy(test4);
+ nsCString T4copyb(test4b);
+ nsCString T5(test5);
+ nsCString T6(test6);
+
+ pos = T4.FindCharInSet(T5.get());
+ NS_ASSERTION(0==pos,"Error in FindcharInSet"); //This should succeed.
+
+ pos = T4.FindCharInSet(T6.get());
+ NS_ASSERTION(kNotFound<pos,"Error in FindcharInSet"); //This should succeed.
+
+ pos = T4.RFindCharInSet(T5.get(),2);
+ NS_ASSERTION(0==pos,"Error in RFindCharInSet"); //This should fail.
+
+ pos = T4.RFindCharInSet(T6.get(),2);
+ NS_ASSERTION(kNotFound<pos,"Error in RFindCharInSet"); //This should fail.
+
+ pos = T4.Find(T5.get(), PR_FALSE, 0, 1);
+ NS_ASSERTION(0==pos,"Error in Find"); //This should succeed.
+
+ pos= T4.Find(T6.get(), PR_FALSE, 0, 1);
+ NS_ASSERTION(kNotFound<pos,"Error in Find"); //This should fail.
+
+ pos = T4.RFind(T5.get(), PR_FALSE, 2, 1);
+ NS_ASSERTION(kNotFound==pos,"Error in RFind");
+
+ pos =T4.RFind(T6.get(), PR_FALSE, 2, 1);
+ NS_ASSERTION(kNotFound==pos,"Error in RFind");
+
+
+/*
+ NOT WORKING IN NEW STRING YET...
+
+ T4.ReplaceChar(PRUnichar(0x4E41),PRUnichar(' '));
+ if(T4 != T4copy)
+ printf("nsCString::ReplaceChar(PRUnichar, PRUnichar) error- replace when it should not\n");
+
+ T4 = test4;
+ T4.ReplaceChar(PRUnichar(0x0041),PRUnichar(' '));
+ if(T4 != T4copyb)
+ printf("nsCString::ReplaceChar(PRUnichar, PRUnichar) error- not replace when it should\n");
+
+*/
+
+ }
+
+ return result;
+}
+
+/**
+ *
+ * @update gess10/30/98
+ * @param
+ * @return
+ */
+int CStringTester::TestConstructors(){
+ int result=0;
+ PRUnichar pbuf[10]={'f','o','o',0};
+ PRUnichar* buf=pbuf;
+
+ nsString s1("hello world");
+ nsCString c1("what's up");
+
+
+ //Test nsCString constructors...
+ {
+ nsCString temp0;
+ nsCString temp1(s1);
+ NS_ASSERTION(temp1==s1,"nsCString Constructor error");
+
+ nsCString temp2(c1);
+ NS_ASSERTION(temp2==c1,"nsCString Constructor error");
+
+ nsCString temp3("hello world");
+ NS_ASSERTION(temp3=="hello world","nsCString Constructor error");
+
+ nsCString temp4(pbuf);
+ NS_ASSERTION(temp4==pbuf,"nsCString Constructor error");
+
+ nsCString temp5('a');
+ NS_ASSERTION(temp5=="a","nsCString Constructor error");
+
+ nsCString temp6(PRUnichar('a'));
+ NS_ASSERTION(temp5=="a","nsCString Constructor error");
+ }
+
+ //now just for fun, let's construct 2byte from 1byte and back...
+ {
+ nsCString temp0("hello");
+ nsString temp1(temp0);
+ nsCString temp2(temp1);
+ }
+
+ return result;
+}
+
+/**
+ *
+ * @update gess10/30/98
+ * @param
+ * @return
+ */
+int CStringTester::TestLogical(){
+ int result=0;
+ stringtype temp8("aaaa");
+ stringtype temp8a("AAAA");
+ stringtype temp9("bbbb");
+
+ const char* aaaa="aaaa";
+ const char* bbbb="bbbb";
+
+
+ //First, test a known error that got checked into the tree...
+ {
+ nsString mURL("file:///c|/test/foo.txt");
+ PRBool result=mURL.Equals("file:/",PR_FALSE);
+ NS_ASSERTION(!result,kEqualsError);
+ result=mURL.Equals("file:/",PR_FALSE,5);
+ NS_ASSERTION(result,kEqualsError);
+ result=mURL.Equals("file:/",PR_FALSE,-1);
+ NS_ASSERTION(!result,kEqualsError);
+
+ nsString s1("rick");
+ result=s1.Equals("rick",PR_FALSE,6);
+ result++;
+ }
+
+
+ {
+ //this little piece of code tests to see whether the PL_strcmp series works
+ //correctly even when we have strings whose buffers contain nulls.
+
+ char *buf1 = "what's up \0\0 doc?";
+ char *buf2 = "what's up \0\0 dog?";
+
+ nsString s1(buf2,17);
+
+ PRInt32 result=s1.Compare(buf1,PR_TRUE,17);
+ result=s1.FindChar('?');
+ result++;
+ }
+
+ {
+ nsString foo("__moz_text");
+ PRInt32 cmp=foo.Compare("pre",PR_FALSE,-1);
+ cmp=cmp;
+ }
+
+ //First test the string compare routines...
+
+ NS_ASSERTION(0>temp8.Compare(bbbb),kComparisonError);
+ NS_ASSERTION(0>temp8.Compare(temp9),kComparisonError);
+ NS_ASSERTION(0<temp9.Compare(temp8),kComparisonError);
+ NS_ASSERTION(0==temp8.Compare(temp8a,PR_TRUE),kComparisonError);
+ NS_ASSERTION(0==temp8.Compare(aaaa),kComparisonError);
+
+ //Now test the boolean operators...
+ NS_ASSERTION(temp8==temp8,kComparisonError);
+ NS_ASSERTION(temp8==aaaa,kComparisonError);
+
+ NS_ASSERTION(temp8!=temp9,kComparisonError);
+ NS_ASSERTION(temp8!=bbbb,kComparisonError);
+
+ NS_ASSERTION(((temp8<temp9) && (temp9>=temp8)),kComparisonError);
+
+ NS_ASSERTION(((temp9>temp8) && (temp8<=temp9)),kComparisonError);
+ NS_ASSERTION(temp9>aaaa,kComparisonError);
+
+ NS_ASSERTION(temp8<=temp8,kComparisonError);
+ NS_ASSERTION(temp8<=temp9,kComparisonError);
+ NS_ASSERTION(temp8<=bbbb,kComparisonError);
+
+ NS_ASSERTION(((temp9>=temp8) && (temp8<temp9)),kComparisonError);
+ NS_ASSERTION(temp9>=temp8,kComparisonError);
+ NS_ASSERTION(temp9>=aaaa,kComparisonError);
+
+ NS_ASSERTION(temp8.Equals(temp8),kEqualsError);
+ NS_ASSERTION(temp8.Equals(aaaa),kEqualsError);
+
+ stringtype temp10(temp8);
+ ToUpperCase(temp10);
+ NS_ASSERTION(temp8.Equals(temp10,PR_TRUE),kEqualsError);
+ NS_ASSERTION(temp8.Equals("AAAA",PR_TRUE),kEqualsError);
+
+
+ //now test the new string Equals APIs..
+ {
+ nsCString s1("hello there");
+ NS_ASSERTION(s1.Equals("hello there"),kEqualsError);
+ NS_ASSERTION(s1.Equals("hello rick",PR_FALSE,5),kEqualsError);
+ NS_ASSERTION(!s1.Equals("hello rick",PR_FALSE-1),kEqualsError);
+
+ nsCString s2("");
+ NS_ASSERTION(s2.Equals(""),kEqualsError);
+
+ nsCString s3("view-source:");
+ NS_ASSERTION(s3.Equals("VIEW-SOURCE:",PR_TRUE,12),kEqualsError);
+ }
+
+ //now test the count argument...
+ {
+ nsString s1("rickgessner");
+ nsString s2("rickricardo");
+ PRInt32 result=s1.Compare(s2); //assume no case conversion, and full-length comparison...
+ result=s1.Compare(s2,PR_FALSE,4);
+ result=s1.Compare(s2,PR_FALSE,5);
+
+ PRBool b=s1.Equals(s2);
+ b=s1.Equals("rick",PR_FALSE,4);
+ b=s1.Equals("rickz",PR_FALSE,5);
+
+ result=10;
+
+ nsString s3("view");
+
+#define kString "view-source"
+
+ b=s3.Equals(kString);
+ result=10;
+ }
+
+ return result;
+}
+
+/**
+ *
+ * @update gess10/30/98
+ * @param
+ * @return
+ */
+int CStringTester::TestAssignAndAdd(){
+ int result=0;
+
+ static const char* s1="hello";
+ static const char* s2="world";
+ static const PRUnichar pbuf[] = {' ','w','o','r','l','d',0};
+
+ nsString ns1("I'm an nsString");
+ nsCString nc1("I'm an nsCString");
+
+ nsAutoString as1("nsAutoString source");
+ nsCAutoString ac1("nsCAutoString source");
+
+
+ {
+ //**** Test assignments to nsCString...
+
+ nsCString theDest;
+ theDest.Assign(theDest); //assign nsString to itself
+ theDest.Assign(ns1); //assign an nsString to an nsString
+ NS_ASSERTION(theDest==ns1,"Assignment error");
+
+ theDest.Assign(nc1); //assign an nsCString to an nsString
+ NS_ASSERTION(theDest==nc1,"Assignment error");
+
+ theDest.Assign(as1); //assign an nsAutoString to an nsString
+// NS_ASSERTION(theDest==as1,"Assignment error");
+
+ theDest.Assign(ac1); //assign an nsCAutoString to an nsString
+// NS_ASSERTION(theDest==ac1,"Assignment error");
+
+ theDest.Assign("simple char*"); //assign a char* to an nsString
+ NS_ASSERTION(theDest=="simple char*","Assignment error");
+
+ theDest.Assign(pbuf); //assign a PRUnichar* to an nsString
+ NS_ASSERTION(theDest==pbuf,"Assignment error");
+
+ theDest.Assign('!'); //assign a char to an nsString
+ NS_ASSERTION(theDest=="!","Assignment error");
+
+ theDest.Assign(PRUnichar('$')); //assign a char to an nsString
+ NS_ASSERTION(theDest=="$","Assignment error");
+
+ theDest=ns1;
+ NS_ASSERTION(theDest==ns1,"Assignment error");
+
+ theDest=nc1;
+ NS_ASSERTION(theDest==nc1,"Assignment error");
+
+ theDest='a';
+ NS_ASSERTION(theDest=="a","Assignment error");
+
+ theDest=PRUnichar('a');
+ NS_ASSERTION(theDest=="a","Assignment error");
+
+ theDest=s1;
+ NS_ASSERTION(theDest==s1,"Assignment error");
+
+ theDest=pbuf;
+ NS_ASSERTION(theDest==pbuf,"Assignment error");
+
+ }
+
+ //test operator+()...
+ {
+
+ /* NOT WORKING YET...
+ nsString s1("hello");
+ nsString s2(" world");
+ nsCString c1(" world");
+
+ stringtype theDest;
+
+ theDest=s1+s2;
+ NS_ASSERTION(theDest=="hello world","Assignment error");
+
+ theDest=s1+c1;
+ NS_ASSERTION(theDest=="hello world","Assignment error");
+
+ theDest=s1+" world";
+ NS_ASSERTION(theDest=="hello world","Assignment error");
+
+ theDest=s1+pbuf;
+ NS_ASSERTION(theDest=="hello world","Assignment error");
+
+ theDest=s1+'!';
+ NS_ASSERTION(theDest=="hello!","Assignment error");
+
+ theDest=s1+PRUnichar('!');
+ NS_ASSERTION(theDest=="hello!","Assignment error");
+*/
+
+ }
+
+ return result;
+}
+
+
+/**
+ *
+ * @update gess10/30/98
+ * @param
+ * @return
+ */
+int CStringTester::TestAppend(){
+ int result=0;
+
+
+ static const char* s1="hello";
+ static const char* s2="world";
+ static const PRUnichar pbuf[] = {' ','w','o','r','l','d',0};
+ static const PRUnichar pbuf1[] = {'a','b','c','d','l','d'};
+
+
+ stringtype theDest;
+ theDest.Append((float)100.100);
+ NS_ASSERTION(theDest=="100.1","Append(float) error");
+
+ theDest.Truncate();
+ theDest.Append(12345);
+ NS_ASSERTION(theDest=="12345","Append(int) error");
+
+ theDest.Truncate();
+ theDest.Append(pbuf1,1);
+ NS_ASSERTION(theDest=="a","Append(PRUnichar*,count) error");
+
+ theDest.Truncate();
+ theDest.Append('a');
+ NS_ASSERTION(theDest=="a","Append(char) error");
+
+
+ static const PRUnichar pbuf2[] = {'w','h','a','t','s',' ','u','p',' ','d','o','c','?',0};
+
+ theDest.Truncate();
+ theDest.Append(pbuf,20); //try appending more chars than actual length of pbuf
+ NS_ASSERTION(theDest!=pbuf,"Append(PRUnichar*) error");
+ //(NOTE: if you tell me to append X chars, I'll assume you really have X chars, and the length
+ // get's set accordingly. This test really is correct; it just seems odd.
+
+ theDest.Truncate(0);
+ theDest.Append(pbuf,5); //try appending fewer chars than actual length of pbuf
+ NS_ASSERTION(theDest==" worl","Append(PRUnichar*) error");
+
+ theDest.Truncate(0);
+ theDest.Append(pbuf); //try appending all of pbuf
+ NS_ASSERTION(theDest==pbuf,"Append(PRUnichar*) error");
+
+ char* ss=0;
+ theDest.Truncate();
+ theDest.Append(ss); //try appending NULL
+ NS_ASSERTION(theDest=="","Append(nullstr) error");
+
+ theDest.Append(pbuf,0); //try appending nothing
+ NS_ASSERTION(theDest=="","Append(nullstr) error");
+
+
+ {
+ //test improvement to unichar appends...
+ stringtype s1("hello");
+ char c='!';
+ s1+=c;
+ NS_ASSERTION(s1=="hello!","operator+=() error");
+
+ c=(char)0xfa;
+ s1+=c;
+ s1.Append(c);
+
+ PRUnichar theChar='f';
+ s1+=theChar;
+
+ char theChar2='g';
+ s1+=theChar2;
+
+// long theLong= 1234;
+// s1+=theLong;
+
+ }
+
+ {
+ //this just proves we can append nulls in our buffers...
+ stringtype c("hello");
+ stringtype s(" there");
+ c.Append(s);
+ char buf[]={'a','b',0,'d','e'};
+ s.Append(buf,5);
+ }
+
+
+ stringtype temp2("there");
+
+ theDest.Append(temp2);
+ theDest.Append(" xxx ");
+ theDest.Append(pbuf);
+ theDest.Append('4');
+ theDest.Append(PRUnichar('Z'));
+
+ stringtype a(s1);
+ stringtype b(s2);
+
+ theDest.Truncate();
+ temp2.Truncate();
+
+/* NOT WORKING YET...
+ theDest=a+b;
+ temp2=a+"world!";
+ temp2=a+pbuf;
+ stringtype temp3;
+ temp3=temp2+'!';
+*/
+ return result;
+}
+
+
+/**
+ *
+ * @update gess10/30/98
+ * @param
+ * @return
+ */
+int CStringTester::TestExtractors(){
+ int result=0;
+
+ //first test the 2 byte version...
+
+
+ {
+ nsString temp1("hello there rick");
+ nsString temp2;
+
+ temp1.Left(temp2,10);
+ NS_ASSERTION(temp2=="hello ther","Left() error");
+
+ temp1.Mid(temp2,6,5);
+ NS_ASSERTION(temp2=="there","Mid() error");
+
+ temp1.Right(temp2,4);
+ NS_ASSERTION(temp2=="rick","Right() error");
+
+ //Now test the character accessor methods...
+ nsString theString("hello");
+ PRUint32 len=theString.Length();
+ PRUnichar theChar;
+ for(PRUint32 i=0;i<len;i++) {
+ theChar=theString.CharAt(i);
+ }
+
+/* NOT WORKING YET...
+ theChar=theString.First();
+ theChar=theString.Last();
+ theChar=theString[3];
+ theString.SetCharAt('X',3);
+*/
+ }
+
+ //now test the 1 byte version
+ {
+ nsCString temp1("hello there rick");
+ nsCString temp2;
+ temp1.Left(temp2,10);
+ temp1.Mid(temp2,6,5);
+ temp1.Right(temp2,4);
+
+ //Now test the character accessor methods...
+ nsCString theString("hello");
+ PRUint32 len=theString.Length();
+ char ch;
+ for(PRUint32 i=0;i<len;i++) {
+ ch=theString.CharAt(i);
+ }
+
+/* NOT WORKING YET...
+
+ ch=theString.First();
+ ch=theString.Last();
+ ch=theString[3];
+ theString.SetCharAt('X',3);
+*/
+ }
+
+
+ return result;
+}
+
+
+
+/**
+ *
+ * @update gess10/30/98
+ * @param
+ * @return
+ */
+int CStringTester::TestCreators(){
+ int result=0;
+
+/* NOT WORKING YET
+ {
+ nsString theString5("");
+ char* str0 = ToNewCString(theString5);
+ Recycle(str0);
+
+ theString5+="hello rick";
+ nsString* theString6=theString5.ToNewString();
+ delete theString6;
+
+ nsString theString1("hello again");
+ PRUnichar* thePBuf=ToNewUnicode(theString1);
+ if(thePBuf)
+ Recycle(thePBuf);
+
+ char* str = ToNewCString(theString5);
+ if(str)
+ Recycle(str);
+
+ char buffer[6];
+ theString5.ToCString(buffer,sizeof(buffer));
+
+ }
+
+ {
+ nsCString theString5("hello rick");
+ nsCString* theString6=theString5.ToNewString();
+ delete theString6;
+
+ PRUnichar* thePBuf=ToNewUnicode(theString5);
+ if(thePBuf)
+ Recycle(thePBuf);
+
+ char* str = ToNewCString(theString5);
+ if(str)
+ Recycle(str);
+
+ char buffer[100];
+ theString5.ToCString(buffer,sizeof(buffer)-1);
+ nsCString theOther=theString5.GetBuffer();
+ }
+ */
+ return result;
+}
+
+
+/**
+ *
+ * @update gess10/30/98
+ * @param
+ * @return
+ */
+int CStringTester::TestInsert(){
+ int result=0;
+
+ {
+ static const char pbuf[] = " world";
+
+ nsCString temp1("hello rick");
+ temp1.Insert("there ",6); //char* insertion
+ NS_ASSERTION(temp1=="hello there rick","Insert error");
+
+ temp1.Insert(pbuf,3); //prunichar* insertion
+ NS_ASSERTION(temp1=="hel worldlo there rick","Insert error");
+
+ temp1.Insert("?",10); //char insertion
+ NS_ASSERTION(temp1=="hel worldl?o there rick","Insert error");
+
+ temp1.Insert('*',10); //char insertion
+ NS_ASSERTION(temp1=="hel worldl*?o there rick","Insert error");
+
+ temp1.Insert("xxx",100,3); //this should append.
+ NS_ASSERTION(temp1=="hel worldl*?o there rickxxx","Insert error");
+
+ nsCString temp2("abcdefghijklmnopqrstuvwxyz");
+// temp2.Insert(temp1,10);
+ temp2.Cut(20,5);
+ NS_ASSERTION(temp2=="abcdefghijklmnopqrstz","Insert error");
+
+ temp2.Cut(100,100); //this should fail.
+ NS_ASSERTION(temp2=="abcdefghijklmnopqrstz","Insert error");
+
+ }
+
+ {
+ static const PRUnichar pbuf[] = {' ','w','o','r','l','d',0};
+
+
+ nsString temp1("llo rick");
+
+ temp1.Insert("he",0); //char* insertion
+ NS_ASSERTION(temp1=="hello rick","Insert error");
+
+ temp1.Insert("there ",6); //char* insertion
+ NS_ASSERTION(temp1=="hello there rick","Insert error");
+
+ temp1.Insert(pbuf,3); //prunichar* insertion
+ NS_ASSERTION(temp1=="hel worldlo there rick","Insert error");
+
+ temp1.Insert("?",10); //char insertion
+ NS_ASSERTION(temp1=="hel worldl?o there rick","Insert error");
+
+ temp1.Insert('*',10); //char insertion
+ NS_ASSERTION(temp1=="hel worldl*?o there rick","Insert error");
+
+ temp1.Insert("xxx",100,3); //this should append.
+ NS_ASSERTION(temp1=="hel worldl*?o there rickxxx","Insert error");
+
+ nsString temp2("abcdefghijklmnopqrstuvwxyz");
+// temp2.Insert(temp1,10);
+ temp2.Cut(20,5);
+ NS_ASSERTION(temp2=="abcdefghijklmnopqrstz","Insert error");
+
+ temp2.Cut(100,100); //this should fail.
+ NS_ASSERTION(temp2=="abcdefghijklmnopqrstz","Insert error");
+
+ }
+
+ return result;
+}
+
+
+
+/**
+ *
+ * @update gess10/30/98
+ * @param
+ * @return
+ */
+int CStringTester::TestDelete(){
+ int result=0;
+
+ //NOTE: You need to run this test program twice for this method to work.
+ // Once with USE_WIDE defined, and once without (to test nsCString)
+
+ //let's try some whacky string deleting calls
+ {
+ const char* pbuf = "whats up doc?";
+
+ nsCString s1(pbuf);
+ s1.Cut(3,20); //try deleting more chars than actual length of pbuf
+ NS_ASSERTION(s1=="wha","Cut error");
+
+ s1=pbuf;
+ s1.Cut(3,-10);
+ NS_ASSERTION(s1==pbuf,"Cut error");
+
+ s1=pbuf;
+ s1.Cut(3,2);
+ NS_ASSERTION(s1=="wha up doc?","Cut error");
+
+ }
+
+ //let's try some whacky string deleting calls
+ {
+ const PRUnichar pbuf[] = {'w','h','a','t','s',' ','u','p',' ','d','o','c','?',0};
+
+ nsString s1(pbuf);
+ s1.Cut(3,20); //try deleting more chars than actual length of pbuf
+ NS_ASSERTION(s1=="wha","Cut error");
+
+ s1=pbuf;
+ s1.Cut(3,-10);
+ NS_ASSERTION(s1==pbuf,"Cut error");
+
+ s1=pbuf;
+ s1.Cut(3,2);
+ NS_ASSERTION(s1=="wha up doc?","Cut error");
+ }
+
+
+ {
+ nsCString s;
+ int i;
+ for(i=0;i<518;i++) {
+ s.Append("0123456789");
+ }
+ s+="abc";
+ s.Cut(0,5);
+ }
+
+ {
+ astringtype ab("ab");
+ stringtype abcde("cde");
+ stringtype cut("abcdef");
+ cut.Cut(7,10); //this is out of bounds, so ignore...
+ //cut.DebugDump(cout);
+ cut.Cut(5,2); //cut last chars
+ //cut.DebugDump(cout);
+ cut.Cut(1,1); //cut first char
+ //cut.DebugDump(cout);
+ cut.Cut(2,1); //cut one from the middle
+ //cut.DebugDump(cout);
+ cut="Hello there Rick";
+ //cut.DebugDump(cout);
+}
+
+ return result;
+}
+
+/**
+ *
+ * @update gess10/30/98
+ * @param
+ * @return
+ */
+int CStringTester::TestTruncate(){
+ int result=0;
+ //test delete against a twobyte string...
+
+ {
+ nsCString s0;
+ nsCString s1(kNumbers[0]);
+ s0=s1;
+ s0.Truncate(100); //should fail
+ s0.Truncate(5); //should work
+ s0.Truncate(0); //should work
+ }
+
+ {
+ nsString s0;
+ nsString s1(kNumbers[0]);
+ s0=s1;
+ s0.Truncate(100); //should fail
+ s0.Truncate(5); //should work
+ s0.Truncate(0); //should work
+ }
+ return result;
+}
+
+/**
+ *
+ * @update gess10/30/98
+ * @param
+ * @return
+ */
+int CStringTester::TestNumerics(){
+ int result=0;
+
+ //try a few numeric conversion routines...
+ {
+ nsCString str1("-12345");
+ NS_ASSERTION(str1=="-12345","Append(int) error");
+
+ nsString str2("hello");
+ nsString str3;
+ nsString str4("0");
+ nsString str5("&#183;");
+ nsString str6("&xi;");
+ nsString str7("#xe3;");
+ nsString str8("#FF;");
+ nsCString str9("-#xa?a;"); //should return -10 (decimal)
+ nsCString str10("&#191;");
+ nsCString str11("&#vvv;");
+ nsCString str12("-vvv;");
+ nsCString str13("-f");
+
+ PRInt32 err;
+ PRInt32 theInt=str1.ToInteger(&err);
+ theInt=str2.ToInteger(&err);
+ NS_ASSERTION(theInt==14,"ToInteger error");
+
+ theInt=str3.ToInteger(&err);
+ NS_ASSERTION(theInt==0,"ToInteger error");
+
+ theInt=str4.ToInteger(&err);
+ NS_ASSERTION(theInt==0,"ToInteger error");
+
+ theInt=str5.ToInteger(&err);
+ NS_ASSERTION(theInt==183,"ToInteger error");
+
+ theInt=str6.ToInteger(&err);
+ NS_ASSERTION(theInt==0,"ToInteger error");
+
+ theInt=str7.ToInteger(&err,16);
+ NS_ASSERTION(theInt==227,"ToInteger error");
+
+ theInt=str8.ToInteger(&err,kAutoDetect);
+ NS_ASSERTION(theInt==255,"ToInteger error");
+
+ theInt=str9.ToInteger(&err,kAutoDetect);
+ NS_ASSERTION(theInt==-10,"ToInteger error");
+
+ theInt=str10.ToInteger(&err);
+ NS_ASSERTION(theInt==191,"ToInteger error");
+
+ theInt=str11.ToInteger(&err);
+ NS_ASSERTION(theInt==0,"ToInteger error");
+
+ theInt=str12.ToInteger(&err);
+ NS_ASSERTION(theInt==0,"ToInteger error");
+
+ theInt=str13.ToInteger(&err);
+ NS_ASSERTION(theInt==-15,"ToInteger error");
+
+
+ Stopwatch watch;
+ int i;
+ for(i=0;i<1000000;i++){
+ theInt=str1.ToInteger(&err,16);
+ }
+ watch.Stop();
+ watch.Print("ToInteger() ");
+
+ str1="100.100";
+ float theFloat=str1.ToFloat(&err);
+ }
+ //try a few numeric conversion routines...
+ {
+ nsCString str1("10000");
+ nsCString str2("hello");
+ nsCString str3;
+ PRInt32 err;
+ PRInt32 theInt=str1.ToInteger(&err);
+ NS_ASSERTION(theInt==10000,"ToInteger error");
+
+ theInt=str2.ToInteger(&err);
+ NS_ASSERTION(theInt==14,"ToInteger error");
+
+ theInt=str3.ToInteger(&err);
+ NS_ASSERTION(theInt==0,"ToInteger error");
+
+ str1="100.100";
+ float theFloat=str1.ToFloat(&err);
+ }
+ return 0;
+}
+
+/**
+ *
+ * @update gess10/30/98
+ * @param
+ * @return
+ */
+int CStringTester::TestLexomorphic(){
+ int result=0;
+ //test delete against a twobyte string...
+
+ //NOTE: You need to run this test program twice for this method to work.
+ // Once with USE_WIDE defined, and once without (to test nsCString)
+
+
+ {
+ nsString theTag("FOO");
+ nsString theLower;
+ theTag.ToLowerCase(theLower);
+ int x=5;
+ }
+
+ PRUnichar pbuf[] = {'h','e','l','l','o','\n','\n','\n','\n',250,'\n','\n','\n','\n','\n','\n','r','i','c','k',0};
+
+ //and hey, why not do a few lexo-morphic tests...
+ nsString s0(pbuf);
+ ToUpperCase(s0);
+ ToLowerCase(s0);
+ s0.StripChars("l");
+ s0.StripChars("\n");
+ s0.StripChar(250);
+ NS_ASSERTION(s0=="heorick","Stripchars error");
+
+ {
+ nsAutoString s1(pbuf);
+ s1.CompressSet("\n ",' ');
+ }
+
+ {
+
+ char pbuf[] = { 0x1C, 0x04, 0x1D, 0x04, 0x20, 0x00, 0x2D, 0x00, 0x20, 0x00, 0x23, 0x04, 0x20, 0x00, 0x40, 0x04,
+ 0x43, 0x04, 0x3B, 0x04, 0x4F, 0x04, 0x20, 0x00, 0x30, 0x04, 0x40, 0x04, 0x3C, 0x04, 0x38, 0x04,
+ 0x38, 0x04, 0x20, 0x00, 0x2D, 0x00, 0x20, 0x00, 0x32, 0x04, 0x42, 0x04, 0x3E, 0x04, 0x40, 0x04,
+ 0x3E, 0x04, 0x41, 0x04, 0x42, 0x04, 0x35, 0x04, 0x3F, 0x04, 0x35, 0x04, 0x3D, 0x04, 0x3D, 0x04,
+ 0x4B, 0x04, 0x35, 0x04, 0x20, 0x00, 0x3B, 0x04, 0x38, 0x04, 0x46, 0x04, 0x30, 0x04, 0x20, 0x00,
+ 0x2D, 0x00, 0x20, 0x00, 0x30, 0x00, 0x39, 0x00, 0x2F, 0x00, 0x32, 0x00, 0x30, 0x00, 0x30, 0x00,
+ 0x30, 0x00, 0x00, 0x00};
+
+ nsAutoString temp((PRUnichar*)pbuf);
+ nsAutoString temp1(temp);
+ temp.CompressWhitespace();
+ PRBool equals=temp.Equals(temp1);
+
+ }
+
+ {
+ nsString s1(" ");
+ s1.Trim("; \t");
+ s1="helvetica";
+ s1.Trim("; \t");
+ }
+
+ s0.Insert(" ",0);
+ NS_ASSERTION(s0==" heorick","Stripchars error");
+
+ s0.Append(" ");
+ NS_ASSERTION(s0==" heorick ","Stripchars error");
+
+ s0.Trim(" ",PR_TRUE,PR_TRUE);
+ NS_ASSERTION(s0=="heorick","Stripchars error");
+
+ s0.Append(" abc 123 xyz ");
+ s0.CompressWhitespace();
+ NS_ASSERTION(s0=="heorick abc 123 xyz","CompressWS error");
+
+ s0.ReplaceChar('r','b');
+ NS_ASSERTION(s0=="heobick abc 123 xyz","ReplaceChar error");
+
+ s0=pbuf;
+ ToUpperCase(s0);
+ ToLowerCase(s0);
+ s0.Append("\n\n\n \r \r \r \t \t \t");
+ s0.StripWhitespace();
+
+ nsCAutoString s1("\n\r hello \n\n\n\r\r\r\t rick \t\t ");
+ ToUpperCase(s1);
+ ToLowerCase(s1);
+ s1.StripChars("o");
+ s1.Trim(" ",PR_TRUE,PR_TRUE);
+ s1.CompressWhitespace();
+ NS_ASSERTION(s1=="hell rick","Compress Error");
+
+ s1.ReplaceChar('h','w');
+ NS_ASSERTION(s1=="well rick","Compress Error");
+
+ ToUpperCase(s1);
+ NS_ASSERTION(s1=="WELL RICK","Compress Error");
+
+ ToLowerCase(s1);
+ s1.Append("\n\n\n \r \r \r \t \t \t");
+ s1.StripWhitespace();
+ NS_ASSERTION(s1=="wellrick","Compress Error");
+
+ {
+ nsCString temp("aaaa");
+ int i;
+ for(i=0;i<100;i++) {
+ temp+="0123456789.";
+ }
+ temp.StripChars("a2468");
+ i=5;
+
+ temp=" hello rick ";
+ temp.StripChars("\n\r\t\b ");
+ NS_ASSERTION(temp=="hellorick","This isn't good");
+ }
+
+ return result;
+}
+
+/**
+ *
+ * @update gess10/30/98
+ * @param
+ * @return
+ */
+int CStringTester::TestAutoStrings(){
+ int result=0;
+
+ PRUnichar pbuf[] = {'h','e','l','l','o',0};
+
+ //this test makes sure that autostrings who assume ownership of a buffer,
+ //don't also try to copy that buffer onto itself... (was a bug)
+ {
+ nsAutoString temp0;
+ nsAutoString temp1("hello rick");
+ nsAutoString temp3(pbuf);
+
+/* NOT WORKING...
+ nsAutoString temp4(CBufDescriptor((char*)pbuf,PR_TRUE,5,5));
+*/
+ nsAutoString temp5(temp3);
+ nsString s(pbuf);
+ nsAutoString temp6(s);
+
+/* NOT WORKING...
+ char buffer[500];
+ nsAutoString temp7(CBufDescriptor((PRUnichar*)buffer,PR_TRUE,sizeof(buffer)-10/2,0));
+ temp7="hello, my name is inigo montoya.";
+*/
+
+ nsAutoString as;
+ int i;
+ for(i=0;i<30;i++){
+ as+='a';
+ }
+ PRBool b=PR_TRUE; //this line doesn't do anything, it just gives a convenient breakpoint.
+ NS_ASSERTION(as=="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","error in operator+=()");
+ }
+
+
+ {
+ nsCAutoString temp0;
+ nsCAutoString temp1("hello rick");
+
+
+ //nsCAutoString temp2("hello rick",PR_TRUE,5);
+ nsCAutoString temp3(pbuf);
+
+ {
+ const char* buf="hello rick";
+ int len=strlen(buf);
+
+// nsAutoString temp4(CBufDescriptor(buf,PR_TRUE,len+1,len)); //NOT WORKING
+ }
+
+ nsCAutoString temp5(temp3);
+ nsString s(pbuf);
+ nsCAutoString temp6(s); //create one from a nsString
+
+ nsCAutoString as;
+ int i;
+ for(i=0;i<30;i++){
+ as+='a';
+ }
+ PRBool b=PR_TRUE;
+
+#if 0
+
+/* NOT WORKING
+ char buffer[500];
+
+ nsCAutoString s3(CBufDescriptor(buffer,PR_TRUE,sizeof(buffer)-1,0));
+ s3="hello, my name is inigo montoya.";
+ */
+ //make an autostring that copies an nsString...
+ nsString s0("eat icecream");
+ nsCAutoString s4(s0);
+ nsCAutoString s5(s0.get());
+ nsString aaa("hi there rick");
+#endif
+ }
+
+ const char* st="hello again";
+ nsString s; //this also forces nsString to run it's selftest.
+ s=st;
+ nsAutoString astr;
+ astr=st;
+
+ return result;
+}
+
+/**
+ *
+ * @update gess10/30/98
+ * @param
+ * @return
+ */
+int CStringTester::TestSubsumables(){
+ int result=0;
+ char* buf="hello rick";
+
+ return result;
+}
+
+/**
+ *
+ * @update gess10/30/98
+ * @param
+ * @return
+ */
+int CStringTester::TestRandomOps(){
+ int result=0;
+
+#if 0
+
+ char* str[]={"abc ","xyz ","123 ","789 ","*** ","... "};
+
+ string theSTLString;
+ nsString theString;
+ nsString thePrevString;
+
+ enum ops {eNOP,eAppend,eDelete,eInsert};
+ char* opStrs[] = {"nop","append","delete","insert"};
+
+ srand( (unsigned)time( NULL ) );
+
+ int err[] = {1,7,9,6,0,4,1,1,1,1};
+
+ ops theOp=eNOP;
+ int pos,len,index;
+
+ fstream output("c:/temp/out.file",ios::out);
+ output<<"dump!";
+
+ for(int theOpIndex=0;theOpIndex<1000000;theOpIndex++){
+
+ int r=rand();
+ char buf[100];
+ sprintf(buf,"%i",r);
+ len=strlen(buf);
+ index=buf[len-1]-'0';
+
+ //debug... index=err[theOp];
+
+ switch(index) {
+ case 0:
+ case 1:
+ case 2:
+ theSTLString.append(str[index]);
+ theString.Append(str[index]);
+ theOp=eAppend;
+ break;
+
+ case 3:
+ case 4:
+ case 5:
+ theOp=eInsert;
+ if (theString.Length()>2) {
+ pos=theString.Length()/2;
+ theSTLString.insert(pos,str[index],4);
+ theString.Insert(str[index],pos);
+ }
+ break;
+
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ theOp=eDelete;
+ if(theString.Length()>10) {
+ len=theString.Length()/2;
+ pos=theString.Length()/4;
+ theSTLString.erase(pos,len);
+ theString.Cut(pos,len);
+ }
+ break;
+
+ default:
+ theOp=eNOP;
+
+ } //for
+
+ if(eNOP<theOp) {
+
+ int lendiff=theString.Length()-theSTLString.length();
+ PRBool equals=theString.Equals(theSTLString.c_str());
+ if(((lendiff)) || (!equals)) {
+ printf("Error in %s at:%i len:%i (%s)!\n",opStrs[theOp],pos,len,str[index]);
+ output.close();
+ theString.Equals(theSTLString.c_str());
+
+ if(theOp==eInsert) {
+ thePrevString.Insert(str[index],pos);
+ }
+ else if(theOp==eAppend) {
+ thePrevString.Append(str[index]);
+ }
+ return 0;
+ }
+
+#if FOO
+ output<< opStrs[theOp];
+ if((eInsert==theOp) || (eAppend==theOp)){
+ output<< "(" << str[index] << ", " << pos << ") ";
+ }
+
+ thePrevString.ToCString(buffer,1000,0);
+ output << " Old: [" << buffer << "]";
+ theString.ToCString(buffer,1000,0);
+ output << " New: [" << buffer << "]";
+ output << " STL: [" << theSTLString.c_str() << "]" << endl;
+
+ if(theString.mStringValue.mLength>300) {
+ theString.Truncate();
+ theSTLString.erase();
+ }
+#endif
+ thePrevString=theString;
+ }
+ }
+#endif
+ return result;
+}
+
+
+/**
+ *
+ * @update gess10/30/98
+ * @param
+ * @return
+ */
+int CStringTester::TestReplace(){
+ int result=0;
+
+ const char* find="..";
+ const char* rep= "+";
+
+ const char* s1="hello..there..rick..gessner.";
+ const char* s2="hello+there+rick+gessner.";
+
+ nsCString s(s1);
+ s.ReplaceSubstring(find,rep);
+ NS_ASSERTION(s==s2,"ReplaceSubstring error");
+
+ s.ReplaceSubstring(rep,find);
+ NS_ASSERTION(s==s1,"ReplaceSubstring error");
+
+ return result;
+}
+
+
+/**
+ * This method tests the performance of various methods.
+ *
+ *
+ * @return
+ */
+int CStringTester::TestWideStringPerformance() {
+
+ printf("Widestring performance tests...\n");
+
+ char* libname[] = {"STL","nsString",0};
+
+
+ //**************************************************
+ //Test Construction against STL::wstring...
+ //**************************************************
+ {
+ nsString theConst;
+ for(int z=0;z<10;z++){
+ theConst.Append("0123456789");
+ }
+
+ Stopwatch watch1;
+ int i;
+ for(i=0;i<1000000;i++){
+ nsString s(theConst);
+ }
+ watch1.Stop();
+
+ wchar_t wbuf[] = {'a','b','c','d','e','f','g','h','i','j',0};
+ wstring theConst2;
+ for(int w=0;w<10;w++){
+ theConst2.append(wbuf);
+ }
+
+ Stopwatch watch2;
+#ifdef USE_STL
+ for(i=0;i<1000000;i++){
+ wstring s(theConst2);
+ }
+#endif
+ watch2.Stop();
+
+ printf("Construct(abcde) NSString: %f STL: %f\n",watch1.Elapsed(),watch2.Elapsed());
+ }
+
+
+ //**************************************************
+ //Test append("abcde") against STL::wstring...
+ //**************************************************
+ {
+
+ PRUnichar pbuf[10]={'a','b','c','d','e',0};
+
+ Stopwatch watch1;
+ int i;
+ for(i=0;i<1000;i++){
+ nsString s;
+ for(int j=0;j<200;j++){
+ s.Append("abcde");
+ }
+ }
+ watch1.Stop();
+
+ wchar_t wbuf[10] = {'a','b','c','d','e',0};
+
+ Stopwatch watch2;
+#ifdef USE_STL
+ for(i=0;i<1000;i++){
+ wstring s;
+ for(int j=0;j<200;j++){
+ s.append(wbuf);
+ }
+ }
+#endif
+ watch2.Stop();
+
+ printf("Append(abcde) NSString: %f STL: %f\n",watch1.Elapsed(),watch2.Elapsed());
+ }
+
+ //**************************************************
+ //Test append(char) against STL::wstring
+ //**************************************************
+ {
+
+ Stopwatch watch1;
+ int i;
+ for(i=0;i<500;i++){
+ nsString s;
+ for(int j=0;j<200;j++){
+ s.Append('a');
+ }
+ }
+ watch1.Stop();
+
+
+ Stopwatch watch2;
+#ifdef USE_STL
+ for(i=0;i<500;i++){
+ wstring s;
+ wchar_t theChar('a');
+ for(int j=0;j<200;j++){
+ s.append('a',1);
+ }
+ }
+#endif
+ watch2.Stop();
+
+ printf("Append('a') NSString: %f STL: %f\n",watch1.Elapsed(),watch2.Elapsed());
+ int x=0;
+ }
+
+ //**************************************************
+ //Test insert("123") against STL::wstring
+ //**************************************************
+ {
+
+ PRUnichar pbuf1[10]={'a','b','c','d','e','f',0};
+ PRUnichar pbuf2[10]={'1','2','3',0};
+
+ Stopwatch watch1;
+ int i;
+ for(i=0;i<1000;i++){
+ nsString s("abcdef");
+ int inspos=3;
+ for(int j=0;j<100;j++){
+ s.Insert(pbuf2,inspos);
+ inspos+=3;
+ }
+ }
+ watch1.Stop();
+
+
+ wchar_t wbuf1[10] = {'a','b','c','d','e','f',0};
+ wchar_t wbuf2[10] = {'1','2','3',0};
+
+ Stopwatch watch2;
+#ifdef USE_STL
+ for(i=0;i<1000;i++){
+ wstring s(wbuf1);
+ int inspos=3;
+ for(int j=0;j<100;j++){
+ s.insert(inspos,wbuf2);
+ inspos+=3;
+ }
+ }
+#endif
+ watch2.Stop();
+
+ printf("Insert(123) NSString: %f STL: %f\n",watch1.Elapsed(),watch2.Elapsed());
+ int x=0;
+ }
+
+ //**************************************************
+ //Let's test substring searching performance...
+ //**************************************************
+ {
+ PRUnichar pbuf1[] = {'a','a','a','a','a','a','a','a','a','a','b',0};
+ PRUnichar pbuf2[] = {'a','a','b',0};
+
+ nsString s(pbuf1);
+ nsString target(pbuf2);
+
+ Stopwatch watch1;
+ int i;
+ for(i=-1;i<200000;i++) {
+ PRInt32 result=s.Find(target,PR_FALSE);
+ }
+ watch1.Stop();
+
+ Stopwatch watch2;
+#ifdef USE_STL
+ wchar_t wbuf1[] = {'a','a','a','a','a','a','a','a','a','a','b',0};
+ wchar_t wbuf2[] = {'a','a','b',0};
+ wstring ws(wbuf1);
+ wstring wtarget(wbuf2);
+
+ for(i=-1;i<200000;i++) {
+ PRInt32 result=ws.find(wtarget);
+ }
+#endif
+ watch2.Stop();
+
+ printf("Find(aab) NSString: %f STL: %f\n",watch1.Elapsed(),watch2.Elapsed());
+ }
+
+ //**************************************************
+ //Now let's test comparisons...
+ //**************************************************
+ {
+ nsString s("aaaaaaaaaaaaaaaaaaab");
+ PRUnichar target[]={'a','a','a','a','a','a','a','a','a','a','a','a','a','b',0};
+ size_t theLen=(sizeof(target)-1)/2;
+
+ Stopwatch watch1;
+ int result=0;
+ int i;
+ for(i=-1;i<1000000;i++) {
+ result=s.Compare(target,PR_FALSE,theLen);
+ result++;
+ }
+ watch1.Stop();
+
+ Stopwatch watch2;
+#ifdef USE_STL
+ wchar_t buf[]={'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','b',0};
+ wstring ws(buf);
+ wchar_t wtarget[]={'a','a','a','a','a','a','a','a','a','a','a','a','a','b',0};
+
+ for(i=-1;i<1000000;i++) {
+ result=ws.compare(0,theLen,wtarget);
+ result++;
+ }
+#endif
+ watch2.Stop();
+
+ printf("Compare(aaaaaaaab) NSString: %f STL: %f\n",watch1.Elapsed(),watch2.Elapsed());
+
+ }
+
+ //**************************************************
+ //Now lets test string deletions...
+ //**************************************************
+ {
+
+ int strcount=6000;
+ int outerIter=100;
+ int innerIter=100;
+
+ PRUnichar pbuf[] = {'1','2','3','4','5','6','7','8','9','0',0};
+ nsString source1; //build up our target string...
+ int i;
+ for(i=0;i<strcount;i++) {
+ source1.Append(pbuf);
+ }
+
+ Stopwatch watch1;
+
+ for(i=0;i<outerIter;i++) {
+ nsString s1(source1);
+ for(int j=0;j<100;j++){
+ s1.Cut(20,50);
+ }
+ }
+ watch1.Stop();
+ printf("Cut(...) NSString: %f ",watch1.Elapsed());
+
+#ifdef USE_STL
+
+ wchar_t wbuf[] = {'1','2','3','4','5','6','7','8','9','0',0};
+ wstring source2; //build up our target string...
+
+ for(i=0;i<strcount;i++) {
+ source2.append(wbuf);
+ }
+
+ Stopwatch watch2;
+
+ for(i=0;i<outerIter;i++) {
+ wstring s2(source2);
+ for(int j=0;j<100;j++){
+ s2.erase(20,50);
+ }
+ }
+ watch2.Stop();
+
+ printf(" STL: %f",watch2.Elapsed());
+#endif
+ printf("\n");
+
+ }
+
+ //**************************************************
+ //Now let's test the findChar routine...
+ //**************************************************
+ {
+
+ nsString s1;
+ int i;
+ for(i=0;i<100;i++) {
+ s1.Append("1234567890",10);
+ }
+ s1+="xyz";
+
+ Stopwatch watch1;
+ for(i=0;i<100000;i++) {
+ int f=s1.FindChar('z',PR_FALSE,0);
+ }
+ watch1.Stop();
+ printf("FindChar('z') NSString: %f",watch1.Elapsed());
+
+#ifdef USE_STL
+ wchar_t wbuf[] = {'1','2','3','4','5','6','7','8','9','0',0};
+ wstring s2;
+ for( i=0;i<100;i++) {
+ s2.append(wbuf);
+ }
+ wchar_t wbuf2[] = {'x','y','z',0};
+ s2.append(wbuf2);
+
+ Stopwatch watch2;
+
+ for(i=0;i<100000;i++) {
+ int f=s2.find_first_of('z',0);
+ }
+ watch2.Stop();
+ printf(" STL: %f",watch2.Elapsed());
+#endif
+ printf("\n");
+
+ }
+ return 0;
+}
+
+
+/************************************************************************************************
+ *
+ * This method tests the performance of various methods.
+ *
+ ************************************************************************************************/
+int CStringTester::TestStringPerformance() {
+ printf("c-String performance tests...\n");
+
+ char* libname[] = {"STL","nsString",0};
+
+ //**************************************************
+ //Test Construction against STL::wstring...
+ //**************************************************
+ {
+ nsCString theConst;
+ for(int z=0;z<10;z++){
+ theConst.Append("0123456789");
+ }
+
+ Stopwatch watch1;
+ int i;
+ for(i=0;i<1000000;i++){
+ nsCString s(theConst);
+ }
+ watch1.Stop();
+
+ char wbuf[] = {'a','b','c','d','e','f','g','h','i','j',0};
+ string theConst2;
+ for(int w=0;w<10;w++){
+ theConst2.append(wbuf);
+ }
+
+ Stopwatch watch2;
+#ifdef USE_STL
+ for(i=0;i<1000000;i++){
+ string s(theConst2);
+ }
+#endif
+ watch2.Stop();
+
+ printf("Construct(abcde) NSCString: %f STL: %f\n",watch1.Elapsed(),watch2.Elapsed());
+ }
+
+ //**************************************************
+ //Test append("abcde") against STL...
+ //**************************************************
+
+ {
+
+ Stopwatch watch1;
+ int i;
+ for(i=0;i<1000;i++){
+ nsCString s;
+ for(int j=0;j<200;j++){
+ s.Append("abcde",5);
+ }
+ }
+ watch1.Stop();
+
+ Stopwatch watch2;
+#ifdef USE_STL
+ for(i=0;i<1000;i++){
+ string s;
+ for(int j=0;j<200;j++){
+ s.append("abcde",5);
+ }
+ }
+#endif
+ watch2.Stop();
+
+ printf("Append(abcde) NSCString: %f STL: %f\n",watch1.Elapsed(),watch2.Elapsed());
+ int x=0;
+ }
+
+ //**************************************************
+ //Test append(char) against STL
+ //**************************************************
+ {
+
+ Stopwatch watch1;
+ int i;
+ for(i=0;i<500;i++){
+ nsCString s;
+ for(int j=0;j<200;j++){
+ s.Append('a');
+ }
+ }
+ watch1.Stop();
+
+ Stopwatch watch2;
+#ifdef USE_STL
+ for(i=0;i<500;i++){
+ string s;
+ wchar_t theChar('a');
+ for(int j=0;j<200;j++){
+ s.append('a',1);
+ }
+ }
+#endif
+ watch2.Stop();
+
+ printf("Append('a') NSCString: %f STL: %f\n",watch1.Elapsed(),watch2.Elapsed());
+ int x=0;
+ }
+
+ //**************************************************
+ //Test insert("123") against STL
+ //**************************************************
+ {
+
+ char pbuf1[10]={'a','b','c','d','e','f',0};
+ char pbuf2[10]={'1','2','3',0};
+
+ Stopwatch watch1;
+ int i;
+ for(i=0;i<1000;i++){
+ nsCString s("abcdef");
+ int inspos=3;
+ for(int j=0;j<100;j++){
+ s.Insert(pbuf2,inspos);
+ inspos+=3;
+ }
+ }
+ watch1.Stop();
+
+ Stopwatch watch2;
+#ifdef USE_STL
+ for(i=0;i<1000;i++){
+ string s(pbuf1);
+ int inspos=3;
+ for(int j=0;j<100;j++){
+ s.insert(inspos,pbuf2);
+ inspos+=3;
+ }
+ }
+#endif
+ watch2.Stop();
+
+ printf("insert(123) NSCString: %f STL: %f\n",watch1.Elapsed(),watch2.Elapsed());
+ int x=0;
+ }
+
+ //**************************************************
+ //Let's test substring searching performance...
+ //**************************************************
+ {
+ char *pbuf1 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" \
+ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+ "aab";
+
+ char *pbuf2 = "aab";
+
+ nsCString s(pbuf1);
+
+ Stopwatch watch1;
+ int i;
+ for(i=-1;i<20000;i++) {
+ PRInt32 result=s.Find(pbuf2,PR_FALSE);
+ }
+ watch1.Stop();
+
+ Stopwatch watch2;
+#ifdef USE_STL
+ string ws(pbuf1);
+ for(i=-1;i<20000;i++) {
+ PRInt32 result=ws.find(pbuf2);
+ }
+#endif
+ watch2.Stop();
+
+ printf("Find(aab) NSCString: %f STL: %f\n",watch1.Elapsed(),watch2.Elapsed());
+ }
+
+ //**************************************************
+ //Now let's test comparisons...
+ //**************************************************
+ {
+ char* target="aaaaaaaaaaaaab";
+ size_t theLen=strlen(target);
+
+ Stopwatch watch1;
+ nsCString s("aaaaaaaaaaaaaaaaaaab");
+ int result=0;
+ int i;
+ for(i=-1;i<1000000;i++) {
+ result=s.Compare(target,PR_FALSE,theLen);
+ result++;
+ }
+ watch1.Stop();
+
+ Stopwatch watch2;
+#ifdef USE_STL
+ string ws("aaaaaaaaaaaaaaaaaaab");
+ for(i=-1;i<1000000;i++) {
+ result=ws.compare(0,theLen,target);
+ result++;
+ }
+#endif
+ watch2.Stop();
+
+ printf("Compare(aaaaaaaab) NSCString: %f STL: %f\n",watch1.Elapsed(),watch2.Elapsed());
+
+ }
+
+ //**************************************************
+ //Now lets test string deletions...
+ //**************************************************
+ {
+
+ int strcount=6000;
+ int outerIter=100;
+ int innerIter=100;
+
+ char* buffer = "1234567890";
+ nsCString source1; //build up our target string...
+ int i;
+ for(i=0;i<strcount;i++) {
+ source1.Append(buffer);
+ }
+
+ Stopwatch watch1;
+ for(i=0;i<outerIter;i++) {
+ nsCString s1(source1);
+ for(int j=0;j<innerIter;j++){
+ s1.Cut(20,50);
+ }
+ }
+ watch1.Stop();
+ printf("Cut(...) NSCString: %f ",watch1.Elapsed());
+
+#ifdef USE_STL
+ string source2; //build up our target string...
+ for(i=0;i<strcount;i++) {
+ source2.append(buffer);
+ }
+
+ Stopwatch watch2;
+ for(i=0;i<outerIter;i++) {
+ string s2(source2);
+ for(int j=0;j<innerIter;j++){
+ s2.erase(20,50);
+ }
+ }
+ watch2.Stop();
+
+ printf(" STL: %f",watch2.Elapsed());
+#endif
+ printf("\n");
+ }
+
+
+ //**************************************************
+ //Now let's test the findChar routine...
+ //**************************************************
+ {
+
+ nsCString s1;
+ int i;
+ for(i=0;i<100;i++) {
+ s1.Append("1234567890",10);
+ }
+ s1+="xyz";
+
+ Stopwatch watch1;
+ for(i=0;i<100000;i++) {
+ int f=s1.FindChar('z',PR_FALSE,0);
+ }
+ watch1.Stop();
+ printf("FindChar('z') NSCString: %f ",watch1.Elapsed());
+
+#ifdef USE_STL
+ string s2;
+ for( i=0;i<100;i++) {
+ s2.append("1234567890");
+ }
+ s2.append("xyz");
+
+ Stopwatch watch2;
+ for(i=0;i<100000;i++) {
+ int f=s2.find_first_of('z',0);
+ }
+ watch2.Stop();
+ printf(" STL: %f\n",watch1.Elapsed(),watch2.Elapsed());
+#endif
+ printf("\n");
+
+ }
+ return 0;
+}
+
+
+/**
+ * This method is here as a place to put known regressions...
+ *
+ *
+ * @return
+ */
+int CStringTester::TestRegressions() {
+
+ nsString s("FTP: Netscape</a>");
+ PRInt32 result=s.Find("</A>",PR_TRUE);
+
+ //this was a known bug...
+ {
+ nsString s0("");
+ PRInt32 pos=s0.RFind("-->");
+ nsString s1("debug");
+ pos=s1.RFind("b");
+ pos=s1.RFind("de",PR_FALSE,1);
+ pos=10;
+ }
+
+ //this was a known bug...
+ {
+ nsString s0("RDF:RDF");
+ PRInt32 pos=s0.Find(":");
+ pos=10;
+ }
+
+ return result;
+}
+
+#endif
+
diff --git a/src/libs/xpcom18a4/xpcom/tests/windows/nsStringTest2.h b/src/libs/xpcom18a4/xpcom/tests/windows/nsStringTest2.h
new file mode 100644
index 00000000..16ffc11a
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/tests/windows/nsStringTest2.h
@@ -0,0 +1,444 @@
+/********************************************************************************************
+ *
+ * MODULES NOTES:
+ *
+ * This file is designed to help test the new nsString classes.
+ *
+ * Contributor(s):
+ * Rick Gessner <rickg@netscape.com>
+ *
+ * History:
+ *
+ * 02.29.2000: Original files (rickg)
+ * 03.02.2000: Flesh out the interface to be compatible with old library (rickg)
+ *
+ ********************************************************************************************/
+
+#ifndef _STRINGTEST2
+#define _STRINGTEST2
+
+
+#include "nsString.h"
+#include <time.h>
+
+#define USE_STL
+
+#ifdef USE_STL
+#include <string>
+using namespace std;
+#endif
+
+#define USE_WIDE 1
+#ifdef USE_WIDE
+ #define stringtype nsString
+ #define astringtype nsAutoString
+ #define chartype PRUnichar
+#else
+ #define stringtype nsCString
+ #define astringtype nsCAutoString
+ #define chartype char
+#endif
+
+#include <stdio.h>
+const double gTicks = 1.0e-7;
+
+
+
+
+
+/********************************************************
+
+ This class's only purpose in life is to test the
+ netscape string library. We exercise the string
+ API's here, and do a bit of performance testing
+ against the standard c++ library string (from STL).
+
+ ********************************************************/
+class CStringTester {
+
+public:
+
+ int TestI18nString();
+
+};
+
+
+
+
+//test 1: unicode char is stripped correctly using StripChars()
+void nsStringTest1(){
+ PRUnichar test[]={0x0041,0x0051,0x0052,0x0000};
+ nsString T(test);
+ PRUnichar result[]={0x0051,0x0052,0x0000};
+ nsString R(result);
+ T.StripChars("ABC");
+ NS_ASSERTION(T.Equals(R), "Test 1: Unicode comparison error");
+}
+//test 2: unicode char is not matched and stripped when high-order byte is not 0x00
+void nsStringTest2(){
+ PRUnichar test[]={0x4e41,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString T(test);
+ PRUnichar result[]={0x4e41,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString R(result);
+ T.StripChars("ABC");
+ NS_ASSERTION(T.Equals(R), "Unicode comparison error");
+}
+ //test 3: unicode char is not matched and stripped when high-order byte is 0xFF
+void nsStringTest3(){
+
+ PRUnichar test[] = {0xFF41,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString T(test);
+ PRUnichar result[] = {0xFF41,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString R(test);
+ T.StripChars("ABC");
+ NS_ASSERTION(T.Equals(R), "Unicode comparison error");
+}
+void nsStringTest4(){
+ //test 4: unicode char is matched and stripped correctly using StripChar()
+ PRUnichar test[] = {0x0041,0x0051,0x0052,0x0000};
+ nsAutoString T(test);
+ PRUnichar result[] = {0x0051,0x0052,0x0000};
+ nsAutoString R(result);
+ T.StripChar('A');
+ NS_ASSERTION(T.Equals(R), "Unicode comparison error");
+}
+void nsStringTest5(){
+ //test 5: unicode char is not matched and stripped when high-order byte is not 0x00
+
+ PRUnichar test[]={0x4e41,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString T(test);
+ PRUnichar result[]={0x4e41,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString R(result);
+ T.StripChar('A');
+ NS_ASSERTION(T.Equals(R), "Unicode comparison error");
+}
+void nsStringTest6(){
+ //test 6: unicode char is not matched and stripped when high-order byte is 0xFF
+
+ PRUnichar test[] = {0xFF41,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString T(test);
+ PRUnichar result[] = {0xFF41,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString R(result);
+ T.StripChar('A');
+ NS_ASSERTION(T.Equals(R), "Unicode comparison error");
+}
+void nsStringTest7(){
+ //test 7: unicode char is matched and replaced correctly using ReplaceChar()
+
+ PRUnichar test[] = {0x0041,0x0051,0x0052,0x0000};
+ nsAutoString T(test);
+ PRUnichar result[] = {0x0050,0x0051,0x0052,0x0000};
+ nsAutoString R(result);
+ T.ReplaceChar('A',0x50);
+ NS_ASSERTION(T.Equals(R), "Unicode comparison error");
+}
+void nsStringTest8(){
+ //test 8: unicode char is not matched or replaced when high-order byte != 0x00
+
+ PRUnichar test[] = {0x4e41,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString T(test);
+ PRUnichar result[] = {0x4e41,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString R(result);
+ T.ReplaceChar('A',0x50);
+ NS_ASSERTION(T.Equals(R), "Unicode comparison error");
+}
+void nsStringTest9(){
+ //test 9: unicode char is not matched or replaced when high-order byte matches search char
+
+ PRUnichar test[] = {0x4150,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString T(test);
+ PRUnichar result[] = {0x4150,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString R(result);
+ T.ReplaceChar('A',0x50);
+ NS_ASSERTION(T.Equals(R), "Unicode comparison error");
+}
+void nsStringTest10(){
+ //test 10: unicode char is not matched or replaced when high-order byte == 0xFF
+
+ PRUnichar test[] = {0xFFc1,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString T(test);
+ PRUnichar result[] = {0xFFc1,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString R(result);
+ T.ReplaceChar('A',0x50);
+ NS_ASSERTION(T.Equals(R), "Unicode comparison error");
+}
+
+void nsStringTest11(){
+ //test 11: unicode char is correctly replaced when parameter 1 is a string
+
+ PRUnichar test[] = {0x0041,0x0051,0x0052,0x0000};
+ nsAutoString T(test);
+ PRUnichar result[] = {0x0050,0x0051,0x0052,0x0000};
+ nsAutoString R(result);
+ T.ReplaceChar("ABC",0x50);
+ NS_ASSERTION(T.Equals(R), "Unicode comparison error");
+}
+void nsStringTest12(){
+ //test 12: unicode char is not replaced when high-order byte != 0x00
+
+ PRUnichar test[] = {0x4e41,0x0051,0x0052,0x0000};
+ nsAutoString T(test);
+ PRUnichar result[] = {0x4e41,0x0051,0x0052,0x0000};
+ nsAutoString R(result);
+ T.ReplaceChar("ABC",0x50);
+ NS_ASSERTION(T.Equals(R), "Unicode comparison error");
+
+}
+void nsStringTest13(){
+ //test 13: unicode char is not replaced when high-order byte matches char in search string
+ PRUnichar test[] = {0x4150,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString T(test);
+ PRUnichar result[] = {0x4150,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString R(result);
+ T.ReplaceChar("ABC",'T');
+ NS_ASSERTION(T.Equals(R), "Unicode comparison error");
+
+}
+void nsStringTest14(){
+ PRUnichar test[] = {0xFFc2,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString T(test);
+ PRUnichar result[] = {0xFFc2,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString R(result);
+ T.ReplaceChar("ABC",'T');
+ NS_ASSERTION(T.Equals(R), "Unicode comparison error");
+}
+void nsStringTest15(){
+ PRUnichar test[] = {0xFFc2,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString T(test);
+ PRUnichar result[] = {0xFFc2,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString R(result);
+ PRUnichar s = 0xc2; //compiler error on this line
+ T.ReplaceChar(s,'T');
+ NS_ASSERTION(T.Equals(R), "Unicode comparison error");
+}
+
+void nsStringTest16(){
+ /* TESTS for ReplaceSubstring()*/
+
+ PRUnichar test[] = {0x0041,0x0042,0x0043,0x0044,0x0045,0x0000};
+ nsAutoString T(test);
+ PRUnichar result[] = {0x0044,0x0045,0x0046,0x0044,0x0045};
+ nsAutoString R(result);
+ T.ReplaceSubstring("ABC","DEF");
+ NS_ASSERTION(T.Equals(R), "Unicode comparison error");
+
+}
+void nsStringTest17(){
+
+ PRUnichar test[] = {0x0041,0x4e42,0x0043,0x0044,0x0045,0x0000};
+ nsAutoString T(test);
+ PRUnichar result[] = {0x0041,0x4e42,0x0043,0x0044,0x0045,0x0000};
+ nsAutoString R(result);
+ T.ReplaceSubstring("ABC","DEF");
+ NS_ASSERTION(T.Equals(R), "Unicode comparison error");
+}
+void nsStringTest18(){
+ /*TESTS for Trim()*/
+
+ PRUnichar test[] = {0x0041,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString T(test);
+ PRUnichar result[] = {0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString R (result);
+ T.Trim("ABC");
+ NS_ASSERTION(T.Equals(R), "Unicode comparison error");
+}
+void nsStringTest19(){
+ PRUnichar test[] = {0x4e41,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString T(test);
+ PRUnichar result[] = {0x4e41,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString R(result);
+ T.Trim("ABC");
+ NS_ASSERTION(T.Equals(R), "Unicode comparison error");
+}
+void nsStringTest22(){
+ PRUnichar test[] = {0x4e51,0x4e52,0x4e53,0x4e41,0x0000};
+ nsAutoString T(test);
+ PRUnichar result[] = {0x4e51,0x4e52,0x4e53,0x4e41,0x0000};
+ nsAutoString R(result);
+ T.Trim("ABC");
+ NS_ASSERTION(T.Equals(R), "Unicode comparison error");
+
+}
+//void nsStringTest23(){
+// PRUnichar test[] = {0x4e51,0x4e52,0x4e53,0x4e22,0x0000};
+// nsAutoString T(test);
+// PRUnichar s(0x4e22);
+// PRUnichar result[] = {0x4e51,0x4e52,0x4e53,0x0000};
+// nsAutoString R(result);
+// T.Trim(s,PR_TRUE,PR_TRUE,PR_FALSE);
+// NS_ASSERTION(T.Equals(R), "Unicode comparison error");
+//}
+void nsStringTest24(){
+ /*TESTS for Find()*/
+ PRUnichar test[] = {0x0041,0x0042,0x0043,0x0051,0x0052,0x0000};
+ nsAutoString T(test);
+ NS_ASSERTION(T.Find("ABC") == 0, "Unicode comparison error");
+
+}
+void nsStringTest25(){
+ PRUnichar test[] = {0x4e41,0x4e42,0x4e43,0x4e53,0x0000};
+ nsAutoString T(test);
+ NS_ASSERTION(T.Find("ABC") == -1, "Unicode comparison error");
+
+}
+void nsStringTest26(){
+ PRUnichar test[] = {0xFFc1,0x0051,0x0052,0x0053,0x0000};
+ nsAutoString T(test);
+ PRUnichar str[] = {0xc1,0x51,0x52};
+ nsAutoString S(str);
+ NS_ASSERTION(T.Find(S) == -1, "Unicode comparison error");
+}
+void nsStringTest27(){
+ /*TESTS for FindChar()*/
+
+ PRUnichar test[] = {0x0041,0x0051,0x0052,0x0000};
+ nsAutoString T(test);
+ NS_ASSERTION(T.FindChar('A') == 0, "Unicode comparison error");
+}
+void nsStringTest28(){
+ PRUnichar test[] = {0x4e41,0x4e42,0x4e43,0x4e53,0x0000};
+ nsAutoString T(test);
+ NS_ASSERTION(T.FindChar('A') == -1, "Unicode comparison error");
+}
+void nsStringTest29(){
+ PRUnichar test[] = {0xFFc1,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString T(test);
+ NS_ASSERTION(T.FindChar(0xc1) == -1, "Unicode comparison error");
+
+}
+void nsStringTest30(){
+ PRUnichar test[] = {0x4132,0x0051,0x0052,0x0000};
+ nsAutoString T(test);
+ NS_ASSERTION(T.FindChar('A1') == -1, "Unicode comparison error");
+}
+ /*TESTS for FindCharInSet()*/
+void nsStringTest31(){
+ PRUnichar test[] = {0x0041,0x0051,0x0052,0x0000};
+ nsAutoString T(test);
+ NS_ASSERTION(T.FindCharInSet("ABC") == 0, "Unicode comparison error");
+}
+void nsStringTest32(){
+ PRUnichar test[] = {0x4e41,0x4e42,0x4e43,0x4e53,0x0000};
+ nsAutoString T(test);
+ NS_ASSERTION(T.FindCharInSet("ABC") == -1, "Unicode comparison error");
+
+}
+void nsStringTest33(){
+ PRUnichar test[] = {0xFFc1,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString T(test);
+ PRUnichar str[] = {0xc1,0x51,0x52};
+ nsAutoString s(str);
+ NS_ASSERTION(T.FindCharInSet(s) == -1, "Unicode comparison error");
+}
+void nsStringTest34(){
+ PRUnichar test[] = {0x4132,0x5132,0x5232,0x0000};
+ nsAutoString T(test);
+ NS_ASSERTION(T.FindCharInSet("ABC") == -1, "Unicode comparison error");
+}
+ /*TESTS for RFind()*/
+void nsStringTest35(){
+
+ PRUnichar test[] = {0x0051,0x0052,0x0041,0x0042,0x0043,0x0000};
+ nsAutoString T(test);
+ NS_ASSERTION(T.RFind("ABC") == 2, "Unicode comparison error");
+}
+void nsStringTest36(){
+ PRUnichar test[] = {0x4e41,0x4e42,0x4e43,0x4e53,0x0000};
+ nsAutoString T(test);
+ NS_ASSERTION(T.RFind("ABC") == -1, "Unicode comparison error");
+}
+void nsStringTest37(){
+ PRUnichar test[] = {0xFFc1,0xFFc2,0xFFc3,0x4e53,0x0000};
+ nsAutoString T(test);
+ PRUnichar str[] = {0xc1,0xc2,0xc3};
+ nsAutoString s(str);
+ NS_ASSERTION(T.RFind(s) == -1, "Unicode comparison error");
+}
+ /*TESTS for RFindCharInSet*/
+void nsStringTest38(){
+
+ PRUnichar test[] = {0x0041,0x0042,0x0043,0x0000};
+ nsAutoString T(test);
+ int res = T.RFindCharInSet("ABC");
+ NS_ASSERTION(res==0, "Unicode comparison error");
+}
+void nsStringTest39(){
+ PRUnichar test[] = {0x4e41,0x4e42,0x4e43,0x4e53,0x0000};
+ nsAutoString T(test);
+ NS_ASSERTION(T.RFindCharInSet("ABC") == -1, "Unicode comparison error");
+}
+void nsStringTest40(){
+ PRUnichar test[] = {0xFFc1,0x4e51,0x4e52,0x4e53,0x0000};
+ nsAutoString T(test);
+ PRUnichar str[] = {0xc1,0xc2,0xc3};
+ nsAutoString s(str);
+ NS_ASSERTION(T.RFindCharInSet(s) == -1, "Unicode comparison error");
+}
+void nsStringTest41(){
+ PRUnichar test[] = {0x4132,0x0051,0x0052,0x0000};
+ nsAutoString T(test);
+ NS_ASSERTION(T.RFindCharInSet("ABC") == -1, "Unicode comparison error");
+}
+ /* TESTS for Compare() */
+void nsStringTest42(){
+ PRUnichar test[] = {0x0041,0x0042,0x0043,0x0000};
+ nsAutoString T(test);
+ NS_ASSERTION(T.Compare("ABC") == 0, "Unicode comparison error");
+}
+void nsStringTest43(){
+ PRUnichar test[] = {0xc341,0xc342,0xc343};
+ nsAutoString T(test);
+ NS_ASSERTION(T.Compare("ABC") == 1, "Unicode comparison error");
+}
+
+
+int CStringTester::TestI18nString(){
+ nsStringTest1();
+ nsStringTest2();
+ nsStringTest3();
+ nsStringTest4();
+ nsStringTest5();
+ nsStringTest6();
+ nsStringTest7();
+ nsStringTest8();
+ nsStringTest9();
+ nsStringTest10();
+ nsStringTest11();
+ nsStringTest12();
+ nsStringTest13();
+ nsStringTest14();
+ nsStringTest15();
+ nsStringTest16();
+ nsStringTest17();
+ nsStringTest18();
+ nsStringTest19();
+ //nsStringTest20();
+ //nsStringTest21();
+ nsStringTest22();
+ //nsStringTest23();
+ nsStringTest24();
+ nsStringTest25();
+ nsStringTest26();
+ nsStringTest27();
+ nsStringTest28();
+ nsStringTest29();
+ nsStringTest30();
+ nsStringTest31();
+ nsStringTest32();
+ nsStringTest33();
+ nsStringTest34();
+ nsStringTest35();
+ nsStringTest36();
+ nsStringTest37();
+ nsStringTest38();
+ nsStringTest39();
+ nsStringTest40();
+ nsStringTest41();
+ nsStringTest42();
+ nsStringTest43();
+
+ return 0;
+}
+
+#endif
+