diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 16:49:04 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 16:49:04 +0000 |
commit | 16f504a9dca3fe3b70568f67b7d41241ae485288 (patch) | |
tree | c60f36ada0496ba928b7161059ba5ab1ab224f9d /src/libs/xpcom18a4/xpcom/tests | |
parent | Initial commit. (diff) | |
download | virtualbox-upstream.tar.xz virtualbox-upstream.zip |
Adding upstream version 7.0.6-dfsg.upstream/7.0.6-dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/libs/xpcom18a4/xpcom/tests')
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 Binary files differnew file mode 100644 index 00000000..12b125ed --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/tests/StringFactoringTests/StringTest.mcp 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("·"); + nsString str6("ξ"); + nsString str7("#xe3;"); + nsString str8("#FF;"); + nsCString str9("-#xa?a;"); //should return -10 (decimal) + nsCString str10("¿"); + 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 + |