Compare commits

..

30 Commits

Author SHA1 Message Date
mcmullen%netscape.com
2f5a1bb974 Resolve an ambiguity.
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21795 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-24 21:58:24 +00:00
mcmullen%netscape.com
ba6697abea Added nsIFileStream.h
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21555 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-23 02:51:31 +00:00
dougt%netscape.com
83e45c0c06 Minor fix.
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21551 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-23 02:40:05 +00:00
mcmullen%netscape.com
082eb36f10 Resolve an ambiguity.
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21547 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-23 02:34:25 +00:00
dougt%netscape.com
c9419449af Minor fixes.
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21546 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-23 02:34:08 +00:00
mcmullen%netscape.com
53d1512433 added nsIFileStream.cpp
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21545 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-23 02:31:48 +00:00
mcmullen%netscape.com
9a8b653ca2 COMify the file stream classes. This is pretty much a rewrite of the file streams.
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21509 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-23 00:46:54 +00:00
dougt%netscape.com
aebd76033c Fixed typo in #ifdef
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21484 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-22 19:27:48 +00:00
mcmullen%netscape.com
5dd8dddb46 Change += because SetLeafName has changed its meaning.
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21480 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-22 19:07:55 +00:00
mcmullen%netscape.com
2b96a39294 Added i.Exists() because bool doesn't compile on Unix.
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21473 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-22 18:57:15 +00:00
dougt%netscape.com
718707ba40 Fixes to unix copy/move/execute testcases
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21448 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-22 01:33:25 +00:00
dougt%netscape.com
10eeba9d76 Bug Fixes.
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21447 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-22 01:31:57 +00:00
mcmullen%netscape.com
91646707bf Since nsFileSpec no longer always resolves aliases, resolve them on open.
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21421 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-21 01:03:35 +00:00
mcmullen%netscape.com
5d54af72be Don't call resolved alias. Allow a file spec to be the spec of an alias.
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21420 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-21 01:02:47 +00:00
mcmullen%netscape.com
2a09be3c39 Unix and windows: directories etc were returning an empty string for the leaf name (because the path ended with the separator). Fixed Get/SetLeafName for this case.
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21419 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-21 01:02:16 +00:00
mcmullen%netscape.com
b77bb8b8c5 Fix unix. Also un-inline a function (to support use of errors in other files)
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21415 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-20 23:40:17 +00:00
mcmullen%netscape.com
946bd4bc0f First Checked In.
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21387 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-20 03:07:31 +00:00
mcmullen%netscape.com
6e77208d7a Removed bool and explicit for Unix compilers
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21328 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-19 20:10:50 +00:00
mcmullen%netscape.com
b5fe3e7a13 Unified all the error handling. Implemented Error() and mError on all platforms. Added an error macro to use the range now reserved for us in nsError.h.
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21182 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-18 20:27:46 +00:00
mcmullen%netscape.com
ec80e4e760 Added a constant for the maximum persistent data size, and thus made two different constants consistent.
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21162 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-18 18:37:41 +00:00
dougt%netscape.com
74774c47f2 Treaks to get persistance working on windows.
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21157 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-18 17:56:15 +00:00
mcmullen%netscape.com
5c1cada60f PersistentFileDescriptor implemented.
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21119 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-18 04:26:23 +00:00
dougt%netscape.com
91f491620b Tweaks to get unix building.
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21091 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-18 02:17:46 +00:00
dougt%netscape.com
9037f57592 Changes bool to PRBool.
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21088 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-18 01:54:29 +00:00
mcmullen%netscape.com
e778f7b001 This time, go in on the BRANCH, I say!
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21074 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-18 00:51:32 +00:00
mcmullen%netscape.com
3afb4537a8 Updated to match the header changes I've been making. Also, added the declaration of the persistent filespec class.
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21064 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-18 00:35:41 +00:00
dougt%netscape.com
4fdcc84d5c Changed an 8-bit "Bullet" char to an *.
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21045 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-17 23:31:53 +00:00
dougt%netscape.com
bde4db995d added Copy(), Move(), Rename(), Execute(), to the nsNativeFileSpec.
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21044 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-17 23:28:38 +00:00
dougt%netscape.com
278fb56b72 Added Copy(), Move(), Rename(), and Execute() to the nsNativeFileSpec.
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@21042 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-17 23:26:38 +00:00
(no author)
4bafe0bf37 This commit was manufactured by cvs2svn to create branch 'BASE_17_FEB_99'.
git-svn-id: svn://10.0.0.236/branches/BASE_17_FEB_99@20989 18797224-902f-48f8-a5cc-f745e15eee43
1999-02-17 18:20:28 +00:00
167 changed files with 42204 additions and 881 deletions

33
mozilla/base/Makefile.in Normal file
View File

@@ -0,0 +1,33 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH = ..
topsrcdir = @top_srcdir@
VPATH = @srcdir@
srcdir = @srcdir@
include $(DEPTH)/config/autoconf.mk
DIRS = public src
ifdef ENABLE_TESTS
DIRS += tests
endif
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,21 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#define _IMPL_NS_BASE 1
#include "MacPrefix_debug.h"

View File

@@ -0,0 +1,21 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#define _IMPL_NS_BASE 1
#include "MacPrefix.h"

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,19 @@
# target: baseDebug.shlb
mozilla/base/src/mac/nsTimerMac.cpp
mozilla/base/src/nsArena.cpp
mozilla/base/src/nsAtomTable.cpp
mozilla/base/src/nsBaseDLL.cpp
mozilla/base/src/nsBTree.cpp
mozilla/base/src/nsByteBuffer.cpp
mozilla/base/src/nsCRT.cpp
mozilla/base/src/nsDeque.cpp
mozilla/base/src/nsEscape.cpp
mozilla/base/src/nsFileSpec.cpp
mozilla/base/src/nsFileStream.cpp
mozilla/base/src/nsRBTree.cpp
mozilla/base/src/nsProperties.cpp
mozilla/base/src/nsSizeOfHandler.cpp
mozilla/base/src/nsString.cpp
mozilla/base/src/nsUnicharBuffer.cpp
mozilla/base/src/nsUnicharInputStream.cpp
mozilla/base/src/nsVoidArray.cpp

View File

@@ -0,0 +1,19 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "MacPrefix_debug.h"

View File

@@ -0,0 +1,19 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "MacPrefix_debug.h"

23
mozilla/base/makefile.win Normal file
View File

@@ -0,0 +1,23 @@
#!nmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=..
IGNORE_MANIFEST=1
DIRS=public src tests
include <$(DEPTH)\config\rules.mak>

View File

@@ -0,0 +1,12 @@
#
# This is a list of local files which get copied to the mozilla:dist:base directory
#
nsAutoLock.h
nsISizeOfHandler.h
nsFileStream.h
nsIFileStream.h
nsFileSpec.h
nsRepeater.h
nsIProperties.h
nsCaretProperties.h

View File

@@ -0,0 +1,44 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DEFINES += -D_IMPL_NS_BASE
EXPORTS = \
nsAutoLock.h \
nsIProperties.h \
nsISizeOfHandler.h \
nsCaretProperties.h \
nsEscape.h \
nsFileSpec.h \
nsFileStream.h \
nsIFileStream.h \
$(NULL)
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
MODULE=base
include $(topsrcdir)/config/config.mk
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,37 @@
#!nmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=..\..
IGNORE_MANIFEST=1
DEFINES = -D_IMPL_NS_BASE
EXPORTS = \
nsAutoLock.h \
nsCaretProperties.h \
nsIProperties.h \
nsISizeOfHandler.h \
nsEscape.h \
nsFileSpec.h \
nsFileStream.h \
nsIFileStream.h \
$(NULL)
MODULE = raptor
include <$(DEPTH)\config\rules.mak>

View File

@@ -0,0 +1,116 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
A stack-based lock object that makes using PRLock a bit more
convenient. It acquires the monitor when constructed, and releases
it when it goes out of scope.
For example,
class Foo {
private:
PRLock* mLock;
public:
Foo(void) {
mLock = PR_NewLock();
}
virtual ~Foo(void) {
PR_DestroyLock(mLock);
}
void ThreadSafeMethod(void) {
// we're don't hold the lock yet...
nsAutoLock lock(mLock);
// ...but now we do.
// we even can do wacky stuff like return from arbitrary places w/o
// worrying about forgetting to release the lock
if (some_weird_condition)
return;
// otherwise do some other stuff
}
void ThreadSafeBlockScope(void) {
// we're not in the lock here...
{
nsAutoLock lock(mLock);
// but we are now, at least until the block scope closes
}
// ...now we're not in the lock anymore
}
};
*/
#ifndef nsAutoLock_h__
#define nsAutoLock_h__
#include "nscore.h"
#include "prlock.h"
#include "prlog.h"
// If you ever decide that you need to add a non-inline method to this
// class, be sure to change the class declaration to "class NS_BASE
// nsAutoLock".
class nsAutoLock {
private:
PRLock* mLock;
// Not meant to be implemented. This makes it a compiler error to
// construct or assign an nsAutoLock object incorrectly.
nsAutoLock(void) {}
nsAutoLock(nsAutoLock& aLock) {}
nsAutoLock& operator =(nsAutoLock& aLock) {
return *this;
}
// Not meant to be implemented. This makes it a compiler error to
// attempt to create an nsAutoLock object on the heap.
static void* operator new(size_t size) {
return nsnull;
}
static void operator delete(void* memory) {}
public:
nsAutoLock(PRLock* aLock) : mLock(aLock) {
PR_ASSERT(mLock);
// This will assert deep in the bowels of NSPR if you attempt
// to re-enter the lock.
PR_Lock(mLock);
}
~nsAutoLock(void) {
PR_Unlock(mLock);
}
};
#endif // nsAutoLock_h__

View File

@@ -0,0 +1,53 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
// this class is used to gather caret properties from the OS. It
// must be implemented by each platform that wants more than
// the generic caret properties.
class nsCaretProperties
{
public:
nsCaretProperties();
virtual ~nsCaretProperties() {}
virtual PRUint32 GetCaretWidth() { return mCaretWidth; }
virtual PRUint32 GetCaretBlinkRate() { return mBlinkRate; }
protected:
// have value for no blinking
enum {
eDefaulBlinkRate = 500, // twice a second
eDefaultCaretWidth = 1 // one pixel wide
};
PRUint32 mCaretWidth; // caret width in twips
PRUint32 mBlinkRate; // blink rate in milliseconds
// members for vertical placement & size?
};
NS_BASE nsCaretProperties* NewCaretProperties();

View File

@@ -0,0 +1,62 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/* First checked in on 98/12/03 by John R. McMullen, derived from net.h/mkparse.c. */
#ifndef _ESCAPE_H_
#define _ESCAPE_H_
#include "prtypes.h"
#include "nscore.h"
/* valid mask values for NET_Escape() and NET_EscapedSize(). */
typedef enum {
url_XAlphas = (1<<0)
, url_XPAlphas = (1<<1)
, url_Path = (1<<2)
} nsEscapeMask;
#ifdef __cplusplus
extern "C" {
#endif
NS_BASE char * nsEscape(const char * str, nsEscapeMask mask);
/* Caller must use delete [] on the result */
NS_BASE char * nsUnescape(char * str);
/* decode % escaped hex codes into character values,
* modifies the parameter, returns the same buffer
*/
NS_BASE char * nsEscapeCount(const char * str, PRInt32 len, nsEscapeMask mask, PRInt32* out_len);
/* Like nsEscape, but if out_len is non-null, return result string length
* in *out_len, and uses len instead of NUL termination.
* Caller must use delete [] on the result.
*/
NS_BASE PRInt32 nsUnescapeCount (char * str);
/* decode % escaped hex codes into character values,
* modifies the parameter buffer, returns the length of the result
* (result may contain \0's).
*/
#ifdef __cplusplus
}
#endif
#endif // _ESCAPE_H_

View File

@@ -0,0 +1,478 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
// First checked in on 98/11/20 by John R. McMullen in the wrong directory.
// Checked in again 98/12/04.
// Polished version 98/12/08.
//========================================================================================
//
// Classes defined:
//
// nsFilePath, nsFileURL, nsFileSpec, nsPersistentFileDescriptor.
//
// Q. How should I represent files at run time?
// A. Use nsFileSpec. Using char* will lose information on some platforms.
//
// Q. Then what are nsFilePath and nsFileURL for?
// A. Only when you need a char* parameter for legacy code.
//
// Q. How should I represent files in a persistent way (eg, in a disk file)?
// A. Use nsPersistentFileDescriptor. Convert to and from nsFileSpec at run time.
//
// This suite provides the following services:
//
// 1. Encapsulates all platform-specific file details, so that files can be
// described correctly without any platform #ifdefs
//
// 2. Type safety. This will fix the problems that used to occur because people
// confused file paths. They used to use const char*, which could mean three
// or four different things. Bugs were introduced as people coded, right up
// to the moment Communicator 4.5 shipped.
//
// 3. Used in conjunction with nsFileStream.h (q.v.), this supports all the power
// and readability of the ansi stream syntax.
//
// Basic example:
//
// nsFilePath myPath("/Development/iotest.txt");
//
// nsOutputFileStream testStream(myPath);
// testStream << "Hello World" << nsEndl;
//
// 4. Handy methods for manipulating file specifiers safely, e.g. MakeUnique(),
// SetLeafName(), Exists().
//
// 5. Easy cross-conversion.
//
// Examples:
//
// Initialize a URL from a string without suffix
//
// nsFileURL fileURL("file:///Development/MPW/MPW%20Shell");
//
// Initialize a Unix path from a URL
//
// nsFilePath filePath(fileURL);
//
// Initialize a native file spec from a URL
//
// nsFileSpec fileSpec(fileURL);
//
// Make the spec unique (this one has no suffix).
//
// fileSpec.MakeUnique();
//
// Assign the spec to a URL
//
// fileURL = fileSpec;
//
// Assign a unix path using a string with a suffix.
//
// filePath = "/Development/MPW/SysErrs.err";
//
// Assign to a file spec using a unix path.
//
// fileSpec = filePath;
//
// Make this unique (this one has a suffix).
//
// fileSpec.MakeUnique();
//
// 6. Fixes a bug that have been there for a long time, and
// is inevitable if you use NSPR alone, where files are described as paths.
//
// The problem affects platforms (Macintosh) in which a path does not fully
// specify a file, because two volumes can have the same name. This
// is solved by holding a "private" native file spec inside the
// nsFilePath and nsFileURL classes, which is used when appropriate.
//
// Not yet done:
//
// Equality operators... much more.
//
//========================================================================================
#ifndef _FILESPEC_H_
#define _FILESPEC_H_
#include "nscore.h"
#include "nsError.h"
//========================================================================================
// Compiler-specific macros, as needed
//========================================================================================
#if !defined(NS_USING_NAMESPACE) && (defined(__MWERKS__) || defined(XP_PC))
#define NS_USING_NAMESPACE
#endif
#ifdef NS_USING_NAMESPACE
#define NS_NAMESPACE_PROTOTYPE
#define NS_NAMESPACE namespace
#define NS_NAMESPACE_END
#define NS_EXPLICIT explicit
#else
#define NS_NAMESPACE_PROTOTYPE static
#define NS_NAMESPACE struct
#define NS_NAMESPACE_END ;
#define NS_EXPLICIT
#endif
//=========================== End Compiler-specific macros ===============================
#ifdef XP_MAC
#include <Files.h>
#elif defined(XP_UNIX) || defined (XP_OS2)
#include <dirent.h>
#elif XP_PC
#include "prio.h"
#endif
//========================================================================================
// Here are the allowable ways to describe a file.
//========================================================================================
class nsFileSpec; // Preferred. For i/o use nsInputFileStream, nsOutputFileStream
class nsFilePath; // This can be passed to NSPR file I/O routines, if you must.
class nsFileURL;
class nsPersistentFileDescriptor; // Used for storage across program launches.
#define kFileURLPrefix "file://"
#define kFileURLPrefixLength (7)
class nsOutputStream;
class nsInputStream;
class nsOutputFileStream;
class nsInputFileStream;
//========================================================================================
// Conversion of native file errors to nsresult values. These are really only for use
// in the file module, clients of this interface shouldn't really need them.
// Error results returned from this interface have, in the low-order 16 bits,
// native errors that are masked to 16 bits. Assumption: a native error of 0 is success
// on all platforms. Note the way we define this using an inline function. This
// avoids multiple evaluation if people go NS_FILE_RESULT(function_call()).
#define NS_FILE_RESULT(x) ns_file_convert_result((PRInt32)x)
nsresult ns_file_convert_result(PRInt32 nativeErr);
#define NS_FILE_FAILURE NS_FILE_RESULT(-1)
//========================================================================================
class NS_BASE nsFileSpec
// This is whatever each platform really prefers to describe files as. Declared first
// because the other two types have an embeded nsFileSpec object.
//========================================================================================
{
public:
nsFileSpec();
NS_EXPLICIT nsFileSpec(const char* inString, PRBool inCreateDirs = PR_FALSE);
NS_EXPLICIT nsFileSpec(const nsFilePath& inPath);
NS_EXPLICIT nsFileSpec(const nsFileURL& inURL);
NS_EXPLICIT nsFileSpec(const nsPersistentFileDescriptor& inURL);
nsFileSpec(const nsFileSpec& inPath);
virtual ~nsFileSpec();
void operator = (const char* inPath);
void operator = (const nsFilePath& inPath);
void operator = (const nsFileURL& inURL);
void operator = (const nsFileSpec& inOther);
void operator = (const nsPersistentFileDescriptor& inOther);
#ifndef XP_MAC
operator const char* () const { return mPath; }
// This is the only automatic conversion to const char*
// that is provided, and it allows the
// path to be "passed" to NSPR file routines.
#endif
#ifdef XP_MAC
// For Macintosh people, this is meant to be useful in its own right as a C++ version
// of the FSSpec struct.
nsFileSpec(
short vRefNum,
long parID,
ConstStr255Param name);
nsFileSpec(const FSSpec& inSpec)
: mSpec(inSpec), mError(NS_OK) {}
operator FSSpec* () { return &mSpec; }
operator const FSSpec* const () { return &mSpec; }
operator FSSpec& () { return mSpec; }
operator const FSSpec& () const { return mSpec; }
void MakeAliasSafe();
// Called for the spec of an alias. Copies the alias to
// a secret temp directory and modifies the spec to point
// to it. Sets mError.
void ResolveAlias(PRBool& wasAliased);
// Called for the spec of an alias. Modifies the spec to
// point to the original. Sets mError.
void MakeUnique(ConstStr255Param inSuggestedLeafName);
StringPtr GetLeafPName() { return mSpec.name; }
ConstStr255Param GetLeafPName() const { return mSpec.name; }
#endif // end of Macintosh utility methods.
PRBool Valid() const { return NS_SUCCEEDED(Error()); }
nsresult Error() const { return mError; }
#if DEBUG
friend NS_BASE nsOutputStream& operator << (
nsOutputStream& s,
const nsFileSpec& spec); // THIS IS FOR DEBUGGING ONLY.
// see PersistentFileDescriptor for the real deal.
#endif
//--------------------------------------------------
// Queries and path algebra. These do not modify the disk.
//--------------------------------------------------
char* GetLeafName() const; // Allocated. Use delete [].
void SetLeafName(const char* inLeafName);
// inLeafName can be a relative path, so this allows
// one kind of concatenation of "paths".
void GetParent(nsFileSpec& outSpec) const;
// Return the filespec of the parent directory. Used
// in conjunction with GetLeafName(), this lets you
// parse a path into a list of node names. Beware,
// however, that the top node is still not a name,
// but a spec. Volumes on Macintosh can have identical
// names. Perhaps could be used for an operator --() ?
nsFileSpec operator + (const char* inRelativePath) const;
void operator += (const char* inRelativePath);
// Concatenate the relative path to this directory.
// Used for constructing the filespec of a descendant.
// This must be a directory for this to work. This differs
// from SetLeafName(), since the latter will work
// starting with a sibling of the directory and throws
// away its leaf information, whereas this one assumes
// this is a directory, and the relative path starts
// "below" this.
void MakeUnique();
void MakeUnique(const char* inSuggestedLeafName);
PRBool IsDirectory() const;
// More stringent than Exists()
PRBool IsFile() const;
// More stringent than Exists()
PRBool Exists() const;
//--------------------------------------------------
// Creation and deletion of objects. These can modify the disk.
//--------------------------------------------------
void CreateDirectory(int mode = 0700 /* for unix */);
void Delete(PRBool inRecursive);
nsresult Rename(const char* inNewName); // not const: gets updated
nsresult Copy(const nsFileSpec& inNewParentDirectory) const;
nsresult Move(const nsFileSpec& inNewParentDirectory) const;
nsresult Execute(const char* args) const;
//--------------------------------------------------
// Data
//--------------------------------------------------
private:
friend class nsFilePath;
#ifdef XP_MAC
FSSpec mSpec;
#else
char* mPath;
#endif
nsresult mError;
}; // class nsFileSpec
// FOR HISTORICAL REASONS:
typedef nsFileSpec nsNativeFileSpec;
//========================================================================================
class NS_BASE nsFileURL
// This is an escaped string that looks like "file:///foo/bar/mumble%20fish". Since URLs
// are the standard way of doing things in mozilla, this allows a string constructor,
// which just stashes the string with no conversion.
//========================================================================================
{
public:
nsFileURL(const nsFileURL& inURL);
NS_EXPLICIT nsFileURL(const char* inString, PRBool inCreateDirs = PR_FALSE);
NS_EXPLICIT nsFileURL(const nsFilePath& inPath);
NS_EXPLICIT nsFileURL(const nsFileSpec& inPath);
virtual ~nsFileURL();
// nsString GetString() const { return mPath; }
// may be needed for implementation reasons,
// but should not provide a conversion constructor.
void operator = (const nsFileURL& inURL);
void operator = (const char* inString);
void operator = (const nsFilePath& inOther);
void operator = (const nsFileSpec& inOther);
friend NS_BASE nsOutputStream& operator << (
nsOutputStream& s, const nsFileURL& spec);
#ifdef XP_MAC
// Accessor to allow quick assignment to a mFileSpec
const nsFileSpec& GetFileSpec() const { return mFileSpec; }
#endif
private:
// Should not be defined (only nsFilePath is to be treated as strings.
operator char* ();
operator const char* const ();
private:
friend class nsFilePath; // to allow construction of nsFilePath
char* mURL;
#ifdef XP_MAC
// Since the path on the macintosh does not uniquely specify a file (volumes
// can have the same name), stash the secret nsFileSpec, too.
nsFileSpec mFileSpec;
#endif
}; // class nsFileURL
//========================================================================================
class NS_BASE nsFilePath
// This is a string that looks like "/foo/bar/mumble%20fish". Same as nsFileURL, but
// without the "file:// prefix".
//========================================================================================
{
public:
nsFilePath(const nsFilePath& inPath);
NS_EXPLICIT nsFilePath(const char* inString, PRBool inCreateDirs = PR_FALSE);
NS_EXPLICIT nsFilePath(const nsFileURL& inURL);
NS_EXPLICIT nsFilePath(const nsFileSpec& inPath);
virtual ~nsFilePath();
operator const char* () const { return mPath; }
// This is the only automatic conversion to const char*
// that is provided, and it allows the
// path to be "passed" to NSPR file routines.
operator char* () { return mPath; }
// This is the only automatic conversion to string
// that is provided, because a naked string should
// only mean a standard file path.
void operator = (const nsFilePath& inPath);
void operator = (const char* inString);
void operator = (const nsFileURL& inURL);
void operator = (const nsFileSpec& inOther);
#ifdef XP_MAC
public:
// Accessor to allow quick assignment to a mFileSpec
const nsFileSpec& GetFileSpec() const { return mFileSpec; }
#endif
private:
char* mPath;
#ifdef XP_MAC
// Since the path on the macintosh does not uniquely specify a file (volumes
// can have the same name), stash the secret nsFileSpec, too.
nsFileSpec mFileSpec;
#endif
}; // class nsFilePath
//========================================================================================
class NS_BASE nsPersistentFileDescriptor
//========================================================================================
{
public:
nsPersistentFileDescriptor() : mDescriptorString(nsnull) {}
// For use prior to reading in from a stream
nsPersistentFileDescriptor(const nsPersistentFileDescriptor& inPath);
virtual ~nsPersistentFileDescriptor();
void operator = (const nsPersistentFileDescriptor& inPath);
// Conversions
nsPersistentFileDescriptor(const nsFileSpec& inPath);
void operator = (const nsFileSpec& inPath);
friend NS_BASE nsInputStream& operator >> (nsInputStream&, nsPersistentFileDescriptor&);
// reads the data from a file
friend NS_BASE nsOutputStream& operator << (nsOutputStream&, const nsPersistentFileDescriptor&);
// writes the data to a file
friend class nsFileSpec;
private:
// Here are the ways to get data in and out of a file.
void GetData(void*& outData, PRInt32& outSize) const;
// DON'T FREE the returned data!
void SetData(const void* inData, PRInt32 inSize);
private:
char* mDescriptorString;
}; // class nsPersistentFileDescriptor
//========================================================================================
class NS_BASE nsDirectoryIterator
// Example:
//
// nsFileSpec parentDir(...); // directory over whose children we shall iterate
// for (nsDirectoryIterator i(parentDir); i; i++)
// {
// // do something with (const nsFileSpec&)i
// }
//
// or:
//
// for (nsDirectoryIterator i(parentDir, PR_FALSE); i; i--)
// {
// // do something with (const nsFileSpec&)i
// }
//
// Currently, the only platform on which backwards iteration actually goes backwards
// is Macintosh. On other platforms, both styles will work, but will go forwards.
//========================================================================================
{
public:
nsDirectoryIterator(
const nsFileSpec& parent,
int iterateDirection = +1);
#ifndef XP_MAC
// Macintosh currently doesn't allocate, so needn't clean up.
virtual ~nsDirectoryIterator();
#endif
PRBool Exists() const { return mExists; }
nsDirectoryIterator& operator ++(); // moves to the next item, if any.
nsDirectoryIterator& operator ++(int) { return ++(*this); } // post-increment.
nsDirectoryIterator& operator --(); // moves to the previous item, if any.
nsDirectoryIterator& operator --(int) { return --(*this); } // post-decrement.
operator nsFileSpec&() { return mCurrent; }
private:
nsFileSpec mCurrent;
bool mExists; // MUST be bool.
#if defined(XP_UNIX)
DIR* mDir;
#elif defined(XP_PC)
PRDir* mDir; // XXX why not use PRDir for Unix & Mac, too?
#elif defined(XP_MAC)
OSErr SetToIndex();
short mIndex;
short mMaxIndex;
#endif
}; // class nsDirectoryIterator
#endif // _FILESPEC_H_

View File

@@ -0,0 +1,547 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0(the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright(C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
// First checked in on 98/11/20 by John R. McMullen in the wrong directory.
// Checked in again 98/12/04.
// Polished version 98/12/08.
// Completely rewritten to integrate with nsIInputStream and nsIOutputStream (the
// xpcom stream objects.
//========================================================================================
//
// Classes defined:
//
// nsInputStream, nsOutputStream
// These are the lightweight STATICALLY LINKED wrappers for
// the xpcom objects nsIInputStream and nsIOutputstream.
// Possible uses:
// If you are implementing a function that accepts one of these xpcom
// streams, just make one of these little jobbies on the stack, and
// the handy << or >> notation can be yours.
//
// nsInputFileStream, nsOutputFileStream
// These are the STATICALLY LINKED versions of the file i/o streams,
// which wrap the NSPR file i/o plus console i/o.
//
// Related files:
// prio.h the NSPR file i/o C API), which is wrapped by
// THIS FILE statically linked C++ wrappers, which in turn are wrapped by
// nsIFileStream.h COM wrappers for this file, which are wrapped by
// nsAutoFileStream.h more easily used, nicer syntax wrappers for the
// COMified ones. Wrapper of a wrapper of a wrapper.
//
// This suite provide the following services:
//
// 1. Encapsulates all platform-specific file details, so that file i/o
// can be done correctly without any platform #ifdefs
//
// 2. Uses NSPR file services (NOT ansi file I/O), in order to get best
// native performance. This performance difference is especially large on
// macintosh.
//
// 3. Allows all the power of the ansi stream syntax.
//
// Basic example:
//
// nsFileSpec myPath("/Development/iotest.txt");
//
// nsOutputFileStream testStream(myPath);
// testStream << "Hello World" << nsEndl;
//
// 4. Requires streams to be constructed using typesafe nsFileSpec specifier
// (not the notorious and bug prone const char*), namely nsFileSpec. See
// nsFileSpec.h for more details.
//
// 5. Fixes a bug that have been there for a long time, and
// is inevitable if you use NSPR alone:
//
// The problem on platforms (Macintosh) in which a path does not fully
// specify a file, because two volumes can have the same name.
//
// Not yet provided:
//
// Endian-awareness for reading and writing crossplatform binary files. At this
// time there seems to be no demand for this.
//
//========================================================================================
#ifndef _FILESTREAM_H_
#define _FILESTREAM_H_
#include "nscore.h"
#ifdef XP_MAC
#include "pprio.h" // To get PR_ImportFile
#else
#include "prio.h"
#endif
#include "nsIFileStream.h"
#include "nsCOMPtr.h"
class nsFileSpec;
class nsInputFileStream;
class nsOutputFileStream;
//========================================================================================
// Compiler-specific macros, as needed
//========================================================================================
#if !defined(NS_USING_NAMESPACE) && (defined(__MWERKS__) || defined(XP_PC))
#define NS_USING_NAMESPACE
#endif
#if !defined(NS_USING_STL) && (defined(__MWERKS__) || defined(XP_PC))
#define NS_USING_STL
#endif
#ifdef NS_USING_NAMESPACE
#define NS_NAMESPACE_PROTOTYPE
#define NS_NAMESPACE namespace
#define NS_NAMESPACE_END
#else
#define NS_NAMESPACE_PROTOTYPE static
#define NS_NAMESPACE struct
#define NS_NAMESPACE_END ;
#endif // NS_USING_NAMESPACE
#ifndef XP_MAC
// PR_STDOUT and PR_STDIN are fatal on Macintosh. So for console i/o, we must use the std
// stream stuff instead. However, we have to require that cout and cin are passed in
// to the constructor because in the current build, there is a copy in the base.shlb,
// and another in the caller's file. Passing it in as a parameter ensures that the
// caller and this library are using the same global object. Groan.
//
// Unix currently does not support iostreams at all. Their compilers do not support
// ANSI C++, or even ARM C++.
//
// Windows supports them, but only if you turn on the -GX compile flag, to support
// exceptions.
// Catch 22.
#define NS_USE_PR_STDIO
#endif
#ifdef NS_USE_PR_STDIO
class istream;
class ostream;
#define CONSOLE_IN 0
#define CONSOLE_OUT 0
#else
#include <iostream>
using std::istream;
using std::ostream;
#define CONSOLE_IN &std::cin
#define CONSOLE_OUT &std::cout
#endif
//=========================== End Compiler-specific macros ===============================
//========================================================================================
class NS_BASE nsInputStream
// This is a convenience class, for use on the STACK ("new" junkies: get detoxed first).
// Given a COM-style stream, this allows you to use the >> operators. It also acquires and
// reference counts its stream.
// Please read the comments at the top of this file
//========================================================================================
{
public:
nsInputStream(nsIInputStream* inStream)
: mInputStream(do_QueryInterface(inStream))
, mEOF(PR_FALSE)
{}
virtual ~nsInputStream();
nsCOMPtr<nsIInputStream> GetIStream() const
{
return mInputStream;
}
char eof() const { return mEOF; }
char get();
PRInt32 read(void* s, PRInt32 n)
{
if (!mInputStream)
return 0;
PRInt32 result = 0;
mInputStream->Read((char*)s, 0, n, (PRUint32*)&result);
if (result < n)
mEOF = PR_TRUE;
return result;
}
// Input streamers. Add more as needed (int&, unsigned int& etc). (but you have to
// add delegators to the derived classes, too, because these operators don't inherit).
nsInputStream& operator >> (char& ch);
// Support manipulators
nsInputStream& operator >> (nsInputStream& (*pf)(nsInputStream&))
{
return pf(*this);
}
private:
nsInputStream& operator >> (char* buf); // TOO DANGEROUS. DON'T DEFINE.
// DATA
protected:
nsCOMPtr<nsIInputStream> mInputStream;
PRBool mEOF;
}; // class nsInputStream
typedef nsInputStream nsBasicInStream; // historic support for this name
//========================================================================================
class NS_BASE nsOutputStream
// This is a convenience class, for use on the STACK ("new" junkies, get detoxed first).
// Given a COM-style stream, this allows you to use the << operators. It also acquires and
// reference counts its stream.
// Please read the comments at the top of this file
//========================================================================================
{
public:
nsOutputStream() {}
nsOutputStream(nsIOutputStream* inStream)
: mOutputStream(do_QueryInterface(inStream))
{}
virtual ~nsOutputStream();
nsCOMPtr<nsIOutputStream> GetIStream() const
{
return mOutputStream;
}
void put(char c);
PRInt32 write(const void* s, PRInt32 n)
{
if (!mOutputStream)
return 0;
PRInt32 result = 0;
mOutputStream->Write((char*)s, 0, n, (PRUint32*)&result);
return result;
}
virtual void flush();
// Output streamers. Add more as needed (but you have to add delegators to the derived
// classes, too, because these operators don't inherit).
nsOutputStream& operator << (const char* buf);
nsOutputStream& operator << (char ch);
nsOutputStream& operator << (short val);
nsOutputStream& operator << (unsigned short val);
nsOutputStream& operator << (long val);
nsOutputStream& operator << (unsigned long val);
// Support manipulators
nsOutputStream& operator << (nsOutputStream& (*pf)(nsOutputStream&))
{
return pf(*this);
}
// DATA
protected:
nsCOMPtr<nsIOutputStream> mOutputStream;
}; // class nsOutputStream
typedef nsOutputStream nsBasicOutStream; // Historic support for this name
//========================================================================================
class NS_BASE nsFileClient
// Because COM does not allow us to write functions which return a boolean value etc,
// this class is here to take care of the tedious "declare variable then call with
// the address of the variable" chores.
//========================================================================================
{
public:
nsFileClient() // for delayed opening
: mResult(NS_OK)
{
}
nsFileClient(const nsCOMPtr<nsIFile>& inFile)
: mFile(do_QueryInterface(inFile))
, mResult(NS_OK)
{
}
PRBool is_file() const
{
return mFile ? PR_TRUE : PR_FALSE;
}
void open(
const nsFileSpec& inFile,
int nsprMode,
PRIntn accessMode)
{
if (mFile)
mResult = mFile->Open(inFile, nsprMode, accessMode);
}
PRBool is_open() const
{
PRBool result = PR_FALSE;
if (mFile)
mFile->GetIsOpen(&result);
return result;
}
PRBool failed() const
{
return NS_FAILED(mResult);
}
void seek(PRInt32 offset)
{
seek(PR_SEEK_SET, offset);
}
void seek(PRSeekWhence whence, PRInt32 offset)
{
if (mFile)
mResult = mFile->Seek(whence, offset);
}
PRIntn tell()
{
PRIntn result = -1;
if (mFile)
mResult = mFile->Tell(&result);
return result;
}
// DATA
protected:
nsCOMPtr<nsIFile> mFile;
PRBool mResult;
}; // class nsFileClient
//========================================================================================
class NS_BASE nsInputFileStream
// Please read the comments at the top of this file
//========================================================================================
: public nsInputStream
, public nsFileClient
{
public:
enum { kDefaultMode = PR_RDONLY };
nsInputFileStream(nsIInputStream* inStream)
: nsInputStream(inStream)
, nsFileClient(do_QueryInterface(inStream))
, mFileInputStream(do_QueryInterface(inStream))
{
}
nsInputFileStream(
const nsFileSpec& inFile,
int nsprMode = kDefaultMode,
PRIntn accessMode = 00700) // <- OCTAL
: nsInputStream(nsnull)
{
nsISupports* stream;
NS_NewIOFileStream(
&stream,
inFile, nsprMode, accessMode);
mFile = nsQueryInterface(stream);
mInputStream = nsQueryInterface(stream);
mFileInputStream = nsQueryInterface(stream);
}
PRBool readline(char* s, PRInt32 n);
// Result always null-terminated.
// Check eof() before each call.
// CAUTION: false result only indicates line was truncated
// to fit buffer, or an error occurred (OTHER THAN eof).
void Open(
const nsFileSpec& inFile,
int nsprMode = kDefaultMode,
PRIntn accessMode = 00700) // <- OCTAL
{
if (mFile)
mFile->Open(inFile, nsprMode, accessMode);
}
// Input streamers. Unfortunately, they don't inherit!
nsInputStream& operator >> (char& ch)
{ return nsInputStream::operator >>(ch); }
nsInputStream& operator >> (nsInputStream& (*pf)(nsInputStream&))
{ return nsInputStream::operator >>(pf); }
// DATA
protected:
nsCOMPtr<nsIFileInputStream> mFileInputStream;
}; // class nsInputFileStream
//========================================================================================
class NS_BASE nsOutputFileStream
// Please read the comments at the top of this file
//========================================================================================
: public nsOutputStream
, public nsFileClient
{
public:
enum { kDefaultMode = (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE) };
nsOutputFileStream() {}
nsOutputFileStream(nsIOutputStream* inStream)
: nsOutputStream(inStream)
, nsFileClient(do_QueryInterface(inStream))
, mFileOutputStream(do_QueryInterface(inStream))
{
}
nsOutputFileStream(
const nsFileSpec& inFile,
int nsprMode = kDefaultMode,
PRIntn accessMode = 00700) // <- OCTAL
: nsOutputStream(nsnull)
{
nsISupports* stream;
if (NS_FAILED(NS_NewIOFileStream(
&stream,
inFile, nsprMode, accessMode)))
return;
mFile = nsQueryInterface(stream);
mOutputStream = nsQueryInterface(stream);
mFileOutputStream = nsQueryInterface(stream);
}
virtual void flush();
// Output streamers. Unfortunately, they don't inherit!
nsOutputStream& operator << (const char* buf)
{ return nsOutputStream::operator << (buf); }
nsOutputStream& operator << (char ch)
{ return nsOutputStream::operator << (ch); }
nsOutputStream& operator << (short val)
{ return nsOutputStream::operator << (val); }
nsOutputStream& operator << (unsigned short val)
{ return nsOutputStream::operator << (val); }
nsOutputStream& operator << (long val)
{ return nsOutputStream::operator << (val); }
nsOutputStream& operator << (unsigned long val)
{ return nsOutputStream::operator << (val); }
nsOutputStream& operator << (nsOutputStream& (*pf)(nsOutputStream&))
{ return nsOutputStream::operator << (pf); }
// DATA
protected:
nsCOMPtr<nsIFileOutputStream> mFileOutputStream;
}; // class nsOutputFileStream
//========================================================================================
class NS_BASE nsOutputConsoleStream
// Please read the comments at the top of this file
//========================================================================================
: public nsOutputFileStream
{
public:
nsOutputConsoleStream()
{
nsISupports* stream;
if (NS_FAILED(NS_NewOutputConsoleStream(&stream)))
return;
mFile = nsQueryInterface(stream);
mOutputStream = nsQueryInterface(stream);
mFileOutputStream = nsQueryInterface(stream);
}
// Output streamers. Unfortunately, they don't inherit!
nsOutputStream& operator << (const char* buf)
{ return nsOutputStream::operator << (buf); }
nsOutputStream& operator << (char ch)
{ return nsOutputStream::operator << (ch); }
nsOutputStream& operator << (short val)
{ return nsOutputStream::operator << (val); }
nsOutputStream& operator << (unsigned short val)
{ return nsOutputStream::operator << (val); }
nsOutputStream& operator << (long val)
{ return nsOutputStream::operator << (val); }
nsOutputStream& operator << (unsigned long val)
{ return nsOutputStream::operator << (val); }
nsOutputStream& operator << (nsOutputStream& (*pf)(nsOutputStream&))
{ return nsOutputStream::operator << (pf); }
}; // class nsOutputConsoleStream
//========================================================================================
class NS_BASE nsIOFileStream
// Please read the comments at the top of this file
//========================================================================================
: public nsInputFileStream
, public nsOutputStream
{
public:
enum { kDefaultMode = (PR_RDWR | PR_CREATE_FILE) };
nsIOFileStream(
nsIInputStream* inInputStream
, nsIOutputStream* inOutputStream)
: nsInputFileStream(inInputStream)
, nsOutputStream(inOutputStream)
, mFileOutputStream(do_QueryInterface(inOutputStream))
{
}
nsIOFileStream(
const nsFileSpec& inFile,
int nsprMode = kDefaultMode,
PRIntn accessMode = 00700) // <- OCTAL
: nsInputFileStream(nsnull)
, nsOutputStream(nsnull)
{
nsISupports* stream;
if (NS_FAILED(NS_NewIOFileStream(
&stream,
inFile, nsprMode, accessMode)))
return;
mFile = nsQueryInterface(stream);
mInputStream = nsQueryInterface(stream);
mOutputStream = nsQueryInterface(stream);
mFileInputStream = nsQueryInterface(stream);
mFileOutputStream = nsQueryInterface(stream);
}
// Output streamers. Unfortunately, they don't inherit!
nsOutputStream& operator << (const char* buf)
{ return nsOutputStream::operator << (buf); }
nsOutputStream& operator << (char ch)
{ return nsOutputStream::operator << (ch); }
nsOutputStream& operator << (short val)
{ return nsOutputStream::operator << (val); }
nsOutputStream& operator << (unsigned short val)
{ return nsOutputStream::operator << (val); }
nsOutputStream& operator << (long val)
{ return nsOutputStream::operator << (val); }
nsOutputStream& operator << (unsigned long val)
{ return nsOutputStream::operator << (val); }
nsOutputStream& operator << (nsOutputStream& (*pf)(nsOutputStream&))
{ return nsOutputStream::operator << (pf); }
// Input streamers. Unfortunately, they don't inherit!
nsInputStream& operator >> (char& ch)
{ return nsInputStream::operator >>(ch); }
nsInputStream& operator >> (nsInputStream& (*pf)(nsInputStream&))
{ return nsInputStream::operator >>(pf); }
// DATA
protected:
nsCOMPtr<nsIFileOutputStream> mFileOutputStream;
}; // class nsIOFileStream
//========================================================================================
// Manipulators
//========================================================================================
NS_BASE nsOutputStream& nsEndl(nsOutputStream& os); // outputs and FLUSHES.
#endif /* _FILESTREAM_H_ */

View File

@@ -0,0 +1,127 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsIFileStream_h___
#define nsIFileStream_h___
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "prio.h"
class nsFileSpec;
/* a6cf90e8-15b3-11d2-932e-00805f8add32 */
#define NS_IFILE_IID \
{ 0xa6cf90e8, 0x15b3, 0x11d2, \
{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
//========================================================================================
class nsIFile
// Represents a file, and supports Open, Tell etc.
//========================================================================================
: public nsISupports
{
public:
static const nsIID& IID() { static nsIID iid = NS_IFILE_IID; return iid; }
NS_IMETHOD Open(
const nsFileSpec& inFile,
int nsprMode,
PRIntn accessMode) = 0;
// Note: Open() is only needed after
// an explicit Close(). All file streams
// are automatically opened on construction.
NS_IMETHOD Seek(PRSeekWhence whence, PRInt32 offset) = 0;
NS_IMETHOD GetIsOpen(PRBool* outOpen) = 0;
NS_IMETHOD Tell(PRIntn* outWhere) = 0;
}; // class nsIFile
/* a6cf90e6-15b3-11d2-932e-00805f8add32 */
#define NS_IFILEINPUTSTREAM_IID \
{ 0xa6cf90e6, 0x15b3, 0x11d2, \
{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
//========================================================================================
class nsIFileInputStream
// These are additional file-specific methods that files have, above what
// nsIInputStream supports. The current implementation supports both
// interfaces.
//========================================================================================
: public nsISupports
{
public:
static const nsIID& IID() { static nsIID iid = NS_IFILEINPUTSTREAM_IID; return iid; }
}; // class nsIFileInputStream
/* a6cf90e7-15b3-11d2-932e-00805f8add32 */
#define NS_IFILEOUTPUTSTREAM_IID \
{ 0xa6cf90e7, 0x15b3, 0x11d2, \
{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
//========================================================================================
class nsIFileOutputStream
// These are additional file-specific methods that files have, above what
// nsIOutputStream supports. The current implementation supports both
// interfaces.
//========================================================================================
: public nsISupports
{
public:
static const nsIID& IID() { static nsIID iid = NS_IFILEOUTPUTSTREAM_IID; return iid; }
NS_IMETHOD Flush() = 0;
// Forces a write to disk.
}; // class nsIFileOutputStream
//----------------------------------------------------------------------------------------
NS_BASE nsresult NS_NewTypicalInputFileStream(
nsISupports** aStreamResult,
const nsFileSpec& inFile
/*Default nsprMode == PR_RDONLY*/
/*Default accessmode = 0700 (octal)*/);
// Factory method to get an nsInputStream from a file, using most common options
//----------------------------------------------------------------------------------------
extern "C" NS_BASE nsresult NS_NewOutputConsoleStream(
nsISupports** aStreamResult);
// Factory method to get an nsOutputStream to the console.
//----------------------------------------------------------------------------------------
extern "C" NS_BASE nsresult NS_NewTypicalOutputFileStream(
nsISupports** aStreamResult, // will implement all the above interfaces
const nsFileSpec& inFile
/*default nsprMode= (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE)*/
/*Default accessMode= 0700 (octal)*/);
// Factory method to get an nsOutputStream to a file - most common case.
//----------------------------------------------------------------------------------------
extern "C" NS_BASE nsresult NS_NewTypicalIOFileStream(
nsISupports** aStreamResult, // will implement all the above interfaces
const nsFileSpec& inFile
/*default nsprMode = (PR_RDWR | PR_CREATE_FILE)*/
/*Default accessMode = 0700 (octal)*/);
// Factory method to get an object that implements both nsIInputStream
// and nsIOutputStream, associated with a single file.
//----------------------------------------------------------------------------------------
extern "C" NS_BASE nsresult NS_NewIOFileStream(
nsISupports** aStreamResult, // will implement all the above interfaces
const nsFileSpec& inFile,
PRInt32 nsprMode,
PRInt32 accessMode);
// Factory method to get an object that implements both nsIInputStream
// and nsIOutputStream, associated with a single file.
#endif /* nsIFileStream_h___ */

View File

@@ -0,0 +1,48 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsIProperties_h___
#define nsIProperties_h___
#include "nsID.h"
#include "nsIInputStream.h"
#include "nsIOutputStream.h"
#include "nsISupports.h"
#include "nsString.h"
// {1A180F60-93B2-11d2-9B8B-00805F8A16D9}
#define NS_IPROPERTIES_IID \
{ 0x1a180f60, 0x93b2, 0x11d2, \
{ 0x9b, 0x8b, 0x0, 0x80, 0x5f, 0x8a, 0x16, 0xd9 } }
// {2245E573-9464-11d2-9B8B-00805F8A16D9}
NS_DECLARE_ID(kPropertiesCID,
0x2245e573, 0x9464, 0x11d2, 0x9b, 0x8b, 0x0, 0x80, 0x5f, 0x8a, 0x16, 0xd9);
class nsIProperties : public nsISupports
{
public:
NS_IMETHOD Load(nsIInputStream* aIn) = 0;
NS_IMETHOD GetProperty(const nsString& aKey, nsString& aValue) = 0;
NS_IMETHOD SetProperty(const nsString& aKey, nsString& aNewValue,
nsString& aOldValue) = 0;
NS_IMETHOD Save(nsIOutputStream* aOut, const nsString& aHeader) = 0;
NS_IMETHOD Subclass(nsIProperties* aSubclass) = 0;
};
#endif /* nsIProperties_h___ */

View File

@@ -0,0 +1,66 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsISizeOfHandler_h___
#define nsISizeOfHandler_h___
#include "nscore.h"
#include "nsISupports.h"
/* c028d1f0-fc9e-11d1-89e4-006008911b81 */
#define NS_ISIZEOF_HANDLER_IID \
{ 0xc028d1f0, 0xfc9e, 0x11d1, {0x89, 0xe4, 0x00, 0x60, 0x08, 0x91, 0x1b, 0x81}}
/**
* An API to managing a sizeof computation of an arbitrary graph.
* The handler is responsible for remembering which objects have been
* seen before. Note that the handler doesn't hold references to
* nsISupport's objects; the assumption is that the objects being
* sized are stationary and will not be modified during the sizing
* computation and therefore do not need an extra reference count.
*/
class nsISizeOfHandler : public nsISupports {
public:
/**
* Add in a simple size value to the running total.
* Always returns NS_OK.
*/
NS_IMETHOD Add(size_t aSize) = 0;
/**
* Update aResult with PR_TRUE if the object has been traversed
* by the sizeof computation before. Otherwise aResult is set to
* PR_FALSE and the object is added to the internal database
* of objects that have been traversed. It's ok to pass a null
* pointer in; aResult will be set to PR_TRUE so you won't accidently
* try to traverse through null pointer.
*
* Note: This violates the COM API standard on purpose; so there!
*/
virtual PRBool HaveSeen(void* anObject) = 0;
/**
* Return the currently computed size.
* Always returns NS_OK.
*/
NS_IMETHOD GetSize(PRUint32& aResult) = 0;
};
extern NS_BASE nsresult
NS_NewSizeOfHandler(nsISizeOfHandler** aInstancePtrResult);
#endif /* nsISizeofHandler_h___ */

View File

@@ -0,0 +1,60 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsRepeater_h___
#define nsRepeater_h___
#include "nscore.h"
class EventRecord;
class NS_BASE Repeater {
public:
Repeater();
virtual ~Repeater();
virtual void RepeatAction(const EventRecord &aMacEvent) = 0;
void StartRepeating();
void StopRepeating();
void StartIdling();
void StopIdling();
static void DoRepeaters(const EventRecord &aMacEvent);
static void DoIdlers(const EventRecord &aMacEvent);
protected:
void AddToRepeatList();
void RemoveFromRepeatList();
void AddToIdleList();
void RemoveFromIdleList();
static Repeater* sRepeaters;
static Repeater* sIdlers;
bool mRepeating;
bool mIdling;
Repeater* mPrevRptr;
Repeater* mNextRptr;
Repeater* mPrevIdlr;
Repeater* mNextIdlr;
};
#endif

View File

@@ -0,0 +1,939 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0(the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright(C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#error "Do not use this file. The unix compilers do not support standard C++. Use nsFileStream"
// First checked in on 98/11/20 by John R. McMullen in the wrong directory.
// Checked in again 98/12/04.
// Polished version 98/12/08.
//========================================================================================
//
// Classes defined:
//
// single-byte char:
//
// nsInputFileStream, nsOutputFileStream, nsIOFileStream
//
// wide char:
//
// nsWideInputFileStream, nsWideOutputFileStream, nsWideIOFileStream
//
// This suite provide the following services:
//
// 1. Encapsulates all platform-specific file details, so that file i/o
// can be done correctly without any platform #ifdefs
//
// 2. Uses NSPR file services (NOT ansi file I/O), in order to get best
// native performance. This performance difference is especially large on
// macintosh.
//
// 3. Allows all the power of the ansi stream syntax: these streams
// ARE derived classes of ostream, istream, and iostream. ALL METHODS OF
// istream, ostream, AND iostream ARE AVAILABLE!
//
// Basic example:
//
// nsFilePath myPath("/Development/iotest.txt");
//
// nsOutputFileStream testStream(myPath);
// testStream << "Hello World" << endl;
//
// 4. Requires streams to be constructed using typesafe nsFilePath specifier
// (not the notorious and bug prone const char*), namely nsFilePath. See
// nsFileSpec.h for more details.
//
// 5. Fixes a bug that have been there for a long time, and
// is inevitable if you use NSPR alone:
//
// The problem on platforms (Macintosh) in which a path does not fully
// specify a file, because two volumes can have the same name.
//
// Not yet provided:
//
// Endian-awareness for reading and writing crossplatform binary files. At this
// time there seems to be no demand for this.
//
//========================================================================================
#ifndef _FILESTREAM_H_
#define _FILESTREAM_H_
#include "nscore.h"
#ifdef XP_MAC
#include "pprio.h" // To get PR_ImportFile
#else
#include "prio.h"
#endif
#include "nsFileSpec.h"
//========================================================================================
// Compiler-specific macros, as needed
//========================================================================================
#if !defined(NS_USING_NAMESPACE) && (defined(__MWERKS__) || defined(XP_PC))
#define NS_USING_NAMESPACE
#endif
#if !defined(NS_USING_STL) && (defined(__MWERKS__) || defined(XP_PC))
#define NS_USING_STL
#endif
#ifdef NS_USING_NAMESPACE
#define NS_NAMESPACE_PROTOTYPE
#define NS_NAMESPACE namespace
#define NS_NAMESPACE_END
#else
#define NS_NAMESPACE_PROTOTYPE static
#define NS_NAMESPACE struct
#define NS_NAMESPACE_END ;
#endif // NS_USING_NAMESPACE
#ifdef NS_USING_STL
// Macintosh and Windows use this section.
//
// Here's where the party is. When Unix wants to join in (by supporting
// a build system with STL headers), what fun we'll have! Meanwhile, I've used
// macros to make this build on all our platforms. Unix doesn't have support for
// STL, and therefore we could not use the template forms of these classes on Unix.
// (it's a long story). Therefore, Unix supports no stream char types except 1-byte
// characters, and therefore nobody else does now either, until Unix catches up.
#define DEFINING_FILE_STREAM // templateers define this when this file is included.
#define IOS_BASE ios_base
#include <istream>
using std::ios_base;
using std::basic_streambuf;
using std::codecvt_base;
using std::codecvt;
using std::streamsize;
using std::locale;
using std::basic_istream;
using std::basic_ostream;
using std::basic_iostream;
using std::char_traits;
#define TEMPLATE_DEF template<class charT, class traits>
#define FILE_BUFFER_TYPE nsFileBufferT<charT, traits>
#define INPUT_FILE_STREAM nsInputFileStreamT<charT, traits>
#define OUTPUT_FILE_STREAM nsOutputFileStreamT<charT, traits>
#define IO_FILE_STREAM nsIOFileStreamT<charT, traits>
#define BASIC_STREAMBUF basic_streambuf<charT, traits>
#define BASIC_ISTREAM basic_istream<charT, traits>
#define BASIC_OSTREAM basic_ostream<charT, traits>
#define BASIC_IOSTREAM basic_iostream<charT, traits>
#define INT_TYPE FILE_BUFFER_TYPE::int_type
#define POS_TYPE FILE_BUFFER_TYPE::pos_type
#define OFF_TYPE FILE_BUFFER_TYPE::off_type
#define SEEK_DIR IOS_BASE::seekdir
#define EOF_VALUE traits::eof()
#else
// Unix uses this section until it supports STL. This means no locales, no traits,
// no wide chars, etc. Also, the stream classes are the original ARM-style ones,
// and are not templatized.
#define IOS_BASE ios
#include <istream.h>
#define TEMPLATE_DEF
#define FILE_BUFFER_TYPE nsFileBufferT
#define INPUT_FILE_STREAM nsInputFileStreamT
#define OUTPUT_FILE_STREAM nsOutputFileStreamT
#define IO_FILE_STREAM nsIOFileStreamT
#define BASIC_STREAMBUF streambuf
#define BASIC_ISTREAM istream
#define BASIC_OSTREAM ostream
#define BASIC_IOSTREAM iostream
#define INT_TYPE int
#define POS_TYPE long
#define OFF_TYPE long
#define SEEK_DIR ios::seek_dir
#define int_type int
#define pos_type long
#define off_type long
#define char_type char
#define EOF_VALUE EOF
#endif // NS_USING_STL
#ifdef __MWERKS__
#ifdef MSIPL_WCHART
#define NS_USING_WIDE_CHAR
#endif
#ifdef MSIPL_EXPLICIT_FUNC_TEMPLATE_ARG
#define NS_EXPLICIT_FUNC_TEMPLATE_ARG
#endif
#define NS_READ_LOCK(mut) READ_LOCK(mut)
#define NS_WRITE_LOCK(mut) WRITE_LOCK(mut)
#else
// Fix me, if necessary, for thread-safety.
#define NS_READ_LOCK(mut)
#define NS_WRITE_LOCK(mut)
#endif // __MWERKS__
//=========================== End Compiler-specific macros ===============================
//========================================================================================
NS_NAMESPACE nsFileStreamHelpers
// Prototypes for common (non-template) implementations in the .cpp file which do not
// need the template args (charT, traits).
//========================================================================================
{
NS_NAMESPACE_PROTOTYPE NS_BASE PRFileDesc* open(
const nsFilePath& inFile,
IOS_BASE::openmode mode,
PRIntn accessMode);
} NS_NAMESPACE_END // nsFileStreamHelpers
//========================================================================================
// Template declarations
//========================================================================================
//========================================================================================
TEMPLATE_DEF
class nsFileBufferT
//========================================================================================
: public BASIC_STREAMBUF
{
#ifdef NS_USING_STL
typedef codecvt_base::result result;
public:
typedef charT char_type;
typedef typename traits::pos_type pos_type;
typedef typename traits::off_type off_type;
typedef typename traits::int_type int_type;
typedef traits traits_type;
typedef typename traits::state_type state_type;
typedef codecvt<charT, char, state_type> ofacet_type;
typedef codecvt<char, charT, state_type> ifacet_type;
#endif
public:
nsFileBufferT();
nsFileBufferT(PRFileDesc* pfile_arg);
virtual ~nsFileBufferT();
bool is_open() const;
FILE_BUFFER_TYPE* open(
const nsFilePath& inFile,
IOS_BASE::openmode mode,
PRIntn accessMode);
FILE_BUFFER_TYPE* close();
protected:
virtual int_type overflow(int_type c=EOF_VALUE);
virtual int_type pbackfail(int_type c=EOF_VALUE);
virtual int_type underflow();
virtual pos_type seekoff(
off_type off, SEEK_DIR way,
IOS_BASE::openmode which=IOS_BASE::in|IOS_BASE::out);
virtual pos_type seekpos(pos_type sp,
IOS_BASE::openmode which=IOS_BASE::in|IOS_BASE::out);
virtual BASIC_STREAMBUF* setbuf(char_type* s, streamsize n);
virtual int sync();
virtual int_type uflow();
#ifdef NS_USING_STL
virtual void imbue(const locale& loc);
#endif
virtual streamsize showmanyc();
virtual streamsize xsgetn(char_type* s, streamsize n);
virtual streamsize xsputn(const char_type* s, streamsize n);
private:
PRFileDesc* mFileDesc;
IOS_BASE::openmode mode_;
}; // class nsFileBufferT
//========================================================================================
TEMPLATE_DEF
class nsInputFileStreamT
//========================================================================================
: public BASIC_ISTREAM
{
#ifdef NS_USING_STL
public:
typedef charT char_type;
typedef typename traits::pos_type pos_type;
typedef typename traits::off_type off_type;
typedef typename traits::int_type int_type;
typedef traits traits_type;
#endif
public:
nsInputFileStreamT();
explicit nsInputFileStreamT(
const nsFilePath& inFile,
IOS_BASE::openmode mode=IOS_BASE::in,
PRIntn accessMode = 0x00400);
virtual ~nsInputFileStreamT();
FILE_BUFFER_TYPE* rdbuf() const;
inline bool is_open();
inline void open(
const nsFilePath& inFile,
IOS_BASE::openmode mode=IOS_BASE::in,
PRIntn accessMode = 0x00400);
inline void close();
private:
FILE_BUFFER_TYPE mBuffer;
}; // class nsInputFileStreamT
//========================================================================================
TEMPLATE_DEF
class nsOutputFileStreamT
//========================================================================================
: public BASIC_OSTREAM
{
#ifdef NS_USING_STL
public:
typedef charT char_type;
typedef typename traits::pos_type pos_type;
typedef typename traits::off_type off_type;
typedef typename traits::int_type int_type;
typedef traits traits_type;
#endif
public:
nsOutputFileStreamT();
explicit nsOutputFileStreamT(
const nsFilePath& inFile,
IOS_BASE::openmode mode = IOS_BASE::out|IOS_BASE::trunc,
PRIntn accessMode = 0x00200);
virtual ~nsOutputFileStreamT();
FILE_BUFFER_TYPE* rdbuf() const;
inline bool is_open();
inline void open(
const nsFilePath& inFile,
IOS_BASE::openmode mode = IOS_BASE::out|IOS_BASE::trunc,
PRIntn accessMode = 0x00200);
inline void close();
private:
FILE_BUFFER_TYPE mBuffer;
}; // class nsOutputFileStreamT
//========================================================================================
// Implementation of nsFileBufferT
//========================================================================================
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline FILE_BUFFER_TYPE::nsFileBufferT()
: BASIC_STREAMBUF(), mFileDesc(NULL)
//----------------------------------------------------------------------------------------
{
}
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline FILE_BUFFER_TYPE::nsFileBufferT(PRFileDesc* pfarg)
: BASIC_STREAMBUF(), mFileDesc(pfarg)
//----------------------------------------------------------------------------------------
{
}
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline FILE_BUFFER_TYPE* FILE_BUFFER_TYPE::close()
// Must precede the destructor because both are inline.
//----------------------------------------------------------------------------------------
{
if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR)
return this;
NS_WRITE_LOCK(_mutex);
return (mFileDesc && PR_Close(mFileDesc) == PR_SUCCESS) ? mFileDesc = 0, this : 0;
}
#if defined(DEFINING_FILE_STREAM)
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
FILE_BUFFER_TYPE::~nsFileBufferT()
//----------------------------------------------------------------------------------------
{
close();
}
#endif // #if defined(DEFINING_FILE_STREAM)
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline bool
FILE_BUFFER_TYPE::is_open() const
//----------------------------------------------------------------------------------------
{
NS_READ_LOCK(_mutex);
return bool(mFileDesc); // in case it is typedefed to int
}
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline FILE_BUFFER_TYPE* FILE_BUFFER_TYPE::open(
const nsFilePath& inFile,
IOS_BASE::openmode mode,
PRIntn accessMode)
//----------------------------------------------------------------------------------------
{
if (mFileDesc)
return 0;
NS_WRITE_LOCK(_mutex);
mFileDesc = nsFileStreamHelpers::open(inFile, mode, accessMode);
if (!mFileDesc)
return 0;
mode_ = mode;
return this;
} // FILE_BUFFER_TYPE::open
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline int FILE_BUFFER_TYPE:: sync()
//----------------------------------------------------------------------------------------
{
return (mFileDesc ? (int)PR_Sync(mFileDesc) : 0);
}
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline BASIC_STREAMBUF* FILE_BUFFER_TYPE::setbuf(char_type*, streamsize)
//----------------------------------------------------------------------------------------
{
return (!mFileDesc) ? 0 : this;
}
#if defined(DEFINING_FILE_STREAM)
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
INT_TYPE FILE_BUFFER_TYPE::overflow(int_type c)
//----------------------------------------------------------------------------------------
{
#ifndef NS_USING_STL
char ch = c;
PRInt32 bytesWrit1 = PR_Write(mFileDesc, &ch, sizeof(ch));
return bytesWrit1 < sizeof(ch) ? EOF_VALUE : c;
#else
#ifdef NS_EXPLICIT_FUNC_TEMPLATE_ARG
const ofacet_type& ft=use_facet<ofacet_type>(getloc());
#elif defined(XP_PC)
const ofacet_type& ft=use_facet(getloc(), (ofacet_type*)0, false);
#else
const ofacet_type& ft=use_facet(getloc(), (ofacet_type*)0);
#endif
char_type ch = traits_type::to_char_type(c);
if (!mFileDesc)
return EOF_VALUE;
if (traits_type::eq_int_type(c, EOF_VALUE))
return traits_type::not_eof(c);
if (ft.always_noconv())
{
PRInt32 bytesWrit1 = PR_Write(mFileDesc, &ch, sizeof(ch));
return bytesWrit1 < sizeof(ch) ? EOF_VALUE : c;
}
{ // <- sic!
state_type fst;
const char_type* end;
char buf[4];
char* ebuf;
result conv;
if ((conv=ft.out(fst, &ch, &ch+1, end, buf, buf+3, ebuf))==
codecvt_base::noconv)
{
PRInt32 bytesWrit2 = PR_Write(mFileDesc, &ch, sizeof(ch));
return bytesWrit2 < sizeof(ch) ? EOF_VALUE : c;
}
if ((conv==codecvt_base::partial)||(conv==codecvt_base::error))
return EOF_VALUE;
*ebuf=0;
PRInt32 bytesWrit3 = strlen(buf);
return PR_Write(mFileDesc, buf, bytesWrit3) < bytesWrit3 ? EOF_VALUE : c;
}
#endif
}
#endif // #if defined(DEFINING_FILE_STREAM)
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline INT_TYPE FILE_BUFFER_TYPE::underflow()
//----------------------------------------------------------------------------------------
{
if (!mFileDesc)
return EOF_VALUE;
char_type s;
PRInt32 request = 1;
if (1 != PR_Read(mFileDesc, &s, request))
return EOF_VALUE;
PR_Seek(mFileDesc, -1, PR_SEEK_CUR);
return (int_type)s;
}
#if defined(DEFINING_FILE_STREAM)
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
streamsize FILE_BUFFER_TYPE::xsputn(const char_type* s, streamsize n)
//----------------------------------------------------------------------------------------
{
#ifndef NS_USING_STL
PRInt32 bytesWrit1 = PR_Write(mFileDesc, s, sizeof(char) * size_t(n));
return bytesWrit1 < 0 ? 0 : (streamsize)bytesWrit1;
#else
#ifdef NS_EXPLICIT_FUNC_TEMPLATE_ARG
const ofacet_type& ft=use_facet<ofacet_type>(loc);
#elif defined(XP_PC)
const ofacet_type& ft=use_facet(getloc(), (ofacet_type*)0, false);
#else
const ofacet_type& ft=use_facet(getloc(), (ofacet_type*)0);
#endif
if (!mFileDesc || !n)
return 0;
if (ft.always_noconv())
{
PRInt32 bytesWrit1 = PR_Write(mFileDesc, s, sizeof(char) * size_t(n));
return bytesWrit1 < 0 ? 0 : (streamsize)bytesWrit1;
}
{ // <- sic!
state_type fst;
const char_type* end;
char buf[8];
char* ebuf;
result conv;
#ifdef NS_EXPLICIT_FUNC_TEMPLATE_ARG
if ((conv=use_facet<ofacet_type>(getloc()).
#elif defined(XP_PC)
if ((conv=use_facet(getloc(), (ofacet_type*)0, false).
#else
if ((conv=use_facet(getloc(), (ofacet_type*)0).
#endif
out(fst, s, s+n, end, buf, buf+7, ebuf))==codecvt_base::noconv)
return (streamsize)PR_Write(mFileDesc, s, sizeof(char) * size_t(n));
if ((conv==codecvt_base::partial) ||(conv==codecvt_base::error))
return 0;
*ebuf=0;
PRInt32 bytesWrit2 = strlen(buf);
bytesWrit2 = PR_Write(mFileDesc, buf, bytesWrit2);
return bytesWrit2 < 0 ? 0 : streamsize(bytesWrit2 / sizeof(char_type));
}
#endif
} // FILE_BUFFER_TYPE::xsputn
#endif // #if defined(DEFINING_FILE_STREAM)
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline INT_TYPE FILE_BUFFER_TYPE::pbackfail(int_type c)
//----------------------------------------------------------------------------------------
{
if (!mFileDesc)
return EOF_VALUE;
if (PR_Seek(mFileDesc, -1, PR_SEEK_CUR) < 0)
return EOF_VALUE;
#ifdef NS_USING_STL
return (traits::eq_int_type(c, EOF_VALUE)) ? traits::not_eof(c) : c;
#else
return c;
#endif
}
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline INT_TYPE FILE_BUFFER_TYPE::uflow()
//----------------------------------------------------------------------------------------
{
if (!mFileDesc)
return EOF_VALUE;
char_type s;
if (1 != PR_Read(mFileDesc, &s, 1)) // attempt to read 1 byte, confirm 1 byte
return EOF_VALUE;
return (int_type)s;
}
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline streamsize FILE_BUFFER_TYPE::xsgetn(char_type* s, streamsize n)
//----------------------------------------------------------------------------------------
{
return mFileDesc ? (streamsize)PR_Read(mFileDesc, s, sizeof(char) * size_t(n)) : 0;
}
#ifdef NS_USING_STL
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline void FILE_BUFFER_TYPE::imbue(const locale& loc_arg)
//----------------------------------------------------------------------------------------
{
#ifdef XP_MAC
loc = loc_arg;
#endif
}
#endif
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline streamsize FILE_BUFFER_TYPE::showmanyc()
//----------------------------------------------------------------------------------------
{
return (streamsize)PR_Available(mFileDesc);
}
#if defined(DEFINING_FILE_STREAM)
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
POS_TYPE FILE_BUFFER_TYPE::seekoff(
OFF_TYPE off,
SEEK_DIR way,
IOS_BASE::openmode /* which */)
//----------------------------------------------------------------------------------------
{
if (!mFileDesc ||
#ifdef NS_USING_STL
((way&IOS_BASE::beg) && off<0) || ((way&IOS_BASE::end) && off > 0)
#else
((way == IOS_BASE::beg) && off<0) || ((way == IOS_BASE::end) && off > 0)
#endif
)
return pos_type(-1);
PRSeekWhence poseek = PR_SEEK_CUR;
switch (way)
{
case IOS_BASE::beg : poseek= PR_SEEK_SET;
break;
case IOS_BASE::end : poseek= PR_SEEK_END;
break;
}
PRInt32 position = PR_Seek(mFileDesc, off, poseek);
if (position < 0)
return pos_type(-1);
return pos_type(position);
}
#endif // #if defined(DEFINING_FILE_STREAM)
#if defined(DEFINING_FILE_STREAM)
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
POS_TYPE FILE_BUFFER_TYPE::seekpos(pos_type sp, IOS_BASE::openmode)
//----------------------------------------------------------------------------------------
{
if (!mFileDesc || sp==pos_type(-1))
return -1;
#if defined(XP_PC) || defined(XP_UNIX)
PRInt32 position = sp;
#else
PRInt32 position = sp.offset();
#endif
position = PR_Seek(mFileDesc, position, PR_SEEK_SET);
if (position < 0)
return pos_type(-1);
return position;
}
#endif // #if defined(DEFINING_FILE_STREAM)
//========================================================================================
// Implementation of nsInputFileStreamT
//========================================================================================
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline INPUT_FILE_STREAM::nsInputFileStreamT()
: BASIC_ISTREAM(&mBuffer)
//----------------------------------------------------------------------------------------
{
// already inited
}
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline INPUT_FILE_STREAM::nsInputFileStreamT(
const nsFilePath& inFile,
IOS_BASE::openmode mode,
PRIntn accessMode)
//----------------------------------------------------------------------------------------
: BASIC_ISTREAM(&mBuffer)
{
// already inited
if (!mBuffer.open(inFile, openmode(mode|in), accessMode))
setstate(failbit);
}
#if defined(DEFINING_FILE_STREAM)
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
INPUT_FILE_STREAM::~nsInputFileStreamT()
//----------------------------------------------------------------------------------------
{
}
#endif // #if defined(DEFINING_FILE_STREAM)
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline FILE_BUFFER_TYPE* INPUT_FILE_STREAM::rdbuf() const
//----------------------------------------------------------------------------------------
{
return (FILE_BUFFER_TYPE*)&mBuffer;
}
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline bool INPUT_FILE_STREAM:: is_open()
//----------------------------------------------------------------------------------------
{
return mBuffer.is_open();
}
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline void INPUT_FILE_STREAM::open(
const nsFilePath& inFile,
IOS_BASE::openmode mode,
PRIntn accessMode)
//----------------------------------------------------------------------------------------
{
if (!mBuffer.open(inFile, openmode(mode|in), accessMode))
setstate(failbit);
}
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline void INPUT_FILE_STREAM::close()
//----------------------------------------------------------------------------------------
{
if (!mBuffer.close())
setstate(failbit);
}
//========================================================================================
// Implementation of nsOutputFileStreamT
//========================================================================================
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline OUTPUT_FILE_STREAM::nsOutputFileStreamT()
: BASIC_OSTREAM(&mBuffer)
//----------------------------------------------------------------------------------------
{
// already inited
}
#if defined(DEFINING_FILE_STREAM)
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
OUTPUT_FILE_STREAM::nsOutputFileStreamT(
const nsFilePath& inFile,
IOS_BASE::openmode mode,
PRIntn accessMode)
//----------------------------------------------------------------------------------------
: BASIC_OSTREAM(&mBuffer)
{
// already inited
if (!mBuffer.open(inFile, openmode(mode|out), accessMode))
setstate(failbit);
}
#endif // #if defined(DEFINING_FILE_STREAM)
#if defined(DEFINING_FILE_STREAM)
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline OUTPUT_FILE_STREAM::~nsOutputFileStreamT()
//----------------------------------------------------------------------------------------
{
}
#endif // #if defined(DEFINING_FILE_STREAM)
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline FILE_BUFFER_TYPE*
OUTPUT_FILE_STREAM::rdbuf() const
//----------------------------------------------------------------------------------------
{
return (FILE_BUFFER_TYPE*)&mBuffer;
}
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline bool OUTPUT_FILE_STREAM:: is_open()
//----------------------------------------------------------------------------------------
{
return mBuffer.is_open();
}
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline void OUTPUT_FILE_STREAM::open(
const nsFilePath& inFile,
IOS_BASE::openmode mode,
PRIntn accessMode)
//----------------------------------------------------------------------------------------
{
if (!mBuffer.open(inFile, openmode(mode | out), accessMode))
setstate(failbit);
}
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline void OUTPUT_FILE_STREAM:: close()
//----------------------------------------------------------------------------------------
{
if (!mBuffer.close())
setstate(failbit);
}
//========================================================================================
TEMPLATE_DEF
class nsIOFileStreamT : public BASIC_IOSTREAM
//========================================================================================
{
#ifdef NS_USING_STL
public:
typedef charT char_type;
typedef typename traits::pos_type pos_type;
typedef typename traits::off_type off_type;
typedef typename traits::int_type int_type;
typedef traits traits_type;
#endif
public:
nsIOFileStreamT();
explicit nsIOFileStreamT(
const nsFilePath& inFile,
IOS_BASE::openmode mode = IOS_BASE::in|IOS_BASE::out,
PRIntn accessMode = 0x00600);
virtual ~nsIOFileStreamT();
FILE_BUFFER_TYPE* rdbuf() const;
inline bool is_open();
inline void open(
const nsFilePath& inFile,
IOS_BASE::openmode mode = IOS_BASE::in|IOS_BASE::out,
PRIntn accessMode = 0x00600);
inline void close();
private:
FILE_BUFFER_TYPE mBuffer;
}; // class nsIOFileStreamT
//========================================================================================
// Implementation of nsIOFileStream
//========================================================================================
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline IO_FILE_STREAM::nsIOFileStreamT()
//----------------------------------------------------------------------------------------
: mBuffer(), BASIC_IOSTREAM(&mBuffer)
{
// already inited
}
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline IO_FILE_STREAM::nsIOFileStreamT(
const nsFilePath& inFile,
IOS_BASE::openmode mode,
PRIntn accessMode)
//----------------------------------------------------------------------------------------
: mBuffer(), BASIC_IOSTREAM(&mBuffer)
{
// already inited
if (!mBuffer.open(inFile, mode, accessMode))
setstate(failbit);
}
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline IO_FILE_STREAM::~nsIOFileStreamT()
//----------------------------------------------------------------------------------------
{
}
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline FILE_BUFFER_TYPE*
IO_FILE_STREAM::rdbuf() const
//----------------------------------------------------------------------------------------
{
return (FILE_BUFFER_TYPE*)&mBuffer;
}
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline bool IO_FILE_STREAM::is_open()
//----------------------------------------------------------------------------------------
{
return mBuffer.is_open();
}
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline void IO_FILE_STREAM::open(
const nsFilePath& inFile,
IOS_BASE::openmode mode,
PRIntn accessMode)
//----------------------------------------------------------------------------------------
{
if (!mBuffer.open(inFile, mode, accessMode))
setstate(failbit);
}
//----------------------------------------------------------------------------------------
TEMPLATE_DEF
inline void IO_FILE_STREAM::close()
//----------------------------------------------------------------------------------------
{
if (!mBuffer.close())
setstate(failbit);
}
//========================================================================================
// Specializations of the stream templates
//========================================================================================
#ifdef NS_USING_STL
typedef nsFileBufferT<char, char_traits<char> > nsFileBuffer;
typedef nsInputFileStreamT<char, char_traits<char> > nsInputFileStream;
typedef nsOutputFileStreamT<char, char_traits<char> > nsOutputFileStream;
typedef nsIOFileStreamT<char, char_traits<char> > nsIOFileStream;
#ifdef NS_USING_WIDE_CHAR
typedef nsFileBufferT<wchar_t, char_traits<wchar_t> > nsWideFileBuffer;
typedef nsInputFileStreamT<wchar_t, char_traits<wchar_t> > nsWideInputFileStream;
typedef nsOutputFileStreamT<wchar_t, char_traits<wchar_t> > nsWideOutputFileStream;
typedef nsIOFileStreamT<wchar_t, char_traits<wchar_t> > nsWideIOFileStream;
#endif // NS_USING_WIDE_CHAR
#else
typedef nsFileBufferT nsFileBuffer;
typedef nsInputFileStreamT nsInputFileStream;
typedef nsOutputFileStreamT nsOutputFileStream;
typedef nsIOFileStreamT nsIOFileStream;
#endif
#endif /* _FILESTREAM_H_ */

24
mozilla/base/src/MANIFEST Normal file
View File

@@ -0,0 +1,24 @@
#
# This is a list of local files which get copied to the mozilla:dist directory
#
nscore.h
nsIArena.h
nsIAtom.h
nsIByteBuffer.h
nsBTree.h
nsCRT.h
nsDeque.h
nsITimer.h
nsITimerCallback.h
nsIUnicharBuffer.h
nsRBTree.h
nsIUnicharInputStream.h
nsString.h
nsVoidArray.h
nsUnitConversion.h
nsIBaseStream.h
nsIInputStream.h
nsIOutputStream.h
nsInt64.h
nsTime.h

View File

@@ -0,0 +1,88 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DEFINES +=-D_IMPL_NS_BASE
DIRS = $(MOZ_TOOLKIT)
LIBRARY_NAME = raptorbase
CPPSRCS = \
nsArena.cpp \
nsAtomTable.cpp \
nsBaseDLL.cpp \
nsBTree.cpp \
nsByteBuffer.cpp \
nsCRT.cpp \
nsDeque.cpp \
nsEscape.cpp \
nsFileSpec.cpp \
nsFileStream.cpp \
nsIFileStream.cpp \
nsProperties.cpp \
nsRBTree.cpp \
nsSizeOfHandler.cpp \
nsString.cpp \
nsUnicharBuffer.cpp \
nsUnicharInputStream.cpp \
nsVoidArray.cpp \
$(NULL)
EXPORTS = \
nscore.h \
nsBTree.h \
nsCRT.h \
nsDeque.h \
nsIArena.h \
nsIAtom.h \
nsIByteBuffer.h \
nsIBaseStream.h \
nsIInputStream.h \
nsIOutputStream.h \
nsITimer.h \
nsITimerCallback.h \
nsIUnicharBuffer.h \
nsIUnicharInputStream.h \
nsInt64.h \
nsRBTree.h \
nsString.h \
nsTime.h \
nsVoidArray.h \
nsUnitConversion.h \
$(NULL)
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
MODULE=base
REQUIRES = xpcom netlib raptor
include $(topsrcdir)/config/config.mk
TARGET = $(LIBARY)
include $(topsrcdir)/config/rules.mk
test:
@echo OS_ARCH = $(OS_ARCH)

View File

@@ -0,0 +1,39 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
LIBRARY_NAME = gmbasegtk
MODULE=base
REQUIRES = xpcom raptor
DEFINES += -D_IMPL_NS_WIDGET
CPPSRCS = nsTimer.cpp
include $(topsrcdir)/config/config.mk
CFLAGS += $(TK_CFLAGS)
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,40 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nscore.h"
#include "nsCaretProperties.h"
//-----------------------------------------------------------------------------
nsCaretProperties::nsCaretProperties()
: mCaretWidth(eDefaultCaretWidth)
, mBlinkRate(eDefaulBlinkRate)
{
// in your platform-specific class, get data from the OS in your constructor
mBlinkRate = 0; // don't blink the caret
}
//-----------------------------------------------------------------------------
nsCaretProperties* NewCaretProperties()
{
return new nsCaretProperties();
}

View File

@@ -0,0 +1,190 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsITimer.h"
#include "nsITimerCallback.h"
#include "nsCRT.h"
#include "prlog.h"
#include <stdio.h>
#include <limits.h>
#include <gtk/gtk.h>
static NS_DEFINE_IID(kITimerIID, NS_ITIMER_IID);
extern "C" gint nsTimerExpired(gpointer aCallData);
/*
* Implementation of timers using Gtk timer facility
*/
class TimerImpl : public nsITimer {
public:
public:
TimerImpl();
virtual ~TimerImpl();
virtual nsresult Init(nsTimerCallbackFunc aFunc,
void *aClosure,
// PRBool aRepeat,
PRUint32 aDelay);
virtual nsresult Init(nsITimerCallback *aCallback,
// PRBool aRepeat,
PRUint32 aDelay);
NS_DECL_ISUPPORTS
virtual void Cancel();
virtual PRUint32 GetDelay() { return mDelay; }
virtual void SetDelay(PRUint32 aDelay) { mDelay=aDelay; };
virtual void* GetClosure() { return mClosure; }
void FireTimeout();
private:
nsresult Init(PRUint32 aDelay);
PRUint32 mDelay;
nsTimerCallbackFunc mFunc;
void *mClosure;
nsITimerCallback *mCallback;
// PRBool mRepeat;
TimerImpl *mNext;
guint mTimerId;
};
void TimerImpl::FireTimeout()
{
if (mFunc != NULL) {
(*mFunc)(this, mClosure);
}
else if (mCallback != NULL) {
mCallback->Notify(this); // Fire the timer
}
// Always repeating here
// if (mRepeat)
// mTimerId = gtk_timeout_add(aDelay, nsTimerExpired, this);
}
TimerImpl::TimerImpl()
{
// printf("TimerImple::TimerImpl called for %p\n", this);
NS_INIT_REFCNT();
mFunc = NULL;
mCallback = NULL;
mNext = NULL;
mTimerId = 0;
mDelay = 0;
mClosure = NULL;
}
TimerImpl::~TimerImpl()
{
//printf("TimerImpl::~TimerImpl called for %p\n", this);
Cancel();
NS_IF_RELEASE(mCallback);
}
nsresult
TimerImpl::Init(nsTimerCallbackFunc aFunc,
void *aClosure,
// PRBool aRepeat,
PRUint32 aDelay)
{
//printf("TimerImpl::Init called with func + closure for %p\n", this);
mFunc = aFunc;
mClosure = aClosure;
// mRepeat = aRepeat;
if ((aDelay > 10000) || (aDelay < 0)) {
printf("Timer::Init() called with bogus value \"%d\"! Not enabling timer.\n",
aDelay);
return Init(aDelay);
}
mTimerId = gtk_timeout_add(aDelay, nsTimerExpired, this);
return Init(aDelay);
}
nsresult
TimerImpl::Init(nsITimerCallback *aCallback,
// PRBool aRepeat,
PRUint32 aDelay)
{
//printf("TimerImpl::Init called with callback only for %p\n", this);
mCallback = aCallback;
// mRepeat = aRepeat;
if ((aDelay > 10000) || (aDelay < 0)) {
printf("Timer::Init() called with bogus value \"%d\"! Not enabling timer.\n",
aDelay);
return Init(aDelay);
}
mTimerId = gtk_timeout_add(aDelay, nsTimerExpired, this);
return Init(aDelay);
}
nsresult
TimerImpl::Init(PRUint32 aDelay)
{
//printf("TimerImpl::Init called with delay %d only for %p\n", aDelay, this);
mDelay = aDelay;
NS_ADDREF(this);
return NS_OK;
}
NS_IMPL_ISUPPORTS(TimerImpl, kITimerIID)
void
TimerImpl::Cancel()
{
//printf("TimerImpl::Cancel called for %p\n", this);
TimerImpl *me = this;
if (mTimerId)
gtk_timeout_remove(mTimerId);
}
NS_BASE nsresult NS_NewTimer(nsITimer** aInstancePtrResult)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
TimerImpl *timer = new TimerImpl();
if (nsnull == timer) {
return NS_ERROR_OUT_OF_MEMORY;
}
return timer->QueryInterface(kITimerIID, (void **) aInstancePtrResult);
}
gint nsTimerExpired(gpointer aCallData)
{
//printf("nsTimerExpired for %p\n", aCallData);
TimerImpl* timer = (TimerImpl *)aCallData;
timer->FireTimeout();
return 0;
}

View File

@@ -0,0 +1,43 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include <Events.h>
#include "nscore.h"
#include "nsCaretProperties.h"
//-----------------------------------------------------------------------------
nsCaretProperties::nsCaretProperties()
: mCaretWidth(eDefaultCaretWidth)
, mBlinkRate(eDefaulBlinkRate)
{
// in your platform-specific class, get data from the OS in your constructor
// MacOS calls
mBlinkRate = ::GetCaretTime() * 1000 / 60;
}
//-----------------------------------------------------------------------------
nsCaretProperties* NewCaretProperties()
{
return new nsCaretProperties();
}

View File

@@ -0,0 +1,930 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
// This file is included by nsFile.cp, and includes the Macintosh-specific
// implementations.
#include "FullPath.h"
#include "FileCopy.h"
#include "MoreFilesExtras.h"
#include "nsEscape.h"
#include <Aliases.h>
#include <Folders.h>
#include <Errors.h>
#include <TextUtils.h>
#include <Processes.h>
const unsigned char* kAliasHavenFolderName = "\pnsAliasHaven";
//========================================================================================
namespace MacFileHelpers
//========================================================================================
{
inline void PLstrcpy(Str255 dst, ConstStr255Param src)
{
memcpy(dst, src, 1 + src[0]);
}
void PLstrcpy(Str255 dst, const char* src, int inMaxLen=255);
void PLstrncpy(Str255 dst, const char* src, int inMaxLen);
void SwapSlashColon(char * s);
OSErr FSSpecFromFullUnixPath(
const char * unixPath,
FSSpec& outSpec,
Boolean resolveAlias,
Boolean allowPartial = false,
Boolean createDirs = false);
char* MacPathFromUnixPath(const char* unixPath);
char* EncodeMacPath(
char* inPath, // NOT const - gets clobbered
Boolean prependSlash,
Boolean doEscape );
OSErr FSSpecFromPathname(
const char* inPathNamePtr,
FSSpec& outSpec,
Boolean inCreateDirs);
char* PathNameFromFSSpec(
const FSSpec& inSpec,
Boolean wantLeafName );
OSErr CreateFolderInFolder(
short refNum, // Parent directory/volume
long dirID,
ConstStr255Param folderName, // Name of the new folder
short& outRefNum, // Volume of the created folder
long& outDirID); //
// Some routines to support an "alias haven" directory. Aliases in this directory
// are never resolved. There is a ResolveAlias here that respects that. This is
// to support attaching of aliases in mail.
void EnsureAliasHaven();
void SetNoResolve(Boolean inResolve);
PRBool IsAliasSafe(const FSSpec& inSpec);
OSErr MakeAliasSafe(FSSpec& inOutSpec);
OSErr ResolveAliasFile(FSSpec& inOutSpec, Boolean& wasAliased);
Boolean sNoResolve = false;
long sAliasHavenDirID = 0;
short sAliasHavenVRefNum = 0;
} // namespace MacFileHelpers
//----------------------------------------------------------------------------------------
void MacFileHelpers::PLstrcpy(Str255 dst, const char* src, int inMax)
//----------------------------------------------------------------------------------------
{
int srcLength = strlen(src);
NS_ASSERTION(srcLength <= inMax, "Oops, string is too long!");
if (srcLength > inMax)
srcLength = inMax;
dst[0] = srcLength;
memcpy(&dst[1], src, srcLength);
}
//----------------------------------------------------------------------------------------
void MacFileHelpers::PLstrncpy(Str255 dst, const char* src, int inMax)
//----------------------------------------------------------------------------------------
{
int srcLength = strlen(src);
if (srcLength > inMax)
srcLength = inMax;
dst[0] = srcLength;
memcpy(&dst[1], src, srcLength);
}
//-----------------------------------
void MacFileHelpers::SwapSlashColon(char * s)
//-----------------------------------
{
while ( *s != 0)
{
if (*s == '/')
*s++ = ':';
else if (*s == ':')
*s++ = '/';
else
*s++;
}
} // MacFileHelpers::SwapSlashColon
//-----------------------------------
char* MacFileHelpers::EncodeMacPath(
char* inPath, // NOT const, gets clobbered
Boolean prependSlash,
Boolean doEscape )
// Transforms Macintosh style path into Unix one
// Method: Swap ':' and '/', hex escape the result
//-----------------------------------
{
if (inPath == nsnull)
return nsnull;
int pathSize = strlen(inPath);
// XP code sometimes chokes if there's a final slash in the unix path.
// Since correct mac paths to folders and volumes will end in ':', strip this
// first.
char* c = inPath + pathSize - 1;
if (*c == ':')
{
*c = 0;
pathSize--;
}
char * newPath = nsnull;
char * finalPath = nsnull;
if (prependSlash)
{
newPath = new char[pathSize + 2];
newPath[0] = ':'; // It will be converted to '/'
memcpy(&newPath[1], inPath, pathSize + 1);
}
else
{
newPath = new char[pathSize + 1];
strcpy(newPath, inPath);
}
if (newPath)
{
SwapSlashColon( newPath );
if (doEscape)
{
finalPath = nsEscape(newPath, url_Path);
delete [] newPath;
}
else
finalPath = newPath;
}
delete [] inPath;
return finalPath;
} // MacFileHelpers::EncodeMacPath
//----------------------------------------------------------------------------------------
inline void MacFileHelpers::SetNoResolve(Boolean inResolve)
//----------------------------------------------------------------------------------------
{
sNoResolve = inResolve;
} // MacFileHelpers::SetNoResolve
//----------------------------------------------------------------------------------------
OSErr MacFileHelpers::MakeAliasSafe(FSSpec& inOutSpec)
// Pass in the spec of an alias. This copies the file to the safe haven folder, and
// returns the spec of the copy to the caller
//----------------------------------------------------------------------------------------
{
EnsureAliasHaven();
nsFileSpec dstDirSpec(sAliasHavenVRefNum, sAliasHavenDirID, "\p");
// Make sure its name is unique
nsFileSpec havenSpec(sAliasHavenVRefNum, sAliasHavenDirID, "\pG'day");
if (havenSpec.Valid())
havenSpec.MakeUnique(inOutSpec.name);
// Copy the file into the haven directory
if (havenSpec.Valid())
{
OSErr err = ::FSpFileCopy(
&inOutSpec,
dstDirSpec,
havenSpec.GetLeafPName(),
nil, 0, true);
// Return the spec of the copy to the caller.
if (err != noErr)
return err;
inOutSpec = havenSpec;
}
return noErr;
} // MacFileHelpers::MakeAliasSafe
//----------------------------------------------------------------------------------------
char* MacFileHelpers::MacPathFromUnixPath(const char* unixPath)
//----------------------------------------------------------------------------------------
{
// Relying on the fact that the unix path is always longer than the mac path:
size_t len = strlen(unixPath);
char* result = new char[len + 2]; // ... but allow for the initial colon in a partial name
if (result)
{
char* dst = result;
const char* src = unixPath;
if (*src == '/') // * full path
src++;
else if (strchr(src, '/')) // * partial path, and not just a leaf name
*dst++ = ':';
strcpy(dst, src);
nsUnescape(dst); // Hex Decode
MacFileHelpers::SwapSlashColon(dst);
}
return result;
} // MacFileHelpers::MacPathFromUnixPath
//----------------------------------------------------------------------------------------
OSErr MacFileHelpers::FSSpecFromPathname(
const char* inPathNamePtr,
FSSpec& outSpec,
Boolean inCreateDirs)
// FSSpecFromPathname reverses PathNameFromFSSpec.
// It returns a FSSpec given a c string which is a mac pathname.
//----------------------------------------------------------------------------------------
{
OSErr err;
// Simplify this routine to use FSMakeFSSpec if length < 255. Otherwise use the MoreFiles
// routine FSpLocationFromFullPath, which allocates memory, to handle longer pathnames.
size_t inLength = strlen(inPathNamePtr);
if (inLength < 255)
{
Str255 ppath;
MacFileHelpers::PLstrcpy(ppath, inPathNamePtr);
err = ::FSMakeFSSpec(0, 0, ppath, &outSpec);
}
else
err = FSpLocationFromFullPath(inLength, inPathNamePtr, &outSpec);
if (err == dirNFErr && inCreateDirs)
{
const char* path = inPathNamePtr;
outSpec.vRefNum = 0;
outSpec.parID = 0;
do {
// Locate the colon that terminates the node.
// But if we've a partial path (starting with a colon), find the second one.
const char* nextColon = strchr(path + (*path == ':'), ':');
// Well, if there are no more colons, point to the end of the string.
if (!nextColon)
nextColon = path + strlen(path);
// Make a pascal string out of this node. Include initial
// and final colon, if any!
Str255 ppath;
MacFileHelpers::PLstrncpy(ppath, path, nextColon - path + 1);
// Use this string as a relative path using the directory created
// on the previous round (or directory 0,0 on the first round).
err = ::FSMakeFSSpec(outSpec.vRefNum, outSpec.parID, ppath, &outSpec);
// If this was the leaf node, then we are done.
if (!*nextColon)
break;
// If we got "file not found", then
// we need to create a directory.
if (err == fnfErr && *nextColon)
err = FSpDirCreate(&outSpec, smCurrentScript, &outSpec.parID);
// For some reason, this usually returns fnfErr, even though it works.
if (err != noErr && err != fnfErr)
return err;
path = nextColon; // next round
} while (1);
}
return err;
} // MacFileHelpers::FSSpecFromPathname
//----------------------------------------------------------------------------------------
OSErr MacFileHelpers::CreateFolderInFolder(
short refNum, // Parent directory/volume
long dirID,
ConstStr255Param folderName, // Name of the new folder
short& outRefNum, // Volume of the created folder
long& outDirID) //
// Creates a folder named 'folderName' inside a folder.
// The errors returned are same as PBDirCreate
//----------------------------------------------------------------------------------------
{
HFileParam hpb;
hpb.ioVRefNum = refNum;
hpb.ioDirID = dirID;
hpb.ioNamePtr = (StringPtr)&folderName;
OSErr err = PBDirCreateSync((HParmBlkPtr)&hpb);
if (err == noErr)
{
outRefNum = hpb.ioVRefNum;
outDirID = hpb.ioDirID;
}
else
{
outRefNum = 0;
outDirID = 0;
}
return err;
} // MacFileHelpers::CreateFolderInFolder
//----------------------------------------------------------------------------------------
void MacFileHelpers::EnsureAliasHaven()
//----------------------------------------------------------------------------------------
{
// Alias Haven is a directory in which we never resolve aliases.
if (sAliasHavenVRefNum != 0)
return;
FSSpec temp;
if (FindFolder(0, kTemporaryFolderType, true, & temp.vRefNum, &temp.parID) == noErr)
{
CreateFolderInFolder(
temp.vRefNum, // Parent directory/volume
temp.parID,
kAliasHavenFolderName, // Name of the new folder
sAliasHavenVRefNum, // Volume of the created folder
sAliasHavenDirID);
}
} // MacFileHelpers::EnsureAliasHaven
//----------------------------------------------------------------------------------------
PRBool MacFileHelpers::IsAliasSafe(const FSSpec& inSpec)
// Returns true if the alias is in the alias haven directory, or if alias resolution
// has been turned off.
//----------------------------------------------------------------------------------------
{
return sNoResolve
|| (inSpec.parID == sAliasHavenDirID && inSpec.vRefNum == sAliasHavenVRefNum);
} // MacFileHelpers::IsAliasSafe
//----------------------------------------------------------------------------------------
OSErr MacFileHelpers::ResolveAliasFile(FSSpec& inOutSpec, Boolean& wasAliased)
//----------------------------------------------------------------------------------------
{
wasAliased = false;
if (IsAliasSafe(inOutSpec))
return noErr;
Boolean dummy;
return ::ResolveAliasFile(&inOutSpec, TRUE, &dummy, &wasAliased);
} // MacFileHelpers::ResolveAliasFile
//-----------------------------------
OSErr MacFileHelpers::FSSpecFromFullUnixPath(
const char * unixPath,
FSSpec& outSpec,
Boolean resolveAlias,
Boolean allowPartial,
Boolean createDirs)
// File spec from URL. Reverses GetURLFromFileSpec
// Its input is only the <path> part of the URL
// JRM 97/01/08 changed this so that if it's a partial path (doesn't start with '/'),
// then it is combined with inOutSpec's vRefNum and parID to form a new spec.
//-----------------------------------
{
if (unixPath == nsnull)
return badFidErr;
char* macPath = MacPathFromUnixPath(unixPath);
if (!macPath)
return memFullErr;
OSErr err = noErr;
if (!allowPartial)
{
NS_ASSERTION(*unixPath == '/' /*full path*/, "Not a full Unix path!");
}
err = FSSpecFromPathname(macPath, outSpec, createDirs);
if (err == fnfErr)
err = noErr;
Boolean dummy;
if (err == noErr && resolveAlias) // Added
err = MacFileHelpers::ResolveAliasFile(outSpec, dummy);
delete [] macPath;
NS_ASSERTION(err==noErr||err==fnfErr||err==dirNFErr||err==nsvErr, "Not a path!");
return err;
} // MacFileHelpers::FSSpecFromLocalUnixPath
//-----------------------------------
char* MacFileHelpers::PathNameFromFSSpec( const FSSpec& inSpec, Boolean wantLeafName )
// Returns a full pathname to the given file
// Returned value is allocated with new [], and must be freed with delete []
// This is taken from FSpGetFullPath in MoreFiles, except that we need to tolerate
// fnfErr.
//-----------------------------------
{
char* result = nil;
OSErr err = noErr;
short fullPathLength = 0;
Handle fullPath = nsnull;
FSSpec tempSpec = inSpec;
if ( tempSpec.parID == fsRtParID )
{
/* The object is a volume */
/* Add a colon to make it a full pathname */
tempSpec.name[++tempSpec.name[0]] = ':';
/* We're done */
err = PtrToHand(&tempSpec.name[1], &fullPath, tempSpec.name[0]);
}
else
{
/* The object isn't a volume */
CInfoPBRec pb = { 0 };
Str63 dummyFileName;
MacFileHelpers::PLstrcpy(dummyFileName, "\pG'day!");
/* Is the object a file or a directory? */
pb.dirInfo.ioNamePtr = (! tempSpec.name[0]) ? (StringPtr)dummyFileName : tempSpec.name;
pb.dirInfo.ioVRefNum = tempSpec.vRefNum;
pb.dirInfo.ioDrDirID = tempSpec.parID;
pb.dirInfo.ioFDirIndex = 0;
err = PBGetCatInfoSync(&pb);
if ( err == noErr || err == fnfErr)
{
// if the object is a directory, append a colon so full pathname ends with colon
// Beware of the "illegal spec" case that Netscape uses (empty name string). In
// this case, we don't want the colon.
if ( err == noErr && tempSpec.name[0] && (pb.hFileInfo.ioFlAttrib & ioDirMask) != 0 )
{
++tempSpec.name[0];
tempSpec.name[tempSpec.name[0]] = ':';
}
/* Put the object name in first */
err = PtrToHand(&tempSpec.name[1], &fullPath, tempSpec.name[0]);
if ( err == noErr )
{
/* Get the ancestor directory names */
pb.dirInfo.ioNamePtr = tempSpec.name;
pb.dirInfo.ioVRefNum = tempSpec.vRefNum;
pb.dirInfo.ioDrParID = tempSpec.parID;
do /* loop until we have an error or find the root directory */
{
pb.dirInfo.ioFDirIndex = -1;
pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID;
err = PBGetCatInfoSync(&pb);
if ( err == noErr )
{
/* Append colon to directory name */
++tempSpec.name[0];
tempSpec.name[tempSpec.name[0]] = ':';
/* Add directory name to beginning of fullPath */
(void) Munger(fullPath, 0, nsnull, 0, &tempSpec.name[1], tempSpec.name[0]);
err = MemError();
}
} while ( err == noErr && pb.dirInfo.ioDrDirID != fsRtDirID );
}
}
}
if ( err != noErr && err != fnfErr)
goto Clean;
fullPathLength = GetHandleSize(fullPath);
err = noErr;
int allocSize = 1 + fullPathLength;
// We only want the leaf name if it's the root directory or wantLeafName is true.
if (inSpec.parID != fsRtParID && !wantLeafName)
allocSize -= inSpec.name[0];
result = new char[allocSize];
if (!result)
goto Clean;
memcpy(result, *fullPath, allocSize - 1);
result[ allocSize - 1 ] = 0;
Clean:
if (fullPath)
DisposeHandle(fullPath);
NS_ASSERTION(result, "Out of memory"); // OOPS! very bad.
return result;
} // MacFileHelpers::PathNameFromFSSpec
//========================================================================================
// Macintosh nsFileSpec implementation
//========================================================================================
//----------------------------------------------------------------------------------------
nsFileSpec::nsFileSpec()
//----------------------------------------------------------------------------------------
: mError(NS_OK)
{
mSpec.name[0] = '\0';
}
//----------------------------------------------------------------------------------------
nsFileSpec::nsFileSpec(const nsFileSpec& inSpec)
//----------------------------------------------------------------------------------------
: mSpec(inSpec.mSpec)
, mError(inSpec.Error())
{
}
//----------------------------------------------------------------------------------------
nsFileSpec::nsFileSpec(const char* inString, PRBool inCreateDirs)
//----------------------------------------------------------------------------------------
{
mError = NS_FILE_RESULT(MacFileHelpers::FSSpecFromFullUnixPath(
inString, mSpec, false, true, inCreateDirs));
// allow a partial path, create as necessary
if (mError == NS_FILE_RESULT(fnfErr))
mError = NS_OK;
} // nsFileSpec::nsFileSpec
//----------------------------------------------------------------------------------------
nsFileSpec::nsFileSpec(
short vRefNum,
long parID,
ConstStr255Param name)
//----------------------------------------------------------------------------------------
{
mError = NS_FILE_RESULT(::FSMakeFSSpec(vRefNum, parID, name, &mSpec));
if (mError == NS_FILE_RESULT(fnfErr))
mError = noErr;
}
//----------------------------------------------------------------------------------------
nsFileSpec::nsFileSpec(const nsFilePath& inPath)
//----------------------------------------------------------------------------------------
{
*this = inPath.GetFileSpec();
}
#if DEBUG
//----------------------------------------------------------------------------------------
nsOutputStream& operator << (nsOutputStream& s, const nsFileSpec& spec)
//----------------------------------------------------------------------------------------
{
s << spec.mSpec.vRefNum << ", " << spec.mSpec.parID << ", \"";
s.write((const char*)&spec.mSpec.name[1], spec.mSpec.name[0]);
return s << "\"";
} // nsOutputStream& operator << (nsOutputStream&, const nsFileSpec&)
#endif
//----------------------------------------------------------------------------------------
void nsFileSpec::operator = (const char* inString)
//----------------------------------------------------------------------------------------
{
mError = NS_FILE_RESULT(MacFileHelpers::FSSpecFromFullUnixPath(inString, mSpec, false));
} // nsFileSpec::operator =
//----------------------------------------------------------------------------------------
void nsFileSpec::operator = (const nsFileSpec& inSpec)
//----------------------------------------------------------------------------------------
{
mSpec = inSpec.mSpec;
mError = inSpec.Error();
} // nsFileSpec::operator =
//----------------------------------------------------------------------------------------
void nsFileSpec::operator = (const nsFilePath& inPath)
//----------------------------------------------------------------------------------------
{
*this = inPath.GetFileSpec();
} // nsFileSpec::operator =
//----------------------------------------------------------------------------------------
PRBool nsFileSpec::Exists() const
//----------------------------------------------------------------------------------------
{
FSSpec temp;
return ::FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, mSpec.name, &temp) == noErr;
} // nsFileSpec::operator =
//----------------------------------------------------------------------------------------
void nsFileSpec::SetLeafName(const char* inLeafName)
// In leaf name can actually be a partial path...
//----------------------------------------------------------------------------------------
{
// what about long relative paths? Hmm?
Str255 partialPath;
MacFileHelpers::PLstrcpy(partialPath, inLeafName);
mError = NS_FILE_RESULT(
::FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, partialPath, &mSpec));
} // nsFileSpec::SetLeafName
//----------------------------------------------------------------------------------------
char* nsFileSpec::GetLeafName() const
// Result needs to be delete[]ed.
//----------------------------------------------------------------------------------------
{
char leaf[64];
memcpy(leaf, &mSpec.name[1], mSpec.name[0]);
leaf[mSpec.name[0]] = '\0';
return nsFileSpecHelpers::StringDup(leaf);
} // nsFileSpec::GetLeafName
//----------------------------------------------------------------------------------------
void nsFileSpec::MakeAliasSafe()
//----------------------------------------------------------------------------------------
{
mError = NS_FILE_RESULT(MacFileHelpers::MakeAliasSafe(mSpec));
} // nsFileSpec::MakeAliasSafe
//----------------------------------------------------------------------------------------
void nsFileSpec::MakeUnique(ConstStr255Param inSuggestedLeafName)
//----------------------------------------------------------------------------------------
{
if (inSuggestedLeafName[0] > 0)
MacFileHelpers::PLstrcpy(mSpec.name, inSuggestedLeafName);
MakeUnique();
} // nsFileSpec::MakeUnique
//----------------------------------------------------------------------------------------
void nsFileSpec::ResolveAlias(PRBool& wasAliased)
//----------------------------------------------------------------------------------------
{
Boolean wasAliased2;
mError = NS_FILE_RESULT(MacFileHelpers::ResolveAliasFile(mSpec, wasAliased2));
wasAliased = (wasAliased2 != false);
} // nsFileSpec::ResolveAlias
//----------------------------------------------------------------------------------------
PRBool nsFileSpec::IsFile() const
//----------------------------------------------------------------------------------------
{
long dirID;
Boolean isDirectory;
return (noErr == FSpGetDirectoryID(&mSpec, &dirID, &isDirectory) && !isDirectory);
} // nsFileSpec::IsFile
//----------------------------------------------------------------------------------------
PRBool nsFileSpec::IsDirectory() const
//----------------------------------------------------------------------------------------
{
long dirID;
Boolean isDirectory;
return (noErr == FSpGetDirectoryID(&mSpec, &dirID, &isDirectory) && isDirectory);
} // nsFileSpec::IsDirectory
//----------------------------------------------------------------------------------------
void nsFileSpec::GetParent(nsFileSpec& outSpec) const
//----------------------------------------------------------------------------------------
{
if (NS_SUCCEEDED(mError))
outSpec.mError
= NS_FILE_RESULT(::FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, nsnull, outSpec));
} // nsFileSpec::GetParent
//----------------------------------------------------------------------------------------
void nsFileSpec::operator += (const char* inRelativePath)
//----------------------------------------------------------------------------------------
{
long dirID;
Boolean isDirectory;
mError = NS_FILE_RESULT(::FSpGetDirectoryID(&mSpec, &dirID, &isDirectory));
if (NS_SUCCEEDED(mError) && isDirectory)
{
Str255 partialPath;
MacFileHelpers::PLstrcpy(partialPath, inRelativePath);
mError = NS_FILE_RESULT(::FSMakeFSSpec(mSpec.vRefNum, dirID, partialPath, *this));
//if (NS_SUCCEEDED(mError))
// SetLeafName(inRelativePath);
}
} // nsFileSpec::operator +=
//----------------------------------------------------------------------------------------
void nsFileSpec::CreateDirectory(int /* unix mode */)
//----------------------------------------------------------------------------------------
{
long ignoredDirID;
FSpDirCreate(&mSpec, smCurrentScript, &ignoredDirID);
} // nsFileSpec::CreateDirectory
//----------------------------------------------------------------------------------------
void nsFileSpec::Delete(PRBool inRecursive)
//----------------------------------------------------------------------------------------
{
if (inRecursive)
{
// MoreFilesExtras
mError = NS_FILE_RESULT(::DeleteDirectory(
mSpec.vRefNum,
mSpec.parID,
const_cast<unsigned char*>(mSpec.name)));
}
else
mError = NS_FILE_RESULT(FSpDelete(&mSpec));
} // nsFileSpec::Delete
//----------------------------------------------------------------------------------------
nsresult nsFileSpec::Rename(const char* inNewName)
//----------------------------------------------------------------------------------------
{
if (strchr(inNewName, '/'))
return -1; // no relative paths here!
Str255 pName;
MacFileHelpers::PLstrcpy(pName, inNewName);
if (FSpRename(&mSpec, pName) != noErr)
return -1;
SetLeafName(inNewName);
return 0;
} // nsFileSpec::Rename
//----------------------------------------------------------------------------------------
nsresult nsFileSpec::Copy(const nsFileSpec& newParentDir) const
//----------------------------------------------------------------------------------------
{
// We can only copy into a directory, and (for now) can not copy entire directories
if (!newParentDir.IsDirectory() || (IsDirectory() ) )
return NS_FILE_FAILURE;
nsresult result = NS_FILE_RESULT(::FSpFileCopy( &mSpec,
&newParentDir.mSpec,
const_cast<StringPtr>(GetLeafPName()),
nsnull,
0,
true));
return result;
} // nsFileSpec::Copy
//----------------------------------------------------------------------------------------
nsresult nsFileSpec::Move(const nsFileSpec& newParentDir) const
//----------------------------------------------------------------------------------------
{
// We can only move into a directory
if (!newParentDir.IsDirectory())
return NS_FILE_FAILURE;
nsresult result = NS_FILE_RESULT(::FSpMoveRenameCompat(&mSpec,
&newParentDir.mSpec,
const_cast<StringPtr>(GetLeafPName())));
return result;
} // nsFileSpec::Move
//----------------------------------------------------------------------------------------
nsresult nsFileSpec::Execute(const char* /*args - how can this be cross-platform? problem! */ ) const
//----------------------------------------------------------------------------------------
{
if (IsDirectory())
return NS_FILE_FAILURE;
LaunchParamBlockRec launchThis;
launchThis.launchAppSpec = const_cast<FSSpec*>(&mSpec);
launchThis.launchAppParameters = nsnull; // args;
/* launch the thing */
launchThis.launchBlockID = extendedBlock;
launchThis.launchEPBLength = extendedBlockLen;
launchThis.launchFileFlags = nsnull;
launchThis.launchControlFlags = launchContinue + launchNoFileFlags + launchUseMinimum;
launchThis.launchControlFlags += launchDontSwitch;
nsresult result = NS_FILE_RESULT(::LaunchApplication(&launchThis));
return result;
} // nsFileSpec::Execute
//========================================================================================
// Macintosh nsFilePath implementation
//========================================================================================
//----------------------------------------------------------------------------------------
nsFilePath::nsFilePath(const char* inString, PRBool inCreateDirs)
//----------------------------------------------------------------------------------------
: mPath(nsnull)
, mFileSpec(inString, inCreateDirs)
{
// Make canonical and absolute.
char * path = MacFileHelpers::PathNameFromFSSpec( mFileSpec, TRUE );
mPath = MacFileHelpers::EncodeMacPath(path, true, true);
}
//----------------------------------------------------------------------------------------
nsFilePath::nsFilePath(const nsFileSpec& inSpec)
//----------------------------------------------------------------------------------------
: mFileSpec(inSpec)
{
char * path = MacFileHelpers::PathNameFromFSSpec( inSpec.mSpec, TRUE );
mPath = MacFileHelpers::EncodeMacPath(path, true, true);
}
//----------------------------------------------------------------------------------------
void nsFilePath::operator = (const nsFileSpec& inSpec)
//----------------------------------------------------------------------------------------
{
delete [] mPath;
char * path = MacFileHelpers::PathNameFromFSSpec( inSpec.mSpec, TRUE );
mPath = MacFileHelpers::EncodeMacPath(path, true, true);
mFileSpec = inSpec;
} // nsFilePath::operator =
//========================================================================================
// nsFileURL implementation
//========================================================================================
//----------------------------------------------------------------------------------------
nsFileURL::nsFileURL(const char* inString, PRBool inCreateDirs)
//----------------------------------------------------------------------------------------
: mURL(nsnull)
, mFileSpec(inString + kFileURLPrefixLength, inCreateDirs)
{
NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!");
// Make canonical and absolute.
char* path = MacFileHelpers::PathNameFromFSSpec( mFileSpec, TRUE );
char* escapedPath = MacFileHelpers::EncodeMacPath(path, true, true);
mURL = nsFileSpecHelpers::StringDup(kFileURLPrefix, kFileURLPrefixLength + strlen(escapedPath));
strcat(mURL, escapedPath);
delete [] escapedPath;
} // nsFileURL::nsFileURL
//========================================================================================
// nsDirectoryIterator
//========================================================================================
//----------------------------------------------------------------------------------------
nsDirectoryIterator::nsDirectoryIterator(
const nsFileSpec& inDirectory
, int inIterateDirection)
//----------------------------------------------------------------------------------------
: mCurrent(inDirectory)
, mExists(false)
, mIndex(-1)
{
CInfoPBRec pb;
DirInfo* dipb = (DirInfo*)&pb;
// Sorry about this, there seems to be a bug in CWPro 4:
const FSSpec& inSpec = inDirectory.nsFileSpec::operator const FSSpec&();
Str255 outName;
MacFileHelpers::PLstrcpy(outName, inSpec.name);
pb.hFileInfo.ioNamePtr = outName;
pb.hFileInfo.ioVRefNum = inSpec.vRefNum;
pb.hFileInfo.ioDirID = inSpec.parID;
pb.hFileInfo.ioFDirIndex = 0; // use ioNamePtr and ioDirID
OSErr err = PBGetCatInfoSync( &pb );
// test that we have got a directory back, not a file
if ( (err != noErr ) || !( dipb->ioFlAttrib & 0x0010 ) )
return;
// Sorry about this, there seems to be a bug in CWPro 4:
FSSpec& currentSpec = mCurrent.nsFileSpec::operator FSSpec&();
currentSpec.vRefNum = inSpec.vRefNum;
currentSpec.parID = dipb->ioDrDirID;
mMaxIndex = pb.dirInfo.ioDrNmFls;
if (inIterateDirection > 0)
{
mIndex = 0; // ready to increment
++(*this); // the pre-increment operator
}
else
{
mIndex = mMaxIndex + 1; // ready to decrement
--(*this); // the pre-decrement operator
}
} // nsDirectoryIterator::nsDirectoryIterator
//----------------------------------------------------------------------------------------
OSErr nsDirectoryIterator::SetToIndex()
//----------------------------------------------------------------------------------------
{
CInfoPBRec cipb;
DirInfo *dipb=(DirInfo *)&cipb;
Str255 objectName;
dipb->ioCompletion = nsnull;
dipb->ioFDirIndex = mIndex;
// Sorry about this, there seems to be a bug in CWPro 4:
FSSpec& currentSpec = mCurrent.nsFileSpec::operator FSSpec&();
dipb->ioVRefNum = currentSpec.vRefNum; /* Might need to use vRefNum, not sure*/
dipb->ioDrDirID = currentSpec.parID;
dipb->ioNamePtr = objectName;
OSErr err = PBGetCatInfoSync(&cipb);
if (err == noErr)
err = FSMakeFSSpec(currentSpec.vRefNum, currentSpec.parID, objectName, &currentSpec);
mExists = err == noErr;
return err;
} // nsDirectoryIterator::SetToIndex()
//----------------------------------------------------------------------------------------
nsDirectoryIterator& nsDirectoryIterator::operator -- ()
//----------------------------------------------------------------------------------------
{
mExists = false;
while (--mIndex > 0)
{
OSErr err = SetToIndex();
if (err == noErr)
break;
}
return *this;
} // nsDirectoryIterator::operator --
//----------------------------------------------------------------------------------------
nsDirectoryIterator& nsDirectoryIterator::operator ++ ()
//----------------------------------------------------------------------------------------
{
mExists = false;
if (mIndex >= 0) // probably trying to use a file as a directory!
while (++mIndex <= mMaxIndex)
{
OSErr err = SetToIndex();
if (err == noErr)
break;
}
return *this;
} // nsDirectoryIterator::operator ++

View File

@@ -0,0 +1,147 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsRepeater.h"
Repeater* Repeater::sRepeaters = 0;
Repeater* Repeater::sIdlers = 0;
Repeater::Repeater()
{
mRepeating = false;
mIdling = false;
mPrevRptr = 0;
mNextRptr = 0;
mPrevIdlr = 0;
mNextIdlr = 0;
}
Repeater::~Repeater()
{
if (mRepeating) RemoveFromRepeatList();
if (mIdling) RemoveFromIdleList();
}
// protected helper functs
//----------------------------------------------------------------------------
void Repeater::AddToRepeatList()
{
if (sRepeaters)
{
sRepeaters->mPrevRptr = this;
mNextRptr = sRepeaters;
}
sRepeaters = this;
}
//----------------------------------------------------------------------------
void Repeater::RemoveFromRepeatList()
{
if (sRepeaters == this) sRepeaters = mNextRptr;
if (mPrevRptr) mPrevRptr->mNextRptr = mNextRptr;
if (mNextRptr) mNextRptr->mPrevRptr = mPrevRptr;
mPrevRptr = 0;
mNextRptr = 0;
}
//----------------------------------------------------------------------------
void Repeater::AddToIdleList()
{
if (sIdlers)
{
sIdlers->mPrevIdlr = this;
mNextIdlr = sIdlers;
}
sIdlers = this;
}
//----------------------------------------------------------------------------
void Repeater::RemoveFromIdleList()
{
if (sIdlers == this) sIdlers = mNextIdlr;
if (mPrevIdlr) mPrevIdlr->mNextIdlr = mNextIdlr;
if (mNextIdlr) mNextIdlr->mPrevIdlr = mPrevIdlr;
mPrevIdlr = 0;
mNextIdlr = 0;
}
// repeater methods
//----------------------------------------------------------------------------
void Repeater::StartRepeating()
{
if (!mRepeating)
{
AddToRepeatList();
mRepeating = true;
}
}
void Repeater::StopRepeating()
{
if (mRepeating)
{
RemoveFromRepeatList();
mRepeating = false;
}
}
void Repeater::DoRepeaters(const EventRecord &aMacEvent)
{
Repeater* theRepeater = sRepeaters;
while (theRepeater)
{
theRepeater->RepeatAction(aMacEvent);
theRepeater = theRepeater->mNextRptr;
}
}
// idler methods
void Repeater::StartIdling()
{
if (!mIdling)
{
AddToIdleList();
mIdling = true;
}
}
void Repeater::StopIdling()
{
if (mIdling)
{
RemoveFromIdleList();
mIdling = false;
}
}
void Repeater::DoIdlers(const EventRecord &aMacEvent)
{
Repeater* theIdler = sIdlers;
while (theIdler)
{
theIdler->RepeatAction(aMacEvent);
theIdler = theIdler->mNextIdlr;
}
}

View File

@@ -0,0 +1,365 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
//
// Mac implementation of the nsITimer interface
//
#include "nsITimer.h"
#include "nsITimerCallback.h"
#include "prlog.h"
#include "nsRepeater.h"
#include <list.h>
#include <Events.h>
#pragma mark class TimerImpl
//========================================================================================
class TimerImpl : public nsITimer
// TimerImpl implements nsITimer API
//========================================================================================
{
friend class TimerPeriodical;
private:
nsTimerCallbackFunc mCallbackFunc;
nsITimerCallback * mCallbackObject;
void * mClosure;
PRUint32 mDelay;
PRUint32 mFireTime; // Timer should fire when TickCount >= this number
TimerImpl * mPrev;
TimerImpl * mNext;
public:
// constructors
TimerImpl();
virtual ~TimerImpl();
NS_DECL_ISUPPORTS
PRUint32 GetFireTime() const { return mFireTime; }
void Fire();
// nsITimer overrides
virtual nsresult Init(nsTimerCallbackFunc aFunc,
void *aClosure,
PRUint32 aDelay);
virtual nsresult Init(nsITimerCallback *aCallback,
PRUint32 aDelay);
virtual void Cancel();
virtual PRUint32 GetDelay();
virtual void SetDelay(PRUint32 aDelay);
virtual void* GetClosure();
#if DEBUG
enum {
eGoodTimerSignature = 'Barf',
eDeletedTimerSignature = 'oops'
};
Boolean IsGoodTimer() const { return (mSignature == eGoodTimerSignature); }
#endif
private:
// Calculates mFireTime too
void SetDelaySelf( PRUint32 aDelay );
#if DEBUG
UInt32 mSignature;
#endif
};
#pragma mark class TimerPeriodical
//========================================================================================
class TimerPeriodical : public Repeater
// TimerPeriodical is a singleton Repeater subclass that fires
// off TimerImpl. The firing is done on idle.
//========================================================================================
{
static TimerPeriodical * gPeriodical;
TimerImpl* mTimers;
public:
// Returns the singleton instance
static TimerPeriodical * GetPeriodical();
TimerPeriodical();
virtual ~TimerPeriodical();
virtual void RepeatAction( const EventRecord &inMacEvent);
nsresult AddTimer( TimerImpl * aTimer);
nsresult RemoveTimer( TimerImpl * aTimer);
};
//========================================================================================
// TimerImpl implementation
//========================================================================================
static NS_DEFINE_IID(kITimerIID, NS_ITIMER_IID);
NS_IMPL_ISUPPORTS(TimerImpl, kITimerIID)
//----------------------------------------------------------------------------------------
TimerImpl::TimerImpl()
//----------------------------------------------------------------------------------------
: mCallbackFunc(nsnull)
, mCallbackObject(nsnull)
, mClosure(nsnull)
, mDelay(0)
, mFireTime(0)
, mPrev(nsnull)
, mNext(nsnull)
#if DEBUG
, mSignature(eGoodTimerSignature)
#endif
{
NS_INIT_REFCNT();
}
//----------------------------------------------------------------------------------------
TimerImpl::~TimerImpl()
//----------------------------------------------------------------------------------------
{
Cancel();
NS_IF_RELEASE(mCallbackObject);
#if DEBUG
mSignature = eDeletedTimerSignature;
#endif
}
//----------------------------------------------------------------------------------------
nsresult TimerImpl::Init(nsTimerCallbackFunc aFunc,
void *aClosure,
PRUint32 aDelay)
//----------------------------------------------------------------------------------------
{
mCallbackFunc = aFunc;
mClosure = aClosure;
SetDelaySelf(aDelay);
return TimerPeriodical::GetPeriodical()->AddTimer(this);
}
//----------------------------------------------------------------------------------------
nsresult TimerImpl::Init(nsITimerCallback *aCallback,
PRUint32 aDelay)
//----------------------------------------------------------------------------------------
{
NS_ADDREF(aCallback);
mCallbackObject = aCallback;
SetDelaySelf(aDelay);
return TimerPeriodical::GetPeriodical()->AddTimer(this);
}
//----------------------------------------------------------------------------------------
void TimerImpl::Cancel()
//----------------------------------------------------------------------------------------
{
TimerPeriodical::GetPeriodical()->RemoveTimer(this);
}
//----------------------------------------------------------------------------------------
PRUint32 TimerImpl::GetDelay()
//----------------------------------------------------------------------------------------
{
return mDelay;
}
//----------------------------------------------------------------------------------------
void TimerImpl::SetDelay(PRUint32 aDelay)
//----------------------------------------------------------------------------------------
{
SetDelaySelf(aDelay);
}
//----------------------------------------------------------------------------------------
void* TimerImpl::GetClosure()
//----------------------------------------------------------------------------------------
{
return mClosure;
}
//----------------------------------------------------------------------------------------
void TimerImpl::Fire()
//----------------------------------------------------------------------------------------
{
NS_PRECONDITION(mRefCnt > 0, "Firing a disposed Timer!");
if (mCallbackFunc != NULL)
{
(*mCallbackFunc)(this, mClosure);
}
else if (mCallbackObject != NULL)
{
nsITimerCallback* object = mCallbackObject;
mCallbackObject = nsnull;
// because the Notify call will release it.
// We will release again it in the destructor if
// it is not null when we go away!
object->Notify(this); // Fire the timer
}
}
//----------------------------------------------------------------------------------------
void TimerImpl::SetDelaySelf( PRUint32 aDelay )
//----------------------------------------------------------------------------------------
{
mDelay = aDelay;
mFireTime = TickCount() + (mDelay * 3) / 50; // We need mFireTime in ticks (1/60th)
// but aDelay is in 1000th (60/1000 = 3/50)
}
TimerPeriodical * TimerPeriodical::gPeriodical = nsnull;
TimerPeriodical * TimerPeriodical::GetPeriodical()
{
if (gPeriodical == NULL)
gPeriodical = new TimerPeriodical();
return gPeriodical;
}
TimerPeriodical::TimerPeriodical()
{
mTimers = nsnull;
}
TimerPeriodical::~TimerPeriodical()
{
PR_ASSERT(mTimers == 0);
}
nsresult TimerPeriodical::AddTimer( TimerImpl * aTimer)
{
// make sure it's not already there
RemoveTimer(aTimer);
// keep list sorted by fire time
if (mTimers)
{
if (aTimer->GetFireTime() < mTimers->GetFireTime())
{
mTimers->mPrev = aTimer;
aTimer->mNext = mTimers;
mTimers = aTimer;
}
else
{
TimerImpl *t = mTimers;
TimerImpl *prevt;
// we know we will enter the while loop at least the first
// time, and thus prevt will be initialized
while (t && (t->GetFireTime() <= aTimer->GetFireTime()))
{
prevt = t;
t = t->mNext;
}
aTimer->mPrev = prevt;
aTimer->mNext = prevt->mNext;
prevt->mNext = aTimer;
if (aTimer->mNext) aTimer->mNext->mPrev = aTimer;
}
}
else mTimers = aTimer;
StartRepeating();
return NS_OK;
}
nsresult TimerPeriodical::RemoveTimer( TimerImpl * aTimer)
{
TimerImpl* t = mTimers;
TimerImpl* next_t = nsnull;
if (t) next_t = t->mNext;
while (t)
{
if (t == aTimer)
{
if (mTimers == t) mTimers = t->mNext;
if (t->mPrev) t->mPrev->mNext = t->mNext;
if (t->mNext) t->mNext->mPrev = t->mPrev;
t->mNext = nsnull;
t->mPrev = nsnull;
}
t = next_t;
if (t) next_t = t->mNext;
}
if ( mTimers == nsnull )
StopRepeating();
return NS_OK;
}
// Called through every event loop
// Loops through the list of available timers, and
// fires off the appropriate ones
void TimerPeriodical::RepeatAction( const EventRecord &inMacEvent)
{
PRBool done = false;
while (!done)
{
TimerImpl* t = mTimers;
while (t)
{
NS_ASSERTION(t->IsGoodTimer(), "Bad timer!");
if (t->GetFireTime() <= inMacEvent.when)
{
RemoveTimer(t);
t->Fire();
break;
}
t = t->mNext;
}
done = true;
}
}
NS_BASE nsresult NS_NewTimer(nsITimer** aInstancePtrResult)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
TimerImpl *timer = new TimerImpl();
if (nsnull == timer) {
return NS_ERROR_OUT_OF_MEMORY;
}
return timer->QueryInterface(kITimerIID, (void **) aInstancePtrResult);
}

View File

@@ -0,0 +1,112 @@
#!nmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=..\..
IGNORE_MANIFEST=1
DIRS = windows
DEFINES=-D_IMPL_NS_BASE -DWIN32_LEAN_AND_MEAN
LIBRARY_NAME=raptorbase
CPPSRCS = \
nsArena.cpp \
nsAtomTable.cpp \
nsBaseDLL.cpp \
nsBTree.cpp \
nsByteBuffer.cpp \
nsCRT.cpp \
nsDeque.cpp \
nsProperties.cpp \
nsRBTree.cpp \
nsSizeOfHandler.cpp \
nsString.cpp \
nsUnicharBuffer.cpp \
nsUnicharInputStream.cpp \
nsVoidArray.cpp \
nsFileSpec.cpp \
nsFileStream.cpp \
nsEscape.cpp \
nsIFileStream.cpp \
$(NULL)
CPP_OBJS = \
.\$(OBJDIR)\nsArena.obj \
.\$(OBJDIR)\nsAtomTable.obj \
.\$(OBJDIR)\nsBaseDLL.obj \
.\$(OBJDIR)\nsBTree.obj \
.\$(OBJDIR)\nsByteBuffer.obj \
.\$(OBJDIR)\nsCRT.obj \
.\$(OBJDIR)\nsDeque.obj \
.\$(OBJDIR)\nsProperties.obj \
.\$(OBJDIR)\nsRBTree.obj \
.\$(OBJDIR)\nsSizeOfHandler.obj \
.\$(OBJDIR)\nsString.obj \
.\$(OBJDIR)\nsUnicharBuffer.obj \
.\$(OBJDIR)\nsUnicharInputStream.obj \
.\$(OBJDIR)\nsVoidArray.obj \
.\$(OBJDIR)\nsFileSpec.obj \
.\$(OBJDIR)\nsFileStream.obj \
.\$(OBJDIR)\nsEscape.obj \
.\$(OBJDIR)\nsIFileStream.obj \
$(NULL)
EXPORTS=nscore.h nsIArena.h nsIAtom.h nsIByteBuffer.h \
nsBTree.h nsCRT.h nsDeque.h nsITimer.h \
nsITimerCallback.h nsIUnicharBuffer.h nsRBTree.h \
nsIUnicharInputStream.h nsString.h nsVoidArray.h \
nsUnitConversion.h \
nsIBaseStream.h nsIInputStream.h nsIOutputStream.h \
nsInt64.h nsTime.h
MODULE=raptor
REQUIRES=xpcom netlib raptor uconv
LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\netlib \
-I$(PUBLIC)\raptor -I$(PUBLIC)\uconv -I$(PUBLIC)\unicharutil
MAKE_OBJ_TYPE = DLL
DLLNAME = raptorbase
DLL=.\$(OBJDIR)\$(DLLNAME).dll
OBJS = $(OBJS) .\$(OBJDIR)\nsTimer.obj
LCFLAGS = \
$(LCFLAGS) \
$(DEFINES) \
$(NULL)
# These are the libraries we need to link with to create the dll
LLIBS= \
$(DIST)\lib\xpcom32.lib \
$(DIST)\lib\libplc21.lib \
$(LIBNSPR)
!if "$(MOZ_BITS)"=="32" && defined(MOZ_DEBUG) && defined(GLOWCODE)
LLIBS=$(LLIBS) $(GLOWDIR)\glowcode.lib
!endif
include <$(DEPTH)\config\rules.mak>
libs:: $(DLL)
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).dll $(DIST)\bin
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).lib $(DIST)\lib
clobber::
rm -f $(DIST)\bin\$(DLLNAME).dll
rm -f $(DIST)\lib\$(DLLNAME).lib

View File

@@ -0,0 +1,36 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
LIBRARY_NAME = gmbasemotif
MODULE=base
REQUIRES = xpcom raptor
DEFINES += -D_IMPL_NS_WIDGET
CPPSRCS = nsTimer.cpp
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,39 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nscore.h"
#include "nsCaretProperties.h"
//-----------------------------------------------------------------------------
nsCaretProperties::nsCaretProperties()
: mCaretWidth(eDefaultCaretWidth)
, mBlinkRate(eDefaulBlinkRate)
{
// in your platform-specific class, get data from the OS in your constructor
}
//-----------------------------------------------------------------------------
nsCaretProperties* NewCaretProperties()
{
return new nsCaretProperties();
}

View File

@@ -0,0 +1,173 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsITimer.h"
#include "nsITimerCallback.h"
#include "nsCRT.h"
#include "prlog.h"
#include <stdio.h>
#include <limits.h>
#include <X11/Intrinsic.h>
static NS_DEFINE_IID(kITimerIID, NS_ITIMER_IID);
// Hack for now. This is Bad because it creates a dependency between the widget
// library and this library. This needs to be replaced with having code
// to pass an interface which can be queried for the app context.
extern XtAppContext gAppContext;
extern void nsTimerExpired(XtPointer aCallData);
/*
* Implementation of timers using Xt timer facility
*/
class TimerImpl : public nsITimer {
public:
public:
TimerImpl();
virtual ~TimerImpl();
virtual nsresult Init(nsTimerCallbackFunc aFunc,
void *aClosure,
// PRBool aRepeat,
PRUint32 aDelay);
virtual nsresult Init(nsITimerCallback *aCallback,
// PRBool aRepeat,
PRUint32 aDelay);
NS_DECL_ISUPPORTS
virtual void Cancel();
virtual PRUint32 GetDelay() { return mDelay; }
virtual void SetDelay(PRUint32 aDelay) { mDelay=aDelay; };
virtual void* GetClosure() { return mClosure; }
void FireTimeout();
private:
nsresult Init(PRUint32 aDelay);
PRUint32 mDelay;
nsTimerCallbackFunc mFunc;
void *mClosure;
nsITimerCallback *mCallback;
// PRBool mRepeat;
TimerImpl *mNext;
XtIntervalId mTimerId;
};
void TimerImpl::FireTimeout()
{
if (mFunc != NULL) {
(*mFunc)(this, mClosure);
}
else if (mCallback != NULL) {
mCallback->Notify(this); // Fire the timer
}
// Always repeating here
// if (mRepeat)
// mTimerId = XtAppAddTimeOut(gAppContext, GetDelay(),(XtTimerCallbackProc)nsTimerExpired, this);
}
TimerImpl::TimerImpl()
{
NS_INIT_REFCNT();
mFunc = NULL;
mCallback = NULL;
mNext = NULL;
mTimerId = 0;
mDelay = 0;
mClosure = NULL;
}
TimerImpl::~TimerImpl()
{
}
nsresult
TimerImpl::Init(nsTimerCallbackFunc aFunc,
void *aClosure,
// PRBool aRepeat,
PRUint32 aDelay)
{
mFunc = aFunc;
mClosure = aClosure;
// mRepeat = aRepeat;
mTimerId = XtAppAddTimeOut(gAppContext, aDelay,(XtTimerCallbackProc)nsTimerExpired, this);
return Init(aDelay);
}
nsresult
TimerImpl::Init(nsITimerCallback *aCallback,
// PRBool aRepeat,
PRUint32 aDelay)
{
mCallback = aCallback;
// mRepeat = aRepeat;
mTimerId = XtAppAddTimeOut(gAppContext, aDelay, (XtTimerCallbackProc)nsTimerExpired, this);
return Init(aDelay);
}
nsresult
TimerImpl::Init(PRUint32 aDelay)
{
mDelay = aDelay;
NS_ADDREF(this);
return NS_OK;
}
NS_IMPL_ISUPPORTS(TimerImpl, kITimerIID)
void
TimerImpl::Cancel()
{
XtRemoveTimeOut(mTimerId);
}
NS_BASE nsresult NS_NewTimer(nsITimer** aInstancePtrResult)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
TimerImpl *timer = new TimerImpl();
if (nsnull == timer) {
return NS_ERROR_OUT_OF_MEMORY;
}
return timer->QueryInterface(kITimerIID, (void **) aInstancePtrResult);
}
void nsTimerExpired(XtPointer aCallData)
{
TimerImpl* timer = (TimerImpl *)aCallData;
timer->FireTimeout();
}

View File

@@ -0,0 +1,80 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsIArena.h"
#include "nsCRT.h"
#define PL_ARENA_CONST_ALIGN_MASK 7
#include "plarena.h"
static NS_DEFINE_IID(kArenaIID, NS_IARENA_IID);
// Simple arena implementation layered on plarena
class ArenaImpl : public nsIArena {
public:
ArenaImpl(PRInt32 aBlockSize);
NS_DECL_ISUPPORTS
virtual void* Alloc(PRInt32 aSize);
protected:
~ArenaImpl();
PLArenaPool mPool;
PRInt32 mBlockSize;
};
ArenaImpl::ArenaImpl(PRInt32 aBlockSize)
{
NS_INIT_REFCNT();
if (aBlockSize < NS_MIN_ARENA_BLOCK_SIZE) {
aBlockSize = NS_DEFAULT_ARENA_BLOCK_SIZE;
}
PL_INIT_ARENA_POOL(&mPool, "nsIArena", aBlockSize);
mBlockSize = aBlockSize;
}
NS_IMPL_ISUPPORTS(ArenaImpl,kArenaIID)
ArenaImpl::~ArenaImpl()
{
PL_FinishArenaPool(&mPool);
}
void* ArenaImpl::Alloc(PRInt32 size)
{
// Adjust size so that it's a multiple of sizeof(double)
PRInt32 align = size & (sizeof(double) - 1);
if (0 != align) {
size += sizeof(double) - align;
}
void* p;
PL_ARENA_ALLOCATE(p, &mPool, size);
return p;
}
NS_BASE nsresult NS_NewHeapArena(nsIArena** aInstancePtrResult,
PRInt32 aArenaBlockSize)
{
ArenaImpl* it = new ArenaImpl(aArenaBlockSize);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kArenaIID, (void **) aInstancePtrResult);
}

View File

@@ -0,0 +1,154 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsIAtom.h"
#include "nsString.h"
#include "nsCRT.h"
#include "plhash.h"
#include "nsISizeOfHandler.h"
/**
* The shared hash table for atom lookups.
*/
static nsrefcnt gAtoms;
static struct PLHashTable* gAtomHashTable;
class AtomImpl : public nsIAtom {
public:
AtomImpl();
~AtomImpl();
NS_DECL_ISUPPORTS
void* operator new(size_t size, const PRUnichar* us, PRInt32 uslen);
virtual void ToString(nsString& aBuf) const;
virtual const PRUnichar* GetUnicode() const;
NS_IMETHOD SizeOf(nsISizeOfHandler* aHandler) const;
// Actually more; 0 terminated. This slot is reserved for the
// terminating zero.
PRUnichar mString[1];
};
AtomImpl::AtomImpl()
{
NS_INIT_REFCNT();
// Every live atom holds a reference on the atom hashtable
gAtoms++;
}
AtomImpl::~AtomImpl()
{
NS_PRECONDITION(nsnull != gAtomHashTable, "null atom hashtable");
if (nsnull != gAtomHashTable) {
PL_HashTableRemove(gAtomHashTable, mString);
nsrefcnt cnt = --gAtoms;
if (0 == cnt) {
// When the last atom is destroyed, the atom arena is destroyed
NS_ASSERTION(0 == gAtomHashTable->nentries, "bad atom table");
PL_HashTableDestroy(gAtomHashTable);
gAtomHashTable = nsnull;
}
}
}
static NS_DEFINE_IID(kIAtomIID, NS_IATOM_IID);
NS_IMPL_ISUPPORTS(AtomImpl, kIAtomIID);
void* AtomImpl::operator new(size_t size, const PRUnichar* us, PRInt32 uslen)
{
size = size + uslen * sizeof(PRUnichar);
AtomImpl* ii = (AtomImpl*) new char[size];
nsCRT::memcpy(ii->mString, us, uslen * sizeof(PRUnichar));
ii->mString[uslen] = 0;
return ii;
}
void AtomImpl::ToString(nsString& aBuf) const
{
aBuf.SetLength(0);
aBuf.Append(mString, nsCRT::strlen(mString));
}
const PRUnichar* AtomImpl::GetUnicode() const
{
return mString;
}
NS_IMETHODIMP
AtomImpl::SizeOf(nsISizeOfHandler* aHandler) const
{
aHandler->Add(sizeof(*this) + nsCRT::strlen(mString) * sizeof(PRUnichar));
return NS_OK;
}
//----------------------------------------------------------------------
static PLHashNumber HashKey(const PRUnichar* k)
{
return (PLHashNumber) nsCRT::HashValue(k);
}
static PRIntn CompareKeys(const PRUnichar* k1, const PRUnichar* k2)
{
return nsCRT::strcmp(k1, k2) == 0;
}
NS_BASE nsIAtom* NS_NewAtom(const char* isolatin1)
{
nsAutoString tmp(isolatin1);
return NS_NewAtom(tmp.GetUnicode());
}
NS_BASE nsIAtom* NS_NewAtom(const nsString& aString)
{
return NS_NewAtom(aString.GetUnicode());
}
NS_BASE nsIAtom* NS_NewAtom(const PRUnichar* us)
{
if (nsnull == gAtomHashTable) {
gAtomHashTable = PL_NewHashTable(8, (PLHashFunction) HashKey,
(PLHashComparator) CompareKeys,
(PLHashComparator) nsnull,
nsnull, nsnull);
}
PRUint32 uslen;
PRUint32 hashCode = nsCRT::HashValue(us, &uslen);
PLHashEntry** hep = PL_HashTableRawLookup(gAtomHashTable, hashCode, us);
PLHashEntry* he = *hep;
if (nsnull != he) {
nsIAtom* id = (nsIAtom*) he->value;
NS_ADDREF(id);
return id;
}
AtomImpl* id = new(us, uslen) AtomImpl();
PL_HashTableRawAdd(gAtomHashTable, hep, hashCode, id->mString, id);
NS_ADDREF(id);
return id;
}
NS_BASE nsrefcnt NS_GetNumberOfAtoms(void)
{
if (nsnull != gAtomHashTable) {
NS_PRECONDITION(nsrefcnt(gAtomHashTable->nentries) == gAtoms, "bad atom table");
}
return gAtoms;
}

View File

@@ -0,0 +1,402 @@
/**
* This file defines the binary tree class and it
* nsNode child class.
*
* This simple version stores nodes, and the
* nodes store void* ptrs.
*
* @update gess 4/11/98
* @param
* @return
*/
#include "nsBTree.h"
/**
* default constructor
*
* @update gess 4/11/98
*/
nsNode::nsNode(){
mLeft=0;
mRight=0;
mParent=0;
mColor=eBlack;
}
/**
* Copy constructor
*
* @update gess 4/11/98
* @param
* @return
*/
nsNode::nsNode(const nsNode& aNode){
mLeft=aNode.mLeft;
mRight=aNode.mRight;
mParent=aNode.mParent;
mColor=aNode.mColor;
}
/**
* destructor
*
* @update gess 4/11/98
*/
nsNode::~nsNode(){
}
/**
* Retrive ptr to parent node
*
* @update gess 4/11/98
* @return ptr to parent node
*/
nsNode* nsNode::GetParentNode(void) const{
return mParent;
}
/**
* Retrieve ptr to left (less) node
*
* @update gess 4/11/98
* @return ptr to left (may be NULL)
*/
nsNode* nsNode::GetLeftNode(void) const{
return mLeft;
}
/**
* Retrieve ptr to right (more) node
*
* @update gess 4/11/98
* @return ptr to right node (may be NULL)
*/
nsNode* nsNode::GetRightNode(void) const{
return mRight;
}
/**
*
*
* @update gess 4/11/98
* @param
* @return
*/
nsNode& nsNode::operator=(const nsNode& aNode){
if(this!=&aNode){
mLeft=aNode.mLeft;
mRight=aNode.mRight;
mParent=aNode.mParent;
mColor=aNode.mColor;
}
return *this;
}
/********************************************************
* Here comes the BTREE class...
********************************************************/
/**
* nsBTree constructor
*
* @update gess 4/11/98
*/
nsBTree::nsBTree(){
mRoot=0;
}
/**
* destructor
*
* @update gess 4/11/98
*/
nsBTree::~nsBTree(){
if(mRoot){
//walk the tree and destroy the children.
}
}
/**
* Given a node, we're supposed to add it into
* our tree.
*
* @update gess 4/11/98
* @param aNode to be added to tree
* @return ptr to added node or NULL
*/
nsNode* nsBTree::Add(nsNode& aNode){
nsNode* node1=mRoot; //x
nsNode* node2=0; //y
while(node1) {
node2=node1;
if(aNode<*node1)
node1=node1->mLeft;
else node1=node1->mRight;
}
aNode.mParent=node2;
if(!node2){
mRoot=&aNode;
}
else{
if(aNode<*node2)
node2->mLeft=&aNode;
else node2->mRight=&aNode;
}
return &aNode;
}
/**
* Removes given node from tree if present.
*
* @update gess 4/11/98
* @param aNode to be found and removed
* @return ptr to remove node, or NULL
*/
nsNode* nsBTree::Remove(nsNode& aNode){
nsNode* result=0;
nsNode* node3=Find(aNode);
if(node3) {
nsNode* node1;
nsNode* node2;
if((!node3->mLeft) || (!node3->mRight))
node2=node3;
else node2=After(*node3);
if(node2->mLeft)
node1=node2->mLeft;
else node1=node2->mRight;
if(node1)
node1->mParent=node2->mParent;
if(node2->mParent) {
if(node2==node2->mParent->mLeft)
node2->mParent->mLeft=node1;
else node2->mParent->mRight=node1;
}
else mRoot=node1;
if(node2!=node3)
(*node3)==(*node2);
if(node2->mColor == nsNode::eBlack)
ReBalance(*node1);
delete node2;
result=&aNode;
}
return result;
}
/**
* Clears the tree of any data.
* Be careful here if your objects are heap based!
* This method doesn't free the objects, so if you
* don't have your own pointers, they will become
* orphaned.
*
* @update gess 4/11/98
* @param
* @return this
*/
nsBTree& nsBTree::Empty(nsNode* aNode) {
mRoot=0;
return *this;
}
/**
* This method destroys all the objects in the tree.
* WARNING: Never call this method on stored objects
* that are stack-based!
*
* @update gess 4/11/98
* @param
* @return this
*/
nsBTree& nsBTree::Erase(nsNode* aNode){
// nsNode* node1 =(aNode) ? aNode : mRoot;
if(aNode) {
Erase(aNode->mLeft); //begin by walking left side
Erase(aNode->mRight); //then search right side
delete aNode; //until a leaf, then delete
}
return *this;
}
/**
* Retrieve ptr to first node in tree
*
* @update gess 4/11/98
* @return
*/
nsNode* nsBTree::First(void) const{
if(mRoot)
return First(*mRoot);
return 0;
}
/**
* Retrive ptr to first node rel to given node
*
* @update gess 4/11/98
* @param node to begin scan from
* @return ptr to first node from given node or NULL
*/
nsNode* nsBTree::First(const nsNode& aNode) const{
nsNode* result=0;
if(mRoot) {
result=mRoot;
while(result->GetLeftNode()) {
result=result->GetLeftNode();
}
}
return result;
}
/**
* Retrive ptr to last node
*
* @update gess 4/11/98
* @return ptr to last node rel to root or NULL
*/
nsNode* nsBTree::Last(void) const{
if(mRoot)
return Last(*mRoot);
return 0;
}
/**
* Retrive ptr to last node rel to given node
*
* @update gess 4/11/98
* @param node to begin scan from
* @return ptr to first node from given node or NULL
*/
nsNode* nsBTree::Last(const nsNode& aNode) const{
nsNode* result=0;
if(mRoot) {
result=mRoot;
while(result->GetRightNode()) {
result=result->GetRightNode();
}
}
return result;
}
/**
* Retrive ptr to prior node rel to given node
*
* @update gess 4/11/98
* @param node to begin scan from
* @return ptr to prior node from given node or NULL
*/
nsNode* nsBTree::Before(const nsNode& aNode) const{
if(aNode.GetLeftNode())
return Last(*aNode.GetLeftNode());
//otherwise...
nsNode* node1=(nsNode*)&aNode;
nsNode* node2=aNode.GetParentNode();
while((node2) && (node1==node2->GetLeftNode())) {
node1=node2;
node2=node2->GetParentNode();
}
return node2;
}
/**
* Retrive ptr to next node rel to given node
*
* @update gess 4/11/98
* @param node to begin scan from
* @return ptr to next node from given node or NULL
*/
nsNode* nsBTree::After(const nsNode& aNode) const{
if(aNode.GetRightNode())
return First(*aNode.GetRightNode());
//otherwise...
nsNode* node1=(nsNode*)&aNode;
nsNode* node2=aNode.GetParentNode();
while((node2) && (node1==node2->GetRightNode())) {
node1=node2;
node2=node2->GetParentNode();
}
return node2;
}
/**
* Scan for given node
*
* @update gess 4/11/98
* @param node to find
* @return ptr to given node, or NULL
*/
nsNode* nsBTree::Find(const nsNode& aNode) const{
nsNode* result=mRoot;
while((result) && (!(aNode==(*result)))) {
if(aNode<*result)
result=result->mLeft;
else result=result->mRight;
}
return (nsNode*)result;
}
/**
* Rebalances tree around the given node. This only
* needs to be called after a node is deleted.
* This method does nothing for btrees, but is
* needed for RBTrees.
*
* @update gess 4/11/98
* @param aNode -- node to balance around
* @return this
*/
nsBTree& nsBTree::ReBalance(nsNode& aNode){
return *this;
}
/**
*
*
* @update gess 4/11/98
* @param
* @return
*/
const nsBTree& nsBTree::ForEach(nsNodeFunctor& aFunctor,nsNode* aNode) const{
nsNode* node1 =(aNode) ? aNode : mRoot;
if(node1) {
if(node1->mLeft)
ForEach(aFunctor,node1->mLeft); //begin by walking left side
aFunctor(*node1);
if(node1->mRight)
ForEach(aFunctor,node1->mRight); //then search right side
}
return *this;
}

283
mozilla/base/src/nsBTree.h Normal file
View File

@@ -0,0 +1,283 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* This file defines the binary tree class and it
* nsNode child class. Note that like all nsBTree
* containers, this one does not automatically balance.
* (Find for random data, bad for pre-ordered data).
*
* This simple version stores nodes, and the
* nodes store void* ptrs.
*
* @update gess 4/11/98
*/
/**
* nsNode
*
* @update gess 4/11/98
* @param
* @return
*/
#ifndef _BTREE_H
#define _BTREE_H
#include "nscore.h"
struct NS_BASE nsNode {
/**
*
* @update gess4/20/98
* @param
* @return
*/
nsNode();
/**
* Copy constructor
* @update gess 4/11/98
*/
nsNode(const nsNode& aNode);
/**
* destructor
* @update gess 4/11/98
*/
virtual ~nsNode();
/**
* Retrieve parent node
*
* @update gess 4/11/98
* @return
*/
nsNode* GetParentNode(void) const;
/**
*
* @update gess 4/11/98
* @param
* @return
*/
nsNode* GetLeftNode() const;
/**
*
* @update gess 4/11/98
* @param
* @return
*/
nsNode* GetRightNode() const;
/**
*
* @update gess 4/11/98
* @param
* @return
*/
virtual nsNode& operator=(const nsNode& aNode);
/**
* This method gets called to determine which of
* two nodes is less. When you create your own
* subclass of nsNode, this is the most important
* method for you to overload.
*
* @update gess 4/11/98
* @param
* @return
*/
virtual PRBool operator<(const nsNode& aNode) const=0;
/**
* This method gets called to determine which of
* two nodes is less. When you create your own
* subclass of nsNode, this is the most important
* method for you to overload.
*
* @update gess 4/11/98
* @param
* @return
*/
virtual PRBool operator==(const nsNode& aNode) const=0;
enum eRBColor {eRed,eBlack};
nsNode* mParent;
nsNode* mLeft;
nsNode* mRight;
eRBColor mColor;
};
/**
* The Nodefunctor class is used when you want to create
* callbacks between the nsRBTree and your generic code.
*
* @update gess4/20/98
*/
class NS_BASE nsNodeFunctor {
public:
virtual nsNodeFunctor& operator()(nsNode& aNode)=0;
};
/****************************************************
* Here comes the nsBTree class...
****************************************************/
class NS_BASE nsBTree {
public:
friend class nsBTreeIterator;
nsBTree();
virtual ~nsBTree();
/**
* Add given node reference into our tree.
*
* @update gess 4/11/98
* @param aNode is a ref to a node to be added
* @return newly added node
*/
nsNode* Add(nsNode& aNode);
/**
* Remove given node reference into our tree.
*
* @update gess 4/11/98
* @param aNode is a ref to a node to be removed
* @return Ptr to node if found (and removed) or NULL
*/
nsNode* Remove(nsNode& aNode);
/**
* Clears the tree of any data.
* Be careful here if your objects are heap based!
* This method doesn't free the objects, so if you
* don't have your own pointers, they will become
* orphaned.
*
* @update gess 4/11/98
* @param
* @return this
*/
nsBTree& Empty(nsNode* aNode=0);
/**
* This method destroys all the objects in the tree.
* WARNING: Never call this method on stored objects
* that are stack-based!
*
* @update gess 4/11/98
* @param
* @return this
*/
nsBTree& Erase(nsNode* aNode=0);
/**
* Retrieve ptr to 1st node in tree (starting at root)
*
* @update gess 4/11/98
* @return ptr to 1st node, possible to be NULL
*/
nsNode* First(void) const;
/**
* Find first node in tree starting at given node
*
* @update gess 4/11/98
* @param aNode node to begin 1st search from
* @return ptr to 1st node below given node
*/
nsNode* First(const nsNode& aNode) const;
/**
* Retrieve ptr to last node in tree relative to root.
*
* @update gess 4/11/98
* @return ptr to last node or NULL
*/
nsNode* Last(void) const;
/**
* Retrieve ptr to last node in tree relative to given node.
*
* @update gess 4/11/98
* @param node to find last node from
* @return ptr to last node or NULL
*/
nsNode* Last(const nsNode& aNode) const;
/**
* Retrieve a ptr to the node that preceeds given node
*
* @update gess 4/11/98
* @param aNode used as reference to find prev.
* @return ptr to prev node or NULL
*/
nsNode* Before(const nsNode& aNode) const;
/**
* Retrieve a ptr to the node after given node
*
* @update gess 4/11/98
* @param aNode used as reference to find next.
* @return ptr to next node or NULL
*/
nsNode* After(const nsNode& aNode) const;
/**
* Find given node in tree.
* (Why would you want to find a node you already have?)
*
* @update gess 4/11/98
* @param aNode is the node you're searching for
* @return ptr to node if found, or NULL
*/
nsNode* Find(const nsNode& aNode) const;
/**
* Walks the tree, starting with root.
*
* @update gess 4/11/98
*/
virtual const nsBTree& ForEach(nsNodeFunctor& aFunctor,nsNode* aNode=0) const;
protected:
/**
* Rebalances tree around the given node. This only
* needs to be called after a node is deleted.
*
* @update gess 4/11/98
* @param aNode -- node to balance around
* @return this
*/
virtual nsBTree& ReBalance(nsNode& aNode);
nsNode* mRoot;
};
#endif

View File

@@ -0,0 +1,80 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsBaseDLL.h"
#include "nscore.h"
#include "nsIProperties.h"
#include "nsProperties.h"
#include "nsRepository.h"
PRInt32 gLockCount = 0;
NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
extern "C" NS_EXPORT nsresult
NSRegisterSelf(const char* path)
{
nsresult ret;
ret = nsRepository::RegisterFactory(kPropertiesCID, path, PR_TRUE,
PR_TRUE);
if (NS_FAILED(ret)) {
return ret;
}
return ret;
}
extern "C" NS_EXPORT nsresult
NSUnregisterSelf(const char* path)
{
nsresult ret;
ret = nsRepository::UnregisterFactory(kPropertiesCID, path);
if (NS_FAILED(ret)) {
return ret;
}
return ret;
}
extern "C" NS_EXPORT nsresult
NSGetFactory(const nsCID& aClass, nsISupports* aServMgr, nsIFactory** aFactory)
{
nsresult res;
if (!aFactory) {
return NS_ERROR_NULL_POINTER;
}
if (aClass.Equals(kPropertiesCID)) {
nsPropertiesFactory *propsFactory = new nsPropertiesFactory();
if (!propsFactory) {
return NS_ERROR_OUT_OF_MEMORY;
}
res = propsFactory->QueryInterface(kIFactoryIID, (void**) aFactory);
if (NS_FAILED(res)) {
*aFactory = nsnull;
delete propsFactory;
}
return res;
}
return NS_NOINTERFACE;
}

View File

@@ -0,0 +1,26 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsBaseDLL_h___
#define nsBaseDLL_h___
#include "prtypes.h"
extern PRInt32 gLockCount;
#endif /* nsBaseDLL_h___ */

View File

@@ -0,0 +1,138 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsIByteBuffer.h"
#include "nsIInputStream.h"
#include "nsCRT.h"
#define MIN_BUFFER_SIZE 32
class ByteBufferImpl : public nsIByteBuffer {
public:
ByteBufferImpl(PRUint32 aBufferSize);
~ByteBufferImpl();
NS_DECL_ISUPPORTS
virtual PRUint32 GetLength(void) const;
virtual PRUint32 GetBufferSize(void) const;
virtual char* GetBuffer() const;
virtual PRBool Grow(PRUint32 aNewSize);
virtual PRInt32 Fill(nsresult* aErrorCode, nsIInputStream* aStream,
PRUint32 aKeep);
char* mBuffer;
PRUint32 mSpace;
PRUint32 mLength;
};
ByteBufferImpl::ByteBufferImpl(PRUint32 aBufferSize)
{
if (aBufferSize < MIN_BUFFER_SIZE) {
aBufferSize = MIN_BUFFER_SIZE;
}
mSpace = aBufferSize;
mBuffer = new char[aBufferSize];
mLength = 0;
NS_INIT_REFCNT();
}
NS_DEFINE_IID(kByteBufferIID,NS_IBYTE_BUFFER_IID);
NS_IMPL_ISUPPORTS(ByteBufferImpl,kByteBufferIID)
ByteBufferImpl::~ByteBufferImpl()
{
if (nsnull != mBuffer) {
delete mBuffer;
mBuffer = nsnull;
}
mLength = 0;
}
PRUint32 ByteBufferImpl::GetLength(void) const
{
return mLength;
}
PRUint32 ByteBufferImpl::GetBufferSize(void) const
{
return mSpace;
}
char* ByteBufferImpl::GetBuffer(void) const
{
return mBuffer;
}
PRBool ByteBufferImpl::Grow(PRUint32 aNewSize)
{
if (aNewSize < MIN_BUFFER_SIZE) {
aNewSize = MIN_BUFFER_SIZE;
}
char* newbuf = new char[aNewSize];
if (nsnull != newbuf) {
if (0 != mLength) {
nsCRT::memcpy(newbuf, mBuffer, mLength);
}
delete mBuffer;
mBuffer = newbuf;
return PR_TRUE;
}
return PR_FALSE;
}
PRInt32 ByteBufferImpl::Fill(nsresult* aErrorCode, nsIInputStream* aStream,
PRUint32 aKeep)
{
NS_PRECONDITION(nsnull != aStream, "null stream");
NS_PRECONDITION(aKeep <= mLength, "illegal keep count");
if ((nsnull == aStream) || (PRUint32(aKeep) > PRUint32(mLength))) {
// whoops
*aErrorCode = NS_BASE_STREAM_ILLEGAL_ARGS;
return -1;
}
if (0 != aKeep) {
// Slide over kept data
nsCRT::memmove(mBuffer, mBuffer + (mLength - aKeep), aKeep);
}
// Read in some new data
mLength = aKeep;
PRUint32 amount = mSpace - aKeep;
PRUint32 nb;
*aErrorCode = aStream->Read(mBuffer, aKeep, amount, &nb);
if (NS_SUCCEEDED(*aErrorCode)) {
mLength += nb;
}
else
nb = 0;
return nb;
}
NS_BASE nsresult NS_NewByteBuffer(nsIByteBuffer** aInstancePtrResult,
nsISupports* aOuter,
PRUint32 aBufferSize)
{
if (nsnull != aOuter) {
return NS_ERROR_NO_AGGREGATION;
}
ByteBufferImpl* it = new ByteBufferImpl(aBufferSize);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kByteBufferIID, (void **) aInstancePtrResult);
}

513
mozilla/base/src/nsCRT.cpp Normal file
View File

@@ -0,0 +1,513 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* MODULE NOTES:
* @update gess7/30/98
*
* Much as I hate to do it, we were using string compares wrong.
* Often, programmers call functions like strcmp(s1,s2), and pass
* one or more null strings. Rather than blow up on these, I've
* added quick checks to ensure that cases like this don't cause
* us to fail.
*
* In general, if you pass a null into any of these string compare
* routines, we simply return 0.
*/
#include "nsCRT.h"
#include "nsUnicharUtilCIID.h"
#include "nsIServiceManager.h"
#include "nsICaseConversion.h"
// XXX Bug: These tables don't lowercase the upper 128 characters properly
// This table maps uppercase characters to lower case characters;
// characters that are neither upper nor lower case are unaffected.
static const unsigned char kUpper2Lower[256] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64,
// upper band mapped to lower [A-Z] => [a-z]
97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,
91, 92, 93, 94, 95,
96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
};
static const unsigned char kLower2Upper[256] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96,
// lower band mapped to upper [a-z] => [A-Z]
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
123,124,125,126,127,
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
};
// XXX bug: this doesn't map 0x80 to 0x9f properly
static const PRUnichar kIsoLatin1ToUCS2[256] = {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
};
//----------------------------------------------------------------------
#define TOLOWER(_ucs2) \
(((_ucs2) < 128) ? PRUnichar(kUpper2Lower[_ucs2]) : _ToLower(_ucs2))
#define TOUPPER(_ucs2) \
(((_ucs2) < 128) ? PRUnichar(kLower2Upper[_ucs2]) : _ToUpper(_ucs2))
class HandleCaseConversionShutdown : public nsIShutdownListener {
public :
NS_IMETHOD OnShutdown(const nsCID& cid, nsISupports* service);
HandleCaseConversionShutdown(void) { NS_INIT_REFCNT(); }
virtual ~HandleCaseConversionShutdown(void) {}
NS_DECL_ISUPPORTS
};
static NS_DEFINE_CID(kUnicharUtilCID, NS_UNICHARUTIL_CID);
static NS_DEFINE_IID(kICaseConversionIID, NS_ICASECONVERSION_IID);
static nsICaseConversion * gCaseConv = NULL;
static NS_DEFINE_IID(kIShutdownListenerIID, NS_ISHUTDOWNLISTENER_IID);
NS_IMPL_ISUPPORTS(HandleCaseConversionShutdown, kIShutdownListenerIID);
nsresult
HandleCaseConversionShutdown::OnShutdown(const nsCID& cid, nsISupports* service)
{
if (cid.Equals(kUnicharUtilCID)) {
NS_ASSERTION(service == gCaseConv, "wrong service!");
nsrefcnt cnt = gCaseConv->Release();
gCaseConv = NULL;
}
return NS_OK;
}
static HandleCaseConversionShutdown* gListener = NULL;
static void StartUpCaseConversion()
{
nsresult err;
if ( NULL == gListener )
{
gListener = new HandleCaseConversionShutdown();
gListener->AddRef();
}
err = nsServiceManager::GetService(kUnicharUtilCID, kICaseConversionIID,
(nsISupports**) &gCaseConv, gListener);
}
static void CheckCaseConversion()
{
if(NULL == gCaseConv )
StartUpCaseConversion();
NS_ASSERTION( gCaseConv != NULL , "cannot obtain UnicharUtil");
}
static PRUnichar _ToLower(PRUnichar aChar)
{
PRUnichar oLower;
CheckCaseConversion();
nsresult err = gCaseConv->ToLower(aChar, &oLower);
NS_ASSERTION( NS_SUCCEEDED(err), "failed to communicate to UnicharUtil");
return ( NS_SUCCEEDED(err) ) ? oLower : aChar ;
}
static PRUnichar _ToUpper(PRUnichar aChar)
{
nsresult err;
PRUnichar oUpper;
CheckCaseConversion();
err = gCaseConv->ToUpper(aChar, &oUpper);
NS_ASSERTION( NS_SUCCEEDED(err), "failed to communicate to UnicharUtil");
return ( NS_SUCCEEDED(err) ) ? oUpper : aChar ;
}
//----------------------------------------------------------------------
PRUnichar nsCRT::ToUpper(PRUnichar aChar)
{
return TOUPPER(aChar);
}
PRUnichar nsCRT::ToLower(PRUnichar aChar)
{
return TOLOWER(aChar);
}
////////////////////////////////////////////////////////////////////////////////
// My lovely strtok routine
#define IS_DELIM(m, c) ((m)[(c) >> 3] & (1 << ((c) & 7)))
#define SET_DELIM(m, c) ((m)[(c) >> 3] |= (1 << ((c) & 7)))
#define DELIM_TABLE_SIZE 32
char* nsCRT::strtok(char* str, const char* delims, char* *newStr)
{
NS_ASSERTION(str, "Unlike regular strtok, the first argument cannot be null.");
char delimTable[DELIM_TABLE_SIZE];
PRUint32 i;
char* result;
for (i = 0; i < DELIM_TABLE_SIZE; i++)
delimTable[i] = '\0';
for (i = 0; i < DELIM_TABLE_SIZE && delims[i]; i++) {
SET_DELIM(delimTable, delims[i]);
}
NS_ASSERTION(delims[i] == '\0', "too many delimiters");
// skip to beginning
while (*str && IS_DELIM(delimTable, *str)) {
str++;
}
result = str;
// fix up the end of the token
while (*str) {
if (IS_DELIM(delimTable, *str)) {
*str++ = '\0';
break;
}
str++;
}
*newStr = str;
return str == result ? NULL : result;
}
////////////////////////////////////////////////////////////////////////////////
PRUint32 nsCRT::strlen(const PRUnichar* s)
{
PRUint32 len = 0;
if(s) {
while (*s++ != 0) {
len++;
}
}
return len;
}
/**
* Compare unichar string ptrs, stopping at the 1st null
* NOTE: If both are null, we return 0.
* @update gess7/30/98
* @param s1 and s2 both point to unichar strings
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
*/
PRInt32 nsCRT::strcmp(const PRUnichar* s1, const PRUnichar* s2)
{
if(s1 && s2) {
for (;;) {
PRUnichar c1 = *s1++;
PRUnichar c2 = *s2++;
if (c1 != c2) {
if (c1 < c2) return -1;
return 1;
}
if ((0==c1) || (0==c2)) break;
}
}
return 0;
}
/**
* Compare unichar string ptrs, stopping at the 1st null or nth char.
* NOTE: If either is null, we return 0.
* @update gess7/30/98
* @param s1 and s2 both point to unichar strings
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
*/
PRInt32 nsCRT::strncmp(const PRUnichar* s1, const PRUnichar* s2, PRUint32 n)
{
if(s1 && s2) {
if(n != 0) {
do {
PRUnichar c1 = *s1++;
PRUnichar c2 = *s2++;
if (c1 != c2) {
if (c1 < c2) return -1;
return 1;
}
if ((0==c1) || (0==c2)) break;
} while (--n != 0);
}
}
return 0;
}
/**
* Compare unichar string ptrs without regard to case
* NOTE: If both are null, we return 0.
* @update gess7/30/98
* @param s1 and s2 both point to unichar strings
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
*/
PRInt32 nsCRT::strcasecmp(const PRUnichar* s1, const PRUnichar* s2)
{
if(s1 && s2) {
for (;;) {
PRUnichar c1 = *s1++;
PRUnichar c2 = *s2++;
if (c1 != c2) {
c1 = TOLOWER(c1);
c2 = TOLOWER(c2);
if (c1 != c2) {
if (c1 < c2) return -1;
return 1;
}
}
if ((0==c1) || (0==c2)) break;
}
}
return 0;
}
/**
* Compare unichar string ptrs, stopping at the 1st null or nth char;
* also ignoring the case of characters.
* NOTE: If both are null, we return 0.
* @update gess7/30/98
* @param s1 and s2 both point to unichar strings
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
*/
PRInt32 nsCRT::strncasecmp(const PRUnichar* s1, const PRUnichar* s2, PRUint32 n)
{
if(s1 && s2) {
if(0<n){
while (--n >= 0) {
PRUnichar c1 = *s1++;
PRUnichar c2 = *s2++;
if (c1 != c2) {
c1 = TOLOWER(c1);
c2 = TOLOWER(c2);
if (c1 != c2) {
if (c1 < c2) return -1;
return 1;
}
}
if ((0==c1) || (0==c2)) break;
}
}
}
return 0;
}
/**
* Compare a unichar string ptr to cstring.
* NOTE: If both are null, we return 0.
* @update gess7/30/98
* @param s1 points to unichar string
* @param s2 points to cstring
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
*/
PRInt32 nsCRT::strcmp(const PRUnichar* s1, const char* s2)
{
if(s1 && s2) {
for (;;) {
PRUnichar c1 = *s1++;
PRUnichar c2 = kIsoLatin1ToUCS2[*(const unsigned char*)s2++];
if (c1 != c2) {
if (c1 < c2) return -1;
return 1;
}
if ((0==c1) || (0==c2)) break;
}
}
return 0;
}
/**
* Compare a unichar string ptr to cstring, up to N chars.
* NOTE: If both are null, we return 0.
* @update gess7/30/98
* @param s1 points to unichar string
* @param s2 points to cstring
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
*/
PRInt32 nsCRT::strncmp(const PRUnichar* s1, const char* s2, PRUint32 n)
{
if(s1 && s2) {
if(n != 0){
do {
PRUnichar c1 = *s1++;
PRUnichar c2 = kIsoLatin1ToUCS2[*(const unsigned char*)s2++];
if (c1 != c2) {
if (c1 < c2) return -1;
return 1;
}
if ((0==c1) || (0==c2)) break;
} while (--n != 0);
}
}
return 0;
}
/**
* Compare a unichar string ptr to cstring without regard to case
* NOTE: If both are null, we return 0.
* @update gess7/30/98
* @param s1 points to unichar string
* @param s2 points to cstring
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
*/
PRInt32 nsCRT::strcasecmp(const PRUnichar* s1, const char* s2)
{
if(s1 && s2) {
for (;;) {
PRUnichar c1 = *s1++;
PRUnichar c2 = kIsoLatin1ToUCS2[*(const unsigned char*)s2++];
if (c1 != c2) {
c1 = TOLOWER(c1);
c2 = TOLOWER(c2);
if (c1 != c2) {
if (c1 < c2) return -1;
return 1;
}
}
if ((0==c1) || (0==c2)) break;
}
}
return 0;
}
/**
* Caseless compare up to N chars between unichar string ptr to cstring.
* NOTE: If both are null, we return 0.
* @update gess7/30/98
* @param s1 points to unichar string
* @param s2 points to cstring
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
*/
PRInt32 nsCRT::strncasecmp(const PRUnichar* s1, const char* s2, PRUint32 n)
{
if(s1 && s2){
if(n != 0){
do {
PRUnichar c1 = *s1++;
PRUnichar c2 = kIsoLatin1ToUCS2[*(const unsigned char*)s2++];
if (c1 != c2) {
c1 = TOLOWER(c1);
c2 = TOLOWER(c2);
if (c1 != c2) {
if (c1 < c2) return -1;
return 1;
}
}
if (c1 == 0) break;
} while (--n != 0);
}
}
return 0;
}
PRUnichar* nsCRT::strdup(const PRUnichar* str)
{
PRUint32 len = nsCRT::strlen(str) + 1; // add one for null
PRUnichar* rslt = new PRUnichar[len];
if (rslt == NULL) return NULL;
nsCRT::memcpy(rslt, str, len * sizeof(PRUnichar));
return rslt;
}
PRUint32 nsCRT::HashValue(const PRUnichar* us)
{
PRUint32 rv = 0;
if(us) {
PRUnichar ch;
while ((ch = *us++) != 0) {
// FYI: rv = rv*37 + ch
rv = ((rv << 5) + (rv << 2) + rv) + ch;
}
}
return rv;
}
PRUint32 nsCRT::HashValue(const PRUnichar* us, PRUint32* uslenp)
{
PRUint32 rv = 0;
PRUint32 len = 0;
PRUnichar ch;
while ((ch = *us++) != 0) {
// FYI: rv = rv*37 + ch
rv = ((rv << 5) + (rv << 2) + rv) + ch;
len++;
}
*uslenp = len;
return rv;
}
PRInt32 nsCRT::atoi( const PRUnichar *string )
{
return atoi(string);
}

161
mozilla/base/src/nsCRT.h Normal file
View File

@@ -0,0 +1,161 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsCRT_h___
#define nsCRT_h___
#include <stdlib.h>
#include <string.h>
#include "plstr.h"
#include "nscore.h"
#define CR '\015'
#define LF '\012'
#define VTAB '\013'
#define FF '\014'
#define TAB '\011'
#define CRLF "\015\012" /* A CR LF equivalent string */
/// This is a wrapper class around all the C runtime functions.
class NS_BASE nsCRT {
public:
/** Copy bytes from aSrc to aDest.
@param aDest the destination address
@param aSrc the source address
@param aCount the number of bytes to copy
*/
static void memcpy(void* aDest, const void* aSrc, PRUint32 aCount) {
::memcpy(aDest, aSrc, (size_t)aCount);
}
static void memmove(void* aDest, const void* aSrc, PRUint32 aCount) {
::memmove(aDest, aSrc, (size_t)aCount);
}
static void memset(void* aDest, PRUint8 aByte, PRUint32 aCount) {
::memset(aDest, aByte, aCount);
}
static void zero(void* aDest, PRUint32 aCount) {
::memset(aDest, 0, (size_t)aCount);
}
/** Compute the string length of s
@param s the string in question
@return the length of s
*/
static PRUint32 strlen(const char* s) {
return PRUint32(::strlen(s));
}
/// Compare s1 and s2.
static PRInt32 strcmp(const char* s1, const char* s2) {
return PRUint32(PL_strcmp(s1, s2));
}
static PRUint32 strncmp(const char* s1, const char* s2,
PRUint32 aMaxLen) {
return PRInt32(PL_strncmp(s1, s2, aMaxLen));
}
/// Case-insensitive string comparison.
static PRInt32 strcasecmp(const char* s1, const char* s2) {
return PRInt32(PL_strcasecmp(s1, s2));
}
/// Case-insensitive string comparison with length
static PRInt32 strncasecmp(const char* s1, const char* s2, PRUint32 aMaxLen) {
return PRInt32(PL_strncasecmp(s1, s2, aMaxLen));
}
static PRInt32 strncmp(const char* s1, const char* s2, PRInt32 aMaxLen) {
return PRInt32(PL_strncmp(s1,s2,aMaxLen));
}
static char* strdup(const char* str) {
return PL_strdup(str);
}
/**
How to use this fancy (thread-safe) version of strtok:
void main( void ) {
printf( "%s\n\nTokens:\n", string );
// Establish string and get the first token:
char* newStr;
token = nsCRT::strtok( string, seps, &newStr );
while( token != NULL ) {
// While there are tokens in "string"
printf( " %s\n", token );
// Get next token:
token = nsCRT::strtok( newStr, seps, &newStr );
}
}
*/
static char* strtok(char* str, const char* delims, char* *newStr);
/// Like strlen except for ucs2 strings
static PRUint32 strlen(const PRUnichar* s);
/// Like strcmp except for ucs2 strings
static PRInt32 strcmp(const PRUnichar* s1, const PRUnichar* s2);
/// Like strcmp except for ucs2 strings
static PRInt32 strncmp(const PRUnichar* s1, const PRUnichar* s2,
PRUint32 aMaxLen);
/// Like strcasecmp except for ucs2 strings
static PRInt32 strcasecmp(const PRUnichar* s1, const PRUnichar* s2);
/// Like strncasecmp except for ucs2 strings
static PRInt32 strncasecmp(const PRUnichar* s1, const PRUnichar* s2,
PRUint32 aMaxLen);
/// Like strcmp with a char* and a ucs2 string
static PRInt32 strcmp(const PRUnichar* s1, const char* s2);
/// Like strncmp with a char* and a ucs2 string
static PRInt32 strncmp(const PRUnichar* s1, const char* s2,
PRUint32 aMaxLen);
/// Like strcasecmp with a char* and a ucs2 string
static PRInt32 strcasecmp(const PRUnichar* s1, const char* s2);
/// Like strncasecmp with a char* and a ucs2 string
static PRInt32 strncasecmp(const PRUnichar* s1, const char* s2,
PRUint32 aMaxLen);
// Note: uses new[] to allocate memory, so you must use delete[] to
// free the memory
static PRUnichar* strdup(const PRUnichar* str);
/// Compute a hashcode for a ucs2 string
static PRUint32 HashValue(const PRUnichar* s1);
/// Same as above except that we return the length in s1len
static PRUint32 HashValue(const PRUnichar* s1, PRUint32* s1len);
/// String to integer.
static PRInt32 atoi( const PRUnichar *string );
static PRUnichar ToUpper(PRUnichar aChar);
static PRUnichar ToLower(PRUnichar aChar);
};
#endif /* nsCRT_h___ */

View File

@@ -0,0 +1,540 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsDeque.h"
#include "nsCRT.h"
//#define _SELFTEST_DEQUE 1
#undef _SELFTEST_DEQUE
/**
* Standard constructor
* @update gess4/18/98
* @return new deque
*/
nsDeque::nsDeque(nsDequeFunctor& aMemDestroyer) : mMemDestroyer(aMemDestroyer) {
mMemDestroyer=aMemDestroyer;
mCapacity=eGrowthDelta;
mOrigin=mSize=0;
mData=new void*[mCapacity];
}
/**
* Destructor
* @update gess4/18/98
*/
nsDeque::~nsDeque() {
Erase();
delete [] mData;
mData=0;
}
/**
* Returns the number of elements currently stored in
* this deque.
*
* @update gess4/18/98
* @param
* @return int contains element count
*/
PRInt32 nsDeque::GetSize(void) const {
return mSize;
}
/**
* Remove all items from container without destroying them.
*
* @update gess4/18/98
* @param
* @return
*/
nsDeque& nsDeque::Empty() {
if((0<mCapacity) && (mData)) {
nsCRT::zero(mData,mCapacity*sizeof(mData));
}
mSize=0;
mOrigin=0;
return *this;
}
/**
* Remove and delete all items from container
*
* @update gess4/18/98
* @return this
*/
nsDeque& nsDeque::Erase() {
ForEach(mMemDestroyer);
return Empty();
}
/**
* This method adds an item to the end of the deque.
* This operation has the potential to cause the
* underlying buffer to resize.
*
* @update gess4/18/98
* @param anItem: new item to be added to deque
* @return nada
*/
nsDeque& nsDeque::Push(void* anItem) {
if(mSize==mCapacity) {
void** temp=new void*[mCapacity+eGrowthDelta];
//Here's the interesting part: You can't just move the elements
//directy (in situ) from the old buffer to the new one.
//Since capacity has changed, the old origin doesn't make
//sense anymore. It's better to resequence the elements now.
int tempi=0;
int i=0;
int j=0;
for(i=mOrigin;i<mCapacity;i++) temp[tempi++]=mData[i]; //copy the leading elements...
for(j=0;j<mOrigin;j++) temp[tempi++]=mData[j]; //copy the trailing elements...
mCapacity+=eGrowthDelta;
mOrigin=0; //now realign the origin...
delete[]mData;
mData=temp;
}
int offset=mOrigin+mSize;
if(offset<mCapacity)
mData[offset]=anItem;
else mData[offset-mCapacity]=anItem;
mSize++;
return *this;
}
/**
* This method adds an item to the front of the deque.
* This operation has the potential to cause the
* underlying buffer to resize.
*
* @update gess4/18/98
* @param anItem: new item to be added to deque
* @return nada
*/
nsDeque& nsDeque::PushFront(void* anItem) {
if(mOrigin>0) {
mOrigin-=1;
mData[mOrigin]=anItem;
mSize++;
}
else {
Push(anItem);
mOrigin=mSize-1;
}
return *this;
}
/**
* Remove and return the last item in the container.
*
* @update gess4/18/98
* @param none
* @return ptr to last item in container
*/
void* nsDeque::Pop(void) {
void* result=0;
if(mSize>0) {
int offset=mOrigin+mSize-1;
if(offset>=mCapacity)
offset-=mCapacity;
result=mData[offset];
mData[offset]=0;
mSize--;
if(0==mSize)
mOrigin=0;
}
return result;
}
/**
* This method gets called you want to remove and return
* the first member in the container.
*
* @update gess4/18/98
* @param nada
* @return last item in container
*/
void* nsDeque::PopFront() {
void* result=0;
if(mSize>0) {
result=mData[mOrigin];
mData[mOrigin++]=0; //zero it out for debugging purposes.
mSize--;
if(mCapacity==mOrigin) //you popped off the end, so cycle back around...
mOrigin=0;
if(0==mSize)
mOrigin=0;
}
NS_ASSERTION(mOrigin<mCapacity,"Error: Bad origin");
return result;
}
/**
* This method gets called you want to peek at the topmost
* member without removing it.
*
* @update gess4/18/98
* @param nada
* @return last item in container
*/
void* nsDeque::Peek() {
void* result=0;
if(mSize>0) {
result=mData[mOrigin];
}
return result;
}
/**
* Call this to retrieve the ith element from this container.
* Keep in mind that accessing the underlying elements is
* done in a relative fashion. Object 0 is not necessarily
* the first element (the first element is at mOrigin).
*
* @update gess4/18/98
* @param anIndex : 0 relative offset of item you want
* @return void* or null
*/
void* nsDeque::ObjectAt(PRInt32 anIndex) const {
void* result=0;
if((anIndex>=0) && (anIndex<mSize))
{
if(anIndex<(mCapacity-mOrigin)) {
result=mData[mOrigin+anIndex];
}
else {
result=mData[anIndex-(mCapacity-mOrigin)];
}
}
return result;
}
/**
* Create and return an iterator pointing to
* the beginning of the queue. Note that this
* takes the circular buffer semantics into account.
*
* @update gess4/18/98
* @return new deque iterator, init'ed to 1st item
*/
nsDequeIterator nsDeque::Begin(void) const{
return nsDequeIterator(*this,0);
}
/**
* Create and return an iterator pointing to
* the last of the queue. Note that this
* takes the circular buffer semantics into account.
*
* @update gess4/18/98
* @return new deque iterator, init'ed to last item
*/
nsDequeIterator nsDeque::End(void) const{
return nsDequeIterator(*this,mSize);
}
/**
* Call this method when you wanto to iterate all the
* members of the container, passing a functor along
* to call your code.
*
* @update gess4/20/98
* @param aFunctor object to call for each member
* @return *this
*/
void nsDeque::ForEach(nsDequeFunctor& aFunctor) const{
int i=0;
for(i=0;i<mSize;i++){
void* obj=ObjectAt(i);
obj=aFunctor(obj);
}
}
/**
* Call this method when you wanto to iterate all the
* members of the container, passing a functor along
* to call your code. Iteration continues until your
* functor returns a non-null.
*
* @update gess4/20/98
* @param aFunctor object to call for each member
* @return *this
*/
const void* nsDeque::FirstThat(nsDequeFunctor& aFunctor) const{
int i=0;
for(i=0;i<mSize;i++){
void* obj=ObjectAt(i);
obj=aFunctor(obj);
if(obj)
return obj;
}
return 0;
}
/******************************************************
* Here comes the nsDequeIterator class...
******************************************************/
/**
* DequeIterator is an object that knows how to iterate (forward and backward)
* a Deque. Normally, you don't need to do this, but there are some special
* cases where it is pretty handy, so here you go.
*
* This is a standard dequeiterator constructor
*
* @update gess4/18/98
* @param aQueue is the deque object to be iterated
* @param anIndex is the starting position for your iteration
*/
nsDequeIterator::nsDequeIterator(const nsDeque& aQueue,int anIndex): mIndex(anIndex), mDeque(aQueue) {
}
/**
* Copy construct a new iterator beginning with given
*
* @update gess4/20/98
* @param aCopy is another iterator to copy from
* @return
*/
nsDequeIterator::nsDequeIterator(const nsDequeIterator& aCopy) : mIndex(aCopy.mIndex), mDeque(aCopy.mDeque) {
}
/**
* Moves iterator to first element in deque
* @update gess4/18/98
* @return this
*/
nsDequeIterator& nsDequeIterator::First(void){
mIndex=0;
return *this;
}
/**
* Standard assignment operator for dequeiterator
*
* @update gess4/18/98
* @param aCopy is an iterator to be copied from
* @return *this
*/
nsDequeIterator& nsDequeIterator::operator=(const nsDequeIterator& aCopy) {
//queue's are already equal.
mIndex=aCopy.mIndex;
return *this;
}
/**
* preform ! operation against to iterators to test for equivalence
* (or lack thereof)!
*
* @update gess4/18/98
* @param anIter is the object to be compared to
* @return TRUE if NOT equal.
*/
PRBool nsDequeIterator::operator!=(nsDequeIterator& anIter) {
return PRBool(!this->operator==(anIter));
}
/**
* Compare 2 iterators for equivalence.
*
* @update gess4/18/98
* @param anIter is the other iterator to be compared to
* @return TRUE if EQUAL
*/
PRBool nsDequeIterator::operator<(nsDequeIterator& anIter) {
return PRBool(((mIndex<anIter.mIndex) && (&mDeque==&anIter.mDeque)));
}
/**
* Compare 2 iterators for equivalence.
*
* @update gess4/18/98
* @param anIter is the other iterator to be compared to
* @return TRUE if EQUAL
*/
PRBool nsDequeIterator::operator==(nsDequeIterator& anIter) {
return PRBool(((mIndex==anIter.mIndex) && (&mDeque==&anIter.mDeque)));
}
/**
* Compare 2 iterators for equivalence.
*
* @update gess4/18/98
* @param anIter is the other iterator to be compared to
* @return TRUE if EQUAL
*/
PRBool nsDequeIterator::operator>=(nsDequeIterator& anIter) {
return PRBool(((mIndex>=anIter.mIndex) && (&mDeque==&anIter.mDeque)));
}
/**
* Pre-increment operator
*
* @update gess4/18/98
* @return object at preincremented index
*/
void* nsDequeIterator::operator++() {
return mDeque.ObjectAt(++mIndex);
}
/**
* Post-increment operator
*
* @update gess4/18/98
* @param param is ignored
* @return object at post-incremented index
*/
void* nsDequeIterator::operator++(int) {
return mDeque.ObjectAt(mIndex++);
}
/**
* Pre-decrement operator
*
* @update gess4/18/98
* @return object at pre-decremented index
*/
void* nsDequeIterator::operator--() {
return mDeque.ObjectAt(--mIndex);
}
/**
* Post-decrement operator
*
* @update gess4/18/98
* @param param is ignored
* @return object at post-decremented index
*/
void* nsDequeIterator::operator--(int) {
return mDeque.ObjectAt(mIndex--);
}
/**
* Dereference operator
*
* @update gess4/18/98
* @return object at ith index
*/
void* nsDequeIterator::GetCurrent(void) {
return mDeque.ObjectAt(mIndex);
}
/**
* Call this method when you wanto to iterate all the
* members of the container, passing a functor along
* to call your code.
*
* @update gess4/20/98
* @param aFunctor object to call for each member
* @return *this
*/
void nsDequeIterator::ForEach(nsDequeFunctor& aFunctor) const{
mDeque.ForEach(aFunctor);
}
/**
* Call this method when you wanto to iterate all the
* members of the container, passing a functor along
* to call your code.
*
* @update gess4/20/98
* @param aFunctor object to call for each member
* @return *this
*/
const void* nsDequeIterator::FirstThat(nsDequeFunctor& aFunctor) const{
return mDeque.FirstThat(aFunctor);
}
#ifdef _SELFTEST_DEQUE
/**************************************************************
Now define the token deallocator class...
**************************************************************/
class _SelfTestDeallocator: public nsDequeFunctor{
public:
_SelfTestDeallocator::_SelfTestDeallocator() {
nsDeque::SelfTest();
}
virtual void* operator()(void* anObject) {
return 0;
}
};
static _SelfTestDeallocator gDeallocator;
#endif
/**
* conduct automated self test for this class
*
* @update gess4/18/98
* @param
* @return
*/
void nsDeque::SelfTest(void) {
#ifdef _SELFTEST_DEQUE
{
nsDeque theDeque(gDeallocator); //construct a simple one...
int ints[200];
int count=sizeof(ints)/sizeof(int);
int i=0;
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++){
int* temp=(int*)theDeque.Pop();
}
for(i=0;i<55;i++){
theDeque.Push(&ints[i]);
}
for(i=0;i<35;i++){
int* temp=(int*)theDeque.Pop();
}
for(i=0;i<35;i++){
theDeque.Push(&ints[i]);
}
for(i=0;i<38;i++){
int* temp=(int*)theDeque.Pop();
}
}
int x;
x=10;
#endif
}

406
mozilla/base/src/nsDeque.h Normal file
View File

@@ -0,0 +1,406 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/**
* MODULE NOTES:
* @update gess 4/15/98 (tax day)
*
* The Deque is a very small, very efficient container object
* than can hold elements of type void*, offering the following features:
* It's interface supports pushing and poping of children.
* It can iterate (via an interator class) it's children.
* When full, it can efficently resize dynamically.
*
*
* NOTE: The only bit of trickery here is that this deque is
* built upon a ring-buffer. Like all ring buffers, the first
* element may not be at index[0]. The mOrigin member determines
* where the first child is. This point is quietly hidden from
* customers of this class.
*
*/
#ifndef _NSDEQUE
#define _NSDEQUE
#include "nscore.h"
/**
* The nsDequefunctor class is used when you want to create
* callbacks between the deque and your generic code.
* Use these objects in a call to ForEach();
*
* @update gess4/20/98
*/
class NS_BASE nsDequeFunctor{
public:
virtual void* operator()(void* anObject)=0;
};
/******************************************************
* Here comes the nsDeque class itself...
******************************************************/
/**
* The deque (double-ended queue) class is a common container type,
* whose behavior mimics a line in your favorite checkout stand.
* Classic CS describes the common behavior of a queue as FIFO.
* A Deque allows items to be added and removed from either end of
* the queue.
*
* @update gess4/20/98
*/
class NS_BASE nsDeque {
friend class nsDequeIterator;
public:
nsDeque(nsDequeFunctor& aMemDestroyer);
~nsDeque();
/**
* Returns the number of elements currently stored in
* this deque.
*
* @update gess4/18/98
* @param
* @return int contains element count
*/
PRInt32 GetSize() const;
/**
* Pushes new member onto the end of the deque
*
* @update gess4/18/98
* @param ptr to object to store
* @return *this
*/
nsDeque& Push(void* anItem);
/**
* Pushes new member onto the front of the deque
*
* @update gess4/18/98
* @param ptr to object to store
* @return *this
*/
nsDeque& PushFront(void* anItem);
/**
* Remove and return the first item in the container.
*
* @update gess4/18/98
* @param none
* @return ptr to first item in container
*/
void* Pop(void);
/**
* Remove and return the first item in the container.
*
* @update gess4/18/98
* @param none
* @return ptr to first item in container
*/
void* PopFront(void);
/**
* Return topmost item without removing it.
*
* @update gess4/18/98
* @param none
* @return ptr to first item in container
*/
void* Peek(void);
/**
* method used to retrieve ptr to
* ith member in container. DOesn't remove
* that item.
*
* @update gess4/18/98
* @param index of desired item
* @return ptr to ith element in list
*/
void* ObjectAt(int anIndex) const;
/**
* Remove all items from container without destroying them
*
* @update gess4/18/98
* @param
* @return
*/
nsDeque& Empty();
/**
* Remove and delete all items from container
*
* @update gess4/18/98
* @param
* @return
*/
nsDeque& Erase();
/**
* Creates a new iterator, init'ed to start of container
*
* @update gess4/18/98
* @return new dequeIterator
*/
nsDequeIterator Begin() const;
/**
* Creates a new iterator, init'ed to end of container
*
* @update gess4/18/98
* @return new dequeIterator
*/
nsDequeIterator End() const;
/**
* Call this method when you wanto to iterate all the
* members of the container, passing a functor along
* to call your code.
*
* @update gess4/20/98
* @param aFunctor object to call for each member
* @return *this
*/
void ForEach(nsDequeFunctor& aFunctor) const;
/**
* Call this method when you wanto to iterate all the
* members of the container, passing a functor along
* to call your code. This process will interupt if
* your function returns a null to this iterator.
*
* @update gess4/20/98
* @param aFunctor object to call for each member
* @return *this
*/
const void* FirstThat(nsDequeFunctor& aFunctor) const;
/**
* Perform automated selftest on the deque
*
* @update gess4/18/98
* @param
* @return
*/
static void SelfTest();
protected:
PRInt32 mSize;
PRInt32 mCapacity;
PRInt32 mOrigin;
nsDequeFunctor& mMemDestroyer;
void** mData;
private:
enum {eGrowthDelta=64};
/**
* Simple default constructor (PRIVATE)
*
* @update gess4/18/98
* @param
* @return
*/
nsDeque();
/**
* Copy constructor (PRIVATE)
*
* @update gess4/18/98
* @param
* @return
*/
nsDeque(const nsDeque& other);
/**
* Deque assignment operator (PRIVATE)
*
* @update gess4/18/98
* @param another deque
* @return *this
*/
nsDeque& operator=(const nsDeque& anOther);
};
/******************************************************
* Here comes the nsDequeIterator class...
******************************************************/
class NS_BASE nsDequeIterator {
public:
/**
* DequeIterator is an object that knows how to iterate (forward and backward)
* a Deque. Normally, you don't need to do this, but there are some special
* cases where it is pretty handy, so here you go.
*
* @update gess4/18/98
* @param aQueue is the deque object to be iterated
* @param anIndex is the starting position for your iteration
*/
nsDequeIterator(const nsDeque& aQueue,int anIndex=0);
/**
* DequeIterator is an object that knows how to iterate (forward and backward)
* a Deque. Normally, you don't need to do this, but there are some special
* cases where it is pretty handy, so here you go.
*
* @update gess4/18/98
* @param aQueue is the deque object to be iterated
* @param anIndex is the starting position for your iteration
*/
nsDequeIterator(const nsDequeIterator& aCopy);
/**
* Moves iterator to first element in deque
* @update gess4/18/98
* @return this
*/
nsDequeIterator& First(void);
/**
* Standard assignment operator for deque
* @update gess4/18/98
* @param
* @return
*/
nsDequeIterator& operator=(const nsDequeIterator& aCopy);
/**
* preform ! operation against to iterators to test for equivalence
* (or lack thereof)!
*
* @update gess4/18/98
* @param anIter is the object to be compared to
* @return TRUE if NOT equal.
*/
PRBool operator!=(nsDequeIterator& anIter);
/**
* Compare 2 iterators for equivalence.
*
* @update gess4/18/98
* @param anIter is the other iterator to be compared to
* @return TRUE if EQUAL
*/
PRBool operator<(nsDequeIterator& anIter);
/**
* Compare 2 iterators for equivalence.
*
* @update gess4/18/98
* @param anIter is the other iterator to be compared to
* @return TRUE if EQUAL
*/
PRBool operator==(nsDequeIterator& anIter);
/**
* Compare 2 iterators for equivalence.
*
* @update gess4/18/98
* @param anIter is the other iterator to be compared to
* @return TRUE if EQUAL
*/
PRBool operator>=(nsDequeIterator& anIter);
/**
* Pre-increment operator
*
* @update gess4/18/98
* @return object at preincremented index
*/
void* operator++();
/**
* Post-increment operator
*
* @update gess4/18/98
* @param param is ignored
* @return object at post-incremented index
*/
void* operator++(int);
/**
* Pre-decrement operator
*
* @update gess4/18/98
* @return object at pre-decremented index
*/
void* operator--();
/**
* Post-decrement operator
*
* @update gess4/18/98
* @param param is ignored
* @return object at post-decremented index
*/
void* operator--(int);
/**
* Retrieve the ptr to the iterators notion of current node
*
* @update gess4/18/98
* @return object at ith index
*/
void* GetCurrent(void);
/**
* Call this method when you wanto to iterate all the
* members of the container, passing a functor along
* to call your code.
*
* @update gess4/20/98
* @param aFunctor object to call for each member
* @return *this
*/
void ForEach(nsDequeFunctor& aFunctor) const;
/**
* Call this method when you wanto to iterate all the
* members of the container, passing a functor along
* to call your code.
*
* @update gess4/20/98
* @param aFunctor object to call for each member
* @return *this
*/
const void* FirstThat(nsDequeFunctor& aFunctor) const;
protected:
PRInt32 mIndex;
const nsDeque& mDeque;
};
#endif

View File

@@ -0,0 +1,152 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
// First checked in on 98/12/03 by John R. McMullen, derived from net.h/mkparse.c.
#include "nsEscape.h"
#include "plstr.h"
const int netCharType[256] =
/* Bit 0 xalpha -- the alphas
** Bit 1 xpalpha -- as xalpha but
** converts spaces to plus and plus to %20
** Bit 3 ... path -- as xalphas but doesn't escape '/'
*/
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0x */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1x */
0,0,0,0,0,0,0,0,0,0,7,4,0,7,7,4, /* 2x !"#$%&'()*+,-./ */
7,7,7,7,7,7,7,7,7,7,0,0,0,0,0,0, /* 3x 0123456789:;<=>? */
0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* 4x @ABCDEFGHIJKLMNO */
/* bits for '@' changed from 7 to 0 so '@' can be escaped */
/* in usernames and passwords in publishing. */
7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,7, /* 5X PQRSTUVWXYZ[\]^_ */
0,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, /* 6x `abcdefghijklmno */
7,7,7,7,7,7,7,7,7,7,7,0,0,0,0,0, /* 7X pqrstuvwxyz{\}~ DEL */
0, };
/* decode % escaped hex codes into character values
*/
#define UNHEX(C) \
((C >= '0' && C <= '9') ? C - '0' : \
((C >= 'A' && C <= 'F') ? C - 'A' + 10 : \
((C >= 'a' && C <= 'f') ? C - 'a' + 10 : 0)))
#define IS_OK(C) (netCharType[((unsigned int) (C))] & (mask))
#define HEX_ESCAPE '%'
//----------------------------------------------------------------------------------------
NS_BASE char* nsEscape(const char * str, nsEscapeMask mask)
//----------------------------------------------------------------------------------------
{
if(!str)
return NULL;
return nsEscapeCount(str, (PRInt32)PL_strlen(str), mask, NULL);
}
//----------------------------------------------------------------------------------------
NS_BASE char* nsEscapeCount(const char * str, PRInt32 len, nsEscapeMask mask, PRInt32 * out_len)
//----------------------------------------------------------------------------------------
{
int32 i, extra = 0;
char *hexChars = "0123456789ABCDEF";
if(!str)
return(0);
register const unsigned char* src = (unsigned char *) str;
for (i = 0; i < len; i++)
{
if (!IS_OK(src[i]))
extra+=2; /* the escape, plus an extra byte for each nibble */
}
char* result = new char[len + extra + 1];
if (!result)
return(0);
register unsigned char* dst = (unsigned char *) result;
for (i = 0; i < len; i++)
{
unsigned char c = src[i];
if (IS_OK(c))
{
*dst++ = c;
}
else if (mask == url_XPAlphas && c == ' ')
{
*dst++ = '+'; /* convert spaces to pluses */
}
else
{
*dst++ = HEX_ESCAPE;
*dst++ = hexChars[c >> 4]; /* high nibble */
*dst++ = hexChars[c & 0x0f]; /* low nibble */
}
}
*dst = '\0'; /* tack on eos */
if(out_len)
*out_len = dst - (unsigned char *) result;
return result;
}
//----------------------------------------------------------------------------------------
NS_BASE char* nsUnescape(char * str)
//----------------------------------------------------------------------------------------
{
nsUnescapeCount(str);
return str;
}
//----------------------------------------------------------------------------------------
NS_BASE PRInt32 nsUnescapeCount(char * str)
//----------------------------------------------------------------------------------------
{
register char *src = str;
register char *dst = str;
while (*src)
if (*src != HEX_ESCAPE)
{
*dst++ = *src++;
}
else
{
src++; /* walk over escape */
if (*src)
{
*dst = UNHEX(*src) << 4;
src++;
}
if (*src)
{
*dst = (*dst + UNHEX(*src));
src++;
}
dst++;
}
*dst = 0;
return (int)(dst - str);
} /* NET_UnEscapeCnt */

View File

@@ -0,0 +1,801 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsFileSpec.h"
#include "nsFileStream.h"
#include "nsDebug.h"
#include "prtypes.h"
#include "plstr.h"
#include "plbase64.h"
#include "prmem.h"
#include <string.h>
#include <stdio.h>
//========================================================================================
NS_NAMESPACE nsFileSpecHelpers
//========================================================================================
{
enum
{ kMaxFilenameLength = 31 // should work on Macintosh, Unix, and Win32.
, kMaxAltDigitLength = 5
, kMaxCoreLeafNameLength = (kMaxFilenameLength - (kMaxAltDigitLength + 1))
};
NS_NAMESPACE_PROTOTYPE void LeafReplace(
char*& ioPath,
char inSeparator,
const char* inLeafName);
#ifndef XP_MAC
NS_NAMESPACE_PROTOTYPE void Canonify(char*& ioPath, PRBool inMakeDirs);
NS_NAMESPACE_PROTOTYPE void MakeAllDirectories(const char* inPath, int mode);
#endif
NS_NAMESPACE_PROTOTYPE char* GetLeaf(const char* inPath, char inSeparator); // allocated
NS_NAMESPACE_PROTOTYPE char* StringDup(const char* inString, int allocLength = 0);
NS_NAMESPACE_PROTOTYPE char* AllocCat(const char* inString1, const char* inString2);
NS_NAMESPACE_PROTOTYPE char* StringAssign(char*& ioString, const char* inOther);
NS_NAMESPACE_PROTOTYPE char* ReallocCat(char*& ioString, const char* inString1);
#ifdef XP_PC
NS_NAMESPACE_PROTOTYPE void NativeToUnix(char*& ioPath);
NS_NAMESPACE_PROTOTYPE void UnixToNative(char*& ioPath);
#endif
} NS_NAMESPACE_END
//----------------------------------------------------------------------------------------
nsresult ns_file_convert_result(PRInt32 nativeErr)
//----------------------------------------------------------------------------------------
{
return nativeErr ?
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES,((nativeErr)&0xFFFF))
: NS_OK;
}
//----------------------------------------------------------------------------------------
char* nsFileSpecHelpers::StringDup(
const char* inString,
int allocLength)
//----------------------------------------------------------------------------------------
{
if (!allocLength && inString)
allocLength = strlen(inString);
char* newPath = inString || allocLength ? new char[allocLength + 1] : nsnull;
if (!newPath)
return nsnull;
strcpy(newPath, inString);
return newPath;
} // nsFileSpecHelpers::StringDup
//----------------------------------------------------------------------------------------
char* nsFileSpecHelpers::AllocCat(
const char* inString1,
const char* inString2)
//----------------------------------------------------------------------------------------
{
if (!inString1)
return inString2 ? StringDup(inString2) : (char*)nsnull;
if (!inString2)
return StringDup(inString1);
char* outString = StringDup(inString1, strlen(inString1) + strlen(inString2));
if (outString)
strcat(outString, inString2);
return outString;
} // nsFileSpecHelpers::StringDup
//----------------------------------------------------------------------------------------
char* nsFileSpecHelpers::StringAssign(
char*& ioString,
const char* inString2)
//----------------------------------------------------------------------------------------
{
if (!inString2)
{
delete [] ioString;
ioString = (char*)nsnull;
return ioString;
}
if (!ioString || (strlen(inString2) > strlen(ioString)))
{
delete [] ioString;
ioString = StringDup(inString2);
return ioString;
}
strcpy(ioString, inString2);
return ioString;
} // nsFileSpecHelpers::StringAssign
//----------------------------------------------------------------------------------------
void nsFileSpecHelpers::LeafReplace(
char*& ioPath,
char inSeparator,
const char* inLeafName)
//----------------------------------------------------------------------------------------
{
// Find the existing leaf name
if (!ioPath)
return;
if (!inLeafName)
{
*ioPath = '\0';
return;
}
char* lastSeparator = strrchr(ioPath, inSeparator);
int oldLength = strlen(ioPath);
PRBool trailingSeparator = (lastSeparator + 1 == ioPath + oldLength);
if (trailingSeparator)
{
*lastSeparator = '\0';
lastSeparator = strrchr(ioPath, inSeparator);
}
if (lastSeparator)
lastSeparator++; // point at the trailing string
else
lastSeparator = ioPath; // the full monty
*lastSeparator = '\0'; // strip the current leaf name
int newLength = (lastSeparator - ioPath) + strlen(inLeafName) + int(trailingSeparator);
if (newLength > oldLength)
{
char* newPath = StringDup(ioPath, newLength + 1);
delete [] ioPath;
ioPath = newPath;
}
strcat(ioPath, inLeafName);
if (trailingSeparator)
{
// If the original ended in a slash, then the new one should, too.
char sepStr[2] = "/";
*sepStr = inSeparator;
strcat(ioPath, sepStr);
}
} // nsFileSpecHelpers::LeafReplace
//----------------------------------------------------------------------------------------
char* nsFileSpecHelpers::GetLeaf(const char* inPath, char inSeparator)
// Returns a pointer to an allocated string representing the leaf.
//----------------------------------------------------------------------------------------
{
if (!inPath)
return nsnull;
const char* lastSeparator = strrchr(inPath, inSeparator);
// If there was no separator, then return a copy of the caller's path.
if (!lastSeparator)
return StringDup(inPath);
// So there's at least one separator. What's just after it?
// If the separator was not the last character, return the trailing string.
const char* leafPointer = lastSeparator + 1;
if (*leafPointer)
return StringDup(leafPointer);
// So now, separator was the last character. Poke in a null instead.
*(char*)lastSeparator = '\0'; // Should use const_cast, but Unix has old compiler.
leafPointer = strrchr(inPath, inSeparator);
char* result = leafPointer ? StringDup(leafPointer++) : StringDup(inPath);
// Restore the poked null before returning.
*(char*)lastSeparator = inSeparator;
#ifdef XP_PC
// If it's a drive letter use the colon notation.
if (!leafPointer && strlen(result) == 2 && result[1] == '|')
result[1] = ':';
#endif
return result;
} // nsFileSpecHelpers::GetLeaf
#if defined(XP_UNIX) || defined(XP_PC)
//----------------------------------------------------------------------------------------
void nsFileSpecHelpers::MakeAllDirectories(const char* inPath, int mode)
// Make the path a valid one by creating all the intermediate directories. Does NOT
// make the leaf into a directory. This should be a unix path.
//----------------------------------------------------------------------------------------
{
if (!inPath)
return;
char* pathCopy = nsFileSpecHelpers::StringDup( inPath );
if (!pathCopy)
return;
const char kSeparator = '/'; // I repeat: this should be a unix-style path.
const int kSkipFirst = 1;
#ifdef XP_PC
// Either this is a relative path, or we ensure that it has
// a drive letter specifier.
NS_ASSERTION( pathCopy[0] != '/' || pathCopy[2] == '|', "No drive letter!" );
#endif
char* currentStart = pathCopy;
char* currentEnd = strchr(currentStart + kSkipFirst, kSeparator);
if (currentEnd)
{
*currentEnd = '\0';
nsFileSpec spec(nsFilePath(pathCopy, PR_FALSE));
do
{
// If the node doesn't exist, and it is not the initial node in a full path,
// then make a directory (We cannot make the initial (volume) node).
if (!spec.Exists() && *currentStart != kSeparator)
spec.CreateDirectory(mode);
if (!spec.Exists())
{
NS_ASSERTION(spec.Exists(), "Could not create the directory?");
break;
}
currentStart = ++currentEnd;
currentEnd = strchr(currentStart, kSeparator);
if (!currentEnd)
break;
spec += currentStart; // "lengthen" the path, adding the next node.
} while (currentEnd);
}
delete [] pathCopy;
} // nsFileSpecHelpers::MakeAllDirectories
#endif // XP_PC || XP_UNIX
//----------------------------------------------------------------------------------------
char* nsFileSpecHelpers::ReallocCat(char*& ioString, const char* inString1)
//----------------------------------------------------------------------------------------
{
char* newString = AllocCat(ioString, inString1);
delete [] ioString;
ioString = newString;
return ioString;
} // nsFileSpecHelpers::ReallocCat
#if defined(XP_PC)
#include "windows/nsFileSpecWin.cpp" // Windows-specific implementations
#elif defined(XP_MAC)
#include "nsFileSpecMac.cpp" // Macintosh-specific implementations
#elif defined(XP_UNIX)
#include "unix/nsFileSpecUnix.cpp" // Unix-specific implementations
#endif
//========================================================================================
// nsFileURL implementation
//========================================================================================
#ifndef XP_MAC
//----------------------------------------------------------------------------------------
nsFileURL::nsFileURL(const char* inString, PRBool inCreateDirs)
//----------------------------------------------------------------------------------------
: mURL(nsnull)
{
if (!inString)
return;
NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!");
// Make canonical and absolute.
nsFilePath path(inString + kFileURLPrefixLength, inCreateDirs);
*this = path;
} // nsFileURL::nsFileURL
#endif
//----------------------------------------------------------------------------------------
nsFileURL::nsFileURL(const nsFileURL& inOther)
//----------------------------------------------------------------------------------------
: mURL(nsFileSpecHelpers::StringDup(inOther.mURL))
#ifdef XP_MAC
, mFileSpec(inOther.GetFileSpec())
#endif
{
} // nsFileURL::nsFileURL
//----------------------------------------------------------------------------------------
nsFileURL::nsFileURL(const nsFilePath& inOther)
//----------------------------------------------------------------------------------------
: mURL(nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)inOther))
#ifdef XP_MAC
, mFileSpec(inOther.GetFileSpec())
#endif
{
} // nsFileURL::nsFileURL
//----------------------------------------------------------------------------------------
nsFileURL::nsFileURL(const nsFileSpec& inOther)
: mURL(nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)nsFilePath(inOther)))
#ifdef XP_MAC
, mFileSpec(inOther)
#endif
//----------------------------------------------------------------------------------------
{
} // nsFileURL::nsFileURL
//----------------------------------------------------------------------------------------
nsFileURL::~nsFileURL()
//----------------------------------------------------------------------------------------
{
delete [] mURL;
}
//----------------------------------------------------------------------------------------
void nsFileURL::operator = (const char* inString)
//----------------------------------------------------------------------------------------
{
nsFileSpecHelpers::StringAssign(mURL, inString);
NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!");
#ifdef XP_MAC
mFileSpec = inString + kFileURLPrefixLength;
#endif
} // nsFileURL::operator =
//----------------------------------------------------------------------------------------
void nsFileURL::operator = (const nsFileURL& inOther)
//----------------------------------------------------------------------------------------
{
mURL = nsFileSpecHelpers::StringAssign(mURL, inOther.mURL);
#ifdef XP_MAC
mFileSpec = inOther.GetFileSpec();
#endif
} // nsFileURL::operator =
//----------------------------------------------------------------------------------------
void nsFileURL::operator = (const nsFilePath& inOther)
//----------------------------------------------------------------------------------------
{
delete [] mURL;
mURL = nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)inOther);
#ifdef XP_MAC
mFileSpec = inOther.GetFileSpec();
#endif
} // nsFileURL::operator =
//----------------------------------------------------------------------------------------
void nsFileURL::operator = (const nsFileSpec& inOther)
//----------------------------------------------------------------------------------------
{
delete [] mURL;
mURL = nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)nsFilePath(inOther));
#ifdef XP_MAC
mFileSpec = inOther;
#endif
} // nsFileURL::operator =
#if DEBUG
//----------------------------------------------------------------------------------------
nsOutputStream& operator << (nsOutputStream& s, const nsFileURL& url)
//----------------------------------------------------------------------------------------
{
return (s << url.mURL);
}
#endif
//========================================================================================
// nsFilePath implementation
//========================================================================================
nsFilePath::nsFilePath(const nsFilePath& inPath)
: mPath(nsFileSpecHelpers::StringDup(inPath.mPath))
#ifdef XP_MAC
, mFileSpec(inPath.mFileSpec)
#endif
{
}
#ifndef XP_MAC
//----------------------------------------------------------------------------------------
nsFilePath::nsFilePath(const char* inString, PRBool inCreateDirs)
//----------------------------------------------------------------------------------------
: mPath(nsFileSpecHelpers::StringDup(inString))
{
NS_ASSERTION(strstr(inString, kFileURLPrefix) != inString, "URL passed as path");
#ifdef XP_PC
nsFileSpecHelpers::UnixToNative(mPath);
#endif
// Make canonical and absolute.
nsFileSpecHelpers::Canonify(mPath, inCreateDirs);
#ifdef XP_PC
NS_ASSERTION( mPath[1] == ':', "unexpected canonical path" );
nsFileSpecHelpers::NativeToUnix(mPath);
#endif
}
#endif
//----------------------------------------------------------------------------------------
nsFilePath::nsFilePath(const nsFileURL& inOther)
//----------------------------------------------------------------------------------------
: mPath(nsFileSpecHelpers::StringDup(inOther.mURL + kFileURLPrefixLength))
#ifdef XP_MAC
, mFileSpec(inOther.GetFileSpec())
#endif
{
}
#ifdef XP_UNIX
//----------------------------------------------------------------------------------------
nsFilePath::nsFilePath(const nsFileSpec& inOther)
//----------------------------------------------------------------------------------------
: mPath(nsFileSpecHelpers::StringDup(inOther.mPath))
{
}
#endif // XP_UNIX
//----------------------------------------------------------------------------------------
nsFilePath::~nsFilePath()
//----------------------------------------------------------------------------------------
{
delete [] mPath;
}
#ifdef XP_UNIX
//----------------------------------------------------------------------------------------
void nsFilePath::operator = (const nsFileSpec& inOther)
//----------------------------------------------------------------------------------------
{
mPath = nsFileSpecHelpers::StringAssign(mPath, inOther.mPath);
}
#endif // XP_UNIX
//----------------------------------------------------------------------------------------
void nsFilePath::operator = (const char* inString)
//----------------------------------------------------------------------------------------
{
NS_ASSERTION(strstr(inString, kFileURLPrefix) != inString, "URL passed as path");
#ifdef XP_MAC
mFileSpec = inString;
nsFileSpecHelpers::StringAssign(mPath, (const char*)nsFilePath(mFileSpec));
#else
#ifdef XP_PC
nsFileSpecHelpers::UnixToNative(mPath);
#endif
// Make canonical and absolute.
nsFileSpecHelpers::Canonify(mPath, PR_FALSE /* XXX? */);
#ifdef XP_PC
nsFileSpecHelpers::NativeToUnix(mPath);
#endif
#endif // XP_MAC
}
//----------------------------------------------------------------------------------------
void nsFilePath::operator = (const nsFileURL& inOther)
//----------------------------------------------------------------------------------------
{
nsFileSpecHelpers::StringAssign(mPath, (const char*)nsFilePath(inOther));
#ifdef XP_MAC
mFileSpec = inOther.GetFileSpec();
#endif
}
//========================================================================================
// nsFileSpec implementation
//========================================================================================
#ifndef XP_MAC
//----------------------------------------------------------------------------------------
nsFileSpec::nsFileSpec()
//----------------------------------------------------------------------------------------
: mPath(nsnull)
, mError(NS_OK)
{
}
#endif
//----------------------------------------------------------------------------------------
nsFileSpec::nsFileSpec(const nsPersistentFileDescriptor& inDescriptor)
//----------------------------------------------------------------------------------------
#ifndef XP_MAC
: mPath(nsnull)
#endif
{
*this = inDescriptor;
}
//----------------------------------------------------------------------------------------
nsFileSpec::nsFileSpec(const nsFileURL& inURL)
//----------------------------------------------------------------------------------------
#ifndef XP_MAC
: mPath(nsnull)
#endif
{
*this = nsFilePath(inURL); // convert to unix path first
}
//----------------------------------------------------------------------------------------
void nsFileSpec::MakeUnique(const char* inSuggestedLeafName)
//----------------------------------------------------------------------------------------
{
if (inSuggestedLeafName && *inSuggestedLeafName)
SetLeafName(inSuggestedLeafName);
MakeUnique();
} // nsFileSpec::MakeUnique
//----------------------------------------------------------------------------------------
void nsFileSpec::MakeUnique()
//----------------------------------------------------------------------------------------
{
if (!Exists())
return;
char* leafName = GetLeafName();
if (!leafName)
return;
char* lastDot = strrchr(leafName, '.');
char* suffix = "";
if (lastDot)
{
suffix = nsFileSpecHelpers::StringDup(lastDot); // include '.'
*lastDot = '\0'; // strip suffix and dot.
}
const int kMaxRootLength
= nsFileSpecHelpers::kMaxCoreLeafNameLength - strlen(suffix) - 1;
if (strlen(leafName) > kMaxRootLength)
leafName[kMaxRootLength] = '\0';
for (short index = 1; index < 1000 && Exists(); index++)
{
// start with "Picture-1.jpg" after "Picture.jpg" exists
char newName[nsFileSpecHelpers::kMaxFilenameLength + 1];
sprintf(newName, "%s-%d%s", leafName, index, suffix);
SetLeafName(newName);
}
if (*suffix)
delete [] suffix;
delete [] leafName;
} // nsFileSpec::MakeUnique
//----------------------------------------------------------------------------------------
void nsFileSpec::operator = (const nsFileURL& inURL)
//----------------------------------------------------------------------------------------
{
*this = nsFilePath(inURL); // convert to unix path first
}
//----------------------------------------------------------------------------------------
void nsFileSpec::operator = (const nsPersistentFileDescriptor& inDescriptor)
//----------------------------------------------------------------------------------------
{
void* data;
PRInt32 dataSize;
inDescriptor.GetData(data, dataSize);
#ifdef XP_MAC
char* decodedData = PL_Base64Decode((const char*)data, (int)dataSize, nsnull);
// Cast to an alias record and resolve.
AliasHandle aliasH = nsnull;
mError = NS_FILE_RESULT(PtrToHand(decodedData, &(Handle)aliasH, (dataSize * 3) / 4));
PR_Free(decodedData);
if (NS_SUCCEEDED(mError))
return; // not enough memory?
Boolean changed;
mError = NS_FILE_RESULT(::ResolveAlias(nsnull, aliasH, &mSpec, &changed));
DisposeHandle((Handle) aliasH);
#else
nsFileSpecHelpers::StringAssign(mPath, (char*)data);
mError = NS_OK;
#endif
}
//========================================================================================
// UNIX & WIN nsFileSpec implementation
//========================================================================================
#ifdef XP_UNIX
//----------------------------------------------------------------------------------------
nsFileSpec::nsFileSpec(const nsFilePath& inPath)
//----------------------------------------------------------------------------------------
: mPath(nsFileSpecHelpers::StringDup((const char*)inPath))
, mError(NS_OK)
{
}
#endif // XP_UNIX
#ifdef XP_UNIX
//----------------------------------------------------------------------------------------
void nsFileSpec::operator = (const nsFilePath& inPath)
//----------------------------------------------------------------------------------------
{
nsFileSpecHelpers::StringAssign(mPath, (const char*)inPath);
mError = NS_OK;
}
#endif //XP_UNIX
#if defined(XP_UNIX) || defined(XP_PC)
//----------------------------------------------------------------------------------------
nsFileSpec::nsFileSpec(const nsFileSpec& inSpec)
//----------------------------------------------------------------------------------------
: mPath(nsFileSpecHelpers::StringDup(inSpec.mPath))
, mError(NS_OK)
{
}
#endif //XP_UNIX
#if defined(XP_UNIX) || defined(XP_PC)
//----------------------------------------------------------------------------------------
nsFileSpec::nsFileSpec(const char* inString, PRBool inCreateDirs)
//----------------------------------------------------------------------------------------
: mPath(nsFileSpecHelpers::StringDup(inString))
, mError(NS_OK)
{
// Make canonical and absolute.
nsFileSpecHelpers::Canonify(mPath, inCreateDirs);
}
#endif //XP_UNIX,PC
//----------------------------------------------------------------------------------------
nsFileSpec::~nsFileSpec()
//----------------------------------------------------------------------------------------
{
#ifndef XP_MAC
delete [] mPath;
#endif
}
#if defined(XP_UNIX) || defined(XP_PC)
//----------------------------------------------------------------------------------------
void nsFileSpec::operator = (const nsFileSpec& inSpec)
//----------------------------------------------------------------------------------------
{
mPath = nsFileSpecHelpers::StringAssign(mPath, inSpec.mPath);
mError = inSpec.Error();
}
#endif //XP_UNIX
#if defined(XP_UNIX) || defined(XP_PC)
//----------------------------------------------------------------------------------------
void nsFileSpec::operator = (const char* inString)
//----------------------------------------------------------------------------------------
{
mPath = nsFileSpecHelpers::StringAssign(mPath, inString);
// Make canonical and absolute.
nsFileSpecHelpers::Canonify(mPath, PR_TRUE /* XXX? */);
mError = NS_OK;
}
#endif //XP_UNIX
#if DEBUG
#if (defined(XP_UNIX) || defined(XP_PC))
//----------------------------------------------------------------------------------------
nsOutputStream& operator << (nsOutputStream& s, const nsFileSpec& spec)
//----------------------------------------------------------------------------------------
{
return (s << (const char*)spec.mPath);
}
#endif // DEBUG && XP_UNIX
#endif
//----------------------------------------------------------------------------------------
nsFileSpec nsFileSpec::operator + (const char* inRelativePath) const
//----------------------------------------------------------------------------------------
{
nsFileSpec result = *this;
result += inRelativePath;
return result;
} // nsFileSpec::operator +
//========================================================================================
// class nsPersistentFileDescriptor
//========================================================================================
//----------------------------------------------------------------------------------------
nsPersistentFileDescriptor::nsPersistentFileDescriptor(const nsPersistentFileDescriptor& inDesc)
//----------------------------------------------------------------------------------------
: mDescriptorString(nsFileSpecHelpers::StringDup(inDesc.mDescriptorString))
{
} // nsPersistentFileDescriptor::nsPersistentFileDescriptor
//----------------------------------------------------------------------------------------
void nsPersistentFileDescriptor::operator = (const nsPersistentFileDescriptor& inDesc)
//----------------------------------------------------------------------------------------
{
nsFileSpecHelpers::StringAssign(mDescriptorString, inDesc.mDescriptorString);
} // nsPersistentFileDescriptor::operator =
//----------------------------------------------------------------------------------------
nsPersistentFileDescriptor::nsPersistentFileDescriptor(const nsFileSpec& inSpec)
//----------------------------------------------------------------------------------------
: mDescriptorString(nsnull)
{
*this = inSpec;
} // nsPersistentFileDescriptor::nsPersistentFileDescriptor
//----------------------------------------------------------------------------------------
void nsPersistentFileDescriptor::operator = (const nsFileSpec& inSpec)
//----------------------------------------------------------------------------------------
{
#ifdef XP_MAC
if (inSpec.Error())
return;
AliasHandle aliasH;
OSErr err = NewAlias(nil, inSpec.operator const FSSpec* const (), &aliasH);
if (err != noErr)
return;
PRUint32 bytes = GetHandleSize((Handle) aliasH);
HLock((Handle) aliasH);
char* buf = PL_Base64Encode((const char*)*aliasH, bytes, nsnull);
DisposeHandle((Handle) aliasH);
nsFileSpecHelpers::StringAssign(mDescriptorString, buf);
PR_Free(buf);
#else
nsFileSpecHelpers::StringAssign(mDescriptorString, inSpec);
#endif // XP_MAC
} // nsPersistentFileDescriptor::operator =
//----------------------------------------------------------------------------------------
nsPersistentFileDescriptor::~nsPersistentFileDescriptor()
//----------------------------------------------------------------------------------------
{
delete [] mDescriptorString;
} // nsPersistentFileDescriptor::~nsPersistentFileDescriptor
//----------------------------------------------------------------------------------------
void nsPersistentFileDescriptor::GetData(void*& outData, PRInt32& outSize) const
//----------------------------------------------------------------------------------------
{
outSize = PL_strlen(mDescriptorString);
outData = mDescriptorString;
}
//----------------------------------------------------------------------------------------
void nsPersistentFileDescriptor::SetData(const void* inData, PRInt32 inSize)
//----------------------------------------------------------------------------------------
{
delete [] mDescriptorString;
mDescriptorString = new char[1 + inSize];
if (!mDescriptorString)
return;
memcpy(mDescriptorString, inData, inSize);
mDescriptorString[inSize] = '\0';
}
#define MAX_PERSISTENT_DATA_SIZE 1000
//----------------------------------------------------------------------------------------
nsInputStream& operator >> (nsInputStream& s, nsPersistentFileDescriptor& d)
// reads the data from a file
//----------------------------------------------------------------------------------------
{
char bigBuffer[MAX_PERSISTENT_DATA_SIZE + 1];
// The first 8 bytes of the data should be a hex version of the data size to follow.
PRInt32 bytesRead = 8;
bytesRead = s.read(bigBuffer, bytesRead);
if (bytesRead != 8)
return (nsInputFileStream&)s;
bigBuffer[8] = '\0';
sscanf(bigBuffer, "%lx", &bytesRead);
if (bytesRead > MAX_PERSISTENT_DATA_SIZE)
return (nsInputFileStream&)s; // preposterous.
// Now we know how many bytes to read, do it.
s.read(bigBuffer, bytesRead);
d.SetData(bigBuffer, bytesRead);
return (nsInputFileStream&)s;
}
//----------------------------------------------------------------------------------------
nsOutputStream& operator << (nsOutputStream& s, const nsPersistentFileDescriptor& d)
// writes the data to a file
//----------------------------------------------------------------------------------------
{
char littleBuf[9];
PRInt32 dataSize;
void* data;
d.GetData(data, dataSize);
// First write (in hex) the length of the data to follow. Exactly 8 bytes
sprintf(littleBuf, "%0.8x", dataSize);
s << littleBuf;
// Now write the data itself
s << d.mDescriptorString;
return s;
}

View File

@@ -0,0 +1,203 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
// First checked in on 98/12/08 by John R. McMullen.
// Since nsFileStream.h is entirely templates, common code (such as open())
// which does not actually depend on the charT, can be placed here.
#include "nsFileStream.h"
#include <string.h>
#include <stdio.h>
//========================================================================================
// nsInputStream
//========================================================================================
//----------------------------------------------------------------------------------------
nsInputStream::~nsInputStream()
//----------------------------------------------------------------------------------------
{
mInputStream->Close();
}
//----------------------------------------------------------------------------------------
char nsInputStream::get()
//----------------------------------------------------------------------------------------
{
char c;
read(&c, sizeof(c));
return c;
}
//----------------------------------------------------------------------------------------
static void TidyEndOfLine(char*& cp)
// Assumes that cp is pointing at \n or \r. Nulls out the character, checks for
// a second terminator (of the opposite persuasion), and returns cp pointing past the
// entire eol construct (one or two characters).
//----------------------------------------------------------------------------------------
{
char ch = *cp;
*cp++ = '\0'; // terminate at the newline, then skip past it
if ((ch == '\n' && *cp == '\r') || (ch == '\r' && *cp == '\n'))
cp++; // possibly a pair.
}
//----------------------------------------------------------------------------------------
nsInputStream& nsInputStream::operator >> (char& c)
//----------------------------------------------------------------------------------------
{
c = get();
return *this;
}
//========================================================================================
// nsOutputStream
//========================================================================================
//----------------------------------------------------------------------------------------
nsOutputStream::~nsOutputStream()
//----------------------------------------------------------------------------------------
{
mOutputStream->Close();
}
//----------------------------------------------------------------------------------------
void nsOutputStream::put(char c)
//----------------------------------------------------------------------------------------
{
write(&c, sizeof(c));
}
//----------------------------------------------------------------------------------------
void nsOutputStream::flush()
//----------------------------------------------------------------------------------------
{
}
//----------------------------------------------------------------------------------------
nsOutputStream& nsOutputStream::operator << (char c)
//----------------------------------------------------------------------------------------
{
put(c);
return *this;
}
//----------------------------------------------------------------------------------------
nsOutputStream& nsOutputStream::operator << (const char* s)
//----------------------------------------------------------------------------------------
{
write(s, strlen(s));
return *this;
}
//----------------------------------------------------------------------------------------
nsOutputStream& nsOutputStream::operator << (short val)
//----------------------------------------------------------------------------------------
{
char buf[30];
sprintf(buf, "%d", val);
return (*this << buf);
}
//----------------------------------------------------------------------------------------
nsOutputStream& nsOutputStream::operator << (unsigned short val)
//----------------------------------------------------------------------------------------
{
char buf[30];
sprintf(buf, "%ud", val);
return (*this << buf);
}
//----------------------------------------------------------------------------------------
nsOutputStream& nsOutputStream::operator << (long val)
//----------------------------------------------------------------------------------------
{
char buf[30];
sprintf(buf, "%ld", val);
return (*this << buf);
}
//----------------------------------------------------------------------------------------
nsOutputStream& nsOutputStream::operator << (unsigned long val)
//----------------------------------------------------------------------------------------
{
char buf[30];
sprintf(buf, "%uld", val);
return (*this << buf);
}
//========================================================================================
// nsInputFileStream
//========================================================================================
//----------------------------------------------------------------------------------------
PRBool nsInputFileStream::readline(char* s, PRInt32 n)
// This will truncate if the buffer is too small. Result will always be null-terminated.
//----------------------------------------------------------------------------------------
{
PRBool bufferLargeEnough = PR_TRUE; // result
if (!s || !n)
return PR_TRUE;
PRIntn position = tell();
if (position < 0)
return PR_FALSE;
PRInt32 bytesRead = read(s, n - 1);
if (failed())
return PR_FALSE;
s[bytesRead] = '\0'; // always terminate at the end of the buffer
char* tp = strpbrk(s, "\n\r");
if (tp)
{
TidyEndOfLine(tp);
bytesRead = (tp - s);
}
else if (!eof())
bufferLargeEnough = PR_FALSE;
position += bytesRead;
seek(position);
return bufferLargeEnough;
} // nsInputStream::readline
//========================================================================================
// nsOutputFileStream
//========================================================================================
//----------------------------------------------------------------------------------------
void nsOutputFileStream::flush()
//----------------------------------------------------------------------------------------
{
if (mFileOutputStream)
mFileOutputStream->Flush();
}
//========================================================================================
// Manipulators
//========================================================================================
//----------------------------------------------------------------------------------------
nsOutputStream& nsEndl(nsOutputStream& os)
//----------------------------------------------------------------------------------------
{
os.put('\n');
os.flush();
return os;
} // nsEndl

View File

@@ -0,0 +1,22 @@
#include "nscore.h"
#include "nsCaretProperties.h"
//-----------------------------------------------------------------------------
nsCaretProperties::nsCaretProperties()
: mCaretWidth(eDefaultCaretWidth)
, mBlinkRate(eDefaulBlinkRate)
{
// in your platform-specific class, get data from the OS in your constructor
}
//-----------------------------------------------------------------------------
nsCaretProperties* NewCaretProperties()
{
return new nsCaretProperties();
}

View File

@@ -0,0 +1,51 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsIArena_h___
#define nsIArena_h___
#include "nscore.h"
#include "nsISupports.h"
#define NS_MIN_ARENA_BLOCK_SIZE 64
#define NS_DEFAULT_ARENA_BLOCK_SIZE 4096
/// Interface IID for nsIArena
#define NS_IARENA_IID \
{ 0xa24fdad0, 0x93b4, 0x11d1, \
{0x89, 0x5b, 0x00, 0x60, 0x08, 0x91, 0x1b, 0x81} }
/** Interface to a memory arena abstraction. Arena's use large blocks
* of memory to allocate smaller objects. Arena's provide no free
* operator; instead, all of the objects in the arena are deallocated
* by deallocating the arena (e.g. when it's reference count goes to
* zero)
*/
class nsIArena : public nsISupports {
public:
virtual void* Alloc(PRInt32 size) = 0;
};
/**
* Create a new arena using the desired block size for allocating the
* underlying memory blocks. The underlying memory blocks are allocated
* using the PR heap.
*/
extern NS_BASE nsresult NS_NewHeapArena(nsIArena** aInstancePtrResult,
PRInt32 aArenaBlockSize = 0);
#endif /* nsIArena_h___ */

View File

@@ -0,0 +1,79 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsIAtom_h___
#define nsIAtom_h___
#include "nscore.h"
#include "nsISupports.h"
class nsString;
class nsISizeOfHandler;
#define NS_IATOM_IID \
{ 0x3d1b15b0, 0x93b4, 0x11d1, \
{0x89, 0x5b, 0x00, 0x60, 0x08, 0x91, 0x1b, 0x81} }
/**
* A globally unique identfier. nsIAtom's can be compared for
* equality by using operator '=='. These objects are reference
* counted like other nsISupports objects. When you are done with
* the atom, NS_RELEASE it.
*/
class nsIAtom : public nsISupports {
public:
static const nsIID& IID() { static nsIID iid = NS_IATOM_IID; return iid; }
/**
* Translate the unicode string into the stringbuf.
*/
virtual void ToString(nsString& aString) const = 0;
/**
* Return a pointer to a zero terminated unicode string.
*/
virtual const PRUnichar* GetUnicode() const = 0;
/**
* Add the size, in bytes, of the atom to the handler.
*/
NS_IMETHOD SizeOf(nsISizeOfHandler* aHandler) const = 0;
};
/**
* Find an atom that matches the given iso-latin1 C string. The
* C string is translated into it's unicode equivalent.
*/
extern NS_BASE nsIAtom* NS_NewAtom(const char* isolatin1);
/**
* Find an atom that matches the given unicode string. The string is assumed
* to be zero terminated.
*/
extern NS_BASE nsIAtom* NS_NewAtom(const PRUnichar* unicode);
/**
* Find an atom that matches the given string.
*/
extern NS_BASE nsIAtom* NS_NewAtom(const nsString& aString);
/**
* Return a count of the total number of atoms currently
* alive in the system.
*/
extern NS_BASE nsrefcnt NS_GetNumberOfAtoms(void);
#endif /* nsIAtom_h___ */

View File

@@ -0,0 +1,58 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsIBaseStream_h___
#define nsIBaseStream_h___
#include "nscore.h"
#include "nsISupports.h"
/* 6ccb17a0-e95e-11d1-beae-00805f8a66dc */
#define NS_IBASESTREAM_IID \
{ 0x6ccb17a0, 0xe95e, 0x11d1, \
{0xbe, 0xae, 0x00, 0x80, 0x5f, 0x8a, 0x66, 0xdc} }
/** Abstract stream */
class nsIBaseStream : public nsISupports {
public:
static const nsIID& IID() { static nsIID iid = NS_IBASESTREAM_IID; return iid; }
/** Close the stream. */
NS_IMETHOD
Close(void) = 0;
};
/** Error codes */
//@{
/// End of file
#define NS_BASE_STREAM_EOF NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_BASE, 1)
/// Stream closed
#define NS_BASE_STREAM_CLOSED NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_BASE, 2)
/// Error from the operating system
#define NS_BASE_STREAM_OSERROR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_BASE, 3)
/// Illegal arguments
#define NS_BASE_STREAM_ILLEGAL_ARGS NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_BASE, 4)
/// For unichar streams
#define NS_BASE_STREAM_NO_CONVERTER NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_BASE, 5)
/// For unichar streams
#define NS_BASE_STREAM_BAD_CONVERSION NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_BASE, 6)
//@}
#endif /* nsInputStream_h___ */

View File

@@ -0,0 +1,57 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsIByteBuffer_h___
#define nsIByteBuffer_h___
#include "nscore.h"
#include "nsISupports.h"
class nsIInputStream;
#define NS_IBYTE_BUFFER_IID \
{ 0xe4a6e4b0, 0x93b4, 0x11d1, \
{0x89, 0x5b, 0x00, 0x60, 0x08, 0x91, 0x1b, 0x81} }
/** Interface to a buffer that holds bytes */
class nsIByteBuffer : public nsISupports {
public:
/** @return length of buffer, i.e. how many bytes are currently in it. */
virtual PRUint32 GetLength(void) const = 0;
/** @return number of bytes allocated in the buffer */
virtual PRUint32 GetBufferSize(void) const = 0;
/** @return the buffer */
virtual char* GetBuffer(void) const = 0;
/** Grow buffer to aNewSize bytes. */
virtual PRBool Grow(PRUint32 aNewSize) = 0;
/** Fill the buffer with data from aStream. Don't grow the buffer, only
* read until length of buffer equals buffer size. */
virtual PRInt32 Fill(nsresult* aErrorCode, nsIInputStream* aStream,
PRUint32 aKeep) = 0;
};
/** Create a new byte buffer using the given buffer size. */
extern NS_BASE nsresult NS_NewByteBuffer(nsIByteBuffer** aInstancePtrResult,
nsISupports* aOuter,
PRUint32 aBufferSize = 0);
#endif /* nsIByteBuffer_h___ */

View File

@@ -0,0 +1,451 @@
#include "nsIFileStream.h"
#include "nsFileSpec.h"
#include "prerror.h"
#ifdef XP_MAC
#include "pprio.h" // To get PR_ImportFile
#else
#include "prio.h"
#endif
#ifdef XP_MAC
#include <Errors.h>
#include <iostream>
#endif
//========================================================================================
class FileImpl
: public nsIOutputStream
, public nsIInputStream
, public nsIFileOutputStream
, public nsIFileInputStream
, public nsIFile
//========================================================================================
{
public:
FileImpl(PRFileDesc* inDesc)
: mFileDesc(inDesc)
, mFailed(PR_FALSE)
, mEOF(PR_FALSE)
, mLength(-1)
{
NS_INIT_REFCNT();
}
FileImpl(
const nsFileSpec& inFile,
int nsprMode,
PRIntn accessMode)
: mFileDesc(nsnull)
, mFailed(PR_FALSE)
, mEOF(PR_FALSE)
{
NS_INIT_REFCNT();
Open(inFile, nsprMode, accessMode);
}
virtual ~FileImpl()
{
Close();
}
// nsISupports interface
NS_DECL_ISUPPORTS
// nsIFile interface
NS_IMETHOD Open(
const nsFileSpec& inFile,
int nsprMode,
PRIntn accessMode);
NS_IMETHOD Close();
NS_IMETHOD Seek(PRSeekWhence whence, PRInt32 offset);
NS_IMETHOD GetIsOpen(PRBool* outOpen)
{
*outOpen = (mFileDesc != nsnull);
return NS_OK;
}
NS_IMETHOD Tell(PRIntn* outWhere);
// nsIInputStream interface
NS_IMETHOD GetLength(PRUint32 *aLength)
{
NS_PRECONDITION(aLength != nsnull, "null ptr");
if (!aLength)
return NS_ERROR_NULL_POINTER;
if (mLength < 0)
return NS_FILE_RESULT(NS_ERROR_UNEXPECTED);
*aLength = mLength;
return NS_OK;
}
NS_IMETHOD Read(char* aBuf,
PRUint32 aOffset,
PRUint32 aCount,
PRUint32 *aReadCount)
{
NS_PRECONDITION(aBuf != nsnull, "null ptr");
if (!aBuf)
return NS_ERROR_NULL_POINTER;
NS_PRECONDITION(aReadCount != nsnull, "null ptr");
if (!aReadCount)
return NS_ERROR_NULL_POINTER;
if (!mFileDesc)
return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
if (mFailed)
return NS_ERROR_FAILURE;
if (aOffset)
PR_Seek(mFileDesc, aOffset, PR_SEEK_CUR);
PRInt32 bytesRead = PR_Read(mFileDesc, aBuf, aCount);
if (bytesRead < 0)
{
*aReadCount = 0;
mFailed = PR_TRUE;
return NS_FILE_RESULT(PR_GetError());
}
*aReadCount = bytesRead;
return NS_OK;
}
// nsIOutputStream interface
NS_IMETHOD Write(const char* aBuf,
PRUint32 aOffset,
PRUint32 aCount,
PRUint32 *aWriteCount)
{
NS_PRECONDITION(aBuf != nsnull, "null ptr");
NS_PRECONDITION(aWriteCount != nsnull, "null ptr");
#ifdef XP_MAC
// Calling PR_Write on stdout is sure suicide.
if (mFileDesc == PR_STDOUT || mFileDesc == PR_STDERR)
{
cout.write(aBuf, aCount);
*aWriteCount = aCount;
return NS_OK;
}
#endif
if (!mFileDesc)
return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
if (mFailed)
return NS_ERROR_FAILURE;
if (aOffset)
PR_Seek(mFileDesc, aOffset, PR_SEEK_CUR);
PRInt32 bytesWrit = PR_Write(mFileDesc, aBuf, aCount);
if (bytesWrit != aCount)
{
mFailed = PR_TRUE;
*aWriteCount = 0;
return NS_FILE_RESULT(PR_GetError());
}
*aWriteCount = bytesWrit;
return NS_OK;
}
NS_IMETHOD Flush();
protected:
PRFileDesc* mFileDesc;
int mNSPRMode;
PRBool mFailed;
PRBool mEOF;
PRInt32 mLength;
}; // class FileImpl
#define SAY_I_IMPLEMENT(classname) \
if (aIID.Equals(classname::IID())) \
{ \
*aInstancePtr = (void*)((classname*)this); \
NS_ADDREF_THIS(); \
return NS_OK; \
}
NS_IMPL_RELEASE(FileImpl)
NS_IMPL_ADDREF(FileImpl)
//----------------------------------------------------------------------------------------
NS_IMETHODIMP FileImpl::QueryInterface(REFNSIID aIID, void** aInstancePtr)
//----------------------------------------------------------------------------------------
{
if (!aInstancePtr)
return NS_ERROR_NULL_POINTER;
*aInstancePtr = nsnull;
SAY_I_IMPLEMENT(nsIFile)
SAY_I_IMPLEMENT(nsIOutputStream)
SAY_I_IMPLEMENT(nsIInputStream)
SAY_I_IMPLEMENT(nsIFileInputStream)
SAY_I_IMPLEMENT(nsIFileOutputStream)
// Note that we derive from two copies of nsIBaseStream (and hence
// of nsISupports), one through
// nsIOutputStream, the other through nsIInputStream. Resolve this
// by giving them a specific one
if (aIID.Equals(((nsIBaseStream*)(nsIOutputStream*)this)->IID()))
{
*aInstancePtr = (void*)((nsIBaseStream*)(nsIOutputStream*)this);
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(((nsISupports*)(nsIOutputStream*)this)->IID()))
{
*aInstancePtr = (void*)((nsISupports*)(nsIOutputStream*)this);
NS_ADDREF_THIS();
return NS_OK;
}
return NS_NOINTERFACE;
} // FileImpl::QueryInterface
//----------------------------------------------------------------------------------------
NS_IMETHODIMP FileImpl::Open(
const nsFileSpec& inFile,
int nsprMode,
PRIntn accessMode)
//----------------------------------------------------------------------------------------
{
if (mFileDesc)
if ((nsprMode & mNSPRMode) == nsprMode)
return NS_OK;
else
return NS_FILE_RESULT(PR_ILLEGAL_ACCESS_ERROR);
const int nspr_modes[]={
PR_WRONLY | PR_CREATE_FILE,
PR_WRONLY | PR_CREATE_FILE | PR_APPEND,
PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
PR_RDONLY,
PR_RDONLY | PR_APPEND,
PR_RDWR | PR_CREATE_FILE,
PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE,
// "wb",
// "ab",
// "wb",
// "rb",
// "r+b",
// "w+b",
0 };
const int* currentLegalMode = nspr_modes;
while (*currentLegalMode && nsprMode != *currentLegalMode)
++currentLegalMode;
if (!*currentLegalMode)
return NS_FILE_RESULT(PR_ILLEGAL_ACCESS_ERROR);
#ifdef XP_MAC
// Use the file spec to open the file, because one path can be common to
// several files on the Macintosh (you can have several volumes with the
// same name, see).
mFileDesc = 0;
if (inFile.Error() != noErr)
return NS_FILE_RESULT(inFile.Error());
OSErr err = noErr;
#if DEBUG
const OSType kCreator = 'CWIE';
#else
const OSType kCreator = 'MOSS';
#endif
// Resolve the alias to the original file.
nsFileSpec original = inFile;
PRBool ignoredResult;
original.ResolveAlias(ignoredResult);
const FSSpec& spec = original.operator const FSSpec&();
if (nsprMode & PR_CREATE_FILE)
err = FSpCreate(&spec, kCreator, 'TEXT', 0);
if (err == dupFNErr)
err = noErr;
if (err != noErr)
return NS_FILE_RESULT(err);
SInt8 perm;
if (nsprMode & PR_RDWR)
perm = fsRdWrPerm;
else if (nsprMode & PR_WRONLY)
perm = fsWrPerm;
else
perm = fsRdPerm;
short refnum;
err = FSpOpenDF(&spec, perm, &refnum);
if (err == noErr && (nsprMode & PR_TRUNCATE))
err = SetEOF(refnum, 0);
if (err == noErr && (nsprMode & PR_APPEND))
err = SetFPos(refnum, fsFromLEOF, 0);
if (err != noErr)
return NS_FILE_RESULT(err);
if ((mFileDesc = PR_ImportFile(refnum)) == 0)
return NS_FILE_RESULT(PR_GetError());
#else
// Platforms other than Macintosh...
// Another bug in NSPR: Mac PR_Open assumes a unix style path, but Win PR_Open assumes
// a windows path.
if ((mFileDesc = PR_Open((const char*)nsFileSpec(inFile), nsprMode, accessMode)) == 0)
return NS_FILE_RESULT(PR_GetError());
#endif
mNSPRMode = nsprMode;
mLength = PR_Available(mFileDesc);
return NS_OK;
} // FileImpl::Open
//----------------------------------------------------------------------------------------
NS_IMETHODIMP FileImpl::Seek(PRSeekWhence whence, PRInt32 offset)
//----------------------------------------------------------------------------------------
{
if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR || !mFileDesc)
return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
mFailed = PR_FALSE; // reset on a seek.
mEOF = PR_FALSE; // reset on a seek.
PRInt32 position = PR_Seek(mFileDesc, 0, PR_SEEK_CUR);
PRInt32 available = PR_Available(mFileDesc);
PRInt32 fileSize = position + available;
PRInt32 newPosition;
switch (whence)
{
case PR_SEEK_CUR: newPosition = position + offset; break;
case PR_SEEK_SET: newPosition = offset; break;
case PR_SEEK_END: newPosition = fileSize + offset; break;
}
if (newPosition < 0)
{
newPosition = 0;
mFailed = PR_TRUE;
}
else if (newPosition >= fileSize)
{
newPosition = fileSize;
mEOF = PR_TRUE;
}
if (PR_Seek(mFileDesc, newPosition, PR_SEEK_SET) < 0)
mFailed = PR_TRUE;
return NS_OK;
} // FileImpl::Seek
//----------------------------------------------------------------------------------------
NS_IMETHODIMP FileImpl::Tell(PRIntn* outWhere)
//----------------------------------------------------------------------------------------
{
if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR || !mFileDesc)
return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
*outWhere = PR_Seek(mFileDesc, 0, PR_SEEK_CUR);
return NS_OK;
} // FileImpl::Tell
//----------------------------------------------------------------------------------------
NS_IMETHODIMP FileImpl::Close()
//----------------------------------------------------------------------------------------
{
if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR || !mFileDesc)
return NS_OK;
if (PR_Close(mFileDesc) == PR_SUCCESS)
mFileDesc = 0;
else
return NS_FILE_RESULT(PR_GetError());
return NS_OK;
} // FileImpl::close
//----------------------------------------------------------------------------------------
NS_IMETHODIMP FileImpl::Flush()
//----------------------------------------------------------------------------------------
{
#ifdef XP_MAC
if (mFileDesc == PR_STDOUT || mFileDesc == PR_STDERR)
{
cout.flush();
return NS_OK;
}
#endif
if (!mFileDesc)
return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
PRBool itFailed = PR_Sync(mFileDesc) != PR_SUCCESS;
#ifdef XP_MAC
// On unix, it seems to fail always.
if (itFailed)
mFailed = PR_TRUE;
#endif
return NS_OK;
} // FileImpl::flush
//----------------------------------------------------------------------------------------
NS_BASE nsresult NS_NewTypicalInputFileStream(
nsISupports** aResult,
const nsFileSpec& inFile
/*Default nsprMode == PR_RDONLY*/
/*Default accessmode = 0700 (octal)*/)
// Factory method to get an nsInputStream from a file, using most common options
//----------------------------------------------------------------------------------------
{
return NS_NewIOFileStream(aResult, inFile, PR_RDONLY, 0700);
}
//----------------------------------------------------------------------------------------
NS_BASE nsresult NS_NewOutputConsoleStream(
nsISupports** aResult)
// Factory method to get an nsOutputStream to the console.
//----------------------------------------------------------------------------------------
{
NS_PRECONDITION(aResult != nsnull, "null ptr");
if (! aResult)
return NS_ERROR_NULL_POINTER;
FileImpl* stream = new FileImpl(PR_STDOUT);
if (! stream)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(stream);
*aResult = (nsISupports*)(void*)stream;
return NS_OK;
}
//----------------------------------------------------------------------------------------
NS_BASE nsresult NS_NewTypicalOutputFileStream(
nsISupports** aResult,
const nsFileSpec& inFile
/*default nsprMode= (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE)*/
/*Default accessMode= 0700 (octal)*/)
// Factory method to get an nsOutputStream to a file - most common case.
//----------------------------------------------------------------------------------------
{
return NS_NewIOFileStream(
aResult,
inFile,
(PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE),
0700);
}
//----------------------------------------------------------------------------------------
NS_BASE nsresult NS_NewIOFileStream(
nsISupports** aResult,
const nsFileSpec& inFile,
PRInt32 nsprMode /*default = (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE)*/,
PRInt32 accessMode /*Default = 0700 (octal)*/)
// Factory method to get an object that implements both nsIInputStream
// and nsIOutputStream, associated with a file.
//----------------------------------------------------------------------------------------
{
NS_PRECONDITION(aResult != nsnull, "null ptr");
if (!aResult)
return NS_ERROR_NULL_POINTER;
FileImpl* stream = new FileImpl(inFile, nsprMode, accessMode);
if (! stream)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(stream);
*aResult = (nsISupports*)(void*)stream;
return NS_OK;
}
//----------------------------------------------------------------------------------------
NS_BASE nsresult NS_NewTypicalIOFileStream(
nsISupports** aResult,
const nsFileSpec& inFile
/*default nsprMode= (PR_RDWR | PR_CREATE_FILE)*/
/*Default accessMode= 0700 (octal)*/)
// Factory method to get an object that implements both nsIInputStream
// and nsIOutputStream, associated with a single file.
//----------------------------------------------------------------------------------------
{
return NS_NewIOFileStream(
aResult,
inFile,
(PR_RDWR | PR_CREATE_FILE),
0700);
}

View File

@@ -0,0 +1,56 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsIInputStream_h___
#define nsIInputStream_h___
#include "nsIBaseStream.h"
#define NS_IINPUTSTREAM_IID \
{ 0x022396f0, 0x93b5, 0x11d1, \
{0x89, 0x5b, 0x00, 0x60, 0x08, 0x91, 0x1b, 0x81} }
/** Abstract byte input stream */
class nsIInputStream : public nsIBaseStream {
public:
static const nsIID& IID() { static nsIID iid = NS_IINPUTSTREAM_IID; return iid; }
/** Return the number of bytes in the stream
* @param aLength out parameter to hold the length
* of the stream. if an error occurs, the length
* will be undefined
* @return error status
*/
NS_IMETHOD
GetLength(PRUint32 *aLength) = 0;
/** Read data from the stream.
* @param aErrorCode the error code if an error occurs
* @param aBuf the buffer into which the data is read
* @param aOffset the start offset of the data
* @param aCount the maximum number of bytes to read
* @param aReadCount out parameter to hold the number of
* bytes read, eof if 0. if an error occurs, the
* read count will be undefined
* @return error status
*/
NS_IMETHOD
Read(char* aBuf, PRUint32 aOffset, PRUint32 aCount, PRUint32 *aReadCount) = 0;
};
#endif /* nsInputStream_h___ */

View File

@@ -0,0 +1,48 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsIOutputStream_h___
#define nsIOutputStream_h___
#include "nsIBaseStream.h"
/* 7f13b870-e95f-11d1-beae-00805f8a66dc */
#define NS_IOUTPUTSTREAM_IID \
{ 0x7f13b870, 0xe95f, 0x11d1, \
{0xbe, 0xae, 0x00, 0x80, 0x5f, 0x8a, 0x66, 0xdc} }
/** Abstract byte output stream */
class nsIOutputStream : public nsIBaseStream {
public:
static const nsIID& IID() { static nsIID iid = NS_IOUTPUTSTREAM_IID; return iid; }
/** Write data into the stream.
* @param aBuf the buffer into which the data is read
* @param aOffset the start offset of the data
* @param aCount the maximum number of bytes to read
* @param aWriteCount out parameter to hold the number of
* bytes written. if an error occurs, the writecount
* is undefined
* @return error status
*/
NS_IMETHOD
Write(const char* aBuf, PRUint32 aOffset, PRUint32 aCount, PRUint32 *aWriteCount) = 0;
};
#endif /* nsOutputStream_h___ */

View File

@@ -0,0 +1,94 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsITimer_h___
#define nsITimer_h___
#include "nscore.h"
#include "nsISupports.h"
class nsITimer;
class nsITimerCallback;
// Implementations of nsITimer should be written such that there are no limitations
// on what can be called by the TimerCallbackFunc. On platforms like the Macintosh this
// means that callback functions must be called from the main event loop NOT from
// an interrupt.
/// Signature of timer callback function
typedef void
(*nsTimerCallbackFunc) (nsITimer *aTimer, void *aClosure);
/// Interface IID for nsITimer
#define NS_ITIMER_IID \
{ 0x497eed20, 0xb740, 0x11d1, \
{ 0x9b, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
/**
* Timer class, used to invoke a function or method after a fixed
* millisecond interval. <B>Note that this interface is subject to
* change!</B>
*/
class nsITimer : public nsISupports {
public:
/**
* Initialize a timer to fire after the given millisecond interval.
* This version takes a function to call and a closure to pass to
* that function.
*
* @param aFunc - The function to invoke
* @param aClosure - an opaque pointer to pass to that function
* @param aRepeat - (Not yet implemented) One-shot or repeating
* @param aDelay - The millisecond interval
* @result - NS_OK if this operation was successful
*/
virtual nsresult Init(nsTimerCallbackFunc aFunc,
void *aClosure,
// PRBool aRepeat,
PRUint32 aDelay)=0;
/**
* Initialize a timer to fire after the given millisecond interval.
* This version takes an interface of type <code>nsITimerCallback</code>.
* The <code>Notify</code> method of this method is invoked.
*
* @param aCallback - The interface to notify
* @param aRepeat - (Not yet implemented) One-shot or repeating
* @param aDelay - The millisecond interval
* @result - NS_OK if this operation was successful
*/
virtual nsresult Init(nsITimerCallback *aCallback,
// PRBool aRepeat,
PRUint32 aDelay)=0;
/// Cancels the timeout
virtual void Cancel()=0;
/// @return the millisecond delay of the timeout
virtual PRUint32 GetDelay()=0;
/// Change the millisecond interval for the timeout
virtual void SetDelay(PRUint32 aDelay)=0;
/// @return the opaque pointer
virtual void* GetClosure()=0;
};
/** Factory method for creating an nsITimer */
extern NS_BASE nsresult NS_NewTimer(nsITimer** aInstancePtrResult);
#endif

View File

@@ -0,0 +1,41 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsITimerCallback_h___
#define nsITimerCallback_h___
#include "nscore.h"
#include "nsISupports.h"
class nsITimer;
/// Interface IID for nsITimerCallback
#define NS_ITIMERCALLBACK_IID \
{ 0x5079b3a0, 0xb743, 0x11d1, \
{ 0x9b, 0xc3, 0x00, 0x60, 0x08, 0x8c, 0xa6, 0xb3 } }
/**
* Interface implemented by users of the nsITimer class. An instance
* of this interface is passed in when creating a timer. The Notify()
* method of that instance is invoked after the specified delay.
*/
class nsITimerCallback : public nsISupports {
public:
virtual void Notify(nsITimer *timer)=0;
};
#endif

View File

@@ -0,0 +1,46 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsIUnicharBuffer_h___
#define nsIUnicharBuffer_h___
#include "nscore.h"
#include "nsISupports.h"
class nsIUnicharInputStream;
#define NS_IUNICHAR_BUFFER_IID \
{ 0x14cf6970, 0x93b5, 0x11d1, \
{0x89, 0x5b, 0x00, 0x60, 0x08, 0x91, 0x1b, 0x81} }
/// Interface to a buffer that holds unicode characters
class nsIUnicharBuffer : public nsISupports {
public:
virtual PRInt32 GetLength() const = 0;
virtual PRInt32 GetBufferSize() const = 0;
virtual PRUnichar* GetBuffer() const = 0;
virtual PRBool Grow(PRInt32 aNewSize) = 0;
virtual PRInt32 Fill(nsresult* aErrorCode, nsIUnicharInputStream* aStream,
PRInt32 aKeep) = 0;
};
/// Factory method for nsIUnicharBuffer.
extern NS_BASE nsresult
NS_NewUnicharBuffer(nsIUnicharBuffer** aInstancePtrResult,
nsISupports* aOuter,
PRUint32 aBufferSize = 0);
#endif /* nsIUnicharBuffer_h___ */

View File

@@ -0,0 +1,62 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsIUnicharInputStream_h___
#define nsIUnicharInputStream_h___
#include "nsIInputStream.h"
class nsString;
#define NS_IUNICHAR_INPUT_STREAM_IID \
{ 0x2d97fbf0, 0x93b5, 0x11d1, \
{0x89, 0x5b, 0x00, 0x60, 0x08, 0x91, 0x1b, 0x81} }
/** Abstract unicode character input stream
* @see nsIInputStream
*/
class nsIUnicharInputStream : public nsISupports {
public:
NS_IMETHOD Read(PRUnichar* aBuf,
PRUint32 aOffset,
PRUint32 aCount,
PRUint32 *aReadCount) = 0;
NS_IMETHOD Close() = 0;
};
/**
* Create a nsIUnicharInputStream that wraps up a string. Data is fed
* from the string out until the done. When this object is destroyed
* it destroyes the string (so make a copy if you don't want it doing
* that)
*/
extern NS_BASE nsresult
NS_NewStringUnicharInputStream(nsIUnicharInputStream** aInstancePtrResult,
nsString* aString);
/** Create a new nsUnicharInputStream that provides a converter for the
* byte input stream aStreamToWrap. If no converter can be found then
* nsnull is returned and the error code is set to
* NS_INPUTSTREAM_NO_CONVERTER.
*/
extern NS_BASE nsresult
NS_NewConverterStream(nsIUnicharInputStream** aInstancePtrResult,
nsISupports* aOuter,
nsIInputStream* aStreamToWrap,
PRInt32 aBufferSize = 0,
nsString* aCharSet = nsnull);
#endif /* nsUnicharInputStream_h___ */

340
mozilla/base/src/nsInt64.h Normal file
View File

@@ -0,0 +1,340 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsInt64_h__
#define nsInt64_h__
#include "prlong.h"
#include "nscore.h"
/**
* This class encapsulates full 64-bit integer functionality and
* provides simple arithmetic and conversion operations.
*/
// If you ever decide that you need to add a non-inline method to this
// class, be sure to change the class declaration to "class NS_BASE
// nsInt64".
class nsInt64
{
private:
PRInt64 mValue;
public:
/**
* Construct a new 64-bit integer.
*/
nsInt64(void) : mValue(LL_ZERO) {
}
/**
* Construct a new 64-bit integer from a 32-bit signed integer
*/
nsInt64(const PRInt32 aInt32) {
LL_I2L(mValue, aInt32);
}
/**
* Construct a new 64-bit integer from a 32-bit unsigned integer
*/
nsInt64(const PRUint32 aUint32) {
LL_UI2L(mValue, aUint32);
}
/**
* Construct a new 64-bit integer from a floating point value.
*/
nsInt64(const PRFloat64 aFloat64) {
LL_D2L(mValue, aFloat64);
}
/**
* Construct a new 64-bit integer from a native 64-bit integer
*/
nsInt64(const PRInt64 aInt64) : mValue(aInt64) {
}
/**
* Construct a new 64-bit integer from another 64-bit integer
*/
nsInt64(const nsInt64& aObject) : mValue(aObject.mValue) {
}
// ~nsInt64(void) -- XXX destructor unnecessary
/**
* Assign a 64-bit integer to another 64-bit integer
*/
const nsInt64& operator =(const nsInt64& aObject) {
mValue = aObject.mValue;
return *this;
}
/**
* Convert a 64-bit integer to a signed 32-bit value
*/
operator PRInt32(void) const {
PRInt32 result;
LL_L2I(result, mValue);
return result;
}
/**
* Convert a 64-bit integer to an unsigned 32-bit value
*/
operator PRUint32(void) const {
PRUint32 result;
LL_L2UI(result, mValue);
return result;
}
/**
* Convert a 64-bit integer to a floating point value
*/
operator PRFloat64(void) const {
PRFloat64 result;
LL_L2D(result, mValue);
return result;
}
/**
* Convert a 64-bit integer to a native 64-bit integer.
*/
operator PRInt64(void) const {
return mValue;
}
/**
* Perform unary negation on a 64-bit integer.
*/
const nsInt64 operator -(void) {
nsInt64 result;
LL_NEG(result.mValue, mValue);
return result;
}
// Arithmetic operators
friend const nsInt64 operator +(const nsInt64& aObject1, const nsInt64& aObject2);
friend const nsInt64 operator -(const nsInt64& aObject1, const nsInt64& aObject2);
friend const nsInt64 operator *(const nsInt64& aObject1, const nsInt64& aObject2);
friend const nsInt64 operator /(const nsInt64& aObject1, const nsInt64& aObject2);
friend const nsInt64 operator %(const nsInt64& aObject1, const nsInt64& aObject2);
/**
* Increment a 64-bit integer by a 64-bit integer amount.
*/
nsInt64& operator +=(const nsInt64& aObject) {
LL_ADD(mValue, mValue, aObject.mValue);
return *this;
}
/**
* Decrement a 64-bit integer by a 64-bit integer amount.
*/
nsInt64& operator -=(const nsInt64& aObject) {
LL_SUB(mValue, mValue, aObject.mValue);
return *this;
}
/**
* Multiply a 64-bit integer by a 64-bit integer amount.
*/
nsInt64& operator *=(const nsInt64& aObject) {
LL_MUL(mValue, mValue, aObject.mValue);
return *this;
}
/**
* Divide a 64-bit integer by a 64-bit integer amount.
*/
nsInt64& operator /=(const nsInt64& aObject) {
LL_DIV(mValue, mValue, aObject.mValue);
return *this;
}
/**
* Compute the modulus of a 64-bit integer to a 64-bit value.
*/
nsInt64& operator %=(const nsInt64& aObject) {
LL_MOD(mValue, mValue, aObject.mValue);
return *this;
}
// Comparison operators
friend PRBool operator ==(const nsInt64& aObject1, const nsInt64& aObject2);
friend PRBool operator !=(const nsInt64& aObject1, const nsInt64& aObject2);
friend PRBool operator >(const nsInt64& aObject1, const nsInt64& aObject2);
friend PRBool operator >=(const nsInt64& aObject1, const nsInt64& aObject2);
friend PRBool operator <(const nsInt64& aObject1, const nsInt64& aObject2);
friend PRBool operator <=(const nsInt64& aObject1, const nsInt64& aObject2);
// Bitwise operators
friend const nsInt64 operator &(const nsInt64& aObject1, const nsInt64& aObject2);
friend const nsInt64 operator |(const nsInt64& aObject1, const nsInt64& aObject2);
friend const nsInt64 operator ^(const nsInt64& aObject1, const nsInt64& aObject2);
/**
* Compute the bitwise NOT of a 64-bit integer
*/
const nsInt64 operator ~(void) {
nsInt64 result;
LL_NOT(result.mValue, mValue);
return result;
}
/**
* Compute the bitwise AND with another 64-bit integer
*/
nsInt64& operator &=(const nsInt64& aObject) {
LL_AND(mValue, mValue, aObject.mValue);
return *this;
}
/**
* Compute the bitwise OR with another 64-bit integer
*/
nsInt64& operator |=(const nsInt64& aObject) {
LL_OR(mValue, mValue, aObject.mValue);
return *this;
}
/**
* Compute the bitwise XOR with another 64-bit integer
*/
nsInt64& operator ^=(const nsInt64& aObject) {
LL_XOR(mValue, mValue, aObject.mValue);
return *this;
}
};
/**
* Add two 64-bit integers.
*/
inline const nsInt64
operator +(const nsInt64& aObject1, const nsInt64& aObject2) {
return nsInt64(aObject1) += aObject2;
}
/**
* Subtract one 64-bit integer from another.
*/
inline const nsInt64
operator -(const nsInt64& aObject1, const nsInt64& aObject2) {
return nsInt64(aObject1) -= aObject2;
}
/**
* Multiply two 64-bit integers
*/
inline const nsInt64
operator *(const nsInt64& aObject1, const nsInt64& aObject2) {
return nsInt64(aObject1) *= aObject2;
}
/**
* Divide one 64-bit integer by another
*/
inline const nsInt64
operator /(const nsInt64& aObject1, const nsInt64& aObject2) {
return nsInt64(aObject1) /= aObject2;
}
/**
* Compute the modulus of two 64-bit integers
*/
inline const nsInt64
operator %(const nsInt64& aObject1, const nsInt64& aObject2) {
return nsInt64(aObject1) %= aObject2;
}
/**
* Determine if two 64-bit integers are equal
*/
inline PRBool
operator ==(const nsInt64& aObject1, const nsInt64& aObject2) {
return LL_EQ(aObject1.mValue, aObject2.mValue);
}
/**
* Determine if two 64-bit integers are not equal
*/
inline PRBool
operator !=(const nsInt64& aObject1, const nsInt64& aObject2) {
return LL_NE(aObject1.mValue, aObject2.mValue);
}
/**
* Determine if one 64-bit integer is strictly greater than another, using signed values
*/
inline PRBool
operator >(const nsInt64& aObject1, const nsInt64& aObject2) {
return LL_CMP(aObject1.mValue, >, aObject2.mValue);
}
/**
* Determine if one 64-bit integer is greater than or equal to another, using signed values
*/
inline PRBool
operator >=(const nsInt64& aObject1, const nsInt64& aObject2) {
return LL_CMP(aObject1.mValue, >=, aObject2.mValue);
}
/**
* Determine if one 64-bit integer is strictly less than another, using signed values
*/
inline PRBool
operator <(const nsInt64& aObject1, const nsInt64& aObject2) {
return LL_CMP(aObject1.mValue, <, aObject2.mValue);
}
/**
* Determine if one 64-bit integers is less than or equal to another, using signed values
*/
inline PRBool
operator <=(const nsInt64& aObject1, const nsInt64& aObject2) {
return LL_CMP(aObject1.mValue, <=, aObject2.mValue);
}
/**
* Perform a bitwise AND of two 64-bit integers
*/
inline const nsInt64
operator &(const nsInt64& aObject1, const nsInt64& aObject2) {
return nsInt64(aObject1) &= aObject2;
}
/**
* Perform a bitwise OR of two 64-bit integers
*/
inline const nsInt64
operator |(const nsInt64& aObject1, const nsInt64& aObject2) {
return nsInt64(aObject1) |= aObject2;
}
/**
* Perform a bitwise XOR of two 64-bit integers
*/
inline const nsInt64
operator ^(const nsInt64& aObject1, const nsInt64& aObject2) {
return nsInt64(aObject1) ^= aObject2;
}
#endif // nsInt64_h__

View File

@@ -0,0 +1,312 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#define NS_IMPL_IDS
#include "nsID.h"
#include "nsBaseDLL.h"
#include "nsCRT.h"
#include "nsIInputStream.h"
#include "nsIProperties.h"
#include "nsIUnicharInputStream.h"
#include "nsProperties.h"
#include "plhash.h"
#include "pratom.h"
class nsProperties : public nsIProperties
{
public:
nsProperties();
virtual ~nsProperties();
NS_DECL_ISUPPORTS
NS_IMETHOD Load(nsIInputStream* aIn);
NS_IMETHOD GetProperty(const nsString& aKey, nsString& aValue);
NS_IMETHOD SetProperty(const nsString& aKey, nsString& aNewValue,
nsString& aOldValue);
NS_IMETHOD Save(nsIOutputStream* aOut, const nsString& aHeader);
NS_IMETHOD Subclass(nsIProperties* aSubclass);
PRInt32 Read();
PRInt32 SkipLine(PRInt32 c);
PRInt32 SkipWhiteSpace(PRInt32 c);
nsIUnicharInputStream* mIn;
nsIProperties* mSubclass;
struct PLHashTable* mTable;
};
nsProperties::nsProperties()
{
NS_INIT_REFCNT();
mIn = nsnull;
mSubclass = NS_STATIC_CAST(nsIProperties*, this);
mTable = nsnull;
}
PR_CALLBACK PRIntn
FreeHashEntries(PLHashEntry* he, PRIntn i, void* arg)
{
delete[] (PRUnichar*)he->key;
delete[] (PRUnichar*)he->value;
return HT_ENUMERATE_REMOVE;
}
nsProperties::~nsProperties()
{
if (mTable) {
// Free the PRUnicode* pointers contained in the hash table entries
PL_HashTableEnumerateEntries(mTable, FreeHashEntries, 0);
PL_HashTableDestroy(mTable);
mTable = nsnull;
}
}
NS_DEFINE_IID(kIPropertiesIID, NS_IPROPERTIES_IID);
NS_IMPL_ISUPPORTS(nsProperties, kIPropertiesIID)
NS_IMETHODIMP
nsProperties::Load(nsIInputStream *aIn)
{
PRInt32 c;
nsresult ret;
ret = NS_NewConverterStream(&mIn, nsnull, aIn);
if (ret != NS_OK) {
cout << "NS_NewConverterStream failed" << endl;
return NS_ERROR_FAILURE;
}
c = Read();
while (1) {
c = SkipWhiteSpace(c);
if (c < 0) {
break;
}
else if ((c == '#') || (c == '!')) {
c = SkipLine(c);
continue;
}
else {
nsAutoString key("");
while ((c >= 0) && (c != '=') && (c != ':')) {
key.Append((PRUnichar) c);
c = Read();
}
if (c < 0) {
break;
}
char *trimThese = " \t";
key.Trim(trimThese, PR_FALSE, PR_TRUE);
c = Read();
nsAutoString value("");
while ((c >= 0) && (c != '\r') && (c != '\n')) {
if (c == '\\') {
c = Read();
if ((c == '\r') || (c == '\n')) {
c = SkipWhiteSpace(c);
}
else {
value.Append('\\');
}
}
value.Append((PRUnichar) c);
c = Read();
}
value.Trim(trimThese, PR_TRUE, PR_TRUE);
nsAutoString oldValue("");
mSubclass->SetProperty(key, value, oldValue);
}
}
mIn->Close();
NS_RELEASE(mIn);
NS_ASSERTION(!mIn, "unexpected remaining reference");
return NS_OK;
}
static PLHashNumber
HashKey(const PRUnichar *aString)
{
return (PLHashNumber) nsCRT::HashValue(aString);
}
static PRIntn
CompareKeys(const PRUnichar *aStr1, const PRUnichar *aStr2)
{
return nsCRT::strcmp(aStr1, aStr2) == 0;
}
NS_IMETHODIMP
nsProperties::SetProperty(const nsString& aKey, nsString& aNewValue,
nsString& aOldValue)
{
// XXX The ToNewCString() calls allocate memory using "new" so this code
// causes a memory leak...
#if 0
cout << "will add " << aKey.ToNewCString() << "=" << aNewValue.ToNewCString() << endl;
#endif
if (!mTable) {
mTable = PL_NewHashTable(8, (PLHashFunction) HashKey,
(PLHashComparator) CompareKeys,
(PLHashComparator) nsnull, nsnull, nsnull);
if (!mTable) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
const PRUnichar *key = aKey.GetUnicode(); // returns internal pointer (not a copy)
PRUint32 len;
PRUint32 hashValue = nsCRT::HashValue(key, &len);
PLHashEntry **hep = PL_HashTableRawLookup(mTable, hashValue, key);
PLHashEntry *he = *hep;
if (he && aOldValue) {
// XXX fix me
}
PL_HashTableRawAdd(mTable, hep, hashValue, aKey.ToNewUnicode(),
aNewValue.ToNewUnicode());
return NS_OK;
}
NS_IMETHODIMP
nsProperties::Save(nsIOutputStream* aOut, const nsString& aHeader)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsProperties::Subclass(nsIProperties* aSubclass)
{
if (aSubclass) {
mSubclass = aSubclass;
}
return NS_OK;
}
NS_IMETHODIMP
nsProperties::GetProperty(const nsString& aKey, nsString& aValue)
{
const PRUnichar *key = aKey;
PRUint32 len;
PRUint32 hashValue = nsCRT::HashValue(key, &len);
PLHashEntry **hep = PL_HashTableRawLookup(mTable, hashValue, key);
PLHashEntry *he = *hep;
if (he) {
aValue = (const PRUnichar*)he->value;
return NS_OK;
}
return NS_ERROR_FAILURE;
}
PRInt32
nsProperties::Read()
{
PRUnichar c;
PRUint32 nRead;
nsresult ret;
ret = mIn->Read(&c, 0, 1, &nRead);
if (ret == NS_OK) {
return c;
}
return -1;
}
#define IS_WHITE_SPACE(c) \
(((c) == ' ') || ((c) == '\t') || ((c) == '\r') || ((c) == '\n'))
PRInt32
nsProperties::SkipWhiteSpace(PRInt32 c)
{
while ((c >= 0) && IS_WHITE_SPACE(c)) {
c = Read();
}
return c;
}
PRInt32
nsProperties::SkipLine(PRInt32 c)
{
while ((c >= 0) && (c != '\r') && (c != '\n')) {
c = Read();
}
if (c == '\r') {
c = Read();
}
if (c == '\n') {
c = Read();
}
return c;
}
nsPropertiesFactory::nsPropertiesFactory()
{
NS_INIT_REFCNT();
}
nsPropertiesFactory::~nsPropertiesFactory()
{
}
NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
NS_IMPL_ISUPPORTS(nsPropertiesFactory, kIFactoryIID);
NS_IMETHODIMP
nsPropertiesFactory::CreateInstance(nsISupports* aOuter, REFNSIID aIID,
void** aResult)
{
if (aOuter) {
return NS_ERROR_NO_AGGREGATION;
}
if (!aResult) {
return NS_ERROR_NULL_POINTER;
}
*aResult = nsnull;
nsProperties* props = new nsProperties();
if (!props) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsresult ret = props->QueryInterface(aIID, aResult);
if (NS_FAILED(ret)) {
delete props;
}
return ret;
}
NS_IMETHODIMP
nsPropertiesFactory::LockFactory(PRBool aLock)
{
if (aLock) {
PR_AtomicIncrement(&gLockCount);
}
else {
PR_AtomicDecrement(&gLockCount);
}
return NS_OK;
}

View File

@@ -0,0 +1,37 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsProperties_h___
#define nsProperties_h___
#include "nsIFactory.h"
class nsPropertiesFactory : public nsIFactory
{
public:
nsPropertiesFactory();
virtual ~nsPropertiesFactory();
NS_DECL_ISUPPORTS
NS_IMETHOD CreateInstance(nsISupports* aOuter, REFNSIID aIID,
void** aResult);
NS_IMETHOD LockFactory(PRBool aLock);
};
#endif /* nsProperties_h___ */

View File

@@ -0,0 +1,423 @@
/**
* This file defines the binary tree class and it
* nsNode child class.
*
* This simple version stores nodes, and the
* nodes store void* ptrs.
*
* @update gess 4/11/98
* @param
* @return
*/
#include "nsRBTree.h"
/**************************************************
Here comes the nsRBTree class...
*************************************************/
/**
* nsRBTree constructor
*
* @update gess 4/11/98
*/
nsRBTree::nsRBTree() : nsBTree() {
mRoot=0;
}
/**
* nsRBTree constructor
*
* @update gess 4/11/98
*/
nsRBTree::nsRBTree(const nsRBTree& aCopy) : nsBTree(aCopy) {
mRoot=aCopy.mRoot;
}
/**
* nsRBTree destructor
*
* @update gess 4/11/98
* @param
* @return
*/
nsRBTree::~nsRBTree(){
if(mRoot){
//walk the tree and destroy the children.
}
}
/**
* Given a node, we're supposed to add it into
* our tree.
*
* @update gess 4/11/98
* @param
* @return
*/
nsNode* nsRBTree::Add(nsNode& aNode){
nsBTree::Add(aNode);
nsNode* node1=&aNode;
nsNode* node2=0;
node1->mColor=nsNode::eRed;
while((node1!=mRoot) && (node1->mParent->mColor==nsNode::eRed)) {
if(node1->mParent==node1->mParent->mParent->mLeft) {
node2=node1->mParent->mParent->mLeft;
if(node2->mColor==nsNode::eRed) {
node1->mParent->mColor=nsNode::eBlack;
node2->mColor=nsNode::eBlack;
node1->mParent->mParent->mColor=nsNode::eRed;
node1=node1->mParent->mParent;
}
else {
if(node1==node1->mParent->mRight) {
node1=node1->mParent;
ShiftLeft(*node1);
}
node1->mParent->mColor=nsNode::eBlack;
node1->mParent->mParent->mColor=nsNode::eRed;
ShiftRight(*node1->mParent->mParent);
}
}
else {
node2=node1->mParent->mParent->mRight;
if (node2->mColor==nsNode::eRed){
node1->mParent->mColor=nsNode::eBlack;
node2->mColor=nsNode::eBlack;
node1->mParent->mParent->mColor=nsNode::eRed;
node1=node1->mParent->mParent;
}
else {
if (node1==node1->mParent->mLeft) {
node1=node1->mParent;
ShiftRight(*node1);
}
node1->mParent->mColor=nsNode::eBlack;
node1->mParent->mParent->mColor=nsNode::eRed;
ShiftLeft(*node1->mParent->mParent);
}
}
}
mRoot->mColor=nsNode::eBlack;
return &aNode;
}
/**
* Retrive the first node in the tree
*
* @update gess 4/11/98
* @param
* @return
*/
nsNode* nsRBTree::First(){
nsNode* result=First(*mRoot);
return result;
}
/**
* Retrieve the first node given a starting node
*
* @update gess 4/11/98
* @param aNode --
* @return node ptr or null
*/
nsNode* nsRBTree::First(nsNode& aNode){
nsNode* result=0;
if(mRoot) {
result=mRoot;
while(result->GetLeftNode()) {
result=result->GetLeftNode();
}
}
return result;
}
/**
* Find the last node in the tree
*
* @update gess 4/11/98
* @param
* @return node ptr or null
*/
nsNode* nsRBTree::Last(){
nsNode* result=Last(*mRoot);
return result;
}
/**
* Find the last node from a given node
*
* @update gess 4/11/98
* @param aNode -- node ptr to start from
* @return node ptr or null
*/
nsNode* nsRBTree::Last(nsNode& aNode){
nsNode* result=0;
if(mRoot) {
result=mRoot;
while(result->GetRightNode()) {
result=result->GetRightNode();
}
}
return result;
}
/**
* Retrieve the node that preceeds the given node
*
* @update gess 4/11/98
* @param aNode -- node to find precedent of
* @return preceeding node ptr, or null
*/
nsNode* nsRBTree::Before(nsNode& aNode){
if(aNode.GetLeftNode())
return Last(*aNode.GetLeftNode());
//otherwise...
nsNode* node1=&aNode;
nsNode* node2=aNode.GetParentNode();
while((node2) && (node1==node2->GetLeftNode())) {
node1=node2;
node2=node2->GetParentNode();
}
return node2;
}
/**
* Retrieve a ptr to the node following the given node
*
* @update gess 4/11/98
* @param aNode -- node to find successor node from
* @return node ptr or null
*/
nsNode* nsRBTree::After(nsNode& aNode){
if(aNode.GetRightNode())
return First(*aNode.GetRightNode());
//otherwise...
nsNode* node1=&aNode;
nsNode* node2=aNode.GetParentNode();
while((node2) && (node1==node2->GetRightNode())) {
node1=node2;
node2=node2->GetParentNode();
}
return node2;
}
/**
* Find a (given) node in the tree
*
* @update gess 4/11/98
* @param node to find in the tree
* @return node ptr (if found) or null
*/
nsNode* nsRBTree::Find(nsNode& aNode){
nsNode* result=mRoot;
while((result) && (!((*result)==aNode))) {
if(aNode<*result)
result=result->mLeft;
else result=result->mRight;
}
return result;
}
/**
* Causes a shift to the left, to keep the
* underlying RB data in balance
*
* @update gess 4/11/98
* @param
* @return this
*/
nsRBTree& nsRBTree::ShiftLeft(nsNode& aNode){
nsNode* temp= aNode.mRight;
aNode.mRight=temp->mLeft;
if(temp->mLeft)
temp->mRight->mParent=&aNode;
temp->mParent= aNode.mParent;
if (aNode.mParent) {
if (&aNode==aNode.mParent->mLeft)
aNode.mParent->mLeft=temp;
else aNode.mParent->mRight=temp;
}
else mRoot=temp;
temp->mLeft=&aNode;;
aNode.mParent=temp;
return *this;
}
/**
* Causes a shift right to occur, to keep the
* underlying RB data in balance
*
* @update gess 4/11/98
* @param aNode -- node at which to perform shift
* @return this
*/
nsRBTree& nsRBTree::ShiftRight(nsNode& aNode){
nsNode* temp=aNode.mLeft;
aNode.mLeft=temp->mRight;
if(temp->mRight)
temp->mRight->mParent=&aNode;
temp->mParent=aNode.mParent;
if(aNode.mParent){
if(&aNode==aNode.mParent->mRight)
aNode.mParent->mRight=temp;
else aNode.mParent->mLeft=temp;
}
else mRoot=temp;
temp->mRight=&aNode;
aNode.mParent=temp;
return *this;
}
/**
* Rebalances tree around the given node. This only
* needs to be called after a node is deleted.
*
* @update gess 4/11/98
* @param aNode -- node to balance around
* @return this
*/
nsBTree& nsRBTree::ReBalance(nsNode& aNode){
nsNode* node1=&aNode;
nsNode* node2=0;
while ((node1!=mRoot) && (node1->mColor==nsNode::eBlack)) {
if(node1==node1->mParent->mLeft) {
node2=node1->mParent->mRight;
if(node2->mColor==nsNode::eRed) {
node2->mColor=nsNode::eBlack;
node1->mParent->mColor=nsNode::eRed;
ShiftLeft(*node1->mParent);
node2=node1->mParent->mRight;
}
if((node2->mLeft->mColor == nsNode::eBlack) &&
(node2->mRight->mColor == nsNode::eBlack)) {
node2->mColor=nsNode::eRed;
node1=node1->mParent;
}
else {
if(node2->mRight->mColor == nsNode::eBlack) {
node2->mLeft->mColor=nsNode::eBlack;
node2->mColor=nsNode::eRed;
ShiftRight(*node2);
node2=node1->mParent->mRight;
}
node2->mColor=node1->mParent->mColor;
node1->mParent->mColor=nsNode::eBlack;
node2->mRight->mColor=nsNode::eBlack;
ShiftLeft(*node1->mParent);
node1=mRoot;
} //else
}
else {
node2=node1->mParent->mLeft;
if(node2->mColor==nsNode::eRed) {
node2->mColor=nsNode::eBlack;
node1->mParent->mColor=nsNode::eRed;
ShiftRight(*node1->mParent);
node2=node1->mParent->mLeft;
}
if((node2->mRight->mColor == nsNode::eBlack) &&
(node2->mLeft->mColor == nsNode::eBlack)) {
node2->mColor=nsNode::eRed;
node1=node1->mParent;
}
else {
if(node2->mLeft->mColor == nsNode::eBlack){
node2->mRight->mColor=nsNode::eBlack;
node2->mColor=nsNode::eRed;
ShiftLeft(*node2);
node2=node1->mParent->mLeft;
}
node2->mColor=node1->mParent->mColor;
node1->mParent->mColor=nsNode::eBlack;
node2->mLeft->mColor=nsNode::eBlack;
ShiftRight(*node1->mParent);
node1=mRoot;
} //else
} //if
} //while
node1->mColor=nsNode::eBlack;
return *this;
}
/**************************************************
Here comes the nsRBTreeIterator class...
*************************************************/
/**
*
*
* @update gess 4/11/98
* @param
* @return
*/
nsRBTreeIterator::nsRBTreeIterator(const nsRBTree& aTree) : mTree(aTree) {
}
/**
* copy constructor
*
* @update gess 4/11/98
* @param aCopy is the object you want to copy from
* @return newly constructed object
*/
nsRBTreeIterator::nsRBTreeIterator(const nsRBTreeIterator& aCopy) : mTree(aCopy.mTree) {
}
/**
* Destructor method
*
* @update gess 4/11/98
*/
nsRBTreeIterator::~nsRBTreeIterator(){
}
/**
* This method iterates over the tree, calling
* aFunctor for each node.
*
* @update gess 4/11/98
* @param aFunctor -- object to call for each node
* @param aNode -- node at which to start iteration
* @return this
*/
const nsRBTreeIterator& nsRBTreeIterator::ForEach(nsNodeFunctor& aFunctor) const{
mTree.ForEach(aFunctor);
return *this;
}

223
mozilla/base/src/nsRBTree.h Normal file
View File

@@ -0,0 +1,223 @@
/**
* This file defines the binary tree class and its
* nsNode child class.
*
* This simple version stores nodes, and the
* nodes store void* ptrs.
*
* @update gess 4/11/98
* @param
* @return
*/
/**
* MODULE NOTES
* @update gess 4/11/98
*
* This file declares the nsRBTree (red/black tree).
* Red/black trees are auto-balancing binary trees.
*
* To use this class, define a subclass of nsNode
* which stores your data type. It's important that
* you overload the following methods:
*
* virtual PRBool operator<()
* virtual PRBool operator==()
*
*/
#ifndef _nsRBTree
#define _nsRBTree
#include "nsBTree.h"
/**
* Here comes the main event: our nsRBTree (red/black tree).
* Red/Black trees are autobalancing binary trees.
*
* @update gess4/20/98
*/
class NS_BASE nsRBTree : public nsBTree {
public:
friend class NS_BASE nsRBTreeIterator;
/**
* nsRBTree constructor
*
* @update gess 4/11/98
*/
nsRBTree();
/**
* nsRBTree constructor
*
* @update gess 4/11/98
*/
nsRBTree(const nsRBTree& aCopy);
/**
* nsRBTree destructor
*
* @update gess 4/11/98
*/
virtual ~nsRBTree();
/**
* Given a node, we're supposed to add it into
* our tree.
*
* @update gess 4/11/98
* @param
* @return
*/
nsNode* Add(nsNode& aNode);
/**
* Retrive the first node in the tree
*
* @update gess 4/11/98
* @param
* @return
*/
nsNode* First(void);
/**
* Retrieve the first node given a starting node
*
* @update gess 4/11/98
* @param aNode --
* @return node ptr or null
*/
nsNode* First(nsNode& aNode);
/**
* Find the last node in the tree
*
* @update gess 4/11/98
* @param
* @return node ptr or null
*/
nsNode* Last(void);
/**
* Find the last node from a given node
*
* @update gess 4/11/98
* @param aNode -- node ptr to start from
* @return node ptr or null
*/
nsNode* Last(nsNode& aNode);
/**
* Retrieve the node that preceeds the given node
*
* @update gess 4/11/98
* @param aNode -- node to find precedent of
* @return preceeding node ptr, or null
*/
nsNode* Before(nsNode& aNode);
/**
* Retrieve a ptr to the node following the given node
*
* @update gess 4/11/98
* @param aNode -- node to find successor node from
* @return node ptr or null
*/
nsNode* After(nsNode& aNode);
/**
* Find a (given) node in the tree
*
* @update gess 4/11/98
* @param node to find in the tree
* @return node ptr (if found) or null
*/
nsNode* Find(nsNode& aNode);
private:
/**
* Causes a shift to the left, to keep the
* underlying RB data in balance
*
* @update gess 4/11/98
* @param
* @return this
*/
nsRBTree& ShiftLeft(nsNode& aNode);
/**
* Causes a shift right to occur, to keep the
* underlying RB data in balance
*
* @update gess 4/11/98
* @param aNode -- node at which to perform shift
* @return this
*/
nsRBTree& ShiftRight(nsNode& aNode);
/**
* Rebalances tree around the given node. This only
* needs to be called after a node is deleted.
*
* @update gess 4/11/98
* @param aNode -- node to balance around
* @return this
*/
virtual nsBTree& ReBalance(nsNode& aNode);
};
class NS_BASE nsRBTreeIterator {
public:
/**
* TreeIterator constructor
*
* @update gess 4/11/98
* @param
* @return
*/
nsRBTreeIterator(const nsRBTree& aTree);
/**
* TreeIterator constructor
*
* @update gess 4/11/98
* @param
* @return
*/
nsRBTreeIterator(const nsRBTreeIterator& aCopy);
/**
* tree iterator destructor
*
* @update gess 4/11/98
* @param
* @return
*/
~nsRBTreeIterator();
/**
* This method iterates over the tree, calling
* aFunctor for each node.
*
* @update gess 4/11/98
* @param aFunctor -- object to call for each node
* @param aNode -- node at which to start iteration
* @return this
*/
const nsRBTreeIterator& ForEach(nsNodeFunctor& aFunctor) const;
protected:
const nsRBTree& mTree;
};
#endif

View File

@@ -0,0 +1,121 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsISizeOfHandler.h"
#include "plhash.h"
static NS_DEFINE_IID(kISizeOfHandlerIID, NS_ISIZEOF_HANDLER_IID);
class nsSizeOfHandler : public nsISizeOfHandler {
public:
nsSizeOfHandler();
~nsSizeOfHandler();
// nsISupports
NS_DECL_ISUPPORTS
// nsISizeOfHandler
NS_IMETHOD Add(size_t aSize);
virtual PRBool HaveSeen(void* anObject);
NS_IMETHOD GetSize(PRUint32& aResult);
protected:
PRUint32 mTotalSize;
PLHashTable* mTable;
};
static PLHashNumber
HashKey(void* key)
{
return (PLHashNumber) key;
}
static PRIntn
CompareKeys(void* key1, void* key2)
{
return key1 == key2;
}
nsSizeOfHandler::nsSizeOfHandler()
{
NS_INIT_REFCNT();
mTotalSize = 0;
mTable = PL_NewHashTable(8, (PLHashFunction) HashKey,
(PLHashComparator) CompareKeys,
(PLHashComparator) nsnull,
nsnull, nsnull);
}
nsSizeOfHandler::~nsSizeOfHandler()
{
if (nsnull != mTable) {
PL_HashTableDestroy(mTable);
}
}
NS_IMPL_ISUPPORTS(nsSizeOfHandler, kISizeOfHandlerIID)
NS_IMETHODIMP
nsSizeOfHandler::Add(size_t aSize)
{
mTotalSize += aSize;
return NS_OK;
}
PRBool
nsSizeOfHandler::HaveSeen(void* anObject)
{
if (nsnull == mTable) {
// When we run out of memory, HaveSeen returns PR_TRUE to stop
// wasting time.
return PR_TRUE;
}
if (nsnull != anObject) {
PRInt32 hashCode = (PRInt32) anObject;
PLHashEntry** hep = PL_HashTableRawLookup(mTable, hashCode, anObject);
PLHashEntry* he = *hep;
if (nsnull != he) {
return PR_TRUE;
}
he = PL_HashTableRawAdd(mTable, hep, hashCode, anObject, anObject);
if (nsnull == he) {
// When we run out of memory, HaveSeen returns PR_TRUE to stop
// wasting time.
return PR_TRUE;
}
return PR_FALSE;
}
return PR_TRUE;
}
NS_IMETHODIMP
nsSizeOfHandler::GetSize(PRUint32& aResult)
{
aResult = mTotalSize;
return NS_OK;
}
NS_BASE nsresult
NS_NewSizeOfHandler(nsISizeOfHandler** aInstancePtrResult)
{
nsISizeOfHandler *it = new nsSizeOfHandler();
if (it == nsnull) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kISizeOfHandlerIID, (void **) aInstancePtrResult);
}

View File

@@ -0,0 +1,133 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
// First checked in on 98/12/08 by John R. McMullen.
// Since nsFileStream.h is entirely templates, common code (such as open())
// which does not actually depend on the charT, can be placed here.
#ifdef XP_UNIX
// Compile the un-inlined functions in this file only.
#define DEFINING_FILE_STREAM
#endif
#include "nsStdFileStream.h"
#ifdef XP_MAC
#include <Errors.h>
#endif
//----------------------------------------------------------------------------------------
PRFileDesc* nsFileStreamHelpers::open(
const nsFilePath& inFile,
IOS_BASE::openmode mode,
PRIntn accessMode)
//----------------------------------------------------------------------------------------
{
PRFileDesc* descriptor = 0;
const IOS_BASE::openmode valid_modes[]=
{
IOS_BASE::out,
IOS_BASE::out | IOS_BASE::app,
IOS_BASE::out | IOS_BASE::trunc,
IOS_BASE::in,
IOS_BASE::in | IOS_BASE::out,
IOS_BASE::in | IOS_BASE::out | IOS_BASE::trunc,
// IOS_BASE::out | IOS_BASE::binary,
// IOS_BASE::out | IOS_BASE::app | IOS_BASE::binary,
// IOS_BASE::out | IOS_BASE::trunc | IOS_BASE::binary,
// IOS_BASE::in | IOS_BASE::binary,
// IOS_BASE::in | IOS_BASE::out | IOS_BASE::binary,
// IOS_BASE::in | IOS_BASE::out | IOS_BASE::trunc | IOS_BASE::binary,
0
};
const int nspr_modes[]={
PR_WRONLY | PR_CREATE_FILE,
PR_WRONLY | PR_CREATE_FILE | PR_APPEND,
PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
PR_RDONLY,
PR_RDONLY | PR_APPEND,
PR_RDWR | PR_CREATE_FILE,
PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE,
// "wb",
// "ab",
// "wb",
// "rb",
// "r+b",
// "w+b",
0 };
int ind=0;
while (valid_modes[ind] && valid_modes[ind] != (mode&~IOS_BASE::ate))
++ind;
if (!nspr_modes[ind])
return 0;
#ifdef XP_MAC
// Use the file spec to open the file, because one path can be common to
// several files on the Macintosh (you can have several volumes with the
// same name, see).
descriptor = 0;
if (inFile.GetNativeSpec().Error() != noErr)
return 0;
OSErr err = noErr;
#if DEBUG
const OSType kCreator = 'CWIE';
#else
const OSType kCreator = 'MOSS';
#endif
nsNativeFileSpec nativeSpec = inFile.GetNativeSpec();
FSSpec* spec = (FSSpec*)nativeSpec;
if (nspr_modes[ind] & PR_CREATE_FILE)
err = FSpCreate(spec, kCreator, 'TEXT', 0);
if (err == dupFNErr)
err = noErr;
if (err != noErr)
return 0;
SInt8 perm;
if (nspr_modes[ind] & PR_RDWR)
perm = fsRdWrPerm;
else if (nspr_modes[ind] & PR_WRONLY)
perm = fsWrPerm;
else
perm = fsRdPerm;
short refnum;
err = FSpOpenDF(spec, perm, &refnum);
if (err == noErr && (nspr_modes[ind] & PR_TRUNCATE))
err = SetEOF(refnum, 0);
if (err == noErr && (nspr_modes[ind] & PR_APPEND))
err = SetFPos(refnum, fsFromLEOF, 0);
if (err != noErr)
return 0;
if ((descriptor = PR_ImportFile(refnum)) == 0)
return 0;
#else
// Platforms other than Macintosh...
if ((descriptor = PR_Open(inFile, nspr_modes[ind], accessMode)) != 0)
#endif
if (mode&IOS_BASE::ate && PR_Seek(descriptor, 0, PR_SEEK_END) >= 0)
{
PR_Close(descriptor);
descriptor = 0;
return 0;
}
return descriptor;
} // nsFileStreamHelpers::open

File diff suppressed because it is too large Load Diff

808
mozilla/base/src/nsString.h Normal file
View File

@@ -0,0 +1,808 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/***********************************************************************
MODULE NOTES:
A. There are two philosophies to building string classes:
1. Hide the underlying buffer & offer API's allow indirect iteration
2. Reveal underlying buffer, risk corruption, but gain performance
We chose the second option for performance reasons.
B Our internal buffer always holds capacity+1 bytes.
***********************************************************************/
#ifndef _NSSTRING
#define _NSSTRING
#include "prtypes.h"
#include "nscore.h"
#include "nsIAtom.h"
#include <iostream.h>
#include <stdio.h>
class nsISizeOfHandler;
class NS_BASE nsString {
public:
/**
* Default constructor. Note that we actually allocate a small buffer
* to begin with. This is because the "philosophy" of the string class
* was to allow developers direct access to the underlying buffer for
* performance reasons.
*/
nsString();
/**
* This constructor accepts an isolatin string
* @param an ascii is a ptr to a 1-byte cstr
*/
nsString(const char* aCString);
/**
* This is our copy constructor
* @param reference to another nsString
*/
nsString(const nsString&);
/**
* Constructor from a unicode string
* @param anicodestr pts to a unicode string
*/
nsString(const PRUnichar* aUnicode);
/**
* Virtual Destructor
*/
virtual ~nsString();
/**
* Retrieve the length of this string
* @return string length
*/
PRInt32 Length() const { return mLength; }
/**
* Sets the new length of the string.
* @param aLength is new string length.
* @return nada
*/
void SetLength(PRInt32 aLength);
/**
* This method truncates this string to given length.
*
* @param anIndex -- new length of string
* @return nada
*/
void Truncate(PRInt32 anIndex=0);
/**
* This method gets called when the internal buffer needs
* to grow to a given size.
* @param aNewLength -- new capacity of string
* @return void
*/
virtual void EnsureCapacityFor(PRInt32 aNewLength);
/**
*
* @param
*/
virtual void SizeOf(nsISizeOfHandler* aHandler) const;
/**
* Determine whether or not the characters in this
* string are in sorted order.
*
* @return TRUE if ordered.
*/
PRBool IsOrdered(void) const;
/**********************************************************************
Accessor methods...
*********************************************************************/
/**
* Retrieve pointer to internal string value
* @return PRUnichar* to internal string
*/
const PRUnichar* GetUnicode(void) const;
/**
*
* @param
* @return
*/
operator const PRUnichar*() const;
/**
* Retrieve unicode char at given index
* @param offset into string
* @return PRUnichar* to internal string
*/
PRUnichar operator()(PRInt32 anIndex) const;
/**
* Retrieve reference to unicode char at given index
* @param offset into string
* @return PRUnichar& from internal string
*/
PRUnichar& operator[](PRInt32 anIndex) const;
/**
* Retrieve reference to unicode char at given index
* @param offset into string
* @return PRUnichar& from internal string
*/
PRUnichar& CharAt(PRInt32 anIndex) const;
/**
* Retrieve reference to first unicode char in string
* @return PRUnichar from internal string
*/
PRUnichar& First() const;
/**
* Retrieve reference to last unicode char in string
* @return PRUnichar from internal string
*/
PRUnichar& Last() const;
/**********************************************************************
String creation methods...
*********************************************************************/
/**
* Create a new string by appending given string to this
* @param aString -- 2nd string to be appended
* @return new string
*/
nsString operator+(const nsString& aString);
/**
* create a new string by adding this to the given buffer.
* @param aCString is a ptr to cstring to be added to this
* @return newly created string
*/
nsString operator+(const char* aCString);
/**
* create a new string by adding this to the given char.
* @param aChar is a char to be added to this
* @return newly created string
*/
nsString operator+(char aChar);
/**
* create a new string by adding this to the given buffer.
* @param aStr unichar buffer to be added to this
* @return newly created string
*/
nsString operator+(const PRUnichar* aBuffer);
/**
* create a new string by adding this to the given char.
* @param aChar is a unichar to be added to this
* @return newly created string
*/
nsString operator+(PRUnichar aChar);
/**
* Converts all chars in internal string to lower
*/
void ToLowerCase();
/**
* Converts all chars in given string to lower
*/
void ToLowerCase(nsString& aString) const;
/**
* Converts all chars in given string to upper
*/
void ToUpperCase();
/**
* Converts all chars in given string to UCS2
* which ensure that the lower 256 chars are correct.
*/
void ToUCS2(PRInt32 aStartOffset);
/**
* Converts all chars in internal string to upper
*/
void ToUpperCase(nsString& aString) const;
/**
* Creates a duplicate clone (ptr) of this string.
* @return ptr to clone of this string
*/
nsString* ToNewString() const;
/**
* Creates an ascii clone of this string
* NOTE: This string is allocated with new; YOU MUST deallocate with delete[]!
* @return ptr to new c-String string
*/
char* ToNewCString() const;
/**
* Copies data from internal buffer onto given char* buffer
* @param aBuf is the buffer where data is stored
* @param aBuflength is the max # of chars to move to buffer
* @return ptr to given buffer
*/
char* ToCString(char* aBuf,PRInt32 aBufLength) const;
/**
* Copies contents of this onto given string.
* @param aString to hold copy of this
* @return nada.
*/
void Copy(nsString& aString) const;
/**
* Creates an unichar clone of this string
* @return ptr to new unichar string
*/
PRUnichar* ToNewUnicode() const;
/**
* Perform string to float conversion.
* @param aErrorCode will contain error if one occurs
* @return float rep of string value
*/
float ToFloat(PRInt32* aErrorCode) const;
/**
* Perform string to int conversion.
* @param aErrorCode will contain error if one occurs
* @return int rep of string value
*/
PRInt32 ToInteger(PRInt32* aErrorCode,PRInt32 aRadix=10) const;
/**********************************************************************
String manipulation methods...
*********************************************************************/
/**
* assign given PRUnichar* to this string
* @param aStr: buffer to be assigned to this
* @param alength is the length of the given str (or -1)
if you want me to determine its length
* @return this
*/
nsString& SetString(const PRUnichar* aStr,PRInt32 aLength=-1);
/**
* assign given char* to this string
* @param aCString: buffer to be assigned to this
* @param alength is the length of the given str (or -1)
if you want me to determine its length
* @return this
*/
nsString& SetString(const char* aCString,PRInt32 aLength=-1);
/**
* assign given string to this one
* @param aString: string to be added to this
* @return this
*/
nsString& operator=(const nsString& aString);
/**
* assign given char* to this string
* @param aCString: buffer to be assigned to this
* @return this
*/
nsString& operator=(const char* aCString);
/**
* assign given char to this string
* @param aChar: char to be assignd to this
* @return this
*/
nsString& operator=(char aChar);
/**
* assign given unichar* to this string
* @param aBuffer: unichar buffer to be assigned to this
* @return this
*/
nsString& operator=(const PRUnichar* aBuffer);
/**
* assign given char to this string
* @param aChar: char to be assignd to this
* @return this
*/
nsString& operator=(PRUnichar aChar);
/**
* append given string to this string
* @param aString : string to be appended to this
* @return this
*/
nsString& operator+=(const nsString& aString);
/**
* append given buffer to this string
* @param aCString: buffer to be appended to this
* @return this
*/
nsString& operator+=(const char* aCString);
/**
* append given buffer to this string
* @param aBuffer: buffer to be appended to this
* @return this
*/
nsString& operator+=(const PRUnichar* aBuffer);
/**
* append given char to this string
* @param aChar: char to be appended to this
* @return this
*/
nsString& operator+=(PRUnichar aChar);
/**
* append given string to this string
* @param aString : string to be appended to this
* @param alength is the length of the given str (or -1)
if you want me to determine its length
* @return this
*/
nsString& Append(const nsString& aString,PRInt32 aLength=-1);
/**
* append given string to this string
* @param aString : string to be appended to this
* @param alength is the length of the given str (or -1)
if you want me to determine its length
* @return this
*/
nsString& Append(const char* aCString,PRInt32 aLength=-1);
/**
* append given string to this string
* @param aString : string to be appended to this
* @return this
*/
nsString& Append(char aChar);
/**
* append given unichar buffer to this string
* @param aString : string to be appended to this
* @param alength is the length of the given str (or -1)
if you want me to determine its length
* @return this
*/
nsString& Append(const PRUnichar* aBuffer,PRInt32 aLength=-1);
/**
* append given unichar character to this string
* @param aChar is the char to be appended to this
* @return this
*/
nsString& Append(PRUnichar aChar);
/**
* Append an integer onto this string
* @param aInteger is the int to be appended
* @param aRadix specifies 8,10,16
* @return this
*/
nsString& Append(PRInt32 aInteger,PRInt32 aRadix); //radix=8,10 or 16
/**
* Append a float value onto this string
* @param aFloat is the float to be appended
* @return this
*/
nsString& Append(float aFloat);
/*
* Copies n characters from this string to given string,
* starting at the leftmost offset.
*
*
* @param aCopy -- Receiving string
* @param aCount -- number of chars to copy
* @return number of chars copied
*/
PRInt32 Left(nsString& aCopy,PRInt32 aCount) const;
/*
* Copies n characters from this string to given string,
* starting at the given offset.
*
*
* @param aCopy -- Receiving string
* @param aCount -- number of chars to copy
* @param anOffset -- position where copying begins
* @return number of chars copied
*/
PRInt32 Mid(nsString& aCopy,PRInt32 anOffset,PRInt32 aCount) const;
/*
* Copies n characters from this string to given string,
* starting at rightmost char.
*
*
* @param aCopy -- Receiving string
* @param aCount -- number of chars to copy
* @return number of chars copied
*/
PRInt32 Right(nsString& aCopy,PRInt32 aCount) const;
/*
* This method inserts n chars from given string into this
* string at str[anOffset].
*
* @param aCopy -- String to be inserted into this
* @param anOffset -- insertion position within this str
* @param aCount -- number of chars to be copied from aCopy
* @return number of chars inserted into this.
*/
PRInt32 Insert(const nsString& aCopy,PRInt32 anOffset,PRInt32 aCount=-1);
/**
* Insert a single unicode char into this string at
* a specified offset.
*
* @param aChar char to be inserted into this string
* @param anOffset is insert pos in str
* @return the number of chars inserted into this string
*/
PRInt32 Insert(PRUnichar aChar,PRInt32 anOffset);
/*
* This method is used to cut characters in this string
* starting at anOffset, continuing for aCount chars.
*
* @param anOffset -- start pos for cut operation
* @param aCount -- number of chars to be cut
* @return *this
*/
nsString& Cut(PRInt32 anOffset,PRInt32 aCount);
/**
* This method is used to remove all occurances of the
* characters found in aSet from this string.
*
* @param aSet -- characters to be cut from this
* @return *this
*/
nsString& StripChars(const char* aSet);
/**
* This method is used to replace all occurances of the
* given source char with the given dest char
*
* @param
* @return *this
*/
nsString& ReplaceChar(PRUnichar aSourceChar, PRUnichar aDestChar);
/**
* This method strips whitespace throughout the string
*
* @return this
*/
nsString& StripWhitespace();
/**
* This method trims characters found in aTrimSet from
* either end of the underlying string.
*
* @param aTrimSet -- contains chars to be trimmed from
* both ends
* @return this
*/
nsString& Trim(const char* aSet,
PRBool aEliminateLeading=PR_TRUE,
PRBool aEliminateTrailing=PR_TRUE);
/**
* This method strips whitespace from string.
* You can control whether whitespace is yanked from
* start and end of string as well.
*
* @param aEliminateLeading controls stripping of leading ws
* @param aEliminateTrailing controls stripping of trailing ws
* @return this
*/
nsString& CompressWhitespace( PRBool aEliminateLeading=PR_TRUE,
PRBool aEliminateTrailing=PR_TRUE);
/**
* Determine if given char is a valid space character
*
* @param aChar is character to be tested
* @return TRUE if is valid space char
*/
static PRBool IsSpace(PRUnichar ch);
/**
* Determine if given char in valid alpha range
*
* @param aChar is character to be tested
* @return TRUE if in alpha range
*/
static PRBool IsAlpha(PRUnichar ch);
/**
* Determine if given char is valid digit
*
* @param aChar is character to be tested
* @return TRUE if char is a valid digit
*/
static PRBool IsDigit(PRUnichar ch);
/**********************************************************************
Searching methods...
*********************************************************************/
/**
* Search for given character within this string.
* This method does so by using a binary search,
* so your string HAD BETTER BE ORDERED!
*
* @param aChar is the unicode char to be found
* @return offset in string, or -1 (kNotFound)
*/
PRInt32 BinarySearch(PRUnichar aChar) const;
/**
* Search for given substring within this string
*
* @param aString is substring to be sought in this
* @return offset in string, or -1 (kNotFound)
*/
PRInt32 Find(const char* aString) const;
PRInt32 Find(const PRUnichar* aString) const;
PRInt32 Find(const nsString& aString) const;
/**
* Search for given char within this string
*
* @param aChar - char to be found
* @return offset in string, or -1 (kNotFound)
*/
PRInt32 Find(PRUnichar aChar,PRInt32 offset=0) const;
/**
* This method searches this string for the first character
* found in the given string
* @param aString contains set of chars to be found
* @param anOffset tells us where to start searching in this
* @return -1 if not found, else the offset in this
*/
PRInt32 FindCharInSet(const char* aString,PRInt32 anOffset=0) const;
PRInt32 FindCharInSet(nsString& aString,PRInt32 anOffset=0) const;
/**
* This method searches this string for the last character
* found in the given string
* @param aString contains set of chars to be found
* @param anOffset tells us where to start searching in this
* @return -1 if not found, else the offset in this
*/
PRInt32 RFindCharInSet(const char* aString,PRInt32 anOffset=0) const;
PRInt32 RFindCharInSet(nsString& aString,PRInt32 anOffset=0) const;
/**
* This methods scans the string backwards, looking for the given string
* @param aString is substring to be sought in this
* @param aIgnoreCase tells us whether or not to do caseless compare
* @return offset in string, or -1 (kNotFound)
*/
PRInt32 RFind(const char* aCString,PRBool aIgnoreCase=PR_FALSE) const;
PRInt32 RFind(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE) const;
PRInt32 RFind(const nsString& aString,PRBool aIgnoreCase=PR_FALSE) const;
/**
* This methods scans the string backwards, looking for the given char
* @param char is the char to be sought in this
* @param aIgnoreCase tells us whether or not to do caseless compare
* @return offset in string, or -1 (kNotFound)
*/
PRInt32 RFind(PRUnichar aChar,PRBool aIgnoreCase=PR_FALSE) const;
/**********************************************************************
Comparison methods...
*********************************************************************/
/**
* Compares a given string type to this string.
* @update gess 7/27/98
* @param S is the string to be compared
* @param aIgnoreCase tells us how to treat case
* @return -1,0,1
*/
virtual PRInt32 Compare(const nsString &aString,PRBool aIgnoreCase=PR_FALSE) const;
virtual PRInt32 Compare(const char *aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aLength=-1) const;
virtual PRInt32 Compare(const PRUnichar *aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aLength=-1) const;
/**
* These methods compare a given string type to this one
* @param aString is the string to be compared to this
* @return TRUE or FALSE
*/
PRBool operator==(const nsString &aString) const;
PRBool operator==(const char *aString) const;
PRBool operator==(const PRUnichar* aString) const;
PRBool operator==(PRUnichar* aString) const;
/**
* These methods perform a !compare of a given string type to this
* @param aString is the string to be compared to this
* @return TRUE
*/
PRBool operator!=(const nsString &aString) const;
PRBool operator!=(const char *aString) const;
PRBool operator!=(const PRUnichar* aString) const;
/**
* These methods test if a given string is < than this
* @param aString is the string to be compared to this
* @return TRUE or FALSE
*/
PRBool operator<(const nsString &aString) const;
PRBool operator<(const char *aString) const;
PRBool operator<(const PRUnichar* aString) const;
/**
* These methods test if a given string is > than this
* @param aString is the string to be compared to this
* @return TRUE or FALSE
*/
PRBool operator>(const nsString &S) const;
PRBool operator>(const char *aCString) const;
PRBool operator>(const PRUnichar* aString) const;
/**
* These methods test if a given string is <= than this
* @param aString is the string to be compared to this
* @return TRUE or FALSE
*/
PRBool operator<=(const nsString &S) const;
PRBool operator<=(const char *aCString) const;
PRBool operator<=(const PRUnichar* aString) const;
/**
* These methods test if a given string is >= than this
* @param aString is the string to be compared to this
* @return TRUE or FALSE
*/
PRBool operator>=(const nsString &S) const;
PRBool operator>=(const char* aCString) const;
PRBool operator>=(const PRUnichar* aString) const;
/**
* Compare this to given string; note that we compare full strings here.
* The optional length argument just lets us know how long the given string is.
* If you provide a length, it is compared to length of this string as an
* optimization.
*
* @param aString -- the string to compare to this
* @param aLength -- optional length of given string.
* @return TRUE if equal
*/
PRBool Equals(const nsString& aString) const;
PRBool Equals(const char* aString,PRInt32 aLength=-1) const;
PRBool Equals(const nsIAtom *aAtom) const;
/**
* Compares to unichar string ptrs to each other
* @param s1 is a ptr to a unichar buffer
* @param s2 is a ptr to a unichar buffer
* @return TRUE if they match
*/
PRBool Equals(const PRUnichar* s1, const PRUnichar* s2) const;
/**
* Compare this to given string; note that we compare full strings here.
* The optional length argument just lets us know how long the given string is.
* If you provide a length, it is compared to length of this string as an
* optimization.
*
* @param aString -- the string to compare to this
* @param aLength -- optional length of given string.
* @return TRUE if equal
*/
PRBool EqualsIgnoreCase(const nsString& aString) const;
PRBool EqualsIgnoreCase(const char* aString,PRInt32 aLength=-1) const;
PRBool EqualsIgnoreCase(const nsIAtom *aAtom) const;
/**
* Compares to unichar string ptrs to each other without respect to case
* @param s1 is a ptr to a unichar buffer
* @param s2 is a ptr to a unichar buffer
* @return TRUE if they match
*/
PRBool EqualsIgnoreCase(const PRUnichar* s1, const PRUnichar* s2) const;
static void SelfTest();
virtual void DebugDump(ostream& aStream) const;
protected:
typedef PRUnichar chartype;
chartype* mStr;
PRInt32 mLength;
PRInt32 mCapacity;
static PRBool mSelfTested;
};
ostream& operator<<(ostream& os,nsString& aString);
extern NS_BASE int fputs(const nsString& aString, FILE* out);
//----------------------------------------------------------------------
/**
* A version of nsString which is designed to be used as an automatic
* variable. It attempts to operate out of a fixed size internal
* buffer until too much data is added; then a dynamic buffer is
* allocated and grown as necessary.
*/
// XXX template this with a parameter for the size of the buffer?
class NS_BASE nsAutoString : public nsString {
public:
nsAutoString();
nsAutoString(const nsString& other);
nsAutoString(const nsAutoString& other);
nsAutoString(PRUnichar aChar);
nsAutoString(const char* aCString);
nsAutoString(const PRUnichar* us, PRInt32 uslen = -1);
virtual ~nsAutoString();
nsAutoString& operator=(const nsString& aString) {nsString::operator=(aString); return *this;}
nsAutoString& operator=(const nsAutoString& aString) {nsString::operator=(aString); return *this;}
nsAutoString& operator=(const char* aCString) {nsString::operator=(aCString); return *this;}
nsAutoString& operator=(char aChar) {nsString::operator=(aChar); return *this;}
nsAutoString& operator=(const PRUnichar* aBuffer) {nsString::operator=(aBuffer); return *this;}
nsAutoString& operator=(PRUnichar aChar) {nsString::operator=(aChar); return *this;}
virtual void SizeOf(nsISizeOfHandler* aHandler) const;
static void SelfTest();
protected:
virtual void EnsureCapacityFor(PRInt32 aNewLength);
chartype mBuf[32];
};
ostream& operator<<(ostream& os,nsAutoString& aString);
#endif

184
mozilla/base/src/nsTime.h Normal file
View File

@@ -0,0 +1,184 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsTime_h__
#define nsTime_h__
#include "prtime.h"
#include "nsInt64.h"
#include "nscore.h"
/**
* This class encapsulates full 64-bit time functionality and
* provides simple arithmetic and conversion operations.
*/
// If you ever decide that you need to add a non-inline method to this
// class, be sure to change the class declaration to "class NS_BASE
// nsTime".
class nsTime
{
private:
nsInt64 mValue;
public:
/**
* Construct the current time.
*/
nsTime(void) : mValue(PR_Now()) {
}
/**
* Construct a time from a PRTime.
*/
nsTime(const PRTime aTime) : mValue(aTime) {
}
/**
* Construct a time from a 64-bit value.
*/
nsTime(const nsInt64& aTime) : mValue(aTime) {
}
/**
* Construct a time from another time.
*/
nsTime(const nsTime& aTime) : mValue(aTime.mValue) {
}
// ~nsTime(void) -- XXX destructor unnecessary
/**
* Assign one time to another.
*/
const nsTime& operator =(const nsTime& aTime) {
mValue = aTime.mValue;
return *this;
}
/**
* Convert a nsTime object to a PRTime
*/
operator PRTime(void) const {
return mValue;
}
/**
* Subtract a 64-bit interval from a time.
*/
nsTime& operator -=(const nsInt64& aInterval) {
mValue -= aInterval;
return *this;
}
/**
* Add a 64-bit interval to a time.
*/
nsTime& operator +=(const nsInt64& aInterval) {
mValue += aInterval;
return *this;
}
// Arithmetic operators
friend const nsTime operator +(const nsTime& aTime, const nsInt64& aInterval);
friend const nsTime operator -(const nsTime& aTime, const nsInt64& aInterval);
friend const nsInt64 operator -(const nsTime& aTime1, const nsTime& aTime2);
// Comparison operators
friend const PRBool operator ==(const nsTime& aTime1, const nsTime& aTime2);
friend const PRBool operator !=(const nsTime& aTime1, const nsTime& aTime2);
friend const PRBool operator <(const nsTime& aTime1, const nsTime& aTime2);
friend const PRBool operator <=(const nsTime& aTime1, const nsTime& aTime2);
friend const PRBool operator >(const nsTime& aTime1, const nsTime& aTime2);
friend const PRBool operator >=(const nsTime& aTime1, const nsTime& aTime2);
};
/**
* Binary addition to add a 64-bit interval to a time.
*/
inline const nsTime
operator +(const nsTime& aTime, const nsInt64& aInterval) {
return nsTime(aTime.mValue + aInterval);
}
/**
* Binary subtraction to subtract a 64-bit interval to a time.
*/
inline const nsTime
operator -(const nsTime& aTime, const nsInt64& aInterval) {
return nsTime(aTime.mValue - aInterval);
}
/**
* Binary subtraction to compute an interval from the difference of two times.
*/
inline const nsInt64
operator -(const nsTime& aTime1, const nsTime& aTime2) {
return aTime1.mValue - aTime2.mValue;
}
/**
* Determine if two times are equal
*/
inline const PRBool
operator ==(const nsTime& aTime1, const nsTime& aTime2) {
return aTime1.mValue == aTime2.mValue;
}
/**
* Determine if two times are different
*/
inline const PRBool
operator !=(const nsTime& aTime1, const nsTime& aTime2) {
return aTime1.mValue != aTime2.mValue;
}
/**
* Determine if one time is strictly less than another
*/
inline const PRBool
operator <(const nsTime& aTime1, const nsTime& aTime2) {
return aTime1.mValue < aTime2.mValue;
}
/**
* Determine if one time is less than or equal to another
*/
inline const PRBool
operator <=(const nsTime& aTime1, const nsTime& aTime2) {
return aTime1.mValue <= aTime2.mValue;
}
/**
* Determine if one time is strictly greater than another
*/
inline const PRBool
operator >(const nsTime& aTime1, const nsTime& aTime2) {
return aTime1.mValue > aTime2.mValue;
}
/**
* Determine if one time is greater than or equal to another
*/
inline const PRBool
operator >=(const nsTime& aTime1, const nsTime& aTime2) {
return aTime1.mValue >= aTime2.mValue;
}
#endif // nsTime_h__

View File

@@ -0,0 +1,142 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsIUnicharBuffer.h"
#include "nsIUnicharInputStream.h"
#include "nsCRT.h"
#define MIN_BUFFER_SIZE 32
class UnicharBufferImpl : public nsIUnicharBuffer {
public:
UnicharBufferImpl(PRUint32 aBufferSize);
~UnicharBufferImpl();
NS_DECL_ISUPPORTS
virtual PRInt32 GetLength() const;
virtual PRInt32 GetBufferSize() const;
virtual PRUnichar* GetBuffer() const;
virtual PRBool Grow(PRInt32 aNewSize);
virtual PRInt32 Fill(nsresult* aErrorCode, nsIUnicharInputStream* aStream,
PRInt32 aKeep);
PRUnichar* mBuffer;
PRUint32 mSpace;
PRUint32 mLength;
};
UnicharBufferImpl::UnicharBufferImpl(PRUint32 aBufferSize)
{
if (aBufferSize < MIN_BUFFER_SIZE) {
aBufferSize = MIN_BUFFER_SIZE;
}
mSpace = aBufferSize;
mBuffer = new PRUnichar[aBufferSize];
mLength = 0;
NS_INIT_REFCNT();
}
NS_DEFINE_IID(kUnicharBufferIID, NS_IUNICHAR_BUFFER_IID);
NS_IMPL_ISUPPORTS(UnicharBufferImpl,kUnicharBufferIID)
UnicharBufferImpl::~UnicharBufferImpl()
{
if (nsnull != mBuffer) {
delete mBuffer;
mBuffer = nsnull;
}
mLength = 0;
}
PRInt32 UnicharBufferImpl::GetLength() const
{
return mLength;
}
PRInt32 UnicharBufferImpl::GetBufferSize() const
{
return mSpace;
}
PRUnichar* UnicharBufferImpl::GetBuffer() const
{
return mBuffer;
}
PRBool UnicharBufferImpl::Grow(PRInt32 aNewSize)
{
if (PRUint32(aNewSize) < MIN_BUFFER_SIZE) {
aNewSize = MIN_BUFFER_SIZE;
}
PRUnichar* newbuf = new PRUnichar[aNewSize];
if (nsnull != newbuf) {
if (0 != mLength) {
nsCRT::memcpy(newbuf, mBuffer, mLength * sizeof(PRUnichar));
}
delete mBuffer;
mBuffer = newbuf;
return PR_TRUE;
}
return PR_FALSE;
}
PRInt32 UnicharBufferImpl::Fill(nsresult* aErrorCode,
nsIUnicharInputStream* aStream,
PRInt32 aKeep)
{
NS_PRECONDITION(nsnull != aStream, "null stream");
NS_PRECONDITION(PRUint32(aKeep) < PRUint32(mLength), "illegal keep count");
if ((nsnull == aStream) || (PRUint32(aKeep) >= PRUint32(mLength))) {
// whoops
*aErrorCode = NS_BASE_STREAM_ILLEGAL_ARGS;
return -1;
}
if (0 != aKeep) {
// Slide over kept data
nsCRT::memmove(mBuffer, mBuffer + (mLength - aKeep),
aKeep * sizeof(PRUnichar));
}
// Read in some new data
mLength = aKeep;
PRInt32 amount = mSpace - aKeep;
PRUint32 nb;
NS_ASSERTION(aKeep >= 0, "unsigned madness");
NS_ASSERTION(amount >= 0, "unsigned madness");
*aErrorCode = aStream->Read(mBuffer, (PRUint32)aKeep, (PRUint32)amount, &nb);
if (NS_SUCCEEDED(*aErrorCode)) {
mLength += nb;
}
else
nb = 0;
return nb;
}
NS_BASE nsresult NS_NewUnicharBuffer(nsIUnicharBuffer** aInstancePtrResult,
nsISupports* aOuter,
PRUint32 aBufferSize)
{
if (nsnull != aOuter) {
return NS_ERROR_NO_AGGREGATION;
}
UnicharBufferImpl* it = new UnicharBufferImpl(aBufferSize);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kUnicharBufferIID, (void **) aInstancePtrResult);
}

View File

@@ -0,0 +1,314 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#define NS_IMPL_IDS
#include "nsIUnicharInputStream.h"
#include "nsIByteBuffer.h"
#include "nsIUnicharBuffer.h"
#include "nsIServiceManager.h"
#include "nsICharsetConverterManager.h"
#include "nsIUnicodeDecoder.h"
#include "nsString.h"
#include "nsCRT.h"
#include <fcntl.h>
#ifdef NS_WIN32
#include <io.h>
#else
#include <unistd.h>
#endif
static NS_DEFINE_IID(kIUnicharInputStreamIID, NS_IUNICHAR_INPUT_STREAM_IID);
class StringUnicharInputStream : public nsIUnicharInputStream {
public:
StringUnicharInputStream(nsString* aString);
~StringUnicharInputStream();
NS_DECL_ISUPPORTS
NS_IMETHOD Read(PRUnichar* aBuf,
PRUint32 aOffset,
PRUint32 aCount,
PRUint32 *aReadCount);
NS_IMETHOD Close();
nsString* mString;
PRUint32 mPos;
PRUint32 mLen;
};
StringUnicharInputStream::StringUnicharInputStream(nsString* aString)
{
NS_INIT_REFCNT();
mString = aString;
mPos = 0;
mLen = aString->Length();
}
StringUnicharInputStream::~StringUnicharInputStream()
{
if (nsnull != mString) {
delete mString;
}
}
nsresult StringUnicharInputStream::Read(PRUnichar* aBuf,
PRUint32 aOffset,
PRUint32 aCount,
PRUint32 *aReadCount)
{
if (mPos >= mLen) {
*aReadCount = 0;
return (nsresult)-1;
}
const PRUnichar* us = mString->GetUnicode();
NS_ASSERTION(mLen >= mPos, "unsigned madness");
PRUint32 amount = mLen - mPos;
if (amount > aCount) {
amount = aCount;
}
nsCRT::memcpy(aBuf + aOffset, us + mPos, sizeof(PRUnichar) * amount);
mPos += amount;
*aReadCount = amount;
return NS_OK;
}
nsresult StringUnicharInputStream::Close()
{
mPos = mLen;
if (nsnull != mString) {
delete mString;
}
return NS_OK;
}
NS_IMPL_ISUPPORTS(StringUnicharInputStream, kIUnicharInputStreamIID);
NS_BASE nsresult
NS_NewStringUnicharInputStream(nsIUnicharInputStream** aInstancePtrResult,
nsString* aString)
{
NS_PRECONDITION(nsnull != aString, "null ptr");
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if ((nsnull == aString) || (nsnull == aInstancePtrResult)) {
return NS_ERROR_NULL_POINTER;
}
StringUnicharInputStream* it = new StringUnicharInputStream(aString);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kIUnicharInputStreamIID,
(void**) aInstancePtrResult);
}
//----------------------------------------------------------------------
/**
* This function used to be public, with the NS_BASE declaration. I am
* changing it right now into a module private visibility because there are
* better and more xpcom-like ways to get a Converter.
*/
nsresult
NS_NewB2UConverter(nsIUnicodeDecoder** aInstancePtrResult,
nsISupports* aOuter,
nsString* aCharSet)
{
if (nsnull != aOuter) {
return NS_ERROR_NO_AGGREGATION;
}
// Create converter
nsresult res;
nsICharsetConverterManager * ccm;
nsAutoString defaultCharset("ISO-8859-1");
if (aCharSet == nsnull) aCharSet = &defaultCharset;
res = nsServiceManager::GetService(kCharsetConverterManagerCID,
kICharsetConverterManagerIID, (nsISupports**)&ccm);
if (NS_FAILED(res)) return res;
res = ccm->GetUnicodeDecoder(aCharSet, aInstancePtrResult);
nsServiceManager::ReleaseService(kCharsetConverterManagerCID, ccm);
return res;
}
//----------------------------------------------------------------------
class ConverterInputStream : public nsIUnicharInputStream {
public:
ConverterInputStream(nsIInputStream* aStream,
nsIUnicodeDecoder* aConverter,
PRUint32 aBufSize);
~ConverterInputStream();
NS_DECL_ISUPPORTS
NS_IMETHOD Read(PRUnichar* aBuf,
PRUint32 aOffset,
PRUint32 aCount,
PRUint32 *aReadCount);
NS_IMETHOD Close();
protected:
PRInt32 Fill(nsresult * aErrorCode);
nsIInputStream* mInput;
nsIUnicodeDecoder* mConverter;
nsIByteBuffer* mByteData;
PRUint32 mByteDataOffset;
nsIUnicharBuffer* mUnicharData;
PRUint32 mUnicharDataOffset;
PRUint32 mUnicharDataLength;
};
ConverterInputStream::ConverterInputStream(nsIInputStream* aStream,
nsIUnicodeDecoder* aConverter,
PRUint32 aBufferSize)
{
NS_INIT_REFCNT();
mInput = aStream; aStream->AddRef();
mConverter = aConverter; aConverter->AddRef();
if (aBufferSize == 0) {
aBufferSize = 8192;
}
nsresult rv1 = NS_NewByteBuffer(&mByteData, nsnull, aBufferSize);
nsresult rv2 = NS_NewUnicharBuffer(&mUnicharData, nsnull, aBufferSize);
mByteDataOffset = 0;
mUnicharDataOffset = 0;
mUnicharDataLength = 0;
}
NS_IMPL_ISUPPORTS(ConverterInputStream,kIUnicharInputStreamIID);
ConverterInputStream::~ConverterInputStream()
{
Close();
}
nsresult ConverterInputStream::Close()
{
if (nsnull != mInput) {
mInput->Release();
mInput = nsnull;
}
if (nsnull != mConverter) {
mConverter->Release();
mConverter = nsnull;
}
if (nsnull != mByteData) {
mByteData->Release();
mByteData = nsnull;
}
if (nsnull != mUnicharData) {
mUnicharData->Release();
mUnicharData = nsnull;
}
return NS_OK;
}
nsresult ConverterInputStream::Read(PRUnichar* aBuf,
PRUint32 aOffset,
PRUint32 aCount,
PRUint32 *aReadCount)
{
NS_ASSERTION(mUnicharDataLength >= mUnicharDataOffset, "unsigned madness");
PRUint32 rv = mUnicharDataLength - mUnicharDataOffset;
nsresult errorCode;
if (0 == rv) {
// Fill the unichar buffer
rv = Fill(&errorCode);
if (rv <= 0) {
*aReadCount = 0;
return errorCode;
}
}
if (rv > aCount) {
rv = aCount;
}
nsCRT::memcpy(aBuf + aOffset, mUnicharData->GetBuffer() + mUnicharDataOffset,
rv * sizeof(PRUnichar));
mUnicharDataOffset += rv;
*aReadCount = rv;
return NS_OK;
}
PRInt32 ConverterInputStream::Fill(nsresult * aErrorCode)
{
if (nsnull == mInput) {
// We already closed the stream!
*aErrorCode = NS_BASE_STREAM_CLOSED;
return -1;
}
NS_ASSERTION(mByteData->GetLength() >= mByteDataOffset, "unsigned madness");
PRUint32 remainder = mByteData->GetLength() - mByteDataOffset;
mByteDataOffset = remainder;
PRInt32 nb = mByteData->Fill(aErrorCode, mInput, remainder);
if (nb <= 0) {
// Because we assume a many to one conversion, the lingering data
// in the byte buffer must be a partial conversion
// fragment. Because we know that we have recieved no more new
// data to add to it, we can't convert it. Therefore, we discard
// it.
return nb;
}
NS_ASSERTION(remainder + nb == mByteData->GetLength(), "bad nb");
// Now convert as much of the byte buffer to unicode as possible
PRInt32 dstLen = mUnicharData->GetBufferSize();
PRInt32 srcLen = remainder + nb;
*aErrorCode = mConverter->Convert(mUnicharData->GetBuffer(), 0, &dstLen,
mByteData->GetBuffer(), 0, &srcLen);
mUnicharDataOffset = 0;
mUnicharDataLength = dstLen;
mByteDataOffset += srcLen;
return dstLen;
}
// XXX hook up auto-detect here (do we need more info, like the url?)
NS_BASE nsresult
NS_NewConverterStream(nsIUnicharInputStream** aInstancePtrResult,
nsISupports* aOuter,
nsIInputStream* aStreamToWrap,
PRInt32 aBufferSize,
nsString* aCharSet)
{
if (nsnull != aOuter) {
return NS_ERROR_NO_AGGREGATION;
}
// Create converter
nsIUnicodeDecoder* converter;
nsresult rv = NS_NewB2UConverter(&converter, nsnull, aCharSet);
if (NS_OK != rv) {
return rv;
}
// Create converter input stream
ConverterInputStream* it =
new ConverterInputStream(aStreamToWrap, converter, aBufferSize);
NS_RELEASE(converter);
if (nsnull == it) {
return NS_ERROR_OUT_OF_MEMORY;
}
return it->QueryInterface(kIUnicharInputStreamIID,
(void **) aInstancePtrResult);
}

View File

@@ -0,0 +1,182 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsUnitConversion_h__
#define nsUnitConversion_h__
#include "nscore.h"
#include <math.h>
/// handy constants
#define TWIPS_PER_POINT_INT 20
#define TWIPS_PER_POINT_FLOAT 20.0f
#define ROUND_EXCLUSIVE_CONST_FLOAT 0.4999999999999999f // XXX this should be derived from platform FLOAT_MIN
#define ROUND_CONST_FLOAT 0.5f
#define CEIL_CONST_FLOAT 0.9999999999999999f // XXX this should be derived from platform FLOAT_MIN
/*
* Coord Rounding Functions
*/
inline nscoord NSToCoordFloor(float aValue)
{
return ((0.0f <= aValue) ? nscoord(aValue) : nscoord(aValue - CEIL_CONST_FLOAT));
}
inline nscoord NSToCoordCeil(float aValue)
{
return ((0.0f <= aValue) ? nscoord(aValue + CEIL_CONST_FLOAT) : nscoord(aValue));
}
inline nscoord NSToCoordRound(float aValue)
{
return ((0.0f <= aValue) ? nscoord(aValue + ROUND_CONST_FLOAT) : nscoord(aValue - ROUND_CONST_FLOAT));
}
inline nscoord NSToCoordRoundExclusive(float aValue)
{
return ((0.0f <= aValue) ? nscoord(aValue + ROUND_EXCLUSIVE_CONST_FLOAT) :
nscoord(aValue - ROUND_EXCLUSIVE_CONST_FLOAT));
}
/*
* Int Rounding Functions
*/
inline PRInt32 NSToIntFloor(float aValue)
{
return ((0.0f <= aValue) ? PRInt32(aValue) : PRInt32(aValue - CEIL_CONST_FLOAT));
}
inline PRInt32 NSToIntCeil(float aValue)
{
return ((0.0f <= aValue) ? PRInt32(aValue + CEIL_CONST_FLOAT) : PRInt32(aValue));
}
inline PRInt32 NSToIntRound(float aValue)
{
return ((0.0f <= aValue) ? PRInt32(aValue + ROUND_CONST_FLOAT) : PRInt32(aValue - ROUND_CONST_FLOAT));
}
inline PRInt32 NSToIntRoundExclusive(float aValue)
{
return ((0.0f <= aValue) ? PRInt32(aValue + ROUND_EXCLUSIVE_CONST_FLOAT) :
PRInt32(aValue - ROUND_EXCLUSIVE_CONST_FLOAT));
}
/*
* Twips/Points conversions
*/
inline nscoord NSFloatPointsToTwips(float aPoints)
{
return NSToCoordRound(aPoints * TWIPS_PER_POINT_FLOAT);
}
inline nscoord NSIntPointsToTwips(PRInt32 aPoints)
{
return nscoord(aPoints * TWIPS_PER_POINT_INT);
}
inline PRInt32 NSTwipsToIntPoints(nscoord aTwips)
{
return NSToIntRound(aTwips / TWIPS_PER_POINT_FLOAT);
}
inline PRInt32 NSTwipsToFloorIntPoints(nscoord aTwips)
{
return NSToIntFloor(aTwips / TWIPS_PER_POINT_FLOAT);
}
inline PRInt32 NSTwipsToCeilIntPoints(nscoord aTwips)
{
return NSToIntCeil(aTwips / TWIPS_PER_POINT_FLOAT);
}
inline float NSTwipsToFloatPoints(nscoord aTwips)
{
return (float(aTwips) / TWIPS_PER_POINT_FLOAT);
}
/*
* Twips/Pixel conversions
*/
inline nscoord NSFloatPixelsToTwips(float aPixels, float aTwipsPerPixel)
{
return NSToCoordRound(aPixels * aTwipsPerPixel);
}
inline nscoord NSIntPixelsToTwips(PRInt32 aPixels, float aTwipsPerPixel)
{
return NSToCoordRound(float(aPixels) * aTwipsPerPixel);
}
inline float NSTwipsToFloatPixels(nscoord aTwips, float aPixelsPerTwip)
{
return (float(aTwips) * aPixelsPerTwip);
}
inline PRInt32 NSTwipsToIntPixels(nscoord aTwips, float aPixelsPerTwip)
{
return NSToIntRound(float(aTwips) * aPixelsPerTwip);
}
/*
* Twips/unit conversions
*/
inline nscoord NSUnitsToTwips(float aValue, float aPointsPerUnit)
{
return NSToCoordRound(aValue * aPointsPerUnit * TWIPS_PER_POINT_FLOAT);
}
inline float NSTwipsToUnits(nscoord aTwips, float aUnitsPerPoint)
{
return (aTwips * (aUnitsPerPoint / TWIPS_PER_POINT_FLOAT));
}
/// Unit conversion macros
//@{
#define NS_INCHES_TO_TWIPS(x) NSUnitsToTwips((x), 72.0f) // 72 points per inch
#define NS_FEET_TO_TWIPS(x) NSUnitsToTwips((x), (72.0f * 12.0f)) // 12 inches per foot
#define NS_MILES_TO_TWIPS(x) NSUnitsToTwips((x), (72.0f * 12.0f * 5280.0f)) // 5280 feet per mile
#define NS_MILLIMETERS_TO_TWIPS(x) NSUnitsToTwips((x), (72.0f * 0.03937f))
#define NS_CENTIMETERS_TO_TWIPS(x) NSUnitsToTwips((x), (72.0f * 0.3937f))
#define NS_METERS_TO_TWIPS(x) NSUnitsToTwips((x), (72.0f * 39.37f))
#define NS_KILOMETERS_TO_TWIPS(x) NSUnitsToTwips((x), (72.0f * 39370.0f))
#define NS_PICAS_TO_TWIPS(x) NSUnitsToTwips((x), 12.0f) // 12 points per pica
#define NS_DIDOTS_TO_TWIPS(x) NSUnitsToTwips((x), (16.0f / 15.0f)) // 15 didots per 16 points
#define NS_CICEROS_TO_TWIPS(x) NSUnitsToTwips((x), (12.0f * (16.0f / 15.0f))) // 12 didots per cicero
#define NS_TWIPS_TO_INCHES(x) NSTwipsToUnits((x), 1.0f / 72.0f)
#define NS_TWIPS_TO_FEET(x) NSTwipsToUnits((x), 1.0f / (72.0f * 12.0f))
#define NS_TWIPS_TO_MILES(x) NSTwipsToUnits((x), 1.0f / (72.0f * 12.0f * 5280.0f))
#define NS_TWIPS_TO_MILLIMETERS(x) NSTwipsToUnits((x), 1.0f / (72.0f * 0.03937f))
#define NS_TWIPS_TO_CENTIMETERS(x) NSTwipsToUnits((x), 1.0f / (72.0f * 0.3937f))
#define NS_TWIPS_TO_METERS(x) NSTwipsToUnits((x), 1.0f / (72.0f * 39.37f))
#define NS_TWIPS_TO_KILOMETERS(x) NSTwipsToUnits((x), 1.0f / (72.0f * 39370.0f))
#define NS_TWIPS_TO_PICAS(x) NSTwipsToUnits((x), 1.0f / 12.0f)
#define NS_TWIPS_TO_DIDOTS(x) NSTwipsToUnits((x), 1.0f / (16.0f / 15.0f))
#define NS_TWIPS_TO_CICEROS(x) NSTwipsToUnits((x), 1.0f / (12.0f * (16.0f / 15.0f)))
//@}
#endif

View File

@@ -0,0 +1,411 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsVoidArray.h"
#include "nsCRT.h"
#include "nsISizeOfHandler.h"
#include "nsString.h"
static PRInt32 kGrowArrayBy = 8;
nsVoidArray::nsVoidArray()
{
mArray = nsnull;
mArraySize = 0;
mCount = 0;
}
nsVoidArray::nsVoidArray(PRInt32 aCount)
{
NS_PRECONDITION(aCount > 0, "bad count");
mCount = mArraySize = aCount;
mArray = new void*[mCount];
nsCRT::memset(mArray, 0, mCount * sizeof(void*));
}
nsVoidArray& nsVoidArray::operator=(const nsVoidArray& other)
{
if (nsnull != mArray) {
delete mArray;
}
PRInt32 otherCount = other.mCount;
mArraySize = otherCount;
mCount = otherCount;
if (otherCount != 0) {
mArray = new void*[otherCount];
nsCRT::memcpy(mArray, other.mArray, otherCount * sizeof(void*));
} else {
mArray = nsnull;
}
return *this;
}
nsVoidArray::~nsVoidArray()
{
if (nsnull != mArray) {
delete [] mArray;
}
}
void
nsVoidArray::SizeOf(nsISizeOfHandler* aHandler) const
{
aHandler->Add(sizeof(*this));
aHandler->Add(sizeof(void*) * mArraySize);
}
void* nsVoidArray::ElementAt(PRInt32 aIndex) const
{
if (PRUint32(aIndex) >= PRUint32(mCount)) {
return nsnull;
}
return mArray[aIndex];
}
PRInt32 nsVoidArray::IndexOf(void* aPossibleElement) const
{
void** ap = mArray;
void** end = ap + mCount;
while (ap < end) {
if (*ap == aPossibleElement) {
return ap - mArray;
}
ap++;
}
return -1;
}
PRBool nsVoidArray::InsertElementAt(void* aElement, PRInt32 aIndex)
{
PRInt32 oldCount = mCount;
if (PRUint32(aIndex) > PRUint32(oldCount)) {
// An invalid index causes the insertion to fail
return PR_FALSE;
}
if (oldCount + 1 > mArraySize) {
// We have to grow the array
PRInt32 newCount = oldCount + kGrowArrayBy;
void** newArray = new void*[newCount];
if (mArray != nsnull && aIndex != 0)
nsCRT::memcpy(newArray, mArray, aIndex * sizeof(void*));
PRInt32 slide = oldCount - aIndex;
if (0 != slide) {
// Slide data over to make room for the insertion
nsCRT::memcpy(newArray + aIndex + 1, mArray + aIndex,
slide * sizeof(void*));
}
if (mArray != nsnull)
delete [] mArray;
mArray = newArray;
mArraySize = newCount;
} else {
// The array is already large enough
PRInt32 slide = oldCount - aIndex;
if (0 != slide) {
// Slide data over to make room for the insertion
nsCRT::memmove(mArray + aIndex + 1, mArray + aIndex,
slide * sizeof(void*));
}
}
mArray[aIndex] = aElement;
mCount++;
return PR_TRUE;
}
PRBool nsVoidArray::ReplaceElementAt(void* aElement, PRInt32 aIndex)
{
if (PRUint32(aIndex) >= PRUint32(mArraySize)) {
PRInt32 requestedCount = aIndex + 1;
PRInt32 growDelta = requestedCount - mCount;
PRInt32 newCount = mCount + (growDelta > kGrowArrayBy ? growDelta : kGrowArrayBy);
void** newArray = new void*[newCount];
nsCRT::memset(newArray, 0, newCount * sizeof(void*));
if (newArray==nsnull)
return PR_FALSE;
if (mArray != nsnull && aIndex != 0) {
nsCRT::memcpy(newArray, mArray, mCount * sizeof(void*));
if (mArray != nsnull)
delete [] mArray;
}
mArray = newArray;
mArraySize = newCount;
}
mArray[aIndex] = aElement;
if (aIndex >= mCount)
mCount = aIndex+1;
return PR_TRUE;
}
PRBool nsVoidArray::RemoveElementAt(PRInt32 aIndex)
{
PRInt32 oldCount = mCount;
if (PRUint32(aIndex) >= PRUint32(oldCount)) {
// An invalid index causes the replace to fail
return PR_FALSE;
}
// We don't need to move any elements if we're removing the
// last element in the array
if (aIndex < (oldCount - 1)) {
nsCRT::memmove(mArray + aIndex, mArray + aIndex + 1,
(oldCount - 1 - aIndex) * sizeof(void*));
}
mCount--;
return PR_TRUE;
}
PRBool nsVoidArray::RemoveElement(void* aElement)
{
void** ep = mArray;
void** end = ep + mCount;
while (ep < end) {
void* e = *ep++;
if (e == aElement) {
ep--;
return RemoveElementAt(PRInt32(ep - mArray));
}
}
return PR_FALSE;
}
void nsVoidArray::Clear()
{
mCount = 0;
}
void nsVoidArray::Compact()
{
PRInt32 count = mCount;
if (mArraySize != count) {
void** newArray = new void*[count];
if (nsnull != newArray) {
nsCRT::memcpy(newArray, mArray, count * sizeof(void*));
delete [] mArray;
mArray = newArray;
mArraySize = count;
}
}
}
PRBool nsVoidArray::EnumerateForwards(nsVoidArrayEnumFunc aFunc, void* aData)
{
PRInt32 index = -1;
PRBool running = PR_TRUE;
while (running && (++index < mCount)) {
running = (*aFunc)(mArray[index], aData);
}
return running;
}
PRBool nsVoidArray::EnumerateBackwards(nsVoidArrayEnumFunc aFunc, void* aData)
{
PRInt32 index = mCount;
PRBool running = PR_TRUE;
while (running && (0 <= --index)) {
running = (*aFunc)(mArray[index], aData);
}
return running;
}
//----------------------------------------------------------------
// nsStringArray
nsStringArray::nsStringArray(void)
: nsVoidArray()
{
}
nsStringArray::~nsStringArray(void)
{
Clear();
}
nsStringArray&
nsStringArray::operator=(const nsStringArray& other)
{
if (nsnull != mArray) {
delete mArray;
}
PRInt32 otherCount = other.mCount;
mArraySize = otherCount;
mCount = otherCount;
if (0 < otherCount) {
mArray = new void*[otherCount];
while (0 <= --otherCount) {
nsString* otherString = (nsString*)(other.mArray[otherCount]);
mArray[otherCount] = new nsString(*otherString);
}
} else {
mArray = nsnull;
}
return *this;
}
void
nsStringArray::SizeOf(nsISizeOfHandler* aHandler) const
{
nsVoidArray::SizeOf(aHandler);
PRInt32 index = mCount;
while (0 <= --index) {
nsString* string = (nsString*)mArray[index];
string->SizeOf(aHandler);
}
}
void
nsStringArray::StringAt(PRInt32 aIndex, nsString& aString) const
{
nsString* string = (nsString*)nsVoidArray::ElementAt(aIndex);
if (nsnull != string) {
aString = *string;
}
else {
aString.Truncate();
}
}
nsString*
nsStringArray::StringAt(PRInt32 aIndex) const
{
return (nsString*)nsVoidArray::ElementAt(aIndex);
}
PRInt32
nsStringArray::IndexOf(const nsString& aPossibleString) const
{
void** ap = mArray;
void** end = ap + mCount;
while (ap < end) {
nsString* string = (nsString*)*ap;
if (string->Equals(aPossibleString)) {
return ap - mArray;
}
ap++;
}
return -1;
}
PRInt32
nsStringArray::IndexOfIgnoreCase(const nsString& aPossibleString) const
{
void** ap = mArray;
void** end = ap + mCount;
while (ap < end) {
nsString* string = (nsString*)*ap;
if (string->EqualsIgnoreCase(aPossibleString)) {
return ap - mArray;
}
ap++;
}
return -1;
}
PRBool
nsStringArray::InsertStringAt(const nsString& aString, PRInt32 aIndex)
{
nsString* string = new nsString(aString);
if (nsVoidArray::InsertElementAt(string, aIndex)) {
return PR_TRUE;
}
delete string;
return PR_FALSE;
}
PRBool
nsStringArray::ReplaceStringAt(const nsString& aString, PRInt32 aIndex)
{
nsString* string = (nsString*)nsVoidArray::ElementAt(aIndex);
if (nsnull != string) {
*string = aString;
return PR_TRUE;
}
return PR_FALSE;
}
PRBool
nsStringArray::RemoveString(const nsString& aString)
{
PRInt32 index = IndexOf(aString);
if (-1 < index) {
return RemoveStringAt(index);
}
return PR_FALSE;
}
PRBool
nsStringArray::RemoveStringIgnoreCase(const nsString& aString)
{
PRInt32 index = IndexOfIgnoreCase(aString);
if (-1 < index) {
return RemoveStringAt(index);
}
return PR_FALSE;
}
PRBool nsStringArray::RemoveStringAt(PRInt32 aIndex)
{
nsString* string = StringAt(aIndex);
if (nsnull != string) {
nsVoidArray::RemoveElementAt(aIndex);
delete string;
return PR_TRUE;
}
return PR_FALSE;
}
void
nsStringArray::Clear(void)
{
PRInt32 index = mCount;
while (0 <= --index) {
nsString* string = (nsString*)mArray[index];
delete string;
}
nsVoidArray::Clear();
}
PRBool
nsStringArray::EnumerateForwards(nsStringArrayEnumFunc aFunc, void* aData)
{
PRInt32 index = -1;
PRBool running = PR_TRUE;
while (running && (++index < mCount)) {
running = (*aFunc)(*((nsString*)mArray[index]), aData);
}
return running;
}
PRBool
nsStringArray::EnumerateBackwards(nsStringArrayEnumFunc aFunc, void* aData)
{
PRInt32 index = mCount;
PRBool running = PR_TRUE;
while (running && (0 <= --index)) {
running = (*aFunc)(*((nsString*)mArray[index]), aData);
}
return running;
}

View File

@@ -0,0 +1,125 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsVoidArray_h___
#define nsVoidArray_h___
#include "nscore.h"
class nsISizeOfHandler;
// Enumerator callback function. Return PR_FALSE to stop
typedef PRBool (*nsVoidArrayEnumFunc)(void* aElement, void *aData);
/// A basic zero-based array of void*'s that manages its own memory
class NS_BASE nsVoidArray {
public:
nsVoidArray();
nsVoidArray(PRInt32 aCount); // initial count of aCount elements set to nsnull
~nsVoidArray();
nsVoidArray& operator=(const nsVoidArray& other);
void SizeOf(nsISizeOfHandler* aHandler) const;
PRInt32 Count() const {
return mCount;
}
void* ElementAt(PRInt32 aIndex) const;
void* operator[](PRInt32 aIndex) const { return ElementAt(aIndex); }
PRInt32 IndexOf(void* aPossibleElement) const;
PRBool InsertElementAt(void* aElement, PRInt32 aIndex);
PRBool ReplaceElementAt(void* aElement, PRInt32 aIndex);
PRBool AppendElement(void* aElement) {
return InsertElementAt(aElement, mCount);
}
PRBool RemoveElement(void* aElement);
PRBool RemoveElementAt(PRInt32 aIndex);
void Clear();
void Compact();
PRBool EnumerateForwards(nsVoidArrayEnumFunc aFunc, void* aData);
PRBool EnumerateBackwards(nsVoidArrayEnumFunc aFunc, void* aData);
protected:
void** mArray;
PRInt32 mArraySize;
PRInt32 mCount;
private:
/// Copy constructors are not allowed
nsVoidArray(const nsVoidArray& other);
};
class nsString;
typedef PRBool (*nsStringArrayEnumFunc)(nsString& aElement, void *aData);
class NS_BASE nsStringArray: protected nsVoidArray
{
public:
nsStringArray(void);
~nsStringArray(void);
nsStringArray& operator=(const nsStringArray& other);
void SizeOf(nsISizeOfHandler* aHandler) const;
PRInt32 Count(void) const {
return mCount;
}
void StringAt(PRInt32 aIndex, nsString& aString) const;
nsString* StringAt(PRInt32 aIndex) const;
nsString* operator[](PRInt32 aIndex) const { return StringAt(aIndex); }
PRInt32 IndexOf(const nsString& aPossibleString) const;
PRInt32 IndexOfIgnoreCase(const nsString& aPossibleString) const;
PRBool InsertStringAt(const nsString& aString, PRInt32 aIndex);
PRBool ReplaceStringAt(const nsString& aString, PRInt32 aIndex);
PRBool AppendString(const nsString& aString) {
return InsertStringAt(aString, mCount);
}
PRBool RemoveString(const nsString& aString);
PRBool RemoveStringIgnoreCase(const nsString& aString);
PRBool RemoveStringAt(PRInt32 aIndex);
void Clear(void);
void Compact(void) {
nsVoidArray::Compact();
}
PRBool EnumerateForwards(nsStringArrayEnumFunc aFunc, void* aData);
PRBool EnumerateBackwards(nsStringArrayEnumFunc aFunc, void* aData);
private:
/// Copy constructors are not allowed
nsStringArray(const nsStringArray& other);
};
#endif /* nsVoidArray_h___ */

168
mozilla/base/src/nscore.h Normal file
View File

@@ -0,0 +1,168 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nscore_h___
#define nscore_h___
#ifdef _WIN32
#define NS_WIN32 1
#endif
#if defined(__unix)
#define NS_UNIX 1
#endif
#include "prtypes.h"
#include "nsDebug.h"
/** ucs2 datatype for 2 byte unicode characters */
typedef PRUint16 PRUcs2;
/** ucs4 datatype for 4 byte unicode characters */
typedef PRUint32 PRUcs4;
#ifdef NS_UCS4
typedef PRUcs4 PRUnichar;
#else
typedef PRUcs2 PRUnichar;
#endif
/// The preferred symbol for null.
#define nsnull 0
/* Define brackets for protecting C code from C++ */
#ifdef __cplusplus
#define NS_BEGIN_EXTERN_C extern "C" {
#define NS_END_EXTERN_C }
#else
#define NS_BEGIN_EXTERN_C
#define NS_END_EXTERN_C
#endif
/*----------------------------------------------------------------------*/
/* Import/export defines */
#ifdef NS_WIN32
#define NS_IMPORT _declspec(dllimport)
#define NS_IMPORT_(type) type _declspec(dllimport) __stdcall
#define NS_EXPORT _declspec(dllexport)
// XXX NS_EXPORT_ defined in nsCOm.h (xpcom) differs in where the __declspec
// is placed. It needs to be done this way to make the 4.x compiler happy...
#undef NS_EXPORT_
#define NS_EXPORT_(type) type _declspec(dllexport) __stdcall
#elif defined(XP_MAC)
#define NS_IMPORT
#define NS_IMPORT_(type) type
// XXX NS_EXPORT_ defined in nsCom.h actually does an export. Here it's just sugar.
#undef NS_EXPORT
#undef NS_EXPORT_
#define NS_EXPORT __declspec(export)
#define NS_EXPORT_(type) type __declspec(export)
#else
/* XXX do something useful? */
#define NS_IMPORT
#define NS_IMPORT_(type) type
#define NS_EXPORT
#define NS_EXPORT_(type) type
#endif
#ifdef _IMPL_NS_BASE
#define NS_BASE NS_EXPORT
#else
#define NS_BASE NS_IMPORT
#endif
#ifdef _IMPL_NS_NET
#define NS_NET NS_EXPORT
#else
#define NS_NET NS_IMPORT
#endif
#ifdef _IMPL_NS_DOM
#define NS_DOM NS_EXPORT
#else
#define NS_DOM NS_IMPORT
#endif
#ifdef _IMPL_NS_WIDGET
#define NS_WIDGET NS_EXPORT
#else
#define NS_WIDGET NS_IMPORT
#endif
#ifdef _IMPL_NS_VIEW
#define NS_VIEW NS_EXPORT
#else
#define NS_VIEW NS_IMPORT
#endif
#ifdef _IMPL_NS_GFXNONXP
#define NS_GFXNONXP NS_EXPORT
#define NS_GFXNONXP_(type) NS_EXPORT_(type)
#else
#define NS_GFXNONXP NS_IMPORT
#define NS_GFXNONXP_(type) NS_IMPORT_(type)
#endif
#ifdef _IMPL_NS_GFX
#define NS_GFX NS_EXPORT
#define NS_GFX_(type) NS_EXPORT_(type)
#else
#define NS_GFX NS_IMPORT
#define NS_GFX_(type) NS_IMPORT_(type)
#endif
#ifdef _IMPL_NS_PLUGIN
#define NS_PLUGIN NS_EXPORT
#else
#define NS_PLUGIN NS_IMPORT
#endif
#ifdef _IMPL_NS_APPSHELL
#define NS_APPSHELL NS_EXPORT
#else
#define NS_APPSHELL NS_IMPORT
#endif
/* ------------------------------------------------------------------------ */
// Casting macros for hiding C++ features from older compilers
#define HAS_C_PLUS_PLUS_CASTS // we'll be optimistic.
#if defined(__sgi) && !defined(__GNUC__)
#undef HAS_C_PLUS_PLUS_CASTS
#endif
#if defined(HAS_C_PLUS_PLUS_CASTS)
#define NS_STATIC_CAST(__type, __ptr) static_cast<__type>(__ptr)
#define NS_CONST_CAST(__type, __ptr) const_cast<__type>(__ptr)
#define NS_REINTERPRET_CAST(__type, __ptr) reinterpret_cast<__type>(__ptr)
#else
#define NS_STATIC_CAST(__type, __ptr) ((__type)(__ptr))
#define NS_CONST_CAST(__type, __ptr) ((__type)(__ptr))
#define NS_REINTERPRET_CAST(__type, __ptr) ((__type)(__ptr))
#endif
// No sense in making an NS_DYNAMIC_CAST() macro: you can't duplicate
// the semantics. So if you want to dynamic_cast, then just use it
// "straight", no macro.
#endif /* nscore_h___ */

View File

@@ -0,0 +1,47 @@
#!gmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
LIBRARY_NAME = gmbaseunix
MODULE=base
REQUIRES=xpcom raptor
DEFINES += -D_IMPL_NS_WIDGET
CPPSRCS= \
nsTimer.cpp
CPP_OBJS= \
./$(OBJDIR)/nsTimer.o \
$(NULL)
include $(topsrcdir)/config/config.mk
TARGETS = $(LIBRARY)
include $(topsrcdir)/config/rules.mk

View File

@@ -0,0 +1,39 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nscore.h"
#include "nsCaretProperties.h"
//-----------------------------------------------------------------------------
nsCaretProperties::nsCaretProperties()
: mCaretWidth(eDefaultCaretWidth)
, mBlinkRate(eDefaulBlinkRate)
{
// in your platform-specific class, get data from the OS in your constructor
}
//-----------------------------------------------------------------------------
nsCaretProperties* NewCaretProperties()
{
return new nsCaretProperties();
}

View File

@@ -0,0 +1,200 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsITimer.h"
#include "nsITimerCallback.h"
#include "nsCRT.h"
#include "prlog.h"
#include <stdio.h>
#include <limits.h>
//
// Copied from the unix version, Rhapsody needs to
// make this work. Stubs to compile things for now.
//
#if 0
Michael Hanni <mhanni@sprintmail.com> suggests:
I understand that nsTimer.cpp in base/rhapsody/ needs to be completed,
yes? Wouldn't this code just use some NSTimers in the NSRunLoop?
Timer = [NSTimer timerWithTimeInterval:0.02 //seconds
target:self
selector:@selector(doThis:)
userInfo:nil
repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:Timer
forMode:NSDefaultRunLoopMode];
I only looked at nsTimer.cpp briefly, but could something like this work
if imbedded in all that c++? ;-)
#endif
static NS_DEFINE_IID(kITimerIID, NS_ITIMER_IID);
extern void nsTimerExpired(void *aCallData);
class TimerImpl : public nsITimer {
public:
public:
TimerImpl();
virtual ~TimerImpl();
virtual nsresult Init(nsTimerCallbackFunc aFunc,
void *aClosure,
// PRBool aRepeat,
PRUint32 aDelay);
virtual nsresult Init(nsITimerCallback *aCallback,
// PRBool aRepeat,
PRUint32 aDelay);
NS_DECL_ISUPPORTS
virtual void Cancel();
virtual PRUint32 GetDelay() { return mDelay; }
virtual void SetDelay(PRUint32 aDelay) { mDelay=aDelay; };
virtual void* GetClosure() { return mClosure; }
void FireTimeout();
private:
nsresult Init(PRUint32 aDelay);
PRUint32 mDelay;
nsTimerCallbackFunc mFunc;
void *mClosure;
nsITimerCallback *mCallback;
// PRBool mRepeat;
TimerImpl *mNext;
int mTimerId;
};
void TimerImpl::FireTimeout()
{
if (mFunc != NULL) {
(*mFunc)(this, mClosure);
}
else if (mCallback != NULL) {
mCallback->Notify(this); // Fire the timer
}
// Always repeating here
// if (mRepeat)
// mTimerId = XtAppAddTimeOut(gAppContext, GetDelay(),(XtTimerCallbackProc)nsTimerExpired, this);
}
TimerImpl::TimerImpl()
{
NS_INIT_REFCNT();
mFunc = NULL;
mCallback = NULL;
mNext = NULL;
mTimerId = 0;
mDelay = 0;
mClosure = NULL;
}
TimerImpl::~TimerImpl()
{
}
nsresult
TimerImpl::Init(nsTimerCallbackFunc aFunc,
void *aClosure,
// PRBool aRepeat,
PRUint32 aDelay)
{
mFunc = aFunc;
mClosure = aClosure;
// mRepeat = aRepeat;
printf("TimerImpl::Init() not implemented\n");
#ifdef RHAPSODY_NEEDS_TO_IMPLEMENT_THIS
mTimerId = XtAppAddTimeOut(gAppContext, aDelay,(XtTimerCallbackProc)nsTimerExpired, this);
#endif
return Init(aDelay);
}
nsresult
TimerImpl::Init(nsITimerCallback *aCallback,
// PRBool aRepeat,
PRUint32 aDelay)
{
mCallback = aCallback;
// mRepeat = aRepeat;
printf("TimerImpl::Init() not implmented.\n");
#ifdef RHAPSODY_NEEDS_TO_IMPLEMENT_THIS
mTimerId = XtAppAddTimeOut(gAppContext, aDelay, (XtTimerCallbackProc)nsTimerExpired, this);
#endif
return Init(aDelay);
}
nsresult
TimerImpl::Init(PRUint32 aDelay)
{
mDelay = aDelay;
NS_ADDREF(this);
return NS_OK;
}
NS_IMPL_ISUPPORTS(TimerImpl, kITimerIID)
void
TimerImpl::Cancel()
{
printf("TimerImpl::Cancel() not implemented.\n");
#ifdef RHAPSODY_NEEDS_TO_IMPLEMENT_THIS
XtRemoveTimeOut(mTimerId);
#endif
}
NS_BASE nsresult NS_NewTimer(nsITimer** aInstancePtrResult)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
TimerImpl *timer = new TimerImpl();
if (nsnull == timer) {
return NS_ERROR_OUT_OF_MEMORY;
}
return timer->QueryInterface(kITimerIID, (void **) aInstancePtrResult);
}
void nsTimerExpired(void *aCallData)
{
TimerImpl* timer = (TimerImpl *)aCallData;
timer->FireTimeout();
}

View File

@@ -0,0 +1,6 @@
This directory is obsolete.
The nsTimer files that used to live here have been moved to ../motif
in order to allow for multiple unix toolkits.
ramiro@netscape.com 11-02-1998

View File

@@ -0,0 +1,365 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
// This file is included by nsFileSpec.cpp, and includes the Unix-specific
// implementations.
#include <sys/stat.h>
#include <sys/param.h>
#include <errno.h>
#include <dirent.h>
#include <unistd.h>
#include <stdlib.h>
#include "nsError.h"
//----------------------------------------------------------------------------------------
void nsFileSpecHelpers::Canonify(char*& ioPath, PRBool inMakeDirs)
// Canonify, make absolute, and check whether directories exist
//----------------------------------------------------------------------------------------
{
if (!ioPath)
return;
if (inMakeDirs)
{
const mode_t mode = 0700;
nsFileSpecHelpers::MakeAllDirectories(ioPath, mode);
}
char buffer[MAXPATHLEN];
errno = 0;
*buffer = '\0';
char* canonicalPath = realpath(ioPath, buffer);
if (!canonicalPath)
{
// Linux's realpath() is pathetically buggy. If the reason for the nil
// result is just that the leaf does not exist, strip the leaf off,
// process that, and then add the leaf back.
char* allButLeaf = nsFileSpecHelpers::StringDup(ioPath);
if (!allButLeaf)
return;
char* lastSeparator = strrchr(allButLeaf, '/');
if (lastSeparator)
{
*lastSeparator = '\0';
canonicalPath = realpath(allButLeaf, buffer);
strcat(buffer, "/");
// Add back the leaf
strcat(buffer, ++lastSeparator);
}
delete [] allButLeaf;
}
if (!canonicalPath && *ioPath != '/' && !inMakeDirs)
{
// Well, if it's a relative path, hack it ourselves.
canonicalPath = realpath(".", buffer);
if (canonicalPath)
{
strcat(canonicalPath, "/");
strcat(canonicalPath, ioPath);
}
}
if (canonicalPath)
nsFileSpecHelpers::StringAssign(ioPath, canonicalPath);
} // nsFileSpecHelpers::Canonify
//----------------------------------------------------------------------------------------
void nsFileSpec::SetLeafName(const char* inLeafName)
//----------------------------------------------------------------------------------------
{
nsFileSpecHelpers::LeafReplace(mPath, '/', inLeafName);
} // nsFileSpec::SetLeafName
//----------------------------------------------------------------------------------------
char* nsFileSpec::GetLeafName() const
//----------------------------------------------------------------------------------------
{
return nsFileSpecHelpers::GetLeaf(mPath, '/');
} // nsFileSpec::GetLeafName
//----------------------------------------------------------------------------------------
PRBool nsFileSpec::Exists() const
//----------------------------------------------------------------------------------------
{
struct stat st;
return 0 == stat(mPath, &st);
} // nsFileSpec::Exists
//----------------------------------------------------------------------------------------
PRBool nsFileSpec::IsFile() const
//----------------------------------------------------------------------------------------
{
struct stat st;
return 0 == stat(mPath, &st) && S_ISREG(st.st_mode);
} // nsFileSpec::IsFile
//----------------------------------------------------------------------------------------
PRBool nsFileSpec::IsDirectory() const
//----------------------------------------------------------------------------------------
{
struct stat st;
return 0 == stat(mPath, &st) && S_ISDIR(st.st_mode);
} // nsFileSpec::IsDirectory
//----------------------------------------------------------------------------------------
void nsFileSpec::GetParent(nsFileSpec& outSpec) const
//----------------------------------------------------------------------------------------
{
nsFileSpecHelpers::StringAssign(outSpec.mPath, mPath);
char* cp = strrchr(outSpec.mPath, '/');
if (cp)
*cp = '\0';
} // nsFileSpec::GetParent
//----------------------------------------------------------------------------------------
void nsFileSpec::operator += (const char* inRelativePath)
//----------------------------------------------------------------------------------------
{
if (!inRelativePath || !mPath)
return;
char endChar = mPath[strlen(mPath) - 1];
if (endChar == '/')
nsFileSpecHelpers::ReallocCat(mPath, "x");
else
nsFileSpecHelpers::ReallocCat(mPath, "/x");
SetLeafName(inRelativePath);
} // nsFileSpec::operator +=
//----------------------------------------------------------------------------------------
void nsFileSpec::CreateDirectory(int mode)
//----------------------------------------------------------------------------------------
{
// Note that mPath is canonical!
mkdir(mPath, mode);
} // nsFileSpec::CreateDirectory
//----------------------------------------------------------------------------------------
void nsFileSpec::Delete(PRBool inRecursive)
// To check if this worked, call Exists() afterwards, see?
//----------------------------------------------------------------------------------------
{
if (IsDirectory())
{
if (inRecursive)
{
for (nsDirectoryIterator i(*this); i.Exists(); i++)
{
nsFileSpec& child = (nsFileSpec&)i;
child.Delete(inRecursive);
}
}
rmdir(mPath);
}
else
remove(mPath);
} // nsFileSpec::Delete
//----------------------------------------------------------------------------------------
nsresult nsFileSpec::Rename(const char* inNewName)
//----------------------------------------------------------------------------------------
{
// This function should not be used to move a file on disk.
if (strchr(inNewName, '/'))
return NS_FILE_FAILURE;
if (PR_Rename(mPath, inNewName) != 0)
{
return NS_FILE_FAILURE;
}
SetLeafName(inNewName);
return NS_OK;
} // nsFileSpec::Rename
static int CrudeFileCopy(const char* in, const char* out)
{
struct stat in_stat;
int stat_result = -1;
char buf [1024];
FILE *ifp, *ofp;
int rbytes, wbytes;
if (!in || !out)
return -1;
stat_result = stat (in, &in_stat);
ifp = fopen (in, "r");
if (!ifp)
{
return -1;
}
ofp = fopen (out, "w");
if (!ofp)
{
fclose (ifp);
return -1;
}
while ((rbytes = fread (buf, 1, sizeof(buf), ifp)) > 0)
{
while (rbytes > 0)
{
if ( (wbytes = fwrite (buf, 1, rbytes, ofp)) < 0 )
{
fclose (ofp);
fclose (ifp);
unlink(out);
return -1;
}
rbytes -= wbytes;
}
}
fclose (ofp);
fclose (ifp);
if (stat_result == 0)
{
chmod (out, in_stat.st_mode & 0777);
}
return 0;
} // nsFileSpec::Rename
//----------------------------------------------------------------------------------------
nsresult nsFileSpec::Copy(const nsFileSpec& inParentDirectory) const
//----------------------------------------------------------------------------------------
{
// We can only copy into a directory, and (for now) can not copy entire directories
nsresult result = NS_FILE_FAILURE;
if (inParentDirectory.IsDirectory() && (! IsDirectory() ) )
{
char *leafname = GetLeafName();
char* destPath = nsFileSpecHelpers::StringDup(inParentDirectory, ( strlen(inParentDirectory) + 1 + strlen(leafname) ) );
strcat(destPath, "/");
strcat(destPath, leafname);
delete [] leafname;
result = NS_FILE_RESULT(CrudeFileCopy(*this, destPath));
delete [] destPath;
}
return result;
} // nsFileSpec::Copy
//----------------------------------------------------------------------------------------
nsresult nsFileSpec::Move(const nsFileSpec& inNewParentDirectory) const
//----------------------------------------------------------------------------------------
{
// We can only copy into a directory, and (for now) can not copy entire directories
nsresult result = NS_FILE_FAILURE;
if (inNewParentDirectory.IsDirectory() && (! IsDirectory() ) )
{
char *leafname = GetLeafName();
char* destPath
= nsFileSpecHelpers::StringDup(
inNewParentDirectory,
strlen(inNewParentDirectory) + 1 + strlen(leafname));
strcat(destPath, "/");
strcat(destPath, leafname);
delete [] leafname;
result = NS_FILE_RESULT(CrudeFileCopy(*this, destPath));
if (result == NS_OK)
{
Delete(PR_FALSE);
}
delete [] destPath;
}
return result;
}
//----------------------------------------------------------------------------------------
nsresult nsFileSpec::Execute(const char* inArgs ) const
//----------------------------------------------------------------------------------------
{
nsresult result = NS_FILE_FAILURE;
if (! IsDirectory())
{
char* fileNameWithArgs
= nsFileSpecHelpers::StringDup(mPath, strlen(mPath) + 1 + strlen(inArgs));
strcat(fileNameWithArgs, " ");
strcat(fileNameWithArgs, inArgs);
result = NS_FILE_RESULT(system(fileNameWithArgs));
delete [] fileNameWithArgs;
}
return result;
} // nsFileSpec::Execute
//========================================================================================
// nsDirectoryIterator
//========================================================================================
//----------------------------------------------------------------------------------------
nsDirectoryIterator::nsDirectoryIterator(
const nsFileSpec& inDirectory
, int inIterateDirection)
//----------------------------------------------------------------------------------------
: mCurrent(inDirectory)
, mDir(nsnull)
, mExists(false)
{
mCurrent += "sysygy"; // prepare the path for SetLeafName
mDir = opendir((const char*)nsFilePath(inDirectory));
++(*this);
} // nsDirectoryIterator::nsDirectoryIterator
//----------------------------------------------------------------------------------------
nsDirectoryIterator::~nsDirectoryIterator()
//----------------------------------------------------------------------------------------
{
if (mDir)
closedir(mDir);
} // nsDirectoryIterator::nsDirectoryIterator
//----------------------------------------------------------------------------------------
nsDirectoryIterator& nsDirectoryIterator::operator ++ ()
//----------------------------------------------------------------------------------------
{
mExists = false;
if (!mDir)
return *this;
char* dot = ".";
char* dotdot = "..";
struct dirent* entry = readdir(mDir);
if (entry && strcmp(entry->d_name, dot) == 0)
entry = readdir(mDir);
if (entry && strcmp(entry->d_name, dotdot) == 0)
entry = readdir(mDir);
if (entry)
{
mExists = true;
mCurrent.SetLeafName(entry->d_name);
}
return *this;
} // nsDirectoryIterator::operator ++
//----------------------------------------------------------------------------------------
nsDirectoryIterator& nsDirectoryIterator::operator -- ()
//----------------------------------------------------------------------------------------
{
return ++(*this); // can't do it backwards.
} // nsDirectoryIterator::operator --

View File

@@ -0,0 +1,40 @@
#!nmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=..\..\..
IGNORE_MANIFEST=1
DEFINES=-D_IMPL_NS_BASE
LIBRARY_NAME=gmbase
MODULE=raptor
REQUIRES=xpcom raptor
CPPSRCS=nsTimer.cpp
CPP_OBJS=.\$(OBJDIR)\nsTimer.obj
LINCS=-I$(XPDIST)\public\xpcom -I$(XPDIST)\public\raptor
LCFLAGS = \
$(LCFLAGS) \
-D_IMPL_NS_BASE \
$(NULL)
include <$(DEPTH)\config\rules.mak>
libs:: $(OBJS)
$(MAKE_INSTALL) $(OBJDIR)\nsTimer.obj ..\$(OBJDIR)

View File

@@ -0,0 +1,40 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nscore.h"
#include "nsCaretProperties.h"
//-----------------------------------------------------------------------------
nsCaretProperties::nsCaretProperties()
: mCaretWidth(eDefaultCaretWidth)
, mBlinkRate(eDefaulBlinkRate)
{
// in your platform-specific class, get data from the OS in your constructor
mCaretWidth = 2; // 2 pixel caret on Windows
}
//-----------------------------------------------------------------------------
nsCaretProperties* NewCaretProperties()
{
return new nsCaretProperties();
}

View File

@@ -0,0 +1,408 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
// This file is included by nsFileSpec.cp, and includes the Windows-specific
// implementations.
#include <sys/stat.h>
#include <direct.h>
#include <stdlib.h>
#include "prio.h"
#include "nsError.h"
#include "windows.h"
#ifdef UNICODE
#define CreateDirectoryW CreateDirectory
#else
#define CreateDirectoryA CreateDirectory
#endif
//----------------------------------------------------------------------------------------
void nsFileSpecHelpers::Canonify(char*& ioPath, PRBool inMakeDirs)
// Canonify, make absolute, and check whether directories exist. This
// takes a (possibly relative) native path and converts it into a
// fully qualified native path.
//----------------------------------------------------------------------------------------
{
if (!ioPath)
return;
if (inMakeDirs) {
const int mode = 0700;
char* unixStylePath = nsFileSpecHelpers::StringDup(ioPath);
nsFileSpecHelpers::NativeToUnix(unixStylePath);
nsFileSpecHelpers::MakeAllDirectories(unixStylePath, mode);
delete[] unixStylePath;
}
char buffer[_MAX_PATH];
errno = 0;
*buffer = '\0';
char* canonicalPath = _fullpath(buffer, ioPath, _MAX_PATH);
NS_ASSERTION( canonicalPath[0] != '\0', "Uh oh...couldn't convert" );
if (canonicalPath[0] == '\0')
return;
nsFileSpecHelpers::StringAssign(ioPath, canonicalPath);
}
//----------------------------------------------------------------------------------------
void nsFileSpecHelpers::UnixToNative(char*& ioPath)
// This just does string manipulation. It doesn't check reality, or canonify, or
// anything
//----------------------------------------------------------------------------------------
{
// Allow for relative or absolute. We can do this in place, because the
// native path is never longer.
if (!ioPath || !*ioPath)
return;
char* src = ioPath;
if (*ioPath == '/')
{
// Strip initial slash for an absolute path
src++;
}
// Convert the vertical slash to a colon
char* cp = src + 1;
// If it was an absolute path, check for the drive letter
if (*ioPath == '/' && strstr(cp, "|/") == cp)
*cp = ':';
// Convert '/' to '\'.
while (*++cp)
{
if (*cp == '/')
*cp = '\\';
}
if (*ioPath == '/') {
for (cp = ioPath; *cp; ++cp)
*cp = *(cp + 1);
}
}
//----------------------------------------------------------------------------------------
void nsFileSpecHelpers::NativeToUnix(char*& ioPath)
// This just does string manipulation. It doesn't check reality, or canonify, or
// anything. The unix path is longer, so we can't do it in place.
//----------------------------------------------------------------------------------------
{
if (!ioPath || !*ioPath)
return;
// Convert the drive-letter separator, if present
char* temp = nsFileSpecHelpers::StringDup("/", 1 + strlen(ioPath));
char* cp = ioPath + 1;
if (strstr(cp, ":\\") == cp) {
*cp = '|'; // absolute path
}
else {
*temp = '\0'; // relative path
}
// Convert '\' to '/'
for (; *cp; cp++)
{
if (*cp == '\\')
*cp = '/';
}
// Add the slash in front.
strcat(temp, ioPath);
StringAssign(ioPath, temp);
delete [] temp;
}
//----------------------------------------------------------------------------------------
nsFileSpec::nsFileSpec(const nsFilePath& inPath)
//----------------------------------------------------------------------------------------
: mPath(NULL)
{
*this = inPath;
}
//----------------------------------------------------------------------------------------
void nsFileSpec::operator = (const nsFilePath& inPath)
//----------------------------------------------------------------------------------------
{
nsFileSpecHelpers::StringAssign(mPath, (const char*)inPath);
nsFileSpecHelpers::UnixToNative(mPath);
mError = NS_OK;
} // nsFileSpec::operator =
//----------------------------------------------------------------------------------------
nsFilePath::nsFilePath(const nsFileSpec& inSpec)
//----------------------------------------------------------------------------------------
: mPath(NULL)
{
*this = inSpec;
} // nsFilePath::nsFilePath
//----------------------------------------------------------------------------------------
void nsFilePath::operator = (const nsFileSpec& inSpec)
//----------------------------------------------------------------------------------------
{
nsFileSpecHelpers::StringAssign(mPath, inSpec.mPath);
nsFileSpecHelpers::NativeToUnix(mPath);
} // nsFilePath::operator =
//----------------------------------------------------------------------------------------
void nsFileSpec::SetLeafName(const char* inLeafName)
//----------------------------------------------------------------------------------------
{
nsFileSpecHelpers::LeafReplace(mPath, '\\', inLeafName);
} // nsFileSpec::SetLeafName
//----------------------------------------------------------------------------------------
char* nsFileSpec::GetLeafName() const
//----------------------------------------------------------------------------------------
{
return nsFileSpecHelpers::GetLeaf(mPath, '\\');
} // nsFileSpec::GetLeafName
//----------------------------------------------------------------------------------------
PRBool nsFileSpec::Exists() const
//----------------------------------------------------------------------------------------
{
struct stat st;
return 0 == stat(mPath, &st);
} // nsFileSpec::Exists
//----------------------------------------------------------------------------------------
PRBool nsFileSpec::IsFile() const
//----------------------------------------------------------------------------------------
{
struct stat st;
return 0 == stat(mPath, &st) && (_S_IFREG & st.st_mode);
} // nsFileSpec::IsFile
//----------------------------------------------------------------------------------------
PRBool nsFileSpec::IsDirectory() const
//----------------------------------------------------------------------------------------
{
struct stat st;
return 0 == stat(mPath, &st) && (_S_IFDIR & st.st_mode);
} // nsFileSpec::IsDirectory
//----------------------------------------------------------------------------------------
void nsFileSpec::GetParent(nsFileSpec& outSpec) const
//----------------------------------------------------------------------------------------
{
nsFileSpecHelpers::StringAssign(outSpec.mPath, mPath);
char* cp = strrchr(outSpec.mPath, '\\');
if (cp)
*cp = '\0';
} // nsFileSpec::GetParent
//----------------------------------------------------------------------------------------
void nsFileSpec::operator += (const char* inRelativePath)
//----------------------------------------------------------------------------------------
{
if (!inRelativePath || !mPath)
return;
if (mPath[strlen(mPath) - 1] == '\\')
nsFileSpecHelpers::ReallocCat(mPath, "x");
else
nsFileSpecHelpers::ReallocCat(mPath, "\\x");
SetLeafName(inRelativePath);
} // nsFileSpec::operator +=
//----------------------------------------------------------------------------------------
void nsFileSpec::CreateDirectory(int /*mode*/)
//----------------------------------------------------------------------------------------
{
// Note that mPath is canonical!
mkdir(mPath);
} // nsFileSpec::CreateDirectory
//----------------------------------------------------------------------------------------
void nsFileSpec::Delete(PRBool inRecursive)
//----------------------------------------------------------------------------------------
{
if (IsDirectory())
{
if (inRecursive)
{
for (nsDirectoryIterator i(*this); i.Exists(); i++)
{
nsFileSpec& child = (nsFileSpec&)i;
child.Delete(inRecursive);
}
}
rmdir(mPath);
}
else
{
remove(mPath);
}
} // nsFileSpec::Delete
//----------------------------------------------------------------------------------------
nsresult nsFileSpec::Rename(const char* inNewName)
//----------------------------------------------------------------------------------------
{
// This function should not be used to move a file on disk.
if (strchr(inNewName, '/'))
return NS_FILE_FAILURE;
if (PR_Rename(*this, inNewName) != NS_OK)
{
return NS_FILE_FAILURE;
}
SetLeafName(inNewName);
return NS_OK;
} // nsFileSpec::Rename
//----------------------------------------------------------------------------------------
nsresult nsFileSpec::Copy(const nsFileSpec& inParentDirectory) const
//----------------------------------------------------------------------------------------
{
// We can only copy into a directory, and (for now) can not copy entire directories
if (inParentDirectory.IsDirectory() && (! IsDirectory() ) )
{
char *leafname = GetLeafName();
char* destPath = nsFileSpecHelpers::StringDup(inParentDirectory, ( strlen(inParentDirectory) + 1 + strlen(leafname) ) );
strcat(destPath, "\\");
strcat(destPath, leafname);
delete [] leafname;
// CopyFile returns non-zero if succeeds
int copyOK = CopyFile(*this, destPath, true);
delete[] destPath;
if (copyOK)
{
return NS_OK;
}
}
return NS_FILE_FAILURE;
} // nsFileSpec::Copy
//----------------------------------------------------------------------------------------
nsresult nsFileSpec::Move(const nsFileSpec& nsNewParentDirectory) const
//----------------------------------------------------------------------------------------
{
// We can only copy into a directory, and (for now) can not copy entire directories
if (nsNewParentDirectory.IsDirectory() && (! IsDirectory() ) )
{
char *leafname = GetLeafName();
char *destPath = nsFileSpecHelpers::StringDup(nsNewParentDirectory, ( strlen(nsNewParentDirectory) + 1 + strlen(leafname) ));
strcat(destPath, "\\");
strcat(destPath, leafname);
delete [] leafname;
// MoveFile returns non-zero if succeeds
int copyOK = MoveFile(*this, destPath);
delete [] destPath;
if (copyOK)
{
return NS_OK;
}
}
return NS_FILE_FAILURE;
} // nsFileSpec::Move
//----------------------------------------------------------------------------------------
nsresult nsFileSpec::Execute(const char* inArgs ) const
//----------------------------------------------------------------------------------------
{
if (! IsDirectory())
{
char* fileNameWithArgs = NULL;
fileNameWithArgs = nsFileSpecHelpers::StringDup(mPath, ( strlen(mPath) + 1 + strlen(inArgs) ) );
strcat(fileNameWithArgs, " ");
strcat(fileNameWithArgs, inArgs);
int execResult = WinExec( fileNameWithArgs, SW_NORMAL );
delete [] fileNameWithArgs;
if (execResult > 31)
{
return NS_OK;
}
}
return NS_FILE_FAILURE;
} // nsFileSpec::Execute
//========================================================================================
// nsDirectoryIterator
//========================================================================================
//----------------------------------------------------------------------------------------
nsDirectoryIterator::nsDirectoryIterator(
const nsFileSpec& inDirectory
, int inIterateDirection)
//----------------------------------------------------------------------------------------
: mCurrent(inDirectory)
, mDir(nsnull)
, mExists(false)
{
mDir = PR_OpenDir(inDirectory);
mCurrent += "dummy";
++(*this);
} // nsDirectoryIterator::nsDirectoryIterator
//----------------------------------------------------------------------------------------
nsDirectoryIterator::~nsDirectoryIterator()
//----------------------------------------------------------------------------------------
{
if (mDir)
PR_CloseDir(mDir);
} // nsDirectoryIterator::nsDirectoryIterator
//----------------------------------------------------------------------------------------
nsDirectoryIterator& nsDirectoryIterator::operator ++ ()
//----------------------------------------------------------------------------------------
{
mExists = false;
if (!mDir)
return *this;
PRDirEntry* entry = PR_ReadDir(mDir, PR_SKIP_BOTH); // Ignore '.' && '..'
if (entry)
{
mExists = true;
mCurrent.SetLeafName(entry->name);
}
return *this;
} // nsDirectoryIterator::operator ++
//----------------------------------------------------------------------------------------
nsDirectoryIterator& nsDirectoryIterator::operator -- ()
//----------------------------------------------------------------------------------------
{
return ++(*this); // can't do it backwards.
} // nsDirectoryIterator::operator --

View File

@@ -0,0 +1,362 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsITimer.h"
#include "nsITimerCallback.h"
#include "nsCRT.h"
#include "prlog.h"
#include <stdio.h>
#include <windows.h>
#include <limits.h>
static NS_DEFINE_IID(kITimerIID, NS_ITIMER_IID);
/*
* Implementation of timers lifted from Windows front-end file timer.cpp
*/
class TimerImpl : public nsITimer {
public:
static TimerImpl *gTimerList;
static UINT gWindowsTimer;
static DWORD gNextFire;
static void ProcessTimeouts(DWORD aNow);
static void SyncTimeoutPeriod(DWORD aTickCount);
public:
TimerImpl();
virtual ~TimerImpl();
virtual nsresult Init(nsTimerCallbackFunc aFunc,
void *aClosure,
// PRBool aRepeat,
PRUint32 aDelay);
virtual nsresult Init(nsITimerCallback *aCallback,
// PRBool aRepeat,
PRUint32 aDelay);
NS_DECL_ISUPPORTS
virtual void Cancel();
void Fire(DWORD aNow);
virtual PRUint32 GetDelay() { return mDelay; }
virtual void SetDelay(PRUint32 aDelay) {};
virtual void* GetClosure() { return mClosure; }
private:
nsresult Init(PRUint32 aDelay);
PRUint32 mDelay;
nsTimerCallbackFunc mFunc;
void *mClosure;
nsITimerCallback *mCallback;
DWORD mFireTime;
// PRBool mRepeat;
TimerImpl *mNext;
};
TimerImpl *TimerImpl::gTimerList = NULL;
UINT TimerImpl::gWindowsTimer = 0;
DWORD TimerImpl::gNextFire = (DWORD)-1;
void CALLBACK FireTimeout(HWND aWindow,
UINT aMessage,
UINT aTimerID,
DWORD aTime)
{
static BOOL bCanEnter = TRUE;
// Don't allow old timer messages in here.
if(aMessage != WM_TIMER) {
PR_ASSERT(0);
return;
}
if(aTimerID != TimerImpl::gWindowsTimer) {
return;
}
// Block only one entry into this function, or else.
if(bCanEnter) {
bCanEnter = FALSE;
// see if we need to fork off any timeout functions
if(TimerImpl::gTimerList) {
TimerImpl::ProcessTimeouts(aTime);
}
bCanEnter = TRUE;
}
}
// Function to correctly have the timer be set.
void
TimerImpl::SyncTimeoutPeriod(DWORD aTickCount)
{
// May want us to set tick count ourselves.
if(aTickCount == 0) {
aTickCount = ::GetTickCount();
}
// If there's no list, we should clear the timer.
if(!gTimerList) {
if(gWindowsTimer) {
::KillTimer(NULL, gWindowsTimer);
gWindowsTimer = 0;
gNextFire = (DWORD)-1;
}
}
else {
// See if we need to clear the current timer.
// Curcumstances are that if the timer will not
// fire on time for the next timeout.
BOOL bSetTimer = FALSE;
TimerImpl *pTimeout = gTimerList;
if(gWindowsTimer) {
if(pTimeout->mFireTime != gNextFire) {
::KillTimer(NULL, gWindowsTimer);
gWindowsTimer = 0;
gNextFire = (DWORD)-1;
// Set the timer.
bSetTimer = TRUE;
}
}
else {
// No timer set, attempt.
bSetTimer = TRUE;
}
if(bSetTimer) {
DWORD dwFireWhen = pTimeout->mFireTime > aTickCount ?
pTimeout->mFireTime - aTickCount : 0;
if(dwFireWhen > UINT_MAX) {
dwFireWhen = UINT_MAX;
}
UINT uFireWhen = (UINT)dwFireWhen;
PR_ASSERT(gWindowsTimer == 0);
gWindowsTimer = ::SetTimer(NULL, 0, uFireWhen, (TIMERPROC)FireTimeout);
if(gWindowsTimer) {
// Set the fire time.
gNextFire = pTimeout->mFireTime;
}
}
}
}
// Walk down the timeout list and launch anyone appropriate
void
TimerImpl::ProcessTimeouts(DWORD aNow)
{
TimerImpl *p = gTimerList;
if(aNow == 0) {
aNow = ::GetTickCount();
}
BOOL bCalledSync = FALSE;
// loop over all entries
while(p) {
// send it
if(p->mFireTime < aNow) {
// Make sure that the timer cannot be deleted during the
// Fire(...) call which may release *all* other references
// to p...
NS_ADDREF(p);
p->Fire(aNow);
// Clear the timer.
// Period synced.
p->Cancel();
bCalledSync = TRUE;
NS_RELEASE(p);
// Reset the loop (can't look at p->pNext now, and called
// code may have added/cleared timers).
// (could do this by going recursive and returning).
p = gTimerList;
} else {
// Make sure we fire an timer.
// Also, we need to check to see if things are backing up (they
// may be asking to be fired long before we ever get to them,
// and we don't want to pass in negative values to the real
// timer code, or it takes days to fire....
if(bCalledSync == FALSE) {
SyncTimeoutPeriod(aNow);
bCalledSync = TRUE;
}
// Get next timer.
p = p->mNext;
}
}
}
TimerImpl::TimerImpl()
{
NS_INIT_REFCNT();
mFunc = NULL;
mCallback = NULL;
mNext = NULL;
mClosure = nsnull;
}
TimerImpl::~TimerImpl()
{
Cancel();
NS_IF_RELEASE(mCallback);
}
nsresult
TimerImpl::Init(nsTimerCallbackFunc aFunc,
void *aClosure,
// PRBool aRepeat,
PRUint32 aDelay)
{
mFunc = aFunc;
mClosure = aClosure;
// mRepeat = aRepeat;
return Init(aDelay);
}
nsresult
TimerImpl::Init(nsITimerCallback *aCallback,
// PRBool aRepeat,
PRUint32 aDelay)
{
mCallback = aCallback;
NS_ADDREF(mCallback);
// mRepeat = aRepeat;
return Init(aDelay);
}
nsresult
TimerImpl::Init(PRUint32 aDelay)
{
DWORD dwNow = ::GetTickCount();
mDelay = aDelay;
mFireTime = (DWORD) aDelay + dwNow;
mNext = NULL;
// add it to the list
if(!gTimerList) {
// no list add it
gTimerList = this;
}
else {
// is it before everything else on the list?
if(mFireTime < gTimerList->mFireTime) {
mNext = gTimerList;
gTimerList = this;
} else {
TimerImpl * pPrev = gTimerList;
TimerImpl * pCurrent = gTimerList;
while(pCurrent && (pCurrent->mFireTime <= mFireTime)) {
pPrev = pCurrent;
pCurrent = pCurrent->mNext;
}
PR_ASSERT(pPrev);
// insert it after pPrev (this could be at the end of the list)
mNext = pPrev->mNext;
pPrev->mNext = this;
}
}
NS_ADDREF(this);
// Sync the timer fire period.
SyncTimeoutPeriod(dwNow);
return NS_OK;
}
NS_IMPL_ISUPPORTS(TimerImpl, kITimerIID)
void
TimerImpl::Fire(DWORD aNow)
{
if (mFunc != NULL) {
(*mFunc)(this, mClosure);
}
else if (mCallback != NULL) {
mCallback->Notify(this);
}
}
void
TimerImpl::Cancel()
{
TimerImpl *me = this;
if(gTimerList == this) {
// first element in the list lossage
gTimerList = mNext;
} else {
// walk until no next pointer
for(TimerImpl * p = gTimerList; p && p->mNext && (p->mNext != this); p = p->mNext)
;
// if we found something valid pull it out of the list
if(p && p->mNext && p->mNext == this) {
p->mNext = mNext;
} else {
// get out before we delete something that looks bogus
return;
}
}
// if we got here it must have been a valid element so trash it
NS_RELEASE(me);
// If there's now no be sure to clear the timer.
SyncTimeoutPeriod(0);
}
NS_BASE nsresult NS_NewTimer(nsITimer** aInstancePtrResult)
{
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
if (nsnull == aInstancePtrResult) {
return NS_ERROR_NULL_POINTER;
}
TimerImpl *timer = new TimerImpl();
if (nsnull == timer) {
return NS_ERROR_OUT_OF_MEMORY;
}
return timer->QueryInterface(kITimerIID, (void **) aInstancePtrResult);
}

View File

@@ -0,0 +1,103 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include <stdio.h>
#include "nsIUnicharInputStream.h"
#include "nsIURL.h"
#include "nsCRT.h"
#include "nsString.h"
#include "prprf.h"
#include "prtime.h"
static nsString* ConvertCharacterSetName(const char* aName)
{
return new nsString(aName);
}
int main(int argc, char** argv)
{
if (3 != argc) {
printf("usage: CvtURL url character-set-name\n");
return -1;
}
char* characterSetName = argv[2];
nsString* cset = ConvertCharacterSetName(characterSetName);
if (PRInt32(cset) < 0) {
printf("illegal character set name: '%s'\n", characterSetName);
return -1;
}
// Create url object
char* urlName = argv[1];
nsIURL* url;
nsresult rv = NS_NewURL(&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_OpenURL(url, &in);
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
nsIUnicharInputStream* uin;
rv = NS_NewConverterStream(&uin, nsnull, in, 0, cset);
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 (ec < 0) {
if (ec != NS_BASE_STREAM_EOF) {
printf("i/o error: %d\n", ec);
}
break;
}
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();
uin->Release();
url->Release();
return 0;
}

View File

@@ -0,0 +1,614 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsFileSpec.h"
#include "nsFileStream.h"
//#include "string.h"
struct FilesTest
{
FilesTest() : mConsole() {}
int RunAllTests();
void WriteStuff(nsOutputFileStream& s);
int InputStream(const char* relativePath);
int OutputStream(const char* relativePath);
int IOStream(const char* relativePath);
int Parent(const char* relativePath, nsFileSpec& outParent);
int Delete(nsFileSpec& victim);
int CreateDirectory(nsFileSpec& victim);
int IterateDirectoryChildren(nsFileSpec& startChild);
int CanonicalPath(const char* relativePath);
int Persistence(const char* relativePath);
int Copy(const char* sourceFile, const char* targDir);
int Move(const char* sourceFile, const char* targDir);
int Rename(const char* sourceFile, const char* newName);
int Execute(const char* appName, const char* args);
void Banner(const char* bannerString);
void Passed();
void Failed();
void Inspect();
nsOutputConsoleStream mConsole;
};
//----------------------------------------------------------------------------------------
void FilesTest::Banner(const char* bannerString)
//----------------------------------------------------------------------------------------
{
mConsole
<< nsEndl
<< "---------------------------" << nsEndl
<< bannerString << " Test" << nsEndl
<< "---------------------------" << nsEndl;
}
//----------------------------------------------------------------------------------------
void FilesTest::Passed()
//----------------------------------------------------------------------------------------
{
((nsOutputStream&)mConsole) << "Test passed.";
mConsole << nsEndl;
}
//----------------------------------------------------------------------------------------
void FilesTest::Failed()
//----------------------------------------------------------------------------------------
{
mConsole << "ERROR: Test failed." << nsEndl;
}
//----------------------------------------------------------------------------------------
void FilesTest::Inspect()
//----------------------------------------------------------------------------------------
{
mConsole << nsEndl << "^^^^^^^^^^ PLEASE INSPECT OUTPUT FOR ERRORS" << nsEndl;
}
//----------------------------------------------------------------------------------------
void FilesTest::WriteStuff(nsOutputFileStream& s)
//----------------------------------------------------------------------------------------
{
// Initialize a URL from a string without suffix. Change the path to suit your machine.
nsFileURL fileURL("file:///Development/MPW/MPW%20Shell", false);
s << "File URL initialized to: \"" << fileURL << "\""<< nsEndl;
// Initialize a Unix path from a URL
nsFilePath filePath(fileURL);
s << "As a unix path: \"" << (const char*)filePath << "\""<< nsEndl;
// Initialize a native file spec from a URL
nsFileSpec fileSpec(fileURL);
s << "As a file spec: " << fileSpec << nsEndl;
// Make the spec unique (this one has no suffix).
fileSpec.MakeUnique();
s << "Unique file spec: " << fileSpec << nsEndl;
// Assign the spec to a URL
fileURL = fileSpec;
s << "File URL assigned from spec: \"" << fileURL << "\""<< nsEndl;
// Assign a unix path using a string with a suffix.
filePath = "/Development/MPW/SysErrs.err";
s << "File path reassigned to: \"" << (const char*)filePath << "\""<< nsEndl;
// Assign to a file spec using a unix path.
fileSpec = filePath;
s << "File spec reassigned to: " << fileSpec << nsEndl;
// Make this unique (this one has a suffix).
fileSpec.MakeUnique();
s << "File spec made unique: " << fileSpec << nsEndl;
} // WriteStuff
//----------------------------------------------------------------------------------------
int FilesTest::OutputStream(const char* relativePath)
//----------------------------------------------------------------------------------------
{
nsFilePath myTextFilePath(relativePath, true); // relative path.
const char* pathAsString = (const char*)myTextFilePath;
nsFileSpec mySpec(myTextFilePath);
{
mConsole << "WRITING IDENTICAL OUTPUT TO " << pathAsString << nsEndl << nsEndl;
nsOutputFileStream testStream(mySpec);
if (!testStream.is_open())
{
mConsole
<< "ERROR: File "
<< pathAsString
<< " could not be opened for output"
<< nsEndl;
return -1;
}
FilesTest::WriteStuff(testStream);
} // <-- Scope closes the stream (and the file).
if (!mySpec.Exists() || mySpec.IsDirectory() || !mySpec.IsFile())
{
mConsole
<< "ERROR: File "
<< pathAsString
<< " is not a file (cela n'est pas un pipe)"
<< nsEndl;
return -1;
}
Passed();
return 0;
}
//----------------------------------------------------------------------------------------
int FilesTest::IOStream(const char* relativePath)
//----------------------------------------------------------------------------------------
{
nsFilePath myTextFilePath(relativePath, true); // relative path.
const char* pathAsString = (const char*)myTextFilePath;
nsFileSpec mySpec(myTextFilePath);
mConsole
<< "Replacing \"path\" by \"ZUUL\" in " << pathAsString << nsEndl << nsEndl;
nsIOFileStream testStream(mySpec);
if (!testStream.is_open())
{
mConsole
<< "ERROR: File "
<< pathAsString
<< " could not be opened for input+output"
<< nsEndl;
return -1;
}
char line[1000];
testStream.seek(0); // check that the seek compiles
while (!testStream.eof())
{
PRInt32 pos = testStream.tell();
testStream.readline(line, sizeof(line));
char* replacementSubstring = strstr(line, "path");
if (replacementSubstring)
{
testStream.seek(pos + (replacementSubstring - line));
testStream << "ZUUL";
testStream.seek(pos); // back to the start of the line
}
}
return 0;
}
//----------------------------------------------------------------------------------------
int FilesTest::Persistence(
const char* relativePathToWrite)
//----------------------------------------------------------------------------------------
{
nsFilePath myTextFilePath(relativePathToWrite, true);
const char* pathAsString = (const char*)myTextFilePath;
nsFileSpec mySpec(myTextFilePath);
nsIOFileStream testStream(mySpec, (PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE));
if (!testStream.is_open())
{
mConsole
<< "ERROR: File "
<< pathAsString
<< " could not be opened for input+output"
<< nsEndl;
return -1;
}
nsPersistentFileDescriptor myPersistent(mySpec);
mConsole
<< "Writing persistent file data " << pathAsString << nsEndl << nsEndl;
testStream.seek(0); // check that the seek compiles
testStream << myPersistent;
testStream.seek(0);
nsPersistentFileDescriptor mySecondPersistent;
testStream >> mySecondPersistent;
mySpec = mySecondPersistent;
#ifdef XP_MAC
if (mySpec.Error())
{
Failed();
return -1;
}
#endif
if (!mySpec.Exists())
{
Failed();
return -1;
}
Passed();
return 0;
}
//----------------------------------------------------------------------------------------
int FilesTest::InputStream(const char* relativePath)
//----------------------------------------------------------------------------------------
{
nsFilePath myTextFilePath(relativePath, true);
const char* pathAsString = (const char*)myTextFilePath;
mConsole << "READING BACK DATA FROM " << pathAsString << nsEndl << nsEndl;
nsFileSpec mySpec(myTextFilePath);
nsInputFileStream testStream2(mySpec);
if (!testStream2.is_open())
{
mConsole
<< "ERROR: File "
<< pathAsString
<< " could not be opened for input"
<< nsEndl;
return -1;
}
char line[1000];
testStream2.seek(0); // check that the seek compiles
while (!testStream2.eof())
{
testStream2.readline(line, sizeof(line));
mConsole << line << nsEndl;
}
Inspect();
return 0;
}
//----------------------------------------------------------------------------------------
int FilesTest::Parent(
const char* relativePath,
nsFileSpec& outParent)
//----------------------------------------------------------------------------------------
{
nsFilePath myTextFilePath(relativePath, true);
const char* pathAsString = (const char*)myTextFilePath;
nsFileSpec mySpec(myTextFilePath);
mySpec.GetParent(outParent);
nsFilePath parentPath(outParent);
mConsole
<< "GetParent() on "
<< "\n\t" << pathAsString
<< "\n yields "
<< "\n\t" << (const char*)parentPath
<< nsEndl;
Inspect();
return 0;
}
//----------------------------------------------------------------------------------------
int FilesTest::Delete(nsFileSpec& victim)
//----------------------------------------------------------------------------------------
{
// - Test of non-recursive delete
nsFilePath victimPath(victim);
mConsole
<< "Attempting to delete "
<< "\n\t" << (const char*)victimPath
<< "\n without recursive option (should fail)"
<< nsEndl;
victim.Delete(false);
if (victim.Exists())
Passed();
else
{
mConsole
<< "ERROR: File "
<< "\n\t" << (const char*)victimPath
<< "\n has been deleted without the recursion option,"
<< "\n and is a nonempty directory!"
<< nsEndl;
return -1;
}
// - Test of recursive delete
mConsole
<< nsEndl
<< "Deleting "
<< "\n\t" << (const char*)victimPath
<< "\n with recursive option"
<< nsEndl;
victim.Delete(true);
if (victim.Exists())
{
mConsole
<< "ERROR: Directory "
<< "\n\t" << (const char*)victimPath
<< "\n has NOT been deleted despite the recursion option!"
<< nsEndl;
return -1;
}
Passed();
return 0;
}
//----------------------------------------------------------------------------------------
int FilesTest::CreateDirectory(nsFileSpec& dirSpec)
//----------------------------------------------------------------------------------------
{
nsFilePath dirPath(dirSpec);
mConsole
<< "Testing CreateDirectory() using"
<< "\n\t" << (const char*)dirPath
<< nsEndl;
dirSpec.CreateDirectory();
if (dirSpec.Exists())
Passed();
else
{
Failed();
return -1;
}
dirSpec.Delete(true);
return 0;
}
//----------------------------------------------------------------------------------------
int FilesTest::IterateDirectoryChildren(nsFileSpec& startChild)
//----------------------------------------------------------------------------------------
{
// - Test of directory iterator
nsFileSpec grandparent;
startChild.GetParent(grandparent); // should be the original default directory.
nsFilePath grandparentPath(grandparent);
mConsole << "Forwards listing of " << (const char*)grandparentPath << ":" << nsEndl;
for (nsDirectoryIterator i(grandparent, +1); i.Exists(); i++)
{
char* itemName = ((nsFileSpec&)i).GetLeafName();
mConsole << '\t' << itemName << nsEndl;
delete [] itemName;
}
mConsole << "Backwards listing of " << (const char*)grandparentPath << ":" << nsEndl;
for (nsDirectoryIterator j(grandparent, -1); j.Exists(); j--)
{
char* itemName = ((nsFileSpec&)j).GetLeafName();
mConsole << '\t' << itemName << nsEndl;
delete [] itemName;
}
Inspect();
return 0;
}
//----------------------------------------------------------------------------------------
int FilesTest::CanonicalPath(
const char* relativePath)
//----------------------------------------------------------------------------------------
{
nsFilePath myTextFilePath(relativePath, true);
const char* pathAsString = (const char*)myTextFilePath;
if (*pathAsString != '/')
{
mConsole
<< "ERROR: after initializing the path object with a relative path,"
<< "\n the path consisted of the string "
<< "\n\t" << pathAsString
<< "\n which is not a canonical full path!"
<< nsEndl;
return -1;
}
Passed();
return 0;
}
//----------------------------------------------------------------------------------------
int FilesTest::Copy(const char* file, const char* dir)
//----------------------------------------------------------------------------------------
{
nsFileSpec dirPath(dir, true);
dirPath.CreateDirectory();
if (! dirPath.Exists())
{
Failed();
return -1;
}
nsFileSpec mySpec(file, true); // relative path.
{
nsIOFileStream testStream(mySpec); // creates the file
// Scope ends here, file gets closed
}
nsFileSpec filePath(file);
if (! filePath.Exists())
{
Failed();
return -1;
}
nsresult error = filePath.Copy(dirPath);
dirPath += filePath.GetLeafName();
if (! dirPath.Exists() || ! filePath.Exists() || NS_FAILED(error))
{
Failed();
return -1;
}
Passed();
return 0;
}
//----------------------------------------------------------------------------------------
int FilesTest::Move(const char* file, const char* dir)
//----------------------------------------------------------------------------------------
{
nsFileSpec dirPath(dir, true);
dirPath.CreateDirectory();
if (! dirPath.Exists())
{
Failed();
return -1;
}
nsFileSpec srcSpec(file, true); // relative path.
{
nsIOFileStream testStream(srcSpec); // creates the file
// file gets closed here because scope ends here.
};
if (! srcSpec.Exists())
{
Failed();
return -1;
}
nsresult error = srcSpec.Move(dirPath);
dirPath += srcSpec.GetLeafName();
if (! dirPath.Exists() || srcSpec.Exists() || NS_FAILED(error))
{
Failed();
return -1;
}
Passed();
return 0;
}
//----------------------------------------------------------------------------------------
int FilesTest::Execute(const char* appName, const char* args)
//----------------------------------------------------------------------------------------
{
nsFileSpec appPath(appName, false);
if (!appPath.Exists())
{
Failed();
return -1;
}
nsresult error = appPath.Execute(args);
if (NS_FAILED(error))
{
Failed();
return -1;
}
Passed();
return 0;
}
//----------------------------------------------------------------------------------------
int FilesTest::RunAllTests()
// For use with DEBUG defined.
//----------------------------------------------------------------------------------------
{
// Test of mConsole output
mConsole << "WRITING TEST OUTPUT TO CONSOLE" << nsEndl << nsEndl;
// Test of nsFileSpec
Banner("Interconversion");
WriteStuff(mConsole);
Inspect();
Banner("Canonical Path");
if (CanonicalPath("mumble/iotest.txt") != 0)
return -1;
Banner("OutputStream");
if (OutputStream("mumble/iotest.txt") != 0)
return -1;
Banner("InputStream");
if (InputStream("mumble/iotest.txt") != 0)
return -1;
Banner("IOStream");
if (IOStream("mumble/iotest.txt") != 0)
return -1;
if (InputStream("mumble/iotest.txt") != 0)
return -1;
Banner("Parent");
nsFileSpec parent;
if (Parent("mumble/iotest.txt", parent) != 0)
return -1;
Banner("Delete");
if (Delete(parent) != 0)
return -1;
Banner("CreateDirectory");
if (CreateDirectory(parent) != 0)
return -1;
Banner("IterateDirectoryChildren");
if (IterateDirectoryChildren(parent) != 0)
return -1;
Banner("Copy");
if (Copy("mumble/copyfile.txt", "mumble/copy") != 0)
return -1;
Banner("Move");
if (Move("mumble/moveFile.txt", "mumble/move") != 0)
return -1;
Banner("Execute");
#ifdef XP_MAC
// This path is hard-coded to test on jrm's machine. Finding an app
// on an arbitrary Macintosh would cost more trouble than it's worth.
// Change path to suit.
if NS_FAILED(Execute("/Projects/Nav45_BRANCH/ns/cmd/macfe/"\
"projects/client45/Client45PPC", ""))
#elif XP_PC
if NS_FAILED(Execute("c:\\windows\\notepad.exe", ""))
#else
if NS_FAILED(Execute("/bin/ls", "/"))
#endif
return -1;
Banner("Persistence");
if (Persistence("mumble/filedesc.dat") != 0)
return -1;
Banner("Delete again (to clean up our mess)");
if (Delete(parent) != 0)
return -1;
return 0;
}
//----------------------------------------------------------------------------------------
int main()
// For use with DEBUG defined.
//----------------------------------------------------------------------------------------
{
FilesTest tester;
return tester.RunAllTests();
} // main

View File

@@ -0,0 +1,66 @@
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
CPPSRCS = TestAtoms.cpp TestCRT.cpp CvtURL.cpp FilesTest.cpp PropertiesTest.cpp TestAutoLock.cpp
LIBS = \
-lnetlib \
-labouturl \
-lfileurl \
-lremoturl \
-lgophurl \
-lnetcnvts \
-lsockstuburl \
-lftpurl \
-lmimetype \
-lpwcac \
-lhttpurl \
-lnetwork \
-lnetutil \
-lnetcache \
-lgmbase$(MOZ_TOOLKIT) \
$(TK_LIBS) \
-lpref \
-lsecfree \
-ljs \
-lxp \
-lraptorbase \
-lxpcom \
-lreg \
$(ZLIB_LIBS) \
$(NSPR_LIBS) \
$(NULL)
SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=)
include $(topsrcdir)/config/rules.mk
INCLUDES += -I$(srcdir)/../src
# needed for mac linux
ifeq ($(OS_ARCH),Linux)
ifneq ($(OS_RELEASE),1.2)
OS_LIBS += /usr/lib/libdl.so
endif
endif

View File

@@ -0,0 +1,127 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#define NS_IMPL_IDS
#include "nsXPComCIID.h"
#include "nsIEventQueueService.h"
#include "nsINetService.h"
#include "nsIProperties.h"
#include "nsIServiceManager.h"
#include "nsIURL.h"
#include "nsRepository.h"
#ifdef XP_PC
#include "plevent.h"
#endif
#define TEST_URL "resource:/res/test.properties"
#ifdef XP_PC
#define NETLIB_DLL "netlib.dll"
#define RAPTORBASE_DLL "raptorbase.dll"
#define XPCOM_DLL "xpcom32.dll"
#else
#ifdef XP_MAC
#define NETLIB_DLL "NETLIB_DLL"
#define RAPTORBASE_DLL "base.shlb"
#define XPCOM_DLL "XPCOM_DLL"
#else
#define NETLIB_DLL "libnetlib.so"
#define RAPTORBASE_DLL "libraptorbase.so"
#define XPCOM_DLL "libxpcom32.so"
#endif
#endif
static NS_DEFINE_IID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
static NS_DEFINE_IID(kIEventQueueServiceIID, NS_IEVENTQUEUESERVICE_IID);
static NS_DEFINE_IID(kINetServiceIID, NS_INETSERVICE_IID);
static NS_DEFINE_IID(kIPropertiesIID, NS_IPROPERTIES_IID);
static NS_DEFINE_IID(kNetServiceCID, NS_NETSERVICE_CID);
#ifdef XP_MAC // have not build this on PC and UNIX yet so make it #ifdef XP_MAC
extern "C" void NS_SetupRegistry();
#endif
int
main(int argc, char *argv[])
{
nsRepository::RegisterFactory(kNetServiceCID, NETLIB_DLL, PR_FALSE,
PR_FALSE);
nsRepository::RegisterFactory(kEventQueueServiceCID, XPCOM_DLL,
PR_FALSE, PR_FALSE);
#ifdef XP_MAC // have not build this on PC and UNIX yet so make it #ifdef XP_MAC
NS_SetupRegistry();
#endif
nsresult ret;
nsIEventQueueService* pEventQueueService = nsnull;
ret = nsServiceManager::GetService(kEventQueueServiceCID,
kIEventQueueServiceIID, (nsISupports**) &pEventQueueService);
if (NS_FAILED(ret)) {
printf("cannot get event queue service\n");
return 1;
}
ret = pEventQueueService->CreateThreadEventQueue();
if (NS_FAILED(ret)) {
printf("CreateThreadEventQueue failed\n");
return 1;
}
nsINetService* pNetService = nsnull;
ret = nsServiceManager::GetService(kNetServiceCID, kINetServiceIID,
(nsISupports**) &pNetService);
if (NS_FAILED(ret)) {
printf("cannot get net service\n");
return 1;
}
nsIURL *url = nsnull;
ret = pNetService->CreateURL(&url, nsString(TEST_URL), nsnull, nsnull,
nsnull);
if (NS_FAILED(ret)) {
printf("cannot create URL\n");
return 1;
}
nsIInputStream *in = nsnull;
ret = pNetService->OpenBlockingStream(url, nsnull, &in);
if (NS_FAILED(ret)) {
printf("cannot open stream\n");
return 1;
}
nsIProperties *props = nsnull;
ret = nsRepository::CreateInstance(kPropertiesCID, NULL,
kIPropertiesIID, (void**) &props);
if (NS_FAILED(ret)) {
printf("create nsIProperties failed\n");
return 1;
}
props->Load(in);
int i = 1;
while (1) {
char name[16];
sprintf(name, "%d", i);
nsAutoString v("");
props->GetProperty(name, v);
if (!v.Length()) {
break;
}
char *value = v.ToNewCString();
cout << "\"" << i << "\"=\"" << value << "\"" << endl;
i++;
}
return 0;
}

View File

@@ -0,0 +1,109 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsIAtom.h"
#include "nsString.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 < 60000; i++) {
char buf[1000];
char* s = fgets(buf, sizeof(buf), fp);
if (nsnull == s) {
break;
}
nsAutoString sb(buf);
strings[count++] = sb.ToNewUnicode();
sb.ToUpperCase();
strings[count++] = sb.ToNewUnicode();
}
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++) {
nsIAtom* id = NS_NewAtom(ids[i]->GetUnicode());
if (id != ids[i]) {
id->ToString(s1);
ids[i]->ToString(s2);
printf("find failed: id='%s' ids[%d]='%s'\n",
s1.ToNewCString(), i, s2.ToNewCString());
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;
}

View File

@@ -0,0 +1,72 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
Some tests for nsAutoLock.
*/
#include "nsAutoLock.h"
#include "prthread.h"
PRLock* gLock;
int gCount;
static void 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;
}

View File

@@ -0,0 +1,89 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsCRT.h"
#include "nsString.h"
#include "plstr.h"
#include <stdlib.h>
// 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 comparision 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(s1), t2(s2);
const PRUnichar* us1 = t1.GetUnicode();
const PRUnichar* us2 = t2.GetUnicode();
PRIntn u = nsCRT::strcmp(us1, s2);
PRIntn u_n = nsCRT::strncmp(us1, s2, n);
PRIntn u_case = nsCRT::strcasecmp(us1, s2);
PRIntn u_case_n = nsCRT::strncasecmp(us1, s2, n);
PRIntn u2 = nsCRT::strcmp(us1, us2);
PRIntn u2_n = nsCRT::strncmp(us1, us2, n);
PRIntn u2_case = nsCRT::strcasecmp(us1, us2);
PRIntn u2_case_n = nsCRT::strncasecmp(us1, us2, n);
NS_ASSERTION(clib == u, "strcmp");
NS_ASSERTION(clib_n == u_n, "strncmp");
NS_ASSERTION(clib_case == u_case, "strcasecmp");
NS_ASSERTION(clib_case_n == u_case_n, "strncasecmp");
NS_ASSERTION(clib == u2, "strcmp");
NS_ASSERTION(clib_n == u2_n, "strncmp");
NS_ASSERTION(clib_case == u2_case, "strcasecmp");
NS_ASSERTION(clib_case_n == u2_case_n, "strncasecmp");
}
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 (sizeof(tests) / sizeof(tests[0]))
void main()
{
Test* tp = tests;
for (PRIntn i = 0; i < NUM_TESTS; i++, tp++) {
Check(tp->s1, tp->s2, tp->n);
}
}

View File

@@ -0,0 +1,202 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "prtypes.h"
#include "nsVoidArray.h"
#include "nsITimer.h"
#include "nsITimerCallback.h"
#include <stdio.h>
#include <stdlib.h>
#include "resources.h"
#include <windows.h>
static char* class1Name = "TimerTest";
static HINSTANCE gInstance, gPrevInstance;
static nsVoidArray *gTimeouts = NULL;
static void CreateRepeat(PRUint32 aDelay);
void
MyCallback (nsITimer *aTimer, void *aClosure)
{
printf("Timer executed with delay %d\n", (int)aClosure);
if (gTimeouts->RemoveElement(aTimer) == PR_TRUE) {
NS_RELEASE(aTimer);
}
}
void
MyRepeatCallback (nsITimer *aTimer, void *aClosure)
{
printf("Timer executed with delay %d\n", (int)aClosure);
if (gTimeouts->RemoveElement(aTimer) == PR_TRUE) {
NS_RELEASE(aTimer);
}
CreateRepeat((PRUint32)aClosure);
}
static void
CreateOneShot(PRUint32 aDelay)
{
nsITimer *timer;
NS_NewTimer(&timer);
timer->Init(MyCallback, (void *)aDelay, aDelay);
gTimeouts->AppendElement(timer);
}
static void
CreateRepeat(PRUint32 aDelay)
{
nsITimer *timer;
NS_NewTimer(&timer);
timer->Init(MyRepeatCallback, (void *)aDelay, aDelay);
gTimeouts->AppendElement(timer);
}
static void
CancelAll()
{
int i, count = gTimeouts->Count();
for (i=0; i < count; i++) {
nsITimer *timer = (nsITimer *)gTimeouts->ElementAt(i);
if (timer != NULL) {
timer->Cancel();
NS_RELEASE(timer);
}
}
gTimeouts->Clear();
}
long PASCAL
WndProc(HWND hWnd, UINT msg, WPARAM param, LPARAM lparam)
{
HMENU hMenu;
switch (msg) {
case WM_COMMAND:
hMenu = GetMenu(hWnd);
switch (LOWORD(param)) {
case TIMER_EXIT:
::DestroyWindow(hWnd);
exit(0);
case TIMER_1SECOND:
CreateOneShot(1000);
break;
case TIMER_5SECOND:
CreateOneShot(5000);
break;
case TIMER_10SECOND:
CreateOneShot(10000);
break;
case TIMER_1REPEAT:
CreateRepeat(1000);
break;
case TIMER_5REPEAT:
CreateRepeat(5000);
break;
case TIMER_10REPEAT:
CreateRepeat(10000);
break;
case TIMER_CANCEL:
CancelAll();
break;
default:
break;
}
default:
break;
}
return DefWindowProc(hWnd, msg, param, lparam);
}
static HWND CreateTopLevel(const char* clazz, const char* title,
int aWidth, int aHeight)
{
// Create a simple top level window
HWND window = ::CreateWindowEx(WS_EX_CLIENTEDGE,
clazz, title,
WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN,
CW_USEDEFAULT, CW_USEDEFAULT,
aWidth, aHeight,
HWND_DESKTOP,
NULL,
gInstance,
NULL);
::ShowWindow(window, SW_SHOW);
::UpdateWindow(window);
return window;
}
int PASCAL
WinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdParam, int nCmdShow)
{
gInstance = instance;
if (!prevInstance) {
WNDCLASS wndClass;
wndClass.style = 0;
wndClass.lpfnWndProc = WndProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = gInstance;
wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = (HBRUSH) GetStockObject(LTGRAY_BRUSH);
wndClass.lpszMenuName = class1Name;
wndClass.lpszClassName = class1Name;
RegisterClass(&wndClass);
}
// Create our first top level window
HWND window = CreateTopLevel(class1Name, "Raptor HTML Viewer", 620, 400);
gTimeouts = new nsVoidArray();
// Process messages
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
void main(int argc, char **argv)
{
WinMain(GetModuleHandle(NULL), NULL, 0, SW_SHOW);
}

View File

@@ -0,0 +1,112 @@
#!nmake
#
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
DEPTH=..\..
MAKE_OBJ_TYPE = EXE
PROG0 = .\$(OBJDIR)\TimerTest.exe
PROG1 = .\$(OBJDIR)\TestAtoms.exe
PROG2 = .\$(OBJDIR)\CvtURL.exe
PROG3 = .\$(OBJDIR)\TestCRT.exe
PROG4 = .\$(OBJDIR)\FilesTest.exe
PROG5 = .\$(OBJDIR)\PropertiesTest.exe
PROG6 = .\$(OBJDIR)\TestAutoLock.exe
RESFILE = timer.res
PROGRAMS = $(PROG0) $(PROG1) \
!ifdef MODULAR_NETLIB
$(PROG2) \
$(PROG3) \
$(PROG5) \
!endif
$(PROG4) \
$(PROG6) \
$(NULL)
LINCS=-I..\src -I$(PUBLIC)\xpcom -I$(PUBLIC)\netlib -I$(PUBLIC)\raptor
LLIBS= \
$(DIST)\lib\xpcom32.lib \
$(DIST)\lib\raptorbase.lib \
!ifdef MODULAR_NETLIB
$(DIST)\lib\netlib.lib \
!endif
$(LIBNSPR) \
$(DIST)\lib\libplc21.lib \
!if "$(MOZ_BITS)"=="32" && defined(MOZ_DEBUG) && defined(GLOWCODE)
$(GLOWDIR)\glowcode.lib \
!endif
$(RESFILE)
include <$(DEPTH)\config\rules.mak>
install:: $(PROGRAMS)
$(MAKE_INSTALL) $(PROG0) $(DIST)\bin
$(MAKE_INSTALL) $(PROG1) $(DIST)\bin
!ifdef MODULAR_NETLIB
$(MAKE_INSTALL) $(PROG2) $(DIST)\bin
$(MAKE_INSTALL) $(PROG3) $(DIST)\bin
$(MAKE_INSTALL) $(PROG5) $(DIST)\bin
$(MAKE_INSTALL) test.properties $(DIST)\bin\res
!endif
$(MAKE_INSTALL) $(PROG4) $(DIST)\bin
$(MAKE_INSTALL) $(PROG6) $(DIST)\bin
clobber::
rm -f $(DIST)\bin\TimerTest.exe
rm -f $(DIST)\bin\TestAtoms.exe
!ifdef MODULAR_NETLIB
rm -f $(DIST)\bin\CvtURL.exe
rm -f $(DIST)\bin\TestCRT.exe
rm -f $(DIST)\bin\PropertiesTest.exe
rm -f $(DIST)\bin\res\test.properties
!endif
rm -f $(DIST)\bin\FilesTest.exe
rm -f $(DIST)\bin\TestAutoLock.exe
# Move this into config/obj.inc when it's allowed
.cpp{.\$(OBJDIR)\}.exe:
$(CC) @<<$(CFGFILE)
$(CFLAGS)
$(LCFLAGS)
$(LINCS)
$(LINCS_1)
$(INCS)
$(LLIBS)
$(OS_LIBS)
-Fd$(PBDFILE)
-Fe.\$(OBJDIR)\
-Fo.\$(OBJDIR)\
$(CURDIR)$(*B).cpp
<<KEEP
$(PROG0): $(OBJDIR) TimerTest.cpp $(RESFILE)
$(PROG1): $(OBJDIR) TestAtoms.cpp
$(PROG4): $(OBJDIR) FilesTest.cpp
!ifdef MODULAR_NETLIB
$(PROG2): $(OBJDIR) CvtURL.cpp
$(PROG3): $(OBJDIR) TestCRT.cpp
$(PROG5): $(OBJDIR) PropertiesTest.cpp
!endif
$(PROG6): $(OBJDIR) TestAutoLock.cpp

View File

@@ -0,0 +1,32 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#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___ */

View File

@@ -0,0 +1,26 @@
# The contents of this file are subject to the Netscape Public License
# Version 1.0 (the "NPL"); you may not use this file except in
# compliance with the NPL. You may obtain a copy of the NPL at
# http://www.mozilla.org/NPL/
#
# Software distributed under the NPL is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
# for the specific language governing rights and limitations under the
# NPL.
#
# The Initial Developer of this code under the NPL is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
# Reserved.
#
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

View File

@@ -0,0 +1,38 @@
/*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "resources.h"
TIMERTEST MENU DISCARDABLE
{
POPUP "Debug"
{
POPUP "One Shot"
{
MENUITEM "1 second", TIMER_1SECOND
MENUITEM "5 second", TIMER_5SECOND
MENUITEM "10 second", TIMER_10SECOND
}
POPUP "Repeated"
{
MENUITEM "1 second", TIMER_1REPEAT
MENUITEM "5 second", TIMER_5REPEAT
MENUITEM "10 second", TIMER_10REPEAT
}
MENUITEM "Cancel All", TIMER_CANCEL
MENUITEM "Exit", TIMER_EXIT
}
}

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More