summaryrefslogtreecommitdiffstats
path: root/src/libs/xpcom18a4/xpcom/obsolete
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 14:19:18 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 14:19:18 +0000
commit4035b1bfb1e5843a539a8b624d21952b756974d1 (patch)
treef1e9cd5bf548cbc57ff2fddfb2b4aa9ae95587e2 /src/libs/xpcom18a4/xpcom/obsolete
parentInitial commit. (diff)
downloadvirtualbox-upstream.tar.xz
virtualbox-upstream.zip
Adding upstream version 6.1.22-dfsg.upstream/6.1.22-dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/Makefile.in130
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/component/Makefile.in81
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/component/nsFileSpecImpl.cpp857
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/component/nsFileSpecImpl.h116
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/component/nsIRegistry.idl186
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/component/nsIRegistryUtils.h63
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/component/nsRegistry.cpp2019
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/component/nsRegistry.h77
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/component/nsXPCOMObsolete.cpp57
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/component/regExport.cpp357
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/component/xpcomobsoletec.pkg6
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/dlldeps.cpp50
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/nsFileSpec.cpp1367
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/nsFileSpec.h782
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecBeOS.cpp547
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecImpl.cpp879
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecImpl.h116
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecMac.cpp1471
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecOS2.cpp840
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecUnix.cpp703
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecWin.cpp766
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/nsFileStream.cpp392
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/nsFileStream.h772
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/nsIFileSpec.idl204
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/nsIFileStream.cpp727
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/nsIFileStream.h157
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/nsIRegistry.idl186
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/nsIRegistryUtils.h63
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/nsSpecialSystemDirectory.cpp1189
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/nsSpecialSystemDirectory.h167
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/nsXPCOMObsolete.cpp54
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/xpcomobsolete.h50
-rw-r--r--src/libs/xpcom18a4/xpcom/obsolete/xpcomobsolete.pkg7
33 files changed, 15438 insertions, 0 deletions
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/Makefile.in b/src/libs/xpcom18a4/xpcom/obsolete/Makefile.in
new file mode 100644
index 00000000..5f8cd041
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/Makefile.in
@@ -0,0 +1,130 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = xpcom_obsolete
+LIBRARY_NAME = xpcom_compat
+ifneq ($(OS_ARCH),WINNT)
+SHORT_LIBNAME = xpcomct
+endif
+
+GRE_MODULE = 1
+PACKAGE_FILE = xpcomobsolete.pkg
+
+DIRS = component
+
+REQUIRES = xpcom \
+ string \
+ $(NULL)
+
+# pull in MoreFiles for MacOSX
+ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
+REQUIRES += macmorefiles
+endif
+
+CPPSRCS = \
+ nsFileSpec.cpp \
+ nsFileStream.cpp \
+ nsIFileStream.cpp \
+ nsFileSpecImpl.cpp \
+ nsSpecialSystemDirectory.cpp \
+ $(NULL)
+
+ifeq ($(OS_ARCH),WINNT)
+REQUIRES += libreg
+CPPSRCS += dlldeps.cpp
+endif
+
+EXPORTS = \
+ xpcomobsolete.h \
+ nsFileSpec.h \
+ nsFileStream.h \
+ nsIFileStream.h \
+ nsSpecialSystemDirectory.h \
+ nsIRegistryUtils.h \
+ $(NULL)
+
+LOCAL_INCLUDES = \
+ -I.. \
+ -I$(srcdir)/../io \
+ $(NULL)
+
+XPIDLSRCS = nsIFileSpec.idl \
+ nsIRegistry.idl \
+ $(NULL)
+# Force use of PIC
+FORCE_USE_PIC = 1
+
+SHARED_LIBRARY_LIBS = \
+ $(DIST)/lib/$(LIB_PREFIX)mozreg_s.$(LIB_SUFFIX) \
+ $(NULL)
+
+# due to symbol conflicts on win32, this needs to be shared
+FORCE_SHARED_LIB = 1
+
+include $(topsrcdir)/config/rules.mk
+
+DEFINES += -D_IMPL_NS_COM_OBSOLETE
+
+
+EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS)
+
+ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
+CXXFLAGS += $(TK_CFLAGS)
+EXTRA_DSO_LDOPTS += $(TK_LIBS)
+endif
+
+ifeq ($(OS_ARCH),BeOS)
+EXTRA_DSO_LDOPTS += -lbe
+endif
+
+ifeq ($(OS_ARCH),WINNT)
+EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME, shell32 ole32)
+ifneq (,$(MOZ_DEBUG)$(NS_TRACE_MALLOC))
+EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME, imagehlp)
+endif
+ifdef GNU_CXX
+DSO_LDOPTS += -Wl,--export-all-symbols
+endif
+endif # WINNT
+
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/component/Makefile.in b/src/libs/xpcom18a4/xpcom/obsolete/component/Makefile.in
new file mode 100644
index 00000000..a8bec32d
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/component/Makefile.in
@@ -0,0 +1,81 @@
+#
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is mozilla.org code.
+#
+# The Initial Developer of the Original Code is
+# Netscape Communications Corporation.
+# Portions created by the Initial Developer are Copyright (C) 1998
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of the GNU General Public License Version 2 or later (the "GPL"),
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = xpcom_compat_c
+MODULE_NAME = xpcomObsoleteModule
+LIBRARY_NAME = xpcom_compat_c
+ifneq ($(OS_ARCH),WINNT)
+SHORT_LIBNAME = xpcomctc
+endif
+
+ifndef MINIMO
+EXPORT_LIBRARY = 1
+endif
+IS_COMPONENT = 1
+GRE_MODULE = 1
+
+PACKAGE_FILE = xpcomobsoletec.pkg
+
+REQUIRES = xpcom \
+ xpcom_obsolete \
+ string \
+ libreg \
+ $(NULL)
+
+CPPSRCS = \
+ nsXPCOMObsolete.cpp \
+ nsRegistry.cpp \
+ $(NULL)
+
+
+LOCAL_INCLUDES = \
+ -I$(srcdir)/../ \
+ $(NULL)
+
+EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS) \
+ $(MOZ_XPCOM_OBSOLETE_LIBS) \
+ $(NULL)
+
+
+include $(topsrcdir)/config/rules.mk
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/component/nsFileSpecImpl.cpp b/src/libs/xpcom18a4/xpcom/obsolete/component/nsFileSpecImpl.cpp
new file mode 100644
index 00000000..7f51cdca
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/component/nsFileSpecImpl.cpp
@@ -0,0 +1,857 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Pierre Phaneuf <pp@ludusdesign.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsFileSpecImpl.h"// Always first, to ensure that it compiles alone.
+
+#include "nsIFileStream.h"
+#include "nsFileStream.h"
+
+#include "nsILocalFile.h"
+
+#include "prmem.h"
+
+NS_IMPL_THREADSAFE_ISUPPORTS1(nsFileSpecImpl, nsIFileSpec)
+
+#ifdef NS_DEBUG
+#define TEST_OUT_PTR(p) \
+ if (!(p)) \
+ return NS_ERROR_NULL_POINTER;
+#else
+#define TEST_OUT_PTR(p)
+#endif
+
+//----------------------------------------------------------------------------------------
+nsFileSpecImpl::nsFileSpecImpl()
+//----------------------------------------------------------------------------------------
+ : mInputStream(nsnull)
+ , mOutputStream(nsnull)
+{
+// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!");
+
+}
+
+//----------------------------------------------------------------------------------------
+nsFileSpecImpl::nsFileSpecImpl(const nsFileSpec& inSpec)
+//----------------------------------------------------------------------------------------
+ : mFileSpec(inSpec)
+ , mInputStream(nsnull)
+ , mOutputStream(nsnull)
+{
+// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!");
+
+}
+
+//----------------------------------------------------------------------------------------
+nsFileSpecImpl::~nsFileSpecImpl()
+//----------------------------------------------------------------------------------------
+{
+ CloseStream();
+}
+
+//----------------------------------------------------------------------------------------
+/* static */
+nsresult nsFileSpecImpl::MakeInterface(const nsFileSpec& inSpec, nsIFileSpec** result)
+//----------------------------------------------------------------------------------------
+{
+ nsFileSpecImpl* it = new nsFileSpecImpl(inSpec);
+ if (!it)
+ return NS_ERROR_OUT_OF_MEMORY;
+ return it->QueryInterface(NS_GET_IID(nsIFileSpec), (void **) result);
+} // nsFileSpecImpl::MakeInterface
+
+#define FILESPEC(ifilespec) ((nsFileSpecImpl*)ifilespec)->mFileSpec
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::FromFileSpec(const nsIFileSpec *original)
+//----------------------------------------------------------------------------------------
+{
+ if (original) {
+ nsresult rv = ((nsIFileSpec *)original)->GetFileSpec( &mFileSpec);
+ if (NS_SUCCEEDED( rv))
+ return mFileSpec.Error();
+ else
+ return( rv);
+ }
+ else
+ return( NS_ERROR_FAILURE);
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::IsChildOf(nsIFileSpec *possibleParent,
+ PRBool *_retval)
+{
+ *_retval = mFileSpec.IsChildOf(FILESPEC(possibleParent));
+ return mFileSpec.Error();
+}
+//----------------------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetURLString(char * *aURLString)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(aURLString)
+ if (mFileSpec.Failed())
+ return mFileSpec.Error();
+ nsFileURL url(mFileSpec);
+ *aURLString = nsCRT::strdup(url.GetURLString());
+ if (!*aURLString)
+ return NS_ERROR_OUT_OF_MEMORY;
+ return NS_OK;
+} // nsFileSpecImpl::GetURLString
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::SetURLString(const char * aURLString)
+//----------------------------------------------------------------------------------------
+{
+ mFileSpec = nsFileURL(aURLString);
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetUnixStyleFilePath(char * *aUnixStyleFilePath)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(aUnixStyleFilePath)
+ if (mFileSpec.Failed())
+ return mFileSpec.Error();
+ nsFilePath path(mFileSpec);
+ *aUnixStyleFilePath = nsCRT::strdup((const char*) path);
+ if (!*aUnixStyleFilePath)
+ return NS_ERROR_OUT_OF_MEMORY;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::SetUnixStyleFilePath(const char * aUnixStyleFilePath)
+//----------------------------------------------------------------------------------------
+{
+ mFileSpec = nsFilePath(aUnixStyleFilePath);
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetPersistentDescriptorString(char * *aPersistentDescriptorString)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(aPersistentDescriptorString)
+ if (mFileSpec.Failed())
+ return mFileSpec.Error();
+ nsPersistentFileDescriptor desc(mFileSpec);
+ nsCAutoString data;
+ desc.GetData(data);
+ *aPersistentDescriptorString = ToNewCString(data);
+ if (!*aPersistentDescriptorString)
+ return NS_ERROR_OUT_OF_MEMORY;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::SetPersistentDescriptorString(const char * aPersistentDescriptorString)
+//----------------------------------------------------------------------------------------
+{
+ nsPersistentFileDescriptor desc(mFileSpec);
+ desc.SetData(nsDependentCString(aPersistentDescriptorString));
+ mFileSpec = desc;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetNativePath(char * *aNativePath)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(aNativePath)
+ if (mFileSpec.Failed())
+ return mFileSpec.Error();
+ *aNativePath = nsCRT::strdup(mFileSpec.GetNativePathCString());
+ if (!*aNativePath)
+ return NS_ERROR_OUT_OF_MEMORY;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::SetNativePath(const char * aNativePath)
+//----------------------------------------------------------------------------------------
+{
+ mFileSpec = aNativePath;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetNSPRPath(char * *aNSPRPath)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(aNSPRPath)
+ if (mFileSpec.Failed())
+ return mFileSpec.Error();
+ nsNSPRPath path(mFileSpec);
+ *aNSPRPath = nsCRT::strdup((const char*) path);
+ if (!*aNSPRPath)
+ return NS_ERROR_OUT_OF_MEMORY;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Error()
+//----------------------------------------------------------------------------------------
+{
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::IsValid(PRBool *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ *_retval = mFileSpec.Valid();
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Failed(PRBool *_retval)
+//----------------------------------------------------------------------------------------
+{
+ *_retval = mFileSpec.Failed();
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetLeafName(char * *aLeafName)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(aLeafName)
+ *aLeafName = mFileSpec.GetLeafName();
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::SetLeafName(const char * aLeafName)
+//----------------------------------------------------------------------------------------
+{
+ mFileSpec.SetLeafName(aLeafName);
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetParent(nsIFileSpec * *aParent)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(aParent)
+ nsFileSpec parent;
+ mFileSpec.GetParent(parent);
+ return MakeInterface(parent, aParent);
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::MakeUnique()
+//----------------------------------------------------------------------------------------
+{
+ mFileSpec.MakeUnique();
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::MakeUniqueWithSuggestedName(const char *suggestedName)
+//----------------------------------------------------------------------------------------
+{
+ mFileSpec.MakeUnique(suggestedName);
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetModDate(PRUint32 *aModDate)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(aModDate)
+ nsFileSpec::TimeStamp stamp;
+ mFileSpec.GetModDate(stamp);
+ *aModDate = stamp;
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::ModDateChanged(PRUint32 oldStamp, PRBool *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ *_retval = mFileSpec.ModDateChanged(oldStamp);
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::IsDirectory(PRBool *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ *_retval = mFileSpec.IsDirectory();
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::IsFile(PRBool *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ *_retval = mFileSpec.IsFile();
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Exists(PRBool *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ *_retval = mFileSpec.Exists();
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::IsHidden(PRBool *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ *_retval = mFileSpec.IsHidden();
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::IsSymlink(PRBool *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ *_retval = mFileSpec.IsSymlink();
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::ResolveSymlink()
+//----------------------------------------------------------------------------------------
+{
+ PRBool ignore;
+ return mFileSpec.ResolveSymlink(ignore);
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetFileSize(PRUint32 *aFileSize)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(aFileSize)
+ *aFileSize = mFileSpec.GetFileSize();
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetDiskSpaceAvailable(PRInt64 *aDiskSpaceAvailable)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(aDiskSpaceAvailable)
+ *aDiskSpaceAvailable = mFileSpec.GetDiskSpaceAvailable();
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::AppendRelativeUnixPath(const char *relativePath)
+//----------------------------------------------------------------------------------------
+{
+ mFileSpec += relativePath;
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Touch()
+//----------------------------------------------------------------------------------------
+{
+ // create an empty file, like the UNIX touch command.
+ nsresult rv;
+ rv = OpenStreamForWriting();
+ if (NS_FAILED(rv)) return rv;
+ rv = CloseStream();
+ return rv;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::CreateDir()
+//----------------------------------------------------------------------------------------
+{
+ mFileSpec.CreateDir();
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Delete(PRBool aRecursive)
+//----------------------------------------------------------------------------------------
+{
+ mFileSpec.Delete(aRecursive);
+ return mFileSpec.Error();
+}
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Truncate(PRInt32 aNewLength)
+//----------------------------------------------------------------------------------------
+{
+ return mFileSpec.Truncate(aNewLength);
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Rename(const char *newLeafName)
+//----------------------------------------------------------------------------------------
+{
+ return mFileSpec.Rename(newLeafName);
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::CopyToDir(const nsIFileSpec *newParentDir)
+//----------------------------------------------------------------------------------------
+{
+ return mFileSpec.CopyToDir(FILESPEC(newParentDir));
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::MoveToDir(const nsIFileSpec *newParentDir)
+//----------------------------------------------------------------------------------------
+{
+ return mFileSpec.MoveToDir(FILESPEC(newParentDir));
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Execute(const char *args)
+//----------------------------------------------------------------------------------------
+{
+ return mFileSpec.Execute(args);
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::OpenStreamForReading()
+//----------------------------------------------------------------------------------------
+{
+ if (mInputStream || mOutputStream)
+ return NS_ERROR_FAILURE;
+ return NS_NewTypicalInputFileStream((nsISupports**)&mInputStream, mFileSpec);
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::OpenStreamForWriting()
+//----------------------------------------------------------------------------------------
+{
+ if (mInputStream || mOutputStream)
+ return NS_ERROR_FAILURE;
+ return NS_NewTypicalOutputFileStream((nsISupports**)&mOutputStream, mFileSpec);
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::OpenStreamForReadingAndWriting()
+//----------------------------------------------------------------------------------------
+{
+ if (mInputStream || mOutputStream)
+ return NS_ERROR_FAILURE;
+ nsresult result = NS_NewTypicalInputFileStream((nsISupports**)&mInputStream, mFileSpec);
+ if (NS_SUCCEEDED(result))
+ result = NS_NewTypicalOutputFileStream((nsISupports**)&mOutputStream, mFileSpec);
+ return result;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::CloseStream()
+//----------------------------------------------------------------------------------------
+{
+ NS_IF_RELEASE(mInputStream);
+ NS_IF_RELEASE(mOutputStream);
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::IsStreamOpen(PRBool *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ *_retval = (mInputStream || mOutputStream);
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetInputStream(nsIInputStream** _retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ if (!mInputStream) {
+ nsresult rv = OpenStreamForReading();
+ if (NS_FAILED(rv)) return rv;
+ }
+ *_retval = mInputStream;
+ NS_IF_ADDREF(mInputStream);
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetOutputStream(nsIOutputStream** _retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ if (!mOutputStream) {
+ nsresult rv = OpenStreamForWriting();
+ if (NS_FAILED(rv)) return rv;
+ }
+ *_retval = mOutputStream;
+ NS_IF_ADDREF(mOutputStream);
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::SetFileContents(const char* inString)
+//----------------------------------------------------------------------------------------
+{
+ nsresult rv = OpenStreamForWriting();
+ if (NS_FAILED(rv)) return rv;
+ PRInt32 count;
+ rv = Write(inString, PL_strlen(inString), &count);
+ nsresult rv2 = CloseStream();
+ return NS_FAILED(rv) ? rv : rv2;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetFileContents(char** _retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ *_retval = nsnull;
+ nsresult rv = OpenStreamForReading();
+ if (NS_FAILED(rv)) return rv;
+ PRInt32 theSize;
+ rv = GetFileSize((PRUint32*)&theSize);
+ if (NS_SUCCEEDED(rv))
+ rv = Read(_retval, theSize, &theSize);
+ if (NS_SUCCEEDED(rv))
+ (*_retval)[theSize] = 0;
+ nsresult rv2 = CloseStream();
+ return NS_FAILED(rv) ? rv : rv2;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetFileSpec(nsFileSpec *aFileSpec)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(aFileSpec)
+ *aFileSpec = mFileSpec;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Equals(nsIFileSpec *spec, PRBool *result)
+//----------------------------------------------------------------------------------------
+{
+ nsresult rv;
+
+ if (!result || !spec) return NS_ERROR_NULL_POINTER;
+
+ nsFileSpec otherSpec;
+
+ rv = spec->GetFileSpec(&otherSpec);
+ if (NS_FAILED(rv)) return rv;
+
+ if (mFileSpec == otherSpec) {
+ *result = PR_TRUE;
+ }
+ else {
+ *result = PR_FALSE;
+ }
+
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::SetFromFileSpec(const nsFileSpec& aFileSpec)
+//----------------------------------------------------------------------------------------
+{
+ mFileSpec = aFileSpec;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Eof(PRBool *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ if (!mInputStream)
+ return NS_ERROR_NULL_POINTER;
+ nsInputFileStream s(mInputStream);
+ *_retval = s.eof();
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Read(char** buffer, PRInt32 requestedCount, PRInt32 *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ TEST_OUT_PTR(buffer)
+ if (!mInputStream) {
+ nsresult rv = OpenStreamForReading();
+ if (NS_FAILED(rv)) return rv;
+ }
+ if (!*buffer)
+ *buffer = (char*)PR_Malloc(requestedCount + 1);
+ if (!mInputStream)
+ return NS_ERROR_NULL_POINTER;
+ nsInputFileStream s(mInputStream);
+ *_retval = s.read(*buffer, requestedCount);
+ return s.error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::ReadLine(char** line, PRInt32 bufferSize, PRBool *wasTruncated)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(wasTruncated)
+ TEST_OUT_PTR(line)
+ if (!mInputStream) {
+ nsresult rv = OpenStreamForReading();
+ if (NS_FAILED(rv)) return rv;
+ }
+ if (!*line)
+ *line = (char*)PR_Malloc(bufferSize + 1);
+ if (!mInputStream)
+ return NS_ERROR_NULL_POINTER;
+ nsInputFileStream s(mInputStream);
+ *wasTruncated = !s.readline(*line, bufferSize);
+ return s.error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Write(const char * data, PRInt32 requestedCount, PRInt32 *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ //if (!mOutputStream)
+ // return NS_ERROR_NULL_POINTER;
+ if (!mOutputStream) {
+ nsresult rv = OpenStreamForWriting();
+ if (NS_FAILED(rv))
+ return rv;
+ }
+ nsOutputFileStream s(mOutputStream);
+ *_retval = s.write(data, requestedCount);
+ return s.error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Flush()
+//----------------------------------------------------------------------------------------
+{
+ if (!mOutputStream)
+ return NS_ERROR_NULL_POINTER;
+ nsOutputFileStream s(mOutputStream);
+ s.flush();
+ return s.error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Seek(PRInt32 offset)
+//----------------------------------------------------------------------------------------
+{
+ nsresult result = NS_OK;
+ if (mOutputStream)
+ {
+ nsOutputFileStream os(mOutputStream);
+ os.seek(offset);
+ result = os.error();
+ }
+ if (NS_SUCCEEDED(result) && mInputStream)
+ {
+ nsInputFileStream is(mInputStream);
+ is.seek(offset);
+ result = is.error();
+ }
+ return result;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Tell(PRInt32 *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ if (!mInputStream)
+ return NS_ERROR_NULL_POINTER;
+ nsInputFileStream s(mInputStream);
+ *_retval = s.tell();
+ return s.error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::EndLine()
+//----------------------------------------------------------------------------------------
+{
+ nsOutputFileStream s(mOutputStream);
+ s << nsEndl;
+ return s.error();
+}
+
+NS_IMPL_ISUPPORTS1(nsDirectoryIteratorImpl, nsIDirectoryIterator)
+
+//----------------------------------------------------------------------------------------
+nsDirectoryIteratorImpl::nsDirectoryIteratorImpl()
+//----------------------------------------------------------------------------------------
+ : mDirectoryIterator(nsnull)
+{
+}
+
+//----------------------------------------------------------------------------------------
+nsDirectoryIteratorImpl::~nsDirectoryIteratorImpl()
+//----------------------------------------------------------------------------------------
+{
+ delete mDirectoryIterator;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsDirectoryIteratorImpl::Init(nsIFileSpec *parent, PRBool resolveSymlink)
+//----------------------------------------------------------------------------------------
+{
+ delete mDirectoryIterator;
+ mDirectoryIterator = new nsDirectoryIterator(FILESPEC(parent), resolveSymlink);
+ if (!mDirectoryIterator)
+ return NS_ERROR_OUT_OF_MEMORY;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsDirectoryIteratorImpl::Exists(PRBool *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ if (!mDirectoryIterator)
+ return NS_ERROR_NULL_POINTER;
+ *_retval = mDirectoryIterator->Exists();
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsDirectoryIteratorImpl::Next()
+//----------------------------------------------------------------------------------------
+{
+ if (!mDirectoryIterator)
+ return NS_ERROR_NULL_POINTER;
+ (*mDirectoryIterator)++;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsDirectoryIteratorImpl::GetCurrentSpec(nsIFileSpec * *aCurrentSpec)
+//----------------------------------------------------------------------------------------
+{
+ if (!mDirectoryIterator)
+ return NS_ERROR_NULL_POINTER;
+ return nsFileSpecImpl::MakeInterface(mDirectoryIterator->Spec(), aCurrentSpec);
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsDirectoryIteratorImpl::Create(nsISupports* outer, const nsIID& aIID, void* *aIFileSpec)
+//----------------------------------------------------------------------------------------
+{
+ if (aIFileSpec == NULL)
+ return NS_ERROR_NULL_POINTER;
+
+ nsDirectoryIteratorImpl* it = new nsDirectoryIteratorImpl;
+ if (!it)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ nsresult rv = it->QueryInterface(aIID, aIFileSpec);
+ if (NS_FAILED(rv))
+ {
+ delete it;
+ return rv;
+ }
+ return rv;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Create(nsISupports* outer, const nsIID& aIID, void* *aIFileSpec)
+//----------------------------------------------------------------------------------------
+{
+ if (aIFileSpec == NULL)
+ return NS_ERROR_NULL_POINTER;
+
+ nsFileSpecImpl* it = new nsFileSpecImpl;
+ if (!it)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ nsresult rv = it->QueryInterface(aIID, aIFileSpec);
+ if (NS_FAILED(rv))
+ {
+ delete it;
+ return rv;
+ }
+ return rv;
+}
+
+//----------------------------------------------------------------------------------------
+nsresult NS_NewFileSpecWithSpec(const nsFileSpec& aSrcFileSpec, nsIFileSpec **result)
+//----------------------------------------------------------------------------------------
+{
+ if (!result)
+ return NS_ERROR_NULL_POINTER;
+
+ return nsFileSpecImpl::MakeInterface(aSrcFileSpec, result);
+}
+
+//----------------------------------------------------------------------------------------
+nsresult NS_NewFileSpec(nsIFileSpec** result)
+//----------------------------------------------------------------------------------------
+{
+ return nsFileSpecImpl::Create(nsnull, NS_GET_IID(nsIFileSpec), (void**)result);
+}
+
+//----------------------------------------------------------------------------------------
+nsresult NS_NewFileSpecFromIFile(nsIFile *aFile, nsIFileSpec **result)
+//----------------------------------------------------------------------------------------
+{
+ nsresult rv = nsFileSpecImpl::Create(nsnull, NS_GET_IID(nsIFileSpec), (void**)result);
+ if (NS_FAILED(rv)) return rv;
+
+ nsCAutoString path;
+ rv = aFile->GetNativePath(path);
+ if (NS_FAILED(rv)) return rv;
+
+ rv = (*result)->SetNativePath(path.get());
+ if (NS_FAILED(rv))
+ NS_RELEASE(*result);
+ return rv;
+}
+
+//----------------------------------------------------------------------------------------
+nsresult NS_NewDirectoryIterator(nsIDirectoryIterator** result)
+//----------------------------------------------------------------------------------------
+{
+ return nsDirectoryIteratorImpl::Create(nsnull, NS_GET_IID(nsIDirectoryIterator), (void**)result);
+}
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/component/nsFileSpecImpl.h b/src/libs/xpcom18a4/xpcom/obsolete/component/nsFileSpecImpl.h
new file mode 100644
index 00000000..502e254f
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/component/nsFileSpecImpl.h
@@ -0,0 +1,116 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef _FILESPECIMPL_H_
+#define _FILESPECIMPL_H_
+
+#include "nscore.h"
+#include "nsIFileSpec.h"
+#include "nsFileSpec.h"
+
+//========================================================================================
+class nsFileSpecImpl
+//========================================================================================
+ : public nsIFileSpec
+{
+
+ public:
+
+ NS_DECL_ISUPPORTS
+
+ NS_DECL_NSIFILESPEC
+
+ //----------------------
+ // COM Cruft
+ //----------------------
+
+ static NS_METHOD Create(nsISupports* outer, const nsIID& aIID, void* *aIFileSpec);
+
+ //----------------------
+ // Implementation
+ //----------------------
+
+ nsFileSpecImpl();
+ nsFileSpecImpl(const nsFileSpec& inSpec);
+ static nsresult MakeInterface(const nsFileSpec& inSpec, nsIFileSpec** outSpec);
+
+ //----------------------
+ // Data
+ //----------------------
+
+ nsFileSpec mFileSpec;
+ nsIInputStream* mInputStream;
+ nsIOutputStream* mOutputStream;
+
+private:
+ ~nsFileSpecImpl();
+}; // class nsFileSpecImpl
+
+//========================================================================================
+class nsDirectoryIteratorImpl
+//========================================================================================
+ : public nsIDirectoryIterator
+{
+
+public:
+
+ nsDirectoryIteratorImpl();
+
+ NS_DECL_ISUPPORTS
+
+ NS_IMETHOD Init(nsIFileSpec *parent, PRBool resolveSymlink);
+
+ NS_IMETHOD Exists(PRBool *_retval);
+
+ NS_IMETHOD Next();
+
+ NS_IMETHOD GetCurrentSpec(nsIFileSpec * *aCurrentSpec);
+
+ //----------------------
+ // COM Cruft
+ //----------------------
+
+ static NS_METHOD Create(nsISupports* outer, const nsIID& aIID, void* *aIFileSpec);
+
+private:
+ ~nsDirectoryIteratorImpl();
+
+protected:
+ nsDirectoryIterator* mDirectoryIterator;
+}; // class nsDirectoryIteratorImpl
+
+#endif // _FILESPECIMPL_H_
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/component/nsIRegistry.idl b/src/libs/xpcom18a4/xpcom/obsolete/component/nsIRegistry.idl
new file mode 100644
index 00000000..bc9990e2
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/component/nsIRegistry.idl
@@ -0,0 +1,186 @@
+/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org Code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#include "nsISupports.idl"
+#include "nsIEnumerator.idl"
+
+interface nsIFile;
+
+typedef PRUint32 nsRegistryKey;
+typedef long nsWellKnownRegistry;
+
+[scriptable,uuid(5D41A440-8E37-11d2-8059-00600811A9C3)]
+interface nsIRegistry : nsISupports
+{
+ const long None = 0;
+ const long Users = 1;
+ const long Common = 2;
+ const long CurrentUser = 3;
+
+ const long ApplicationComponentRegistry = 1;
+ const long ApplicationRegistry = 2;
+
+ // Dont use this one. This for internal use only.
+ const long ApplicationCustomRegistry = -1;
+
+ void open(in nsIFile regFile);
+ void openWellKnownRegistry(in nsWellKnownRegistry regid);
+
+ void flush();
+ boolean isOpen();
+
+ nsRegistryKey addKey(in nsRegistryKey baseKey, in wstring keyname);
+ nsRegistryKey getKey(in nsRegistryKey baseKey, in wstring keyname);
+ void removeKey(in nsRegistryKey baseKey, in wstring keyname);
+
+ wstring getString(in nsRegistryKey baseKey, in wstring valname);
+ void setString(in nsRegistryKey baseKey, in wstring valname, in wstring value);
+
+ string getStringUTF8(in nsRegistryKey baseKey, in string path);
+ void setStringUTF8(in nsRegistryKey baseKey, in string path, in string value);
+
+ void getBytesUTF8(in nsRegistryKey baseKey, in string path, out PRUint32 length, [retval, array, size_is(length)] out PRUint8 valueArray);
+ void setBytesUTF8(in nsRegistryKey baseKey, in string path, in PRUint32 length, [array, size_is(length)] in PRUint8 valueArray);
+ PRInt32 getInt(in nsRegistryKey baseKey, in string path);
+ void setInt(in nsRegistryKey baseKey, in string path, in PRInt32 value);
+ PRInt64 getLongLong(in nsRegistryKey baseKey, in string path);
+ void setLongLong(in nsRegistryKey baseKey, in string path, inout PRInt64 value);
+
+ /**
+ * addSubtree() and friends need to be renamed to addKeyUTF8().
+ * If you are using these forms make sure you pass UTF8 data
+ */
+ nsRegistryKey addSubtree(in nsRegistryKey baseKey, in string path);
+ void removeSubtree(in nsRegistryKey baseKey, in string path);
+ nsRegistryKey getSubtree(in nsRegistryKey baseKey, in string path);
+
+ nsRegistryKey addSubtreeRaw(in nsRegistryKey baseKey, in string path);
+ void removeSubtreeRaw(in nsRegistryKey baseKey, in string path);
+ nsRegistryKey getSubtreeRaw(in nsRegistryKey baseKey, in string path);
+
+ nsIEnumerator enumerateSubtrees(in nsRegistryKey baseKey);
+ nsIEnumerator enumerateAllSubtrees(in nsRegistryKey baseKey);
+ nsIEnumerator enumerateValues(in nsRegistryKey baseKey);
+
+ const unsigned long String = 1;
+ const unsigned long Int32 = 2;
+ const unsigned long Bytes = 3;
+ const unsigned long File = 4;
+
+ unsigned long getValueType(in nsRegistryKey baseKey, in string path);
+ PRUint32 getValueLength(in nsRegistryKey baseKey, in string path);
+ void deleteValue(in nsRegistryKey baseKey, in string path);
+
+ /**
+ * escapeKey() takes arbitrary binary data and converts it into
+ * valid ASCII which can be used as registry key or value names
+ */
+ void escapeKey([array, size_is(length)] in PRUint8 key, in PRUint32 terminator, inout PRUint32 length, [retval, array, size_is(length)] out PRUint8 escaped);
+ void unescapeKey([array, size_is(length)] in PRUint8 escaped, in PRUint32 terminator, inout PRUint32 length, [retval, array, size_is(length)] out PRUint8 key);
+
+ attribute string currentUserName;
+
+ void pack();
+};
+
+[scriptable, uuid(8cecf236-1dd2-11b2-893c-f9848956eaec)]
+interface nsIRegistryEnumerator : nsIEnumerator
+{
+ void currentItemInPlaceUTF8(out nsRegistryKey key,
+ [shared, retval] out string item);
+};
+
+[scriptable, uuid(D1B54831-AC07-11d2-805E-00600811A9C3)]
+interface nsIRegistryNode : nsISupports
+{
+ readonly attribute string nameUTF8;
+ readonly attribute wstring name;
+ readonly attribute nsRegistryKey key;
+};
+
+[scriptable,uuid(5316C380-B2F8-11d2-A374-0080C6F80E4B)]
+interface nsIRegistryValue : nsISupports
+{
+ readonly attribute wstring name;
+ readonly attribute string nameUTF8;
+ readonly attribute unsigned long type;
+ readonly attribute PRUint32 length;
+};
+
+[uuid(3A15FC88-7A61-4Ab4-8E58-31E95fAB3DA8)]
+/**
+ * It sucks that nsIRegistry has to always allocate and return
+ * strings. nsIRegistryGetter adds in interfaces for non allocating getters
+ * to registry values.
+ */
+interface nsIRegistryGetter : nsISupports
+{
+ /**
+ * Get a string value of attribute valname in widestring or utf8 format
+ *
+ * @return
+ * NS_OK on success.
+ * buf has the string value copied into it. length is NOT changed.
+ * NS_ERROR_REG_BUFFER_TOO_SMALL if not enough buffer space.
+ * length is updated to actual length in chars including
+ * terminating NULL and buf will be unchanged.
+ * NS_ERROR_FAILURE if an unknown error happened. state of buf and
+ * length undefined.
+ * various failure codes otherwise. buf and length wont be updated.
+ */
+ void getStringUTF8IntoBuffer(in nsRegistryKey baseKey, in string path,
+ inout char buf, inout PRUint32 length);
+
+ /**
+ * Get a a byte array value of attribute valname
+ *
+ * @return
+ * NS_OK on success. buf has the string value copied into it.
+ * length is updated to actual number of bytes copied into buf.
+ * NS_ERROR_REG_BUFFER_TOO_SMALL if not enough buffer space.
+ * length is updated to actual length in PRUint8s including
+ * terminating NULL and buf will be unchanged.
+ * NS_ERROR_FAILURE if an unknown error happened. state of buf and
+ * length undefined.
+ * various other failure codes otherwise. buf and length wont be updated.
+ */
+ void getBytesUTF8IntoBuffer(in nsRegistryKey baseKey, in string path,
+ inout PRUint8 buf, inout PRUint32 length);
+};
+
+%{ C++
+#include "nsIRegistryUtils.h"
+%}
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/component/nsIRegistryUtils.h b/src/libs/xpcom18a4/xpcom/obsolete/component/nsIRegistryUtils.h
new file mode 100644
index 00000000..a3d74d7a
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/component/nsIRegistryUtils.h
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#ifndef __nsIRegistryUtils_h
+#define __nsIRegistryUtils_h
+
+#define NS_REGISTRY_CONTRACTID "@mozilla.org/registry;1"
+#define NS_REGISTRY_CLASSNAME "Mozilla Registry"
+/* be761f00-a3b0-11d2-996c-0080c7cb1081 */
+#define NS_REGISTRY_CID \
+{ \
+ 0xbe761f00, \
+ 0xa3b0, \
+ 0x11d2, \
+ {0x99, 0x6c, 0x00, 0x80, 0xc7, 0xcb, 0x10, 0x81} \
+}
+
+/*------------------------------- Error Codes ----------------------------------
+------------------------------------------------------------------------------*/
+#define NS_ERROR_REG_BADTYPE NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 1 )
+#define NS_ERROR_REG_NO_MORE NS_ERROR_GENERATE_SUCCESS( NS_ERROR_MODULE_REG, 2 )
+#define NS_ERROR_REG_NOT_FOUND NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 3 )
+#define NS_ERROR_REG_NOFILE NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 4 )
+#define NS_ERROR_REG_BUFFER_TOO_SMALL NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 5 )
+#define NS_ERROR_REG_NAME_TOO_LONG NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 6 )
+#define NS_ERROR_REG_NO_PATH NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 7 )
+#define NS_ERROR_REG_READ_ONLY NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 8 )
+#define NS_ERROR_REG_BAD_UTF8 NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 9 )
+
+#endif
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/component/nsRegistry.cpp b/src/libs/xpcom18a4/xpcom/obsolete/component/nsRegistry.cpp
new file mode 100644
index 00000000..d3ecfe62
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/component/nsRegistry.cpp
@@ -0,0 +1,2019 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifdef MOZ_LOGGING
+#define FORCE_PR_LOG /* Allow logging in the release build */
+#endif
+
+#include "nsIGenericFactory.h"
+
+#include "nsRegistry.h"
+#include "nsIEnumerator.h"
+#include "nsDirectoryService.h"
+#include "nsDirectoryServiceDefs.h"
+#include "nsAppDirectoryServiceDefs.h"
+#include "NSReg.h"
+#include "prmem.h"
+#include "prlock.h"
+#include "prlog.h"
+#include "prprf.h"
+#include "nsCRT.h"
+#include "nsMemory.h"
+
+#include "nsCOMPtr.h"
+#include "nsILocalFile.h"
+#include "nsIServiceManager.h"
+#include "nsTextFormatter.h"
+
+#ifdef XP_BEOS
+#include <FindDirectory.h>
+#include <Path.h>
+#endif
+
+/* extra locking for the paranoid */
+/* #define EXTRA_THREADSAFE */
+#ifndef EXTRA_THREADSAFE
+#define PR_Lock(x) (void)0
+#define PR_Unlock(x) (void)0
+#endif
+
+// Logging of debug output
+extern PRLogModuleInfo *nsComponentManagerLog;
+
+PRUnichar widestrFormat[] = { PRUnichar('%'),PRUnichar('s'),PRUnichar(0)};
+
+/*-------------------------------- nsRegistry ----------------------------------
+| This class implements the nsIRegistry interface using the functions |
+| provided by libreg (as declared in mozilla/modules/libreg/include/NSReg.h). |
+| |
+| Since that interface is designed to match the libreg function, this class |
+| is implemented with each member function being a simple wrapper for the |
+| corresponding libreg function. |
+| |
+| #define EXTRA_THREADSAFE if you are worried about libreg thread safety. |
+| It should not be necessary, but I'll leave in the code for the paranoid. |
+------------------------------------------------------------------------------*/
+
+#define NS_MOZILLA_DIR_PERMISSION 00700
+
+#include "nsRegistry.h"
+/*
+struct nsRegistry : public nsIRegistry {
+ // This class implements the nsISupports interface functions.
+ NS_DECL_ISUPPORTS
+
+ // This class implements the nsIRegistry interface functions.
+ NS_DECL_NSIREGISTRY
+
+ // ctor/dtor
+ nsRegistry();
+
+private:
+ ~nsRegistry();
+
+protected:
+ HREG mReg; // Registry handle.
+#ifdef EXTRA_THREADSAFE
+ PRLock *mregLock; // libreg isn't threadsafe. Use locks to synchronize.
+#endif
+ char *mCurRegFile; // these are to prevent open from opening the registry again
+ nsWellKnownRegistry mCurRegID;
+
+ NS_IMETHOD Close();
+}; // nsRegistry
+*/
+
+#include "nsIFactory.h"
+/*----------------------------- nsRegistryFactory ------------------------------
+| Class factory for nsRegistry objects. |
+------------------------------------------------------------------------------*/
+struct nsRegistryFactory : public nsIFactory {
+ // This class implements the nsISupports interface functions.
+ NS_DECL_ISUPPORTS
+
+ // nsIFactory methods
+ NS_IMETHOD CreateInstance(nsISupports *,const nsIID &,void **);
+ NS_IMETHOD LockFactory(PRBool aLock);
+
+ // ctor
+ nsRegistryFactory();
+};
+
+
+/*--------------------------- nsRegSubtreeEnumerator ---------------------------
+| This class implements the nsIEnumerator interface and is used to implement |
+| the nsRegistry EnumerateSubtrees and EnumerateAllSubtrees functions. |
+------------------------------------------------------------------------------*/
+struct nsRegSubtreeEnumerator : public nsIRegistryEnumerator {
+ // This class implements the nsISupports interface functions.
+ NS_DECL_ISUPPORTS
+
+ // This class implements the nsIEnumerator interface functions.
+ NS_DECL_NSIENUMERATOR
+
+ // And our magic behind-the-back fast-path thing.
+ NS_DECL_NSIREGISTRYENUMERATOR
+
+ // ctor/dtor
+ nsRegSubtreeEnumerator( HREG hReg, RKEY rKey, PRBool all );
+ // virtual dtor since subclasses call our Release()
+ virtual ~nsRegSubtreeEnumerator();
+
+protected:
+ NS_IMETHOD advance(); // Implementation file; does appropriate NR_RegEnum call.
+ HREG mReg; // Handle to registry we're affiliated with.
+ RKEY mKey; // Base key being enumerated.
+ char mName[MAXREGPATHLEN]; // The name of the current key which is in mNext
+ REGENUM mEnum; // Corresponding libreg "enumerator".
+ REGENUM mNext; // Lookahead value.
+ PRUint32 mStyle; // Style (indicates all or some);
+ PRBool mDone; // Done flag.
+#ifdef EXTRA_THREADSAFE
+ PRLock *mregLock;
+#endif
+}; // nsRegSubtreeEnumerator
+
+
+/*--------------------------- nsRegValueEnumerator -----------------------------
+| This class is a variation on nsRegSubtreeEnumerator that allocates |
+| nsRegistryValue objects rather than nsRegistryNode objects. It also |
+| overrides certain functions to make sure the "value" oriented libreg |
+| functions used rather than the subtree oriented ones. |
+------------------------------------------------------------------------------*/
+struct nsRegValueEnumerator : public nsRegSubtreeEnumerator {
+ // Override CurrentItem to allocate nsRegistryValue objects.
+ NS_IMETHOD CurrentItem( nsISupports **result );
+
+ // Override advance() to use proper NR_RegEnumEntries.
+ NS_IMETHOD advance();
+
+ // ctor/dtor
+ nsRegValueEnumerator( HREG hReg, RKEY rKey );
+}; // nsRegValueEnumerator
+
+/*------------------------------ nsRegistryNode --------------------------------
+| This class implements the nsIRegistryNode interface. Instances are |
+| allocated by nsRegSubtreeEnumerator::CurrentItem. |
+------------------------------------------------------------------------------*/
+struct nsRegistryNode : public nsIRegistryNode {
+ // This class implements the nsISupports interface functions.
+ NS_DECL_ISUPPORTS
+
+ // This class implements the nsIRegistryNode interface functions.
+ NS_DECL_NSIREGISTRYNODE
+
+ // ctor
+ nsRegistryNode( HREG hReg, char *name, RKEY childKey );
+
+private:
+ ~nsRegistryNode();
+
+protected:
+ HREG mReg; // Handle to registry this node is part of.
+ char mName[MAXREGPATHLEN]; // Buffer to hold name.
+ RKEY mChildKey; // Key corresponding to mName
+#ifdef EXTRA_THREADSAFE
+ PRLock *mregLock;
+#endif
+}; // nsRegistryNode
+
+
+/*------------------------------ nsRegistryValue -------------------------------
+| This class implements the nsIRegistryValue interface. Instances are |
+| allocated by nsRegValueEnumerator::CurrentItem. |
+------------------------------------------------------------------------------*/
+struct nsRegistryValue : public nsIRegistryValue {
+ // This class implements the nsISupports interface functions.
+ NS_DECL_ISUPPORTS
+
+ // This class implements the nsIRegistryValue interface functions.
+ NS_DECL_NSIREGISTRYVALUE
+
+ // ctor
+ nsRegistryValue( HREG hReg, RKEY key, REGENUM slot );
+
+private:
+ ~nsRegistryValue();
+
+protected:
+ nsresult getInfo(); // Get registry info.
+ HREG mReg; // Handle to registry this node is part of.
+ RKEY mKey; // Key this node is under.
+ REGENUM mEnum; // Copy of corresponding content of parent enumerator.
+ REGINFO mInfo; // Value info.
+ char mName[MAXREGNAMELEN]; // Buffer to hold name.
+ REGERR mErr; // XXX This causes this class to be NON THREAD SAFE
+#ifdef EXTRA_THREADSAFE
+ PRLock *mregLock;
+#endif
+}; // nsRegistryValue
+
+
+/*----------------------------- regerr2nsresult --------------------------------
+| This utility function maps a REGERR value to a corresponding nsresult |
+| error code. |
+------------------------------------------------------------------------------*/
+static nsresult regerr2nsresult( REGERR err ) {
+ nsresult rv = NS_ERROR_UNEXPECTED;
+ switch( err ) {
+ case REGERR_OK:
+ rv = NS_OK;
+ break;
+
+ case REGERR_FAIL:
+ rv = NS_ERROR_FAILURE;
+ break;
+
+ case REGERR_NOMORE:
+ rv = NS_ERROR_REG_NO_MORE;
+ break;
+
+ case REGERR_NOFIND:
+ rv = NS_ERROR_REG_NOT_FOUND;
+ break;
+
+ case REGERR_PARAM:
+ case REGERR_BADTYPE:
+ case REGERR_BADNAME:
+ rv = NS_ERROR_INVALID_ARG;
+ break;
+
+ case REGERR_NOFILE:
+ rv = NS_ERROR_REG_NOFILE;
+ break;
+
+ case REGERR_MEMORY:
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ break;
+
+ case REGERR_BUFTOOSMALL:
+ rv = NS_ERROR_REG_BUFFER_TOO_SMALL;
+ break;
+
+ case REGERR_NAMETOOLONG:
+ rv = NS_ERROR_REG_NAME_TOO_LONG;
+ break;
+
+ case REGERR_NOPATH:
+ rv = NS_ERROR_REG_NO_PATH;
+ break;
+
+ case REGERR_READONLY:
+ rv = NS_ERROR_REG_READ_ONLY;
+ break;
+
+ case REGERR_BADUTF8:
+ rv = NS_ERROR_REG_BAD_UTF8;
+ break;
+
+ }
+ return rv;
+}
+
+/*----------------------------- reginfo2DataType -------------------------------
+| This utility function converts the type field in the REGINFO structure to |
+| the corresponding nsIRegistry::DataType value. |
+------------------------------------------------------------------------------*/
+static void reginfo2DataType( const REGINFO &in, PRUint32 &out ) {
+ // Transfer information, based on entry type.
+ switch( in.entryType ) {
+ case REGTYPE_ENTRY_STRING_UTF:
+ out = nsIRegistry::String;
+ //out.length = in.entryLength;
+ break;
+
+ case REGTYPE_ENTRY_INT32_ARRAY:
+ out = nsIRegistry::Int32;
+ // Convert length in bytes to array dimension.
+ //out.length = in.entryLength / sizeof(PRInt32);
+ break;
+
+ case REGTYPE_ENTRY_BYTES:
+ out = nsIRegistry::Bytes;
+ //out.length = in.entryLength;
+ break;
+
+ case REGTYPE_ENTRY_FILE:
+ out = nsIRegistry::File;
+ //out.length = in.entryLength;
+ break;
+ }
+}
+
+/*----------------------------- reginfo2DataType -------------------------------
+| This utility function converts the length field in the REGINFO structure to |
+| the proper units (if type==Int32 array, we divide by sizeof(PRInt32)). |
+------------------------------------------------------------------------------*/
+static void reginfo2Length( const REGINFO &in, PRUint32 &out ) {
+ // Transfer information, based on entry type.
+ switch( in.entryType ) {
+ case REGTYPE_ENTRY_STRING_UTF:
+ out = in.entryLength;
+ break;
+
+ case REGTYPE_ENTRY_INT32_ARRAY:
+ // Convert length in bytes to array dimension.
+ out = in.entryLength / sizeof(PRInt32);
+ break;
+
+ case REGTYPE_ENTRY_BYTES:
+ out = in.entryLength;
+ break;
+
+ case REGTYPE_ENTRY_FILE:
+ out = in.entryLength;
+ break;
+ }
+}
+
+/*------------------------ nsISupports Implementation --------------------------
+| This code generates the implementation of the nsISupports member functions |
+| for each class implemented in this file. |
+------------------------------------------------------------------------------*/
+NS_IMPL_THREADSAFE_ISUPPORTS2(nsRegistry, nsIRegistry, nsIRegistryGetter)
+NS_IMPL_ISUPPORTS2( nsRegSubtreeEnumerator, nsIEnumerator,
+ nsIRegistryEnumerator)
+NS_IMPL_ISUPPORTS1( nsRegistryNode, nsIRegistryNode )
+NS_IMPL_ISUPPORTS1( nsRegistryValue, nsIRegistryValue )
+
+/*-------------------------- nsRegistry::nsRegistry ----------------------------
+| Vanilla nsRegistry constructor. |
+------------------------------------------------------------------------------*/
+nsRegistry::nsRegistry()
+ : mReg(0), mCurRegID(0) {
+#ifdef EXTRA_THREADSAFE
+ mregLock = PR_NewLock();
+#endif
+ NR_StartupRegistry();
+ return;
+}
+
+/*------------------------- nsRegistry::~nsRegistry ----------------------------
+| The dtor closes the registry file(if open). |
+------------------------------------------------------------------------------*/
+nsRegistry::~nsRegistry() {
+ if( mReg ) {
+ Close();
+ }
+#ifdef EXTRA_THREADSAFE
+ if (mregLock) {
+ PR_DestroyLock(mregLock);
+ }
+#endif
+ NR_ShutdownRegistry();
+ return;
+}
+
+/*----------------------------- nsRegistry::Open -------------------------------
+| If the argument is null, delegate to OpenDefault, else open the registry |
+| file. We first check to see if a registry file is already open and close |
+| it if so. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::Open( nsIFile *regFile ) {
+ REGERR err = REGERR_OK;
+
+ // Check for default.
+ if( !regFile ) {
+ return OpenWellKnownRegistry(nsIRegistry::ApplicationRegistry);
+ }
+
+ nsCAutoString regPath;
+ nsresult rv = regFile->GetNativePath(regPath);
+ if (NS_FAILED(rv)) return rv;
+
+#ifdef DEBUG_dp
+ printf("nsRegistry: Opening registry %s\n", regPath.get());
+#endif /* DEBUG_dp */
+
+ if (mCurRegID != nsIRegistry::None && mCurRegID != nsIRegistry::ApplicationCustomRegistry)
+ {
+ // Cant open another registry without closing explictly.
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ // Do we have an open registry ?
+ if (mCurRegID != nsIRegistry::None)
+ {
+ PRBool equals;
+ if (mCurRegFile && NS_SUCCEEDED(mCurRegFile->Equals(regFile, &equals)) && equals)
+ {
+ // The right one is already open
+ return NS_OK;
+ }
+ else
+ {
+ // Opening a new registry without closing an already open one.
+ // This is an error.
+ return NS_ERROR_FAILURE;
+ }
+ }
+
+ // Open specified registry.
+ PR_Lock(mregLock);
+ err = NR_RegOpen(NS_CONST_CAST(char*,regPath.get()), &mReg);
+ PR_Unlock(mregLock);
+
+ mCurRegID = nsIRegistry::ApplicationCustomRegistry;
+
+ // No error checking for no mem. Trust me.
+ if (NS_FAILED(regFile->Clone(getter_AddRefs(mCurRegFile))))
+ mCurRegFile = nsnull; // not fatal
+
+ // Convert the result.
+ return regerr2nsresult( err );
+}
+
+static void
+EnsureDefaultRegistryDirectory() {
+#if defined(XP_UNIX) && !defined(XP_MACOSX)
+ // Create ~/.mozilla as that is the default place for the registry file
+
+ /* The default registry on the unix system is $HOME/.mozilla/registry per
+ * vr_findGlobalRegName(). vr_findRegFile() will create the registry file
+ * if it doesn't exist. But it wont create directories.
+ *
+ * Hence we need to create the directory if it doesn't exist already.
+ *
+ * Why create it here as opposed to the app ?
+ * ------------------------------------------
+ * The app cannot create the directory in main() as most of the registry
+ * and initialization happens due to use of static variables.
+ * And we dont want to be dependent on the order in which
+ * these static stuff happen.
+ *
+ * Permission for the $HOME/.mozilla will be Read,Write,Execute
+ * for user only. Nothing to group and others.
+ */
+ char *home = getenv("HOME");
+ if (home != NULL)
+ {
+ char dotMozillaDir[1024];
+ PR_snprintf(dotMozillaDir, sizeof(dotMozillaDir),
+ "%s/" MOZ_USER_DIR, home);
+ if (PR_Access(dotMozillaDir, PR_ACCESS_EXISTS) != PR_SUCCESS)
+ {
+ PR_MkDir(dotMozillaDir, NS_MOZILLA_DIR_PERMISSION);
+ PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS,
+ ("nsComponentManager: Creating Directory %s", dotMozillaDir));
+ }
+ }
+#endif /* XP_UNIX */
+
+#ifdef XP_BEOS
+ BPath p;
+ const char *settings = "/boot/home/config/settings";
+ if(find_directory(B_USER_SETTINGS_DIRECTORY, &p) == B_OK)
+ settings = p.Path();
+ char settingsMozillaDir[1024];
+ PR_snprintf(settingsMozillaDir, sizeof(settingsMozillaDir),
+ "%s/" MOZ_USER_DIR, settings);
+ if (PR_Access(settingsMozillaDir, PR_ACCESS_EXISTS) != PR_SUCCESS) {
+ PR_MkDir(settingsMozillaDir, NS_MOZILLA_DIR_PERMISSION);
+ PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS,
+ ("nsComponentManager: Creating Directory %s", settingsMozillaDir));
+ }
+#endif
+}
+
+/*----------------------------- nsRegistry::OpenWellKnownRegistry --------------
+| Takes a registry id and maps that to a file name for opening. We first check |
+| to see if a registry file is already open and close it if so. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::OpenWellKnownRegistry( nsWellKnownRegistry regid )
+{
+ REGERR err = REGERR_OK;
+
+ if (mCurRegID != nsIRegistry::None && mCurRegID != regid)
+ {
+ // Cant open another registry without closing explictly.
+ return NS_ERROR_INVALID_ARG;
+ }
+
+ if (mCurRegID == regid)
+ {
+ // Already opened.
+ return NS_OK;
+ }
+
+ nsresult rv;
+ nsCOMPtr<nsIFile> registryLocation;
+
+ PRBool foundReg = PR_FALSE;
+ nsCAutoString regFile;
+
+ switch ( (nsWellKnownRegistry) regid ) {
+ case ApplicationComponentRegistry:
+ NS_WARNING("ApplicationComponentRegistry is unsupported!");
+ break;
+ case ApplicationRegistry:
+ {
+ EnsureDefaultRegistryDirectory();
+ nsCOMPtr<nsIProperties> directoryService = do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
+ if (NS_FAILED(rv)) return rv;
+ directoryService->Get(NS_APP_APPLICATION_REGISTRY_FILE, NS_GET_IID(nsIFile),
+ getter_AddRefs(registryLocation));
+
+ if (registryLocation)
+ {
+ foundReg = PR_TRUE;
+ rv = registryLocation->GetNativePath(regFile); // dougt fix...
+ // dveditz needs to fix his registry so that I can pass an
+ // nsIFile interface and not hack
+ if (NS_FAILED(rv))
+ return rv;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (foundReg == PR_FALSE) {
+ return NS_ERROR_REG_BADTYPE;
+ }
+
+#ifdef DEBUG_dp
+ printf("nsRegistry: Opening std registry %s\n", regFile.get());
+#endif /* DEBUG_dp */
+
+ PR_Lock(mregLock);
+ err = NR_RegOpen(NS_CONST_CAST(char*, regFile.get()), &mReg );
+ PR_Unlock(mregLock);
+
+ // Store the registry that was opened for optimizing future opens.
+ mCurRegID = regid;
+
+ // Convert the result.
+ return regerr2nsresult( err );
+}
+
+#if 0
+/*-------------------------- nsRegistry::OpenDefault ---------------------------
+| Open the "default" registry; in the case of this libreg-based implementation |
+| that is done by passing a null file name pointer to NR_RegOpen. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::OpenDefault() {
+ return OpenWellKnownRegistry(nsIRegistry::ApplicationRegistry);
+}
+#endif
+
+/*----------------------------- nsRegistry::Close ------------------------------
+| Tests the mReg handle and if non-null, closes the registry via NR_RegClose. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::Close() {
+ REGERR err = REGERR_OK;
+ if( mReg ) {
+ PR_Lock(mregLock);
+ err = NR_RegClose( mReg );
+ PR_Unlock(mregLock);
+ mReg = 0;
+ mCurRegFile = nsnull;
+ mCurRegID = 0;
+ }
+ return regerr2nsresult( err );
+}
+
+/*----------------------------- nsRegistry::Flush ------------------------------
+| Flushes the registry via NR_RegFlush. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::Flush() {
+ REGERR err = REGERR_FAIL;
+ if( mReg ) {
+ PR_Lock(mregLock);
+ err = NR_RegFlush( mReg );
+ PR_Unlock(mregLock);
+ }
+ return regerr2nsresult( err );
+}
+
+/*----------------------------- nsRegistry::IsOpen -----------------------------
+| Tests the mReg handle and returns whether the registry is open or not. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::IsOpen( PRBool *result ) {
+ *result = ( mReg != 0 );
+ return NS_OK;
+}
+
+
+/*--------------------------- nsRegistry::AddKey -------------------------------
+| Add a key into the registry or find an existing one. This is generally used |
+| instead of GetKey unless it's an error for the key not to exist already i
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::AddKey( nsRegistryKey baseKey, const PRUnichar *keyname, nsRegistryKey *_retval)
+{
+ if ( !keyname )
+ return NS_ERROR_NULL_POINTER;
+
+ return AddSubtree( baseKey, NS_ConvertUCS2toUTF8(keyname).get(), _retval );
+}
+
+/*--------------------------- nsRegistry::GetKey -------------------------------
+| returns the nsRegistryKey associated with a given node in the registry |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::GetKey(nsRegistryKey baseKey, const PRUnichar *keyname, nsRegistryKey *_retval)
+{
+ if ( !keyname || !_retval )
+ return NS_ERROR_NULL_POINTER;
+
+ return GetSubtree( baseKey, NS_ConvertUCS2toUTF8(keyname).get(), _retval );
+}
+
+/*--------------------------- nsRegistry::RemoveKey ----------------------------
+| Delete a key from the registry |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::RemoveKey(nsRegistryKey baseKey, const PRUnichar *keyname)
+{
+ if ( !keyname )
+ return NS_ERROR_NULL_POINTER;
+
+ return RemoveSubtree( baseKey, NS_ConvertUCS2toUTF8(keyname).get() );
+}
+
+NS_IMETHODIMP nsRegistry::GetString(nsRegistryKey baseKey, const PRUnichar *valname, PRUnichar **_retval)
+{
+ // Make sure caller gave us place for result.
+ if ( !valname || !_retval )
+ return NS_ERROR_NULL_POINTER;
+
+ // initialize the return value
+ *_retval = nsnull;
+ nsXPIDLCString tmpstr;
+
+ nsresult rv = GetStringUTF8( baseKey, NS_ConvertUCS2toUTF8(valname).get(), getter_Copies(tmpstr) );
+
+ if (NS_SUCCEEDED(rv))
+ {
+ *_retval = nsTextFormatter::smprintf( widestrFormat, tmpstr.get() );
+ if ( *_retval == nsnull )
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ return rv;
+}
+
+NS_IMETHODIMP nsRegistry::SetString(nsRegistryKey baseKey, const PRUnichar *valname, const PRUnichar *value)
+{
+ if ( !valname || ! value )
+ return NS_ERROR_NULL_POINTER;
+
+ return SetStringUTF8( baseKey,
+ NS_ConvertUCS2toUTF8(valname).get(),
+ NS_ConvertUCS2toUTF8(value).get() );
+}
+
+/*--------------------------- nsRegistry::GetString ----------------------------
+| First, look for the entry using GetValueInfo. If found, and it's a string, |
+| allocate space for it and fetch the value. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::GetStringUTF8( nsRegistryKey baseKey, const char *path, char **result ) {
+ nsresult rv = NS_OK;
+ REGERR err = REGERR_OK;
+
+ // Make sure caller gave us place for result.
+ if ( !result )
+ return NS_ERROR_NULL_POINTER;
+
+ char regStr[MAXREGPATHLEN];
+
+ // initialize the return value
+ *result = 0;
+
+ // Attempt to get string into our fixed buffer
+ PR_Lock(mregLock);
+ err = NR_RegGetEntryString( mReg,(RKEY)baseKey,(char*)path, regStr,
+ sizeof(regStr) );
+ PR_Unlock(mregLock);
+
+ if ( err == REGERR_OK )
+ {
+ *result = nsCRT::strdup(regStr);
+ if (!*result)
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ }
+ else if ( err == REGERR_BUFTOOSMALL )
+ {
+ // find the real size and malloc it
+ PRUint32 length;
+ rv = GetValueLength( baseKey, path, &length );
+ // See if that worked.
+ if( rv == NS_OK )
+ {
+ *result =(char*)nsMemory::Alloc( length + 1 );
+ if( *result )
+ {
+ // Get string from registry into result buffer.
+ PR_Lock(mregLock);
+ err = NR_RegGetEntryString( mReg,(RKEY)baseKey,(char*)path, *result, length+1 );
+ PR_Unlock(mregLock);
+
+ // Convert status.
+ rv = regerr2nsresult( err );
+ if ( rv != NS_OK )
+ {
+ // Didn't get result, free buffer
+ nsCRT::free( *result );
+ *result = 0;
+ }
+ }
+ else
+ {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ }
+ }
+ }
+ else
+ {
+ // Convert status.
+ rv = regerr2nsresult( err );
+ NS_ASSERTION(NS_FAILED(rv), "returning success code on failure");
+ }
+
+ return rv;
+}
+
+NS_IMETHODIMP
+nsRegistry::GetStringUTF8IntoBuffer( nsRegistryKey baseKey, const char *path,
+ char *buf, PRUint32 *length )
+{
+ REGERR err = REGERR_OK;
+
+ // Attempt to get string into our fixed buffer
+ PR_Lock(mregLock);
+ err = NR_RegGetEntryString( mReg,(RKEY)baseKey,(char*)path, buf, *length );
+ PR_Unlock(mregLock);
+
+ // Convert status.
+ nsresult rv = regerr2nsresult( err );
+
+ if (rv == NS_ERROR_REG_BUFFER_TOO_SMALL) {
+ // fill length with the actual length
+ nsresult rv1 = GetValueLength( baseKey, path, length );
+ if(NS_FAILED(rv1))
+ return rv1;
+ }
+
+ return rv;
+}
+
+/*--------------------------- nsRegistry::SetString ----------------------------
+| Simply sets the registry contents using NR_RegSetEntryString. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::SetStringUTF8( nsRegistryKey baseKey, const char *path, const char *value ) {
+ REGERR err = REGERR_OK;
+ // Set the contents.
+ PR_Lock(mregLock);
+ err = NR_RegSetEntryString( mReg,(RKEY)baseKey,(char*)path,(char*)value );
+ PR_Unlock(mregLock);
+ // Convert result.
+ return regerr2nsresult( err );
+}
+
+/*---------------------------- nsRegistry::GetBytesUTF8 ------------------------------
+| This function is just shorthand for fetching a char array. We |
+| implement it "manually" using NR_RegGetEntry |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::GetBytesUTF8( nsRegistryKey baseKey, const char *path, PRUint32* length, PRUint8** result) {
+ nsresult rv = NS_OK;
+ REGERR err = REGERR_OK;
+
+ if ( !result )
+ return NS_ERROR_NULL_POINTER;
+
+ char regStr[MAXREGPATHLEN];
+
+ // initialize the return value
+ *length = 0;
+ *result = 0;
+
+ // Get info about the requested entry.
+ PRUint32 type;
+ rv = GetValueType( baseKey, path, &type );
+ // See if that worked.
+ if( rv == NS_OK )
+ {
+ // Make sure the entry is an PRInt8 array.
+ if( type == Bytes )
+ {
+ // Attempt to get string into our fixed buffer
+ PR_Lock(mregLock);
+ uint32 length2 = sizeof regStr;
+ err = NR_RegGetEntry( mReg,(RKEY)baseKey,NS_CONST_CAST(char*,path), regStr, &length2);
+ PR_Unlock(mregLock);
+
+ if ( err == REGERR_OK )
+ {
+ *length = length2;
+ *result = (PRUint8*)(nsCRT::strdup(regStr));
+ if (!*result)
+ {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ *length = 0;
+ }
+ else
+ {
+ *length = length2;
+ }
+ }
+ else if ( err == REGERR_BUFTOOSMALL )
+ {
+ // find the real size and malloc it
+ rv = GetValueLength( baseKey, path, length );
+ // See if that worked.
+ if( rv == NS_OK )
+ {
+ *result = NS_REINTERPRET_CAST(PRUint8*,nsMemory::Alloc( *length ));
+ if( *result )
+ {
+ // Get bytes from registry into result field.
+ PR_Lock(mregLock);
+ length2 = *length;
+ err = NR_RegGetEntry( mReg,(RKEY)baseKey,NS_CONST_CAST(char*,path), *result, &length2);
+ *length = length2;
+ PR_Unlock(mregLock);
+ // Convert status.
+ rv = regerr2nsresult( err );
+ if ( rv != NS_OK )
+ {
+ // Didn't get result, free buffer
+ nsCRT::free( NS_REINTERPRET_CAST(char*, *result) );
+ *result = 0;
+ *length = 0;
+ }
+ }
+ else
+ {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ }
+ }
+ }
+ }
+ else
+ {
+ // They asked for the wrong type of value.
+ rv = NS_ERROR_REG_BADTYPE;
+ }
+ }
+ return rv;
+}
+
+NS_IMETHODIMP
+nsRegistry::GetBytesUTF8IntoBuffer( nsRegistryKey baseKey, const char *path,
+ PRUint8 *buf, PRUint32* length )
+{
+ REGERR err = REGERR_OK;
+
+ // Get info about the requested entry.
+ PRUint32 type;
+ nsresult rv = GetValueType( baseKey, path, &type );
+ // See if that worked.
+ if(NS_FAILED(rv))
+ return rv;
+ // Make sure we are dealing with bytes
+ if (type != Bytes)
+ return NS_ERROR_REG_BADTYPE;
+
+ // Attempt to get bytes into our fixed buffer
+ PR_Lock(mregLock);
+ err = NR_RegGetEntry( mReg,(RKEY)baseKey,NS_CONST_CAST(char*,path),
+ buf, (uint32 *)length );
+ PR_Unlock(mregLock);
+
+ rv = regerr2nsresult(rv);
+
+ if (rv == NS_ERROR_REG_BUFFER_TOO_SMALL) {
+ // fill length with the actual length
+ nsresult rv1 = GetValueLength( baseKey, path, length );
+ if(NS_FAILED(rv1))
+ return rv1;
+ }
+
+
+ return rv;
+}
+
+/*---------------------------- nsRegistry::GetInt ------------------------------
+| This function is just shorthand for fetching a 1-element PRInt32 array. We |
+| implement it "manually" using NR_RegGetEntry |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::GetInt( nsRegistryKey baseKey, const char *path, PRInt32 *result ) {
+ nsresult rv = NS_OK;
+ REGERR err = REGERR_OK;
+
+ // Make sure caller gave us place for result.
+ if( result ) {
+ // Get info about the requested entry.
+ PRUint32 type;
+ rv = GetValueType( baseKey, path, &type );
+ // See if that worked.
+ if( rv == NS_OK ) {
+ // Make sure the entry is an PRInt32 array.
+ if( type == Int32 ) {
+ uint32 len = sizeof *result;
+ // Get int from registry into result field.
+ PR_Lock(mregLock);
+ err = NR_RegGetEntry( mReg,(RKEY)baseKey,(char*)path, result, &len );
+ PR_Unlock(mregLock);
+ // Convert status.
+ rv = regerr2nsresult( err );
+ } else {
+ // They asked for the wrong type of value.
+ rv = NS_ERROR_REG_BADTYPE;
+ }
+ }
+ } else {
+ rv = NS_ERROR_NULL_POINTER;
+ }
+ return rv;
+}
+
+
+/*---------------------------- nsRegistry::GetLongLong--------------------------
+| This function is just shorthand for fetching a 1-element PRInt64 array. We |
+| implement it "manually" using NR_RegGetEntry |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::GetLongLong( nsRegistryKey baseKey, const char *path, PRInt64 *result ) {
+ REGERR err = REGERR_OK;
+
+ PR_Lock(mregLock);
+
+ uint32 length = sizeof(PRInt64);
+ err = NR_RegGetEntry( mReg,(RKEY)baseKey,(char*)path,(void*)result,&length);
+
+ PR_Unlock(mregLock);
+
+ // Convert status.
+ return regerr2nsresult( err );
+}
+/*---------------------------- nsRegistry::SetBytesUTF8 ------------------------------
+| Write out the value as a char array, using NR_RegSetEntry. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::SetBytesUTF8( nsRegistryKey baseKey, const char *path, PRUint32 length, PRUint8* value) {
+ REGERR err = REGERR_OK;
+ // Set the contents.
+ PR_Lock(mregLock);
+ err = NR_RegSetEntry( mReg,
+ (RKEY)baseKey,
+ (char*)path,
+ REGTYPE_ENTRY_BYTES,
+ (char*)value,
+ length);
+ PR_Unlock(mregLock);
+ // Convert result.
+ return regerr2nsresult( err );
+}
+
+/*---------------------------- nsRegistry::SetInt ------------------------------
+| Write out the value as a one-element PRInt32 array, using NR_RegSetEntry. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::SetInt( nsRegistryKey baseKey, const char *path, PRInt32 value ) {
+ REGERR err = REGERR_OK;
+ // Set the contents.
+ PR_Lock(mregLock);
+ err = NR_RegSetEntry( mReg,
+ (RKEY)baseKey,
+ (char*)path,
+ REGTYPE_ENTRY_INT32_ARRAY,
+ &value,
+ sizeof value );
+ PR_Unlock(mregLock);
+ // Convert result.
+ return regerr2nsresult( err );
+}
+
+
+
+/*---------------------------- nsRegistry::SetLongLong---------------------------
+| Write out the value as a one-element PRInt64 array, using NR_RegSetEntry. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::SetLongLong( nsRegistryKey baseKey, const char *path, PRInt64* value ) {
+ REGERR err = REGERR_OK;
+ // Set the contents.
+ PR_Lock(mregLock);
+
+ err = NR_RegSetEntry( mReg,
+ (RKEY)baseKey,
+ (char*)path,
+ REGTYPE_ENTRY_BYTES,
+ (void*)value,
+ sizeof(PRInt64) );
+
+ PR_Unlock(mregLock);
+ // Convert result.
+ return regerr2nsresult( err );
+}
+
+/*-------------------------- nsRegistry::AddSubtree ----------------------------
+| Add a new registry subkey with the specified name, using NR_RegAddKey. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::AddSubtree( nsRegistryKey baseKey, const char *path, nsRegistryKey *result ) {
+ REGERR err = REGERR_OK;
+ // Add the subkey.
+ PR_Lock(mregLock);
+ err = NR_RegAddKey( mReg,(RKEY)baseKey,(char*)path,(RKEY*)result );
+ PR_Unlock(mregLock);
+ // Convert result.
+ return regerr2nsresult( err );
+}
+
+/*-------------------------- nsRegistry::AddSubtreeRaw--------------------------
+| Add a new registry subkey with the specified name, using NR_RegAddKeyRaw |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::AddSubtreeRaw( nsRegistryKey baseKey, const char *path, nsRegistryKey *result ) {
+ REGERR err = REGERR_OK;
+ // Add the subkey.
+ PR_Lock(mregLock);
+ err = NR_RegAddKeyRaw( mReg,(RKEY)baseKey,(char*)path,(RKEY*)result );
+ PR_Unlock(mregLock);
+ // Convert result.
+ return regerr2nsresult( err );
+}
+
+
+/*------------------------- nsRegistry::RemoveSubtree --------------------------
+| Deletes the subtree at a given location using NR_RegDeleteKey. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::RemoveSubtree( nsRegistryKey baseKey, const char *path ) {
+ nsresult rv = NS_OK;
+ REGERR err = REGERR_OK;
+
+ // libreg doesn't delete keys if there are subkeys under the key
+ // Hence we have to recurse through to delete the subtree
+
+ RKEY key;
+
+ PR_Lock(mregLock);
+ err = NR_RegGetKey(mReg, baseKey, (char *)path, &key);
+ PR_Unlock(mregLock);
+ if (err != REGERR_OK)
+ {
+ rv = regerr2nsresult( err );
+ return rv;
+ }
+
+ // Now recurse through and delete all keys under hierarchy
+
+ char subkeyname[MAXREGPATHLEN+1];
+ REGENUM state = 0;
+ subkeyname[0] = '\0';
+ while (NR_RegEnumSubkeys(mReg, key, &state, subkeyname, sizeof(subkeyname),
+ REGENUM_NORMAL) == REGERR_OK)
+ {
+#ifdef DEBUG_dp
+ printf("...recursing into %s\n", subkeyname);
+#endif /* DEBUG_dp */
+ // Even though this is not a "Raw" API the subkeys may still, in fact,
+ // *be* raw. Since we're recursively deleting this will work either way.
+ // If we were guaranteed none would be raw then a depth-first enumeration
+ // would be much more efficient.
+ err = RemoveSubtreeRaw(key, subkeyname);
+ if (err != REGERR_OK) break;
+ }
+
+ // If success in deleting all subkeys, delete this key too
+ if (err == REGERR_OK)
+ {
+#ifdef DEBUG_dp
+ printf("...deleting %s\n", path);
+#endif /* DEBUG_dp */
+ PR_Lock(mregLock);
+ err = NR_RegDeleteKey(mReg, baseKey, (char *)path);
+ PR_Unlock(mregLock);
+ }
+
+ // Convert result.
+ rv = regerr2nsresult( err );
+ return rv;
+}
+
+
+/*------------------------- nsRegistry::RemoveSubtreeRaw -----------------------
+| Deletes the subtree at a given location using NR_RegDeleteKeyRaw |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::RemoveSubtreeRaw( nsRegistryKey baseKey, const char *keyname ) {
+ nsresult rv = NS_OK;
+ REGERR err = REGERR_OK;
+
+ // libreg doesn't delete keys if there are subkeys under the key
+ // Hence we have to recurse through to delete the subtree
+
+ RKEY key;
+ char subkeyname[MAXREGPATHLEN+1];
+ int n = sizeof(subkeyname);
+ REGENUM state = 0;
+
+ PR_Lock(mregLock);
+ err = NR_RegGetKeyRaw(mReg, baseKey, (char *)keyname, &key);
+ PR_Unlock(mregLock);
+ if (err != REGERR_OK)
+ {
+ rv = regerr2nsresult( err );
+ return rv;
+ }
+
+ // Now recurse through and delete all keys under hierarchy
+
+ subkeyname[0] = '\0';
+ while (NR_RegEnumSubkeys(mReg, key, &state, subkeyname, n, REGENUM_NORMAL) == REGERR_OK)
+ {
+#ifdef DEBUG_dp
+ printf("...recursing into %s\n", subkeyname);
+#endif /* DEBUG_dp */
+ err = RemoveSubtreeRaw(key, subkeyname);
+ if (err != REGERR_OK) break;
+ }
+
+ // If success in deleting all subkeys, delete this key too
+ if (err == REGERR_OK)
+ {
+#ifdef DEBUG_dp
+ printf("...deleting %s\n", keyname);
+#endif /* DEBUG_dp */
+ PR_Lock(mregLock);
+ err = NR_RegDeleteKeyRaw(mReg, baseKey, (char *)keyname);
+ PR_Unlock(mregLock);
+ }
+
+ // Convert result.
+ rv = regerr2nsresult( err );
+ return rv;
+}
+/*-------------------------- nsRegistry::GetSubtree ----------------------------
+| Returns a nsRegistryKey(RKEY) for a given key/path. The key is |
+| obtained using NR_RegGetKey. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::GetSubtree( nsRegistryKey baseKey, const char *path, nsRegistryKey *result ) {
+ nsresult rv = NS_OK;
+ REGERR err = REGERR_OK;
+ // Make sure we have a place for the result.
+ if( result ) {
+ // Get key.
+ PR_Lock(mregLock);
+ err = NR_RegGetKey( mReg,(RKEY)baseKey,(char*)path,(RKEY*)result );
+ PR_Unlock(mregLock);
+ // Convert result.
+ rv = regerr2nsresult( err );
+ } else {
+ rv = NS_ERROR_NULL_POINTER;
+ }
+ return rv;
+}
+
+/*-------------------------- nsRegistry::GetSubtreeRaw--------------------------
+| Returns a nsRegistryKey(RKEY) for a given key/path. The key is |
+| obtained using NR_RegGetKeyRaw. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::GetSubtreeRaw( nsRegistryKey baseKey, const char *path, nsRegistryKey *result ) {
+ nsresult rv = NS_OK;
+ REGERR err = REGERR_OK;
+ // Make sure we have a place for the result.
+ if( result ) {
+ // Get key.
+ PR_Lock(mregLock);
+ err = NR_RegGetKeyRaw( mReg,(RKEY)baseKey,(char*)path,(RKEY*)result );
+ PR_Unlock(mregLock);
+ // Convert result.
+ rv = regerr2nsresult( err );
+ } else {
+ rv = NS_ERROR_NULL_POINTER;
+ }
+ return rv;
+}
+
+
+/*----------------------- nsRegistry::EnumerateSubtrees ------------------------
+| Allocate a nsRegSubtreeEnumerator object and return it to the caller. |
+| We construct the enumerator using the registry handle from this registry |
+| object, the user-specified registry key, and indicate that we don't want |
+| to recurse down subtrees. No libreg functions are invoked at this point |
+|(that will happen when the enumerator member functions are called). |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::EnumerateSubtrees( nsRegistryKey baseKey, nsIEnumerator **result ) {
+ nsresult rv = NS_OK;
+ // Make sure we have a place to put the result.
+ if( result ) {
+ *result = new nsRegSubtreeEnumerator( mReg,(RKEY)baseKey, PR_FALSE );
+ // Check for success.
+ if( *result ) {
+ // Bump refcnt on behalf of caller.
+ NS_ADDREF(*result);
+ } else {
+ // Unable to allocate space for the enumerator object.
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ }
+ } else {
+ rv = NS_ERROR_NULL_POINTER;
+ }
+ return rv;
+}
+
+/*--------------------- nsRegistry::EnumerateAllSubtrees -----------------------
+| Same as EnumerateSubtrees but we pass PR_TRUE to request that the |
+| enumerator object descend subtrees when it is used. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::EnumerateAllSubtrees( nsRegistryKey baseKey, nsIEnumerator **result ) {
+ nsresult rv = NS_OK;
+ // Make sure we have a place to put the result.
+ if( result ) {
+ *result = new nsRegSubtreeEnumerator( mReg,(RKEY)baseKey, PR_TRUE );
+ // Check for success.
+ if( *result ) {
+ // Bump refcnt on behalf of caller.
+ NS_ADDREF(*result);
+ } else {
+ // Unable to allocate space for the enumerator object.
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ }
+ } else {
+ rv = NS_ERROR_NULL_POINTER;
+ }
+ return rv;
+}
+
+/*------------------------- nsRegistry::GetValueType ---------------------------
+| Gets the type from the registry using the NR_GetEntryInfo libreg API. |
+| The result is transferred to the PRUint32 value passed in (with conversion |
+| to the appropriate nsIRegistry::DataType value). |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::GetValueType( nsRegistryKey baseKey, const char *path, PRUint32 *result ) {
+ nsresult rv = NS_OK;
+ REGERR err = REGERR_OK;
+ // Make sure we have a place to put the result.
+ if( result ) {
+ // Get registry info into local structure.
+ REGINFO info = { sizeof info, 0, 0 };
+ PR_Lock(mregLock);
+ err = NR_RegGetEntryInfo( mReg,(RKEY)baseKey,(char*)path, &info );
+ PR_Unlock(mregLock);
+ if( err == REGERR_OK ) {
+ // Copy info to user's result value.
+ reginfo2DataType( info, *result );
+ } else {
+ rv = regerr2nsresult( err );
+ }
+ } else {
+ rv = NS_ERROR_NULL_POINTER;
+ }
+ return rv;
+}
+
+/*------------------------ nsRegistry::GetValueLength --------------------------
+| Gets the registry value info via NR_RegGetEntryInfo. The length is |
+| converted to the proper "units" via reginfo2Length. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::GetValueLength( nsRegistryKey baseKey, const char *path, PRUint32 *result ) {
+ nsresult rv = NS_OK;
+ REGERR err = REGERR_OK;
+ // Make sure we have a place to put the result.
+ if( result ) {
+ // Get registry info into local structure.
+ REGINFO info = { sizeof info, 0, 0 };
+ PR_Lock(mregLock);
+ err = NR_RegGetEntryInfo( mReg,(RKEY)baseKey,(char*)path, &info );
+ PR_Unlock(mregLock);
+ if( err == REGERR_OK ) {
+ // Copy info to user's result value.
+ reginfo2Length( info, *result );
+ } else {
+ rv = regerr2nsresult( err );
+ }
+ } else {
+ rv = NS_ERROR_NULL_POINTER;
+ }
+ return rv;
+}
+
+/*-------------------------- nsRegistry::DeleteValue ---------------------------
+| Remove the registry value with the specified name |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::DeleteValue( nsRegistryKey baseKey, const char *path)
+{
+ REGERR err = REGERR_OK;
+ // Delete the value
+ PR_Lock(mregLock);
+ err = NR_RegDeleteEntry( mReg,(RKEY)baseKey,(char*)path );
+ PR_Unlock(mregLock);
+ // Convert result.
+ return regerr2nsresult( err );
+}
+
+/*------------------------ nsRegistry::EnumerateValues -------------------------
+| Allocates and returns an instance of nsRegValueEnumerator constructed in |
+| a similar fashion as the nsRegSubtreeEnumerator is allocated/returned by |
+| EnumerateSubtrees. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::EnumerateValues( nsRegistryKey baseKey, nsIEnumerator **result ) {
+ nsresult rv = NS_OK;
+ // Make sure we have a place to put the result.
+ if( result ) {
+ *result = new nsRegValueEnumerator( mReg,(RKEY)baseKey );
+ // Check for success.
+ if( *result ) {
+ // Bump refcnt on behalf of caller.
+ NS_ADDREF(*result);
+ } else {
+ // Unable to allocate space for the enumerator object.
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ }
+ } else {
+ rv = NS_ERROR_NULL_POINTER;
+ }
+ return rv;
+}
+
+/*---------------------- nsRegistry::GetCurrentUserName ------------------------
+| Simple wrapper for NR_RegGetUsername. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::GetCurrentUserName( char **result ) {
+ nsresult rv = NS_OK;
+ REGERR err = REGERR_OK;
+ // Make sure we have a place to put the result.
+ if( result ) {
+ // Get the user name.
+ PR_Lock(mregLock);
+ err = NR_RegGetUsername( result );
+ PR_Unlock(mregLock);
+ // Convert the result.
+ rv = regerr2nsresult( err );
+ } else {
+ rv = NS_ERROR_NULL_POINTER;
+ }
+ return rv;
+}
+
+/*---------------------- nsRegistry::SetCurrentUserName ------------------------
+| Simple wrapper for NR_RegSetUsername. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::SetCurrentUserName( const char *name ) {
+ nsresult rv = NS_OK;
+ REGERR err = REGERR_OK;
+ // Set the user name.
+ PR_Lock(mregLock);
+ err = NR_RegSetUsername( name );
+ PR_Unlock(mregLock);
+ // Convert result.
+ rv = regerr2nsresult( err );
+ return rv;
+}
+
+/*----------------------------- nsRegistry::Pack -------------------------------
+| Simple wrapper for NR_RegPack. We don't set up any callback. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::Pack() {
+ nsresult rv = NS_OK;
+ REGERR err = REGERR_OK;
+ // Pack the registry.
+ PR_Lock(mregLock);
+ err = NR_RegPack( mReg, 0, 0 );
+ PR_Unlock(mregLock);
+ // Convert result.
+ rv = regerr2nsresult( err );
+ return rv;
+}
+
+/*----------------------------- nsRegistry::EscapeKey -------------------------------
+| Escape a binary key so that the registry works OK, since it expects UTF8
+| with no slashes or control characters. This is probably better than raw.
+| If no escaping is required, then the method is successful and a null is
+| returned, indicating that the caller should use the original string.
+------------------------------------------------------------------------------*/
+static const char sEscapeKeyHex[] = "0123456789abcdef0123456789ABCDEF";
+NS_IMETHODIMP nsRegistry::EscapeKey(PRUint8* key, PRUint32 termination, PRUint32* length, PRUint8** escaped)
+{
+ nsresult rv = NS_OK;
+ char* value = (char*)key;
+ char* b = value;
+ char* e = b + *length;
+ int escapees = 0;
+ while (b < e) // Count characters outside legal range or slash
+ {
+ int c = *b++;
+ if (c <= ' '
+ || c > '~'
+ || c == '/'
+ || c == '%')
+ {
+ escapees++;
+ }
+ }
+ if (escapees == 0) // If no escapees, then no results
+ {
+ *length = 0;
+ *escaped = nsnull;
+ return NS_OK;
+ }
+ // New length includes two extra chars for escapees.
+ *length += escapees * 2;
+ *escaped = (PRUint8*)nsMemory::Alloc(*length + termination);
+ if (*escaped == nsnull)
+ {
+ *length = 0;
+ *escaped = nsnull;
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ char* n = (char*)*escaped;
+ b = value;
+ while (escapees && b < e)
+ {
+ char c = *b++;
+ if (c < ' '
+ || c > '~'
+ || c == '/'
+ || c == '%')
+ {
+ *(n++) = '%';
+ *(n++) = sEscapeKeyHex[ 0xF & (c >> 4) ];
+ *(n++) = sEscapeKeyHex[ 0xF & c ];
+ escapees--;
+ }
+ else
+ {
+ *(n++) = c;
+ }
+ }
+ e += termination;
+ if (b < e)
+ {
+ strncpy(n, b, e - b);
+ }
+ return rv;
+}
+
+/*----------------------------- nsRegistry::UnescapeKey -------------------------------
+| Unscape a binary key so that the registry works OK, since it expects UTF8
+| with no slashes or control characters. This is probably better than raw.
+| If no escaping is required, then the method is successful and a null is
+| returned, indicating that the caller should use the original string.
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistry::UnescapeKey(PRUint8* escaped, PRUint32 termination, PRUint32* length, PRUint8** key)
+{
+ nsresult rv = NS_OK;
+ char* value = (char*)escaped;
+ char* b = value;
+ char* e = b + *length;
+ int escapees = 0;
+ while (b < e) // Count characters outside legal range or slash
+ {
+ if (*b++ == '%')
+ {
+ escapees++;
+ }
+ }
+ if (escapees == 0) // If no escapees, then no results
+ {
+ *length = 0;
+ *key = nsnull;
+ return NS_OK;
+ }
+ // New length includes two extra chars for escapees.
+ *length -= escapees * 2;
+ *key = (PRUint8*)nsMemory::Alloc(*length + termination);
+ if (*key == nsnull)
+ {
+ *length = 0;
+ *key = nsnull;
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ char* n = (char*)*key;
+ b = value;
+ while (escapees && b < e)
+ {
+ char c = *(b++);
+ if (c == '%')
+ {
+ if (e - b >= 2)
+ {
+ const char* c1 = strchr(sEscapeKeyHex, *(b++));
+ const char* c2 = strchr(sEscapeKeyHex, *(b++));
+ if (c1 != nsnull
+ && c2 != nsnull)
+ {
+ *(n++) = ((c2 - sEscapeKeyHex) & 0xF)
+ | (((c1 - sEscapeKeyHex) & 0xF) << 4);
+ }
+ else
+ {
+ escapees = -1;
+ }
+ }
+ else
+ {
+ escapees = -1;
+ }
+ escapees--;
+ }
+ else
+ {
+ *(n++) = c;
+ }
+ }
+ if (escapees < 0)
+ {
+ nsMemory::Free(*key);
+ *length = 0;
+ *key = nsnull;
+ return NS_ERROR_INVALID_ARG;
+ }
+ e += termination;
+ if (b < e)
+ {
+ strncpy(n, b, e - b);
+ }
+ return rv;
+}
+
+
+/*-------------- nsRegistry::SetBufferSize-------------------------------------
+| Sets the size of the file used for the registry's buffer size. |
+------------------------------------------------------------------------------*/
+int nsRegistry::SetBufferSize( int bufsize )
+{
+ int newSize;
+ // set the file buffer size
+ PR_Lock(mregLock);
+ newSize = NR_RegSetBufferSize( mReg, bufsize );
+ PR_Unlock(mregLock);
+ return newSize;
+}
+
+
+/*-------------- nsRegSubtreeEnumerator::nsRegSubtreeEnumerator ----------------
+| The ctor simply stashes all the information that will be needed to enumerate |
+| the subkeys. |
+------------------------------------------------------------------------------*/
+nsRegSubtreeEnumerator::nsRegSubtreeEnumerator( HREG hReg, RKEY rKey, PRBool all )
+ : mReg( hReg ), mKey( rKey ), mEnum( 0 ), mNext( 0 ),
+ mStyle( all ? REGENUM_DESCEND : REGENUM_CHILDREN ), mDone( PR_FALSE ) {
+
+ mName[0] = '\0';
+
+#ifdef EXTRA_THREADSAFE
+ // Create a registry lock
+ mregLock = PR_NewLock();
+#endif
+ return;
+}
+
+nsRegSubtreeEnumerator::~nsRegSubtreeEnumerator()
+{
+#ifdef EXTRA_THREADSAFE
+ if (mregLock) {
+ PR_DestroyLock(mregLock);
+ }
+#endif
+}
+
+/*----------------------- nsRegSubtreeEnumerator::First ------------------------
+| Set mEnum to 0; this will cause the next NR_RegEnum call to go to |
+| the beginning. We then do a Next() call in order to do a "lookahead" to |
+| properly detect an empty list (i.e., set the mDone flag). |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP
+nsRegSubtreeEnumerator::First() {
+ nsresult rv = NS_OK;
+ // Reset "done" flag.
+ mDone = PR_FALSE;
+ // Clear Name
+ mName[0] = '\0';
+ // Go to beginning.
+ mEnum = mNext = 0;
+ // Lookahead so mDone flag gets set for empty list.
+ rv = Next();
+ return rv;
+}
+
+/*----------------------- nsRegSubtreeEnumerator::Next -------------------------
+| First, we check if we've already advanced to the end by checking the mDone |
+| flag. |
+| |
+| We advance mEnum to the next enumeration value which is in the mNext |
+| lookahead buffer. We must then call advance to lookahead and properly set |
+| the isDone flag. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP
+nsRegSubtreeEnumerator::Next() {
+ nsresult rv = NS_OK;
+ // Check for at end.
+ if ( !mDone ) {
+ // Advance to next spot.
+ mEnum = mNext;
+ // Lookahead so mDone is properly set (and to update mNext).
+ rv = advance();
+ } else {
+ // Set result accordingly.
+ rv = regerr2nsresult( REGERR_NOMORE );
+ }
+ return rv;
+}
+
+/*---------------------- nsRegSubtreeEnumerator::advance -----------------------
+| Advance mNext to next subkey using NR_RegEnumSubkeys. We set mDone if |
+| there are no more subkeys. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegSubtreeEnumerator::advance() {
+ REGERR err = REGERR_OK;
+ PR_Lock(mregLock);
+ err = NR_RegEnumSubkeys( mReg, mKey, &mNext, mName, sizeof mName, mStyle );
+ // See if we ran off end.
+ if( err == REGERR_NOMORE ) {
+ // Remember we've run off end.
+ mDone = PR_TRUE;
+ }
+ PR_Unlock(mregLock);
+ // Convert result.
+ nsresult rv = regerr2nsresult( err );
+ return rv;
+}
+
+/*-------------------- nsRegSubtreeEnumerator::CurrentItem ---------------------
+| Allocates and returns a new instance of class nsRegistryNode. The node |
+| object will hold the curent mEnum value so it can obtain its name from |
+| the registry when asked. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP
+nsRegSubtreeEnumerator::CurrentItem( nsISupports **result) {
+ nsresult rv = NS_OK;
+ // Make sure there is a place to put the result.
+ if( result ) {
+ *result = new nsRegistryNode( mReg, mName, (RKEY) mNext );
+ if( *result ) {
+ NS_ADDREF(*result);
+ } else {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ }
+ } else {
+ rv = NS_ERROR_NULL_POINTER;
+ }
+ return rv;
+}
+
+/*--------------nsRegSubtreeEnumerator::CurrentItemInPlaceUTF8-----------------
+| An ugly name for an ugly function. Hands back a shared pointer to the |
+| name (encoded as UTF-8), and the subkey identifier. |
+-----------------------------------------------------------------------------*/
+NS_IMETHODIMP
+nsRegSubtreeEnumerator::CurrentItemInPlaceUTF8( nsRegistryKey *childKey ,
+ const char **name )
+{
+ *childKey = mNext;
+ /* [shared] */
+ *name = mName;
+ return NS_OK;
+}
+
+/*---------------------- nsRegSubtreeEnumerator::IsDone ------------------------
+| Simply return mDone. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP
+nsRegSubtreeEnumerator::IsDone() {
+ nsresult rv = mDone ? NS_OK : NS_ENUMERATOR_FALSE;
+ return rv;
+}
+
+
+/*---------------- nsRegValueEnumerator::nsRegValueEnumerator ------------------
+| Delegates everything to the base class constructor. |
+------------------------------------------------------------------------------*/
+nsRegValueEnumerator::nsRegValueEnumerator( HREG hReg, RKEY rKey )
+ : nsRegSubtreeEnumerator( hReg, rKey, PR_FALSE ) {
+ return;
+}
+
+
+/*--------------------- nsRegValueEnumerator::CurrentItem ----------------------
+| As the nsRegSubtreeEnumerator counterpart, but allocates an object of |
+| class nsRegistryValue. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP
+nsRegValueEnumerator::CurrentItem( nsISupports **result ) {
+ nsresult rv = NS_OK;
+ // Make sure there is a place to put the result.
+ if( result ) {
+ *result = new nsRegistryValue( mReg, mKey, mEnum );
+ if( *result ) {
+ NS_ADDREF(*result);
+ } else {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ }
+ } else {
+ rv = NS_ERROR_NULL_POINTER;
+ }
+ return rv;
+}
+
+/*----------------------- nsRegValueEnumerator::advance ------------------------
+| Advance mNext to next subkey using NR_RegEnumEntries. We set mDone if |
+| there are no more entries. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegValueEnumerator::advance() {
+ REGERR err = REGERR_OK;
+ char name[MAXREGNAMELEN];
+ PRUint32 len = sizeof name;
+ REGINFO info = { sizeof info, 0, 0 };
+ PR_Lock(mregLock);
+ err = NR_RegEnumEntries( mReg, mKey, &mNext, name, len, &info );
+ // See if we ran off end.
+ if( err == REGERR_NOMORE ) {
+ // Remember we've run off end.
+ mDone = PR_TRUE;
+ }
+ PR_Unlock(mregLock);
+ // Convert result.
+ nsresult rv = regerr2nsresult( err );
+ return rv;
+}
+
+
+/*---------------------- nsRegistryNode::nsRegistryNode ------------------------
+| Store the arguments in the corresponding data members and initialize |
+| the other data members. We defer the libreg calls till we're asked for |
+| our name. We use mErr==-1 to indicate we haven't fetched the name yet. |
+------------------------------------------------------------------------------*/
+nsRegistryNode::nsRegistryNode( HREG hReg, char *name, RKEY childKey )
+ : mReg( hReg ), mChildKey( childKey ) {
+
+ PR_ASSERT(name != nsnull);
+ strcpy(mName, name);
+
+#ifdef EXTRA_THREADSAFE
+ mregLock = PR_NewLock();
+#endif
+
+ return;
+}
+
+nsRegistryNode::~nsRegistryNode()
+{
+#ifdef EXTRA_THREADSAFE
+ if (mregLock) {
+ PR_DestroyLock(mregLock);
+ }
+#endif
+}
+
+/*-------------------------- nsRegistryNode::GetName ---------------------------
+| If we haven't fetched it yet, get the name of the corresponding subkey now, |
+| using NR_RegEnumSubkeys. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistryNode::GetName( PRUnichar **result ) {
+ if (result == nsnull) return NS_ERROR_NULL_POINTER;
+ // Make sure there is a place to put the result.
+ *result = nsTextFormatter::smprintf( widestrFormat, mName );
+ if ( !*result ) return NS_ERROR_OUT_OF_MEMORY;
+ return NS_OK;
+}
+
+/*-------------------------- nsRegistryNode::GetNameUTF8 -----------------------
+| If we haven't fetched it yet, get the name of the corresponding subkey now, |
+| using NR_RegEnumSubkeys. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistryNode::GetNameUTF8( char **result ) {
+ if (result == nsnull) return NS_ERROR_NULL_POINTER;
+ // Make sure there is a place to put the result.
+ *result = nsCRT::strdup( mName );
+ if ( !*result ) return NS_ERROR_OUT_OF_MEMORY;
+ return NS_OK;
+}
+
+/*-------------------------- nsRegistryNode::GetKey ----------------------------
+| Get the subkey corresponding to this node |
+| using NR_RegEnumSubkeys. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistryNode::GetKey( nsRegistryKey *r_key ) {
+ nsresult rv = NS_OK;
+ if (r_key == nsnull) return NS_ERROR_NULL_POINTER;
+ *r_key = mChildKey;
+ return rv;
+}
+
+
+
+/*--------------------- nsRegistryValue::nsRegistryValue -----------------------
+| Implemented the same way as the nsRegistryNode ctor. |
+------------------------------------------------------------------------------*/
+nsRegistryValue::nsRegistryValue( HREG hReg, RKEY key, REGENUM slot )
+ : mReg( hReg ), mKey( key ), mEnum( slot ), mErr( -1 ) {
+#ifdef EXTRA_THREADSAFE
+ mregLock = PR_NewLock();
+#endif
+ mInfo.size = sizeof(REGINFO);
+}
+
+nsRegistryValue::~nsRegistryValue()
+{
+#ifdef EXTRA_THREADSAFE
+ if (mregLock) {
+ PR_DestroyLock(mregLock);
+ }
+#endif
+}
+
+/*------------------------- nsRegistryValue::GetName ---------------------------
+| See nsRegistryNode::GetName; we use NR_RegEnumEntries in this case. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistryValue::GetName( PRUnichar **result ) {
+ nsresult rv = NS_OK;
+ // Make sure we have a place to put the result.
+ if( result ) {
+ // Ensure we've got the info we need.
+ rv = getInfo();
+ if( rv == NS_OK || rv == NS_ERROR_REG_NO_MORE ) {
+ // worked, return actual result.
+ *result = nsTextFormatter::smprintf( widestrFormat, mName );
+ if ( *result ) {
+ rv = NS_OK;
+ } else {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ }
+ }
+ } else {
+ rv = NS_ERROR_NULL_POINTER;
+ }
+ return rv;
+}
+
+/*------------------------- nsRegistryValue::GetNameUTF8 -----------------------
+| See nsRegistryNode::GetName; we use NR_RegEnumEntries in this case. |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistryValue::GetNameUTF8( char **result ) {
+ nsresult rv = NS_OK;
+ // Make sure we have a place to put the result.
+ if( result ) {
+ // Ensure we've got the info we need.
+ rv = getInfo();
+ if( rv == NS_OK || rv == NS_ERROR_REG_NO_MORE ) {
+ // worked, return actual result.
+ *result = nsCRT::strdup( mName );
+ if ( *result ) {
+ rv = NS_OK;
+ } else {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ }
+ }
+ } else {
+ rv = NS_ERROR_NULL_POINTER;
+ }
+ return rv;
+}
+
+/*----------------------- nsRegistryValue::GetType ------------------------
+| We test if we've got the info already. If not, we git it by calling |
+| getInfo. We calculate the result by converting the REGINFO type field to |
+| a nsIRegistry::DataType value (using reginfo2DataType). |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistryValue::GetType( PRUint32 *result ) {
+ nsresult rv = NS_OK;
+ // Make sure we have room for th result.
+ if( result ) {
+ // Make sure we've got the info we need.
+ rv = getInfo();
+ // Check if it worked.
+ if( rv == NS_OK ) {
+ // Convert result from REGINFO to nsIRegistry::ValueInfo.
+ reginfo2DataType( mInfo, *result );
+ }
+ } else {
+ rv = NS_ERROR_NULL_POINTER;
+ }
+ return rv;
+}
+
+/*---------------------- nsRegistryValue::GetLength -----------------------
+| We test if we've got the info already. If not, we git it by calling |
+| getInfo. We calculate the result by converting the REGINFO type field to |
+| a nsIRegistry::DataType value (using reginfo2Length). |
+------------------------------------------------------------------------------*/
+NS_IMETHODIMP nsRegistryValue::GetLength( PRUint32 *result ) {
+ nsresult rv = NS_OK;
+ // Make sure we have room for th result.
+ if( result ) {
+ // Make sure we've got the info we need.
+ rv = getInfo();
+ // Check if it worked.
+ if( rv == NS_OK ) {
+ // Convert result from REGINFO to length.
+ reginfo2Length( mInfo, *result );
+ }
+ } else {
+ rv = NS_ERROR_NULL_POINTER;
+ }
+ return rv;
+}
+
+/*------------------------- nsRegistryValue::getInfo ---------------------------
+| Call NR_RegEnumEntries to set the mInfo/mName data members. |
+------------------------------------------------------------------------------*/
+nsresult nsRegistryValue::getInfo() {
+ nsresult rv = NS_OK;
+ // Test whether we haven't tried to get it yet.
+ if( mErr == -1 ) {
+ REGENUM temp = mEnum;
+ // Get name and info.
+ PR_Lock(mregLock);
+ mErr = NR_RegEnumEntries( mReg, mKey, &temp, mName, sizeof mName, &mInfo );
+ // Convert result.
+ rv = regerr2nsresult( mErr );
+ PR_Unlock(mregLock);
+ }
+ return rv;
+}
+
+
+nsRegistryFactory::nsRegistryFactory() {
+}
+
+NS_IMPL_ISUPPORTS1(nsRegistryFactory, nsIFactory)
+
+NS_IMETHODIMP
+nsRegistryFactory::CreateInstance(nsISupports *aOuter,
+ const nsIID &aIID,
+ void **aResult) {
+ nsresult rv = NS_OK;
+ nsRegistry* newRegistry;
+
+ if(aResult == nsnull) {
+ return NS_ERROR_NULL_POINTER;
+ } else {
+ *aResult = nsnull;
+ }
+
+ if(0 != aOuter) {
+ return NS_ERROR_NO_AGGREGATION;
+ }
+
+ NS_NEWXPCOM(newRegistry, nsRegistry);
+
+ if(newRegistry == nsnull) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ NS_ADDREF(newRegistry);
+ rv = newRegistry->QueryInterface(aIID, aResult);
+ NS_RELEASE(newRegistry);
+
+ return rv;
+}
+
+nsresult
+nsRegistryFactory::LockFactory(PRBool aLock)
+{
+ // Not implemented in simplest case.
+ return NS_OK;
+}
+
+// This is a temporary hack; needs work to support dynamic binding
+// via nsComponentManager and support for multiple factories per DLL.
+extern "C" NS_EXPORT nsresult
+NS_RegistryGetFactory(nsIFactory** aFactory ) {
+ nsresult rv = NS_OK;
+
+ if( aFactory == 0 ) {
+ return NS_ERROR_NULL_POINTER;
+ } else {
+ *aFactory = 0;
+ }
+
+ nsIFactory* inst = new nsRegistryFactory();
+ if(0 == inst) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ } else {
+ NS_ADDREF(inst);
+ *aFactory = inst;
+ }
+
+ return rv;
+}
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/component/nsRegistry.h b/src/libs/xpcom18a4/xpcom/obsolete/component/nsRegistry.h
new file mode 100644
index 00000000..8b59db36
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/component/nsRegistry.h
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Edward Kandrot <kandrot@netscape.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+#ifndef nsRegistry_h__
+#define nsRegistry_h__
+
+#include "nsIRegistry.h"
+#include "NSReg.h"
+#include "nsIFile.h"
+#include "nsCOMPtr.h"
+
+struct nsRegistry : public nsIRegistry, nsIRegistryGetter {
+ // This class implements the nsISupports interface functions.
+ NS_DECL_ISUPPORTS
+
+ // This class implements the nsIRegistry interface functions.
+ NS_DECL_NSIREGISTRY
+
+ // Fast registry getters
+ NS_DECL_NSIREGISTRYGETTER
+
+ int SetBufferSize( int bufsize ); // changes the file buffer size for this registry
+
+ // ctor/dtor
+ nsRegistry();
+
+private:
+ ~nsRegistry();
+
+protected:
+ HREG mReg; // Registry handle.
+#ifdef EXTRA_THREADSAFE
+ PRLock *mregLock; // libreg isn't threadsafe. Use locks to synchronize.
+#endif
+ nsCOMPtr<nsIFile> mCurRegFile; // these are to prevent open from opening the registry again
+ nsWellKnownRegistry mCurRegID;
+
+ NS_IMETHOD Close();
+}; // nsRegistry
+
+#endif
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/component/nsXPCOMObsolete.cpp b/src/libs/xpcom18a4/xpcom/obsolete/component/nsXPCOMObsolete.cpp
new file mode 100644
index 00000000..9a71a916
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/component/nsXPCOMObsolete.cpp
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsXPCOM.h"
+#include "nsIGenericFactory.h"
+
+#include "nsFileSpecImpl.h"
+#include "nsRegistry.h"
+
+#define COMPONENT(NAME, Ctor) \
+ { NS_##NAME##_CLASSNAME, NS_##NAME##_CID, NS_##NAME##_CONTRACTID, Ctor }
+
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsRegistry)
+
+static const nsModuleComponentInfo components[] =
+{
+ COMPONENT(FILESPEC, nsFileSpecImpl::Create),
+ COMPONENT(DIRECTORYITERATOR, nsDirectoryIteratorImpl::Create),
+ COMPONENT(REGISTRY, nsRegistryConstructor),
+};
+
+NS_IMPL_NSGETMODULE(xpcomObsoleteModule, components)
+
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/component/regExport.cpp b/src/libs/xpcom18a4/xpcom/obsolete/component/regExport.cpp
new file mode 100644
index 00000000..d1b2f85e
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/component/regExport.cpp
@@ -0,0 +1,357 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <stdio.h>
+
+#include "nsIServiceManager.h"
+#include "nsIComponentManager.h"
+#include "nsCOMPtr.h"
+#include "nsIRegistry.h"
+#include "nsIEnumerator.h"
+#include "nsILocalFile.h"
+#include "nsDependentString.h"
+#include "prmem.h"
+#include "plstr.h"
+#include "nsMemory.h"
+
+static void display( nsIRegistry *reg, nsRegistryKey root, const char *name );
+static void displayValues( nsIRegistry *reg, nsRegistryKey root );
+static void printString( const char *value, int indent );
+
+int main( int argc, char *argv[] ) {
+
+
+#ifdef __MWERKS__
+ // Hack in some arguments. A NULL registry name is supposed to tell libreg
+ // to use the default registry (which does seem to work).
+ argc = 1;
+ const char* myArgs[] =
+ {
+ "regExport"
+ };
+ argv = const_cast<char**>(myArgs);
+#endif
+
+ nsresult rv;
+
+ // Initialize XPCOM
+ nsIServiceManager *servMgr = NULL;
+ rv = NS_InitXPCOM2(&servMgr, NULL, NULL);
+ if (NS_FAILED(rv))
+ {
+ // Cannot initialize XPCOM
+ printf("Cannot initialize XPCOM. Exit. [rv=0x%08X]\n", (int)rv);
+ exit(-1);
+ }
+ {
+ // Get the component manager
+ static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
+ nsCOMPtr<nsIComponentManager> compMgr = do_GetService(kComponentManagerCID, &rv);
+ if (NS_FAILED(rv))
+ {
+ // Cant get component manager
+ printf("Cannot get component manager from service manager.. Exit. [rv=0x%08X]\n", (int)rv);
+ exit(-1);
+ }
+
+ nsIRegistry *reg;
+
+ if (argc>1) {
+ // Create the registry
+ rv = compMgr->CreateInstanceByContractID(NS_REGISTRY_CONTRACTID, NULL,
+ NS_GET_IID(nsIRegistry),
+ (void **) &reg);
+ // Check result.
+ if ( NS_FAILED(rv) )
+ {
+ printf( "Error opening registry file %s, rv=0x%08X\n", argv[1] , (int)rv );
+ return rv;
+ }
+ // Open it against the input file name.
+ nsCOMPtr<nsILocalFile> regFile;
+ rv = NS_NewNativeLocalFile( nsDependentCString(argv[1]), PR_FALSE, getter_AddRefs(regFile) );
+ if ( NS_FAILED(rv) ) {
+ printf( "Error instantiating local file for %s, rv=0x%08X\n", argv[1], (int)rv );
+ return rv;
+ }
+
+ rv = reg->Open( regFile );
+
+ if ( rv == NS_OK )
+ {
+ printf( "Registry %s opened OK.\n", argv[1] );
+
+ // Recurse over all 3 branches.
+ display( reg, nsIRegistry::Common, "nsRegistry::Common" );
+ display( reg, nsIRegistry::Users, "nsRegistry::Users" );
+ }
+ NS_RELEASE(reg);
+ }
+ else
+ {
+ // Called with no arguments. Print both the default registry and
+ // the components registry. We already printed the default regsitry.
+ // So just do the component registry.
+ rv = compMgr->CreateInstanceByContractID(NS_REGISTRY_CONTRACTID, NULL,
+ NS_GET_IID(nsIRegistry),
+ (void **) &reg);
+
+ // Check result.
+ if ( NS_FAILED(rv) )
+ {
+ printf( "Error opening creating registry instance, rv=0x%08X\n", (int)rv );
+ return rv;
+ }
+ rv = reg->OpenWellKnownRegistry(nsIRegistry::ApplicationComponentRegistry);
+ if ( rv == NS_ERROR_REG_BADTYPE ) {
+ printf( "\n\n\nThere is no <Application Component Registry>\n" );
+ }
+ else if ( rv == NS_OK ) {
+
+ printf( "\n\n\nRegistry %s opened OK.\n", "<Application Component Registry>\n" );
+
+ // Recurse over all 3 branches.
+ display( reg, nsIRegistry::Common, "nsRegistry::Common" );
+ display( reg, nsIRegistry::Users, "nsRegistry::Users" );
+ }
+ NS_RELEASE(reg);
+ }
+ }
+ NS_ShutdownXPCOM( servMgr );
+
+ return rv;
+}
+
+void display( nsIRegistry *reg, nsRegistryKey root, const char *rootName ) {
+ // Print out key name.
+ printf( "%s\n", rootName );
+
+ // Make sure it isn't a "root" key.
+ if ( root != nsIRegistry::Common
+ &&
+ root != nsIRegistry::Users
+ &&
+ root != nsIRegistry::CurrentUser ) {
+ // Print values stored under this key.
+ displayValues( reg, root );
+ }
+
+ // Enumerate all subkeys (immediately) under the given node.
+ nsIEnumerator *keys;
+ nsresult rv = reg->EnumerateSubtrees( root, &keys );
+
+ // Check result.
+ if ( rv == NS_OK ) {
+ // Set enumerator to beginning.
+ rv = keys->First();
+ // Enumerate subkeys till done.
+ while( NS_SUCCEEDED( rv ) && (NS_OK != keys->IsDone()) ) {
+ nsISupports *base;
+ rv = keys->CurrentItem( &base );
+ // Test result.
+ if ( rv == NS_OK ) {
+ // Get specific interface.
+ nsIRegistryNode *node;
+ nsIID nodeIID = NS_IREGISTRYNODE_IID;
+ rv = base->QueryInterface( nodeIID, (void**)&node );
+ // Test that result.
+ if ( rv == NS_OK ) {
+ // Get node name.
+ char *name;
+ rv = node->GetNameUTF8( &name );
+ // Test result.
+ if ( rv == NS_OK ) {
+ // Build complete name.
+ char *fullName = new char[ PL_strlen(rootName) + PL_strlen(name) + 5 ];
+ PL_strcpy( fullName, rootName );
+ PL_strcat( fullName, " - " );
+ PL_strcat( fullName, name );
+ // Display contents under this subkey.
+ nsRegistryKey key;
+ rv = reg->GetSubtreeRaw( root, name, &key );
+ if ( rv == NS_OK ) {
+ display( reg, key, fullName );
+ printf( "\n" );
+ } else {
+ printf( "Error getting key, rv=0x%08X\n", (int)rv );
+ }
+ delete [] fullName;
+ } else {
+ printf( "Error getting subtree name, rv=0x%08X\n", (int)rv );
+ }
+ // Release node.
+ node->Release();
+ } else {
+ printf( "Error converting base node ptr to nsIRegistryNode, rv=0x%08X\n", (int)rv );
+ }
+ // Release item.
+ base->Release();
+
+ // Advance to next key.
+ rv = keys->Next();
+ // Check result.
+ if ( NS_SUCCEEDED( rv ) ) {
+ } else {
+ printf( "Error advancing enumerator, rv=0x%08X\n", (int)rv );
+ }
+ } else {
+ printf( "Error getting current item, rv=0x%08X\n", (int)rv );
+ }
+ }
+ // Release key enumerator.
+ keys->Release();
+ } else {
+ printf( "Error creating enumerator for %s, root=0x%08X, rv=0x%08X\n",
+ rootName, (int)root, (int)rv );
+ }
+ return;
+}
+
+static void displayValues( nsIRegistry *reg, nsRegistryKey root ) {
+ // Emumerate values at this registry location.
+ nsIEnumerator *values;
+ nsresult rv = reg->EnumerateValues( root, &values );
+
+ // Check result.
+ if ( rv == NS_OK ) {
+ // Go to beginning.
+ rv = values->First();
+
+ // Enumerate values till done.
+ while( rv == NS_OK && (NS_OK != values->IsDone()) ) {
+ nsISupports *base;
+ rv = values->CurrentItem( &base );
+ // Test result.
+ if ( rv == NS_OK ) {
+ // Get specific interface.
+ nsIRegistryValue *value;
+ nsIID valueIID = NS_IREGISTRYVALUE_IID;
+ rv = base->QueryInterface( valueIID, (void**)&value );
+ // Test that result.
+ if ( rv == NS_OK ) {
+ // Get node name.
+ char *name;
+ rv = value->GetNameUTF8( &name );
+ // Test result.
+ if ( rv == NS_OK ) {
+ // Print name:
+ printf( "\t\t%s", name );
+ // Get info about this value.
+ PRUint32 type;
+ rv = reg->GetValueType( root, name, &type );
+ if ( rv == NS_OK ) {
+ // Print value contents.
+ switch ( type ) {
+ case nsIRegistry::String: {
+ char *strValue;
+ rv = reg->GetStringUTF8( root, name, &strValue );
+ if ( rv == NS_OK ) {
+ printString( strValue, strlen(name) );
+ nsMemory::Free( strValue );
+ } else {
+ printf( "\t Error getting string value, rv=0x%08X", (int)rv );
+ }
+ }
+ break;
+
+ case nsIRegistry::Int32:
+ {
+ PRInt32 val = 0;
+ rv = reg->GetInt( root, name, &val );
+ if (NS_SUCCEEDED(rv)) {
+ printf( "\t= Int32 [%d, 0x%x]", val, val);
+ }
+ else {
+ printf( "\t Error getting int32 value, rv=%08X", (int)rv);
+ }
+ }
+ break;
+
+ case nsIRegistry::Bytes:
+ printf( "\t= Bytes" );
+ break;
+
+ case nsIRegistry::File:
+ printf( "\t= File (?)" );
+ break;
+
+ default:
+ printf( "\t= ? (unknown type=0x%02X)", (int)type );
+ break;
+ }
+ } else {
+ printf( "\t= ? (error getting value, rv=0x%08X)", (int)rv );
+ }
+ printf("\n");
+ nsMemory::Free( name );
+ } else {
+ printf( "Error getting value name, rv=0x%08X\n", (int)rv );
+ }
+ // Release node.
+ value->Release();
+ } else {
+ printf( "Error converting base node ptr to nsIRegistryNode, rv=0x%08X\n", (int)rv );
+ }
+ // Release item.
+ base->Release();
+
+ // Advance to next key.
+ rv = values->Next();
+ // Check result.
+ if ( NS_SUCCEEDED( rv ) ) {
+ } else {
+ printf( "Error advancing enumerator, rv=0x%08X\n", (int)rv );
+ break;
+ }
+ } else {
+ printf( "Error getting current item, rv=0x%08X\n", (int)rv );
+ break;
+ }
+ }
+
+ values->Release();
+ } else {
+ printf( "\t\tError enumerating values, rv=0x%08X\n", (int)rv );
+ }
+ return;
+}
+
+static void printString( const char *value, int /*indent*/ ) {
+ // For now, just dump contents.
+ printf( "\t = %s", value );
+ return;
+}
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/component/xpcomobsoletec.pkg b/src/libs/xpcom18a4/xpcom/obsolete/component/xpcomobsoletec.pkg
new file mode 100644
index 00000000..88cbf236
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/component/xpcomobsoletec.pkg
@@ -0,0 +1,6 @@
+[gecko xpi-bootstrap]
+#if SHARED_LIBRARY
+dist/bin/components/@SHARED_LIBRARY@
+#else
+!staticcomp @LIBRARY@ @MODULE_NAME@
+#endif
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/dlldeps.cpp b/src/libs/xpcom18a4/xpcom/obsolete/dlldeps.cpp
new file mode 100644
index 00000000..d904e071
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/dlldeps.cpp
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2003
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// Force references to all of the symbols that we want exported from
+// the dll that are located in the .lib files we link with
+
+#include "nsFileSpec.h"
+#include "NSReg.h"
+
+void XXXNeverCalled()
+{
+ nsFileURL(NULL);
+ nsFileSpec s;
+
+ NR_RegSetBufferSize(NULL, 0);
+}
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpec.cpp b/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpec.cpp
new file mode 100644
index 00000000..9be29eb9
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpec.cpp
@@ -0,0 +1,1367 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsFileSpec.h"
+
+#include "nsDebug.h"
+#include "nsEscape.h"
+#include "nsMemory.h"
+
+#include "prtypes.h"
+#include "plstr.h"
+#include "plbase64.h"
+#include "prmem.h"
+
+#include "nsCOMPtr.h"
+#include "nsIServiceManager.h"
+#include "nsILocalFile.h"
+
+#include <string.h>
+#include <stdio.h>
+
+#if defined(XP_WIN)
+#include <mbstring.h>
+#endif
+
+#ifdef XP_OS2
+extern unsigned char* _mbsrchr( const unsigned char*, int);
+#endif
+
+// return pointer to last instance of the given separator
+static inline char *GetLastSeparator(const char *str, char sep)
+{
+#if defined(XP_WIN) || defined(XP_OS2)
+ return (char*) _mbsrchr((const unsigned char *) str, sep);
+#else
+ return (char*) strrchr(str, sep);
+#endif
+}
+
+#if defined(XP_MACOSX)
+#include <sys/stat.h>
+#endif
+
+#if defined(XP_MAC) || defined(XP_MACOSX)
+#include <Aliases.h>
+#include <TextUtils.h>
+#endif
+
+//========================================================================================
+// class nsSimpleCharString
+//========================================================================================
+
+//----------------------------------------------------------------------------------------
+nsSimpleCharString::nsSimpleCharString()
+//----------------------------------------------------------------------------------------
+: mData(nsnull)
+{
+
+} // nsSimpleCharString::nsSimpleCharString
+
+//----------------------------------------------------------------------------------------
+nsSimpleCharString::nsSimpleCharString(const char* inString)
+//----------------------------------------------------------------------------------------
+: mData(nsnull)
+{
+ if (inString)
+ CopyFrom(inString, strlen(inString));
+} // nsSimpleCharString::nsSimpleCharString
+
+//----------------------------------------------------------------------------------------
+nsSimpleCharString::nsSimpleCharString(const nsString& inString)
+//----------------------------------------------------------------------------------------
+: mData(nsnull)
+{
+ *this = inString;
+} // nsSimpleCharString::nsSimpleCharString
+
+//----------------------------------------------------------------------------------------
+nsSimpleCharString::nsSimpleCharString(const nsSimpleCharString& inOther)
+//----------------------------------------------------------------------------------------
+{
+ mData = inOther.mData;
+ AddRefData();
+} // nsSimpleCharString::nsSimpleCharString
+
+//----------------------------------------------------------------------------------------
+nsSimpleCharString::nsSimpleCharString(const char* inData, PRUint32 inLength)
+//----------------------------------------------------------------------------------------
+: mData(nsnull)
+{
+ CopyFrom(inData, inLength);
+} // nsSimpleCharString::nsSimpleCharString
+
+//----------------------------------------------------------------------------------------
+nsSimpleCharString::~nsSimpleCharString()
+//----------------------------------------------------------------------------------------
+{
+ ReleaseData();
+} // nsSimpleCharString::nsSimpleCharString
+
+//----------------------------------------------------------------------------------------
+void nsSimpleCharString::operator = (const char* inString)
+//----------------------------------------------------------------------------------------
+{
+ if (inString)
+ CopyFrom(inString, strlen(inString));
+ else
+ SetToEmpty();
+} // nsSimpleCharString::operator =
+
+//----------------------------------------------------------------------------------------
+void nsSimpleCharString::operator = (const nsString& inString)
+//----------------------------------------------------------------------------------------
+{
+ PRUint32 len = inString.Length();
+ ReallocData(len);
+ if (!mData)
+ return;
+ inString.ToCString(mData->mString, len + 1);
+} // nsSimpleCharString::operator =
+
+//----------------------------------------------------------------------------------------
+void nsSimpleCharString::operator = (const nsSimpleCharString& inOther)
+//----------------------------------------------------------------------------------------
+{
+ if (mData == inOther.mData)
+ return;
+ ReleaseData();
+ mData = inOther.mData;
+ AddRefData();
+} // nsSimpleCharString::operator =
+
+//----------------------------------------------------------------------------------------
+void nsSimpleCharString::operator += (const char* inOther)
+//----------------------------------------------------------------------------------------
+{
+ if (!inOther)
+ return;
+ int newLength = Length() + strlen(inOther);
+ ReallocData(newLength);
+ strcat(mData->mString, inOther);
+} // nsSimpleCharString::operator =
+
+//----------------------------------------------------------------------------------------
+nsSimpleCharString nsSimpleCharString::operator + (const char* inOther) const
+//----------------------------------------------------------------------------------------
+{
+ nsSimpleCharString result(*this);
+ result += inOther;
+ return result;
+} // nsSimpleCharString::operator =
+
+//----------------------------------------------------------------------------------------
+void nsSimpleCharString::Catenate(const char* inString1, const char* inString2)
+//----------------------------------------------------------------------------------------
+{
+ if (!inString2)
+ {
+ *this += inString1;
+ return;
+ }
+ int newLength = Length() + strlen(inString1) + strlen(inString2);
+ ReallocData(newLength);
+ strcat(mData->mString, inString1);
+ strcat(mData->mString, inString2);
+} // nsSimpleCharString::operator =
+
+//----------------------------------------------------------------------------------------
+void nsSimpleCharString::CopyFrom(const char* inData, PRUint32 inLength)
+//----------------------------------------------------------------------------------------
+{
+ if (!inData)
+ return;
+ ReallocData(inLength);
+ if (!mData)
+ return;
+ if (inLength != 0) {
+ memcpy(mData->mString, inData, inLength);
+ }
+ mData->mString[inLength] = '\0';
+} // nsSimpleCharString::CopyFrom
+
+//----------------------------------------------------------------------------------------
+void nsSimpleCharString::SetToEmpty()
+//----------------------------------------------------------------------------------------
+{
+ ReleaseData();
+} // nsSimpleCharString::SetToEmpty
+
+//----------------------------------------------------------------------------------------
+void nsSimpleCharString::Unescape()
+//----------------------------------------------------------------------------------------
+{
+ if (!mData)
+ return;
+ ReallocData(mData->mLength);
+ if (!mData)
+ return;
+ nsUnescape(mData->mString);
+ mData->mLength = strlen(mData->mString);
+} // nsSimpleCharString::Unescape
+
+
+//----------------------------------------------------------------------------------------
+void nsSimpleCharString::AddRefData()
+//----------------------------------------------------------------------------------------
+{
+ if (mData)
+ ++mData->mRefCount;
+} // nsSimpleCharString::AddRefData
+
+//----------------------------------------------------------------------------------------
+void nsSimpleCharString::ReleaseData()
+//----------------------------------------------------------------------------------------
+{
+ if (!mData)
+ return;
+ NS_ASSERTION(mData->mRefCount > 0, "String deleted too many times!");
+ if (--mData->mRefCount == 0)
+ PR_Free(mData);
+ mData = nsnull;
+} // nsSimpleCharString::ReleaseData
+
+//----------------------------------------------------------------------------------------
+inline PRUint32 CalculateAllocLength(PRUint32 logicalLength)
+// Round up to the next multiple of 256.
+//----------------------------------------------------------------------------------------
+{
+ return ((1 + (logicalLength >> 8)) << 8);
+}
+
+//----------------------------------------------------------------------------------------
+void nsSimpleCharString::ReallocData(PRUint32 inLength)
+// Reallocate mData to a new length. Since this presumably precedes a change to the string,
+// we want to detach ourselves if the data is shared by another string, even if the length
+// requested would not otherwise require a reallocation.
+//----------------------------------------------------------------------------------------
+{
+ PRUint32 newAllocLength = CalculateAllocLength(inLength);
+ PRUint32 oldAllocLength = CalculateAllocLength(Length());
+ if (mData)
+ {
+ NS_ASSERTION(mData->mRefCount > 0, "String deleted too many times!");
+ if (mData->mRefCount == 1)
+ {
+ // We are the sole owner, so just change its length, if necessary.
+ if (newAllocLength > oldAllocLength)
+ mData = (Data*)PR_Realloc(mData, newAllocLength + sizeof(Data));
+ mData->mLength = inLength;
+ mData->mString[inLength] = '\0'; // we may be truncating
+ return;
+ }
+ }
+ PRUint32 copyLength = Length();
+ if (inLength < copyLength)
+ copyLength = inLength;
+ Data* newData = (Data*)PR_Malloc(newAllocLength + sizeof(Data));
+ // If data was already allocated when we get to here, then we are cloning the data
+ // from a shared pointer.
+ if (mData)
+ {
+ memcpy(newData, mData, sizeof(Data) + copyLength);
+ mData->mRefCount--; // Say goodbye
+ }
+ else
+ newData->mString[0] = '\0';
+
+ mData = newData;
+ mData->mRefCount = 1;
+ mData->mLength = inLength;
+} // nsSimpleCharString::ReleaseData
+
+
+//========================================================================================
+NS_NAMESPACE nsFileSpecHelpers
+//========================================================================================
+{
+ enum
+ { kMaxFilenameLength = 31 // should work on Macintosh, Unix, and Win32.
+ , kMaxAltDigitLength = 5
+ , kMaxCoreLeafNameLength = (kMaxFilenameLength - (kMaxAltDigitLength + 1))
+ };
+#if !defined(XP_MAC)
+ NS_NAMESPACE_PROTOTYPE void Canonify(nsSimpleCharString& ioPath, PRBool inMakeDirs);
+ NS_NAMESPACE_PROTOTYPE void MakeAllDirectories(const char* inPath, int mode);
+#endif
+#if defined(XP_WIN) || defined(XP_OS2)
+ NS_NAMESPACE_PROTOTYPE void NativeToUnix(nsSimpleCharString& ioPath);
+ NS_NAMESPACE_PROTOTYPE void UnixToNative(nsSimpleCharString& 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;
+}
+
+//----------------------------------------------------------------------------------------
+void nsSimpleCharString::LeafReplace(char inSeparator, const char* inLeafName)
+//----------------------------------------------------------------------------------------
+{
+ // Find the existing leaf name
+ if (IsEmpty())
+ return;
+ if (!inLeafName)
+ {
+ SetToEmpty();
+ return;
+ }
+ char* chars = mData->mString;
+ char* lastSeparator = GetLastSeparator(chars, inSeparator);
+ int oldLength = Length();
+ PRBool trailingSeparator = (lastSeparator + 1 == chars + oldLength);
+ if (trailingSeparator)
+ {
+ char savedCh = *lastSeparator;
+ char *savedLastSeparator = lastSeparator;
+ *lastSeparator = '\0';
+ lastSeparator = GetLastSeparator(chars, inSeparator);
+ *savedLastSeparator = savedCh;
+ }
+ if (lastSeparator)
+ lastSeparator++; // point at the trailing string
+ else
+ lastSeparator = chars; // the full monty
+
+ PRUint32 savedLastSeparatorOffset = (lastSeparator - chars);
+ int newLength =
+ (lastSeparator - chars) + strlen(inLeafName) + (trailingSeparator != 0);
+ ReallocData(newLength);
+
+ chars = mData->mString; // it might have moved.
+ chars[savedLastSeparatorOffset] = '\0'; // strip the current leaf name
+
+ strcat(chars, inLeafName);
+ if (trailingSeparator)
+ {
+ // If the original ended in a slash, then the new one should, too.
+ char sepStr[2] = "/";
+ *sepStr = inSeparator;
+ strcat(chars, sepStr);
+ }
+} // nsSimpleCharString::LeafReplace
+
+//----------------------------------------------------------------------------------------
+char* nsSimpleCharString::GetLeaf(char inSeparator) const
+// Returns a pointer to an allocated string representing the leaf.
+//----------------------------------------------------------------------------------------
+{
+ if (IsEmpty())
+ return nsnull;
+
+ char* chars = mData->mString;
+ const char* lastSeparator = GetLastSeparator(chars, inSeparator);
+ // If there was no separator, then return a copy of our path.
+ if (!lastSeparator)
+ return nsCRT::strdup(*this);
+
+ // 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 nsCRT::strdup(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 = GetLastSeparator(chars, inSeparator);
+ char* result = leafPointer ? nsCRT::strdup(++leafPointer) : nsCRT::strdup(chars);
+ // Restore the poked null before returning.
+ *(char*)lastSeparator = inSeparator;
+#if defined(XP_WIN) || defined(XP_OS2)
+ // If it's a drive letter use the colon notation.
+ if (!leafPointer && result[1] == '|' && result[2] == 0)
+ result[1] = ':';
+#endif
+ return result;
+} // nsSimpleCharString::GetLeaf
+
+
+#if 0
+#pragma mark -
+#endif
+
+#if (defined(XP_UNIX) || defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS))
+
+//----------------------------------------------------------------------------------------
+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 = nsCRT::strdup( inPath );
+ if (!pathCopy)
+ return;
+
+ const char kSeparator = '/'; // I repeat: this should be a unix-style path.
+ const int kSkipFirst = 1;
+
+#if defined(XP_WIN) || defined(XP_OS2)
+ // Either this is a relative path, or we ensure that it has
+ // a drive letter specifier.
+ NS_ASSERTION( pathCopy[0] != '/' || (pathCopy[1] && (pathCopy[2] == '|' || pathCopy[2] == '/')),
+ "Not a UNC path and no drive letter!" );
+#endif
+ char* currentStart = pathCopy;
+ char* currentEnd = strchr(currentStart + kSkipFirst, kSeparator);
+ if (currentEnd)
+ {
+ nsFileSpec spec;
+ *currentEnd = '\0';
+
+#if defined(XP_WIN) || defined(XP_OS2)
+ /*
+ if we have a drive letter path, we must make sure that the inital path has a '/' on it, or
+ Canonify will turn "/c|" into a path relative to the running executable.
+ */
+ if (pathCopy[0] == '/' && pathCopy[1] && pathCopy[2] == '|')
+ {
+ char* startDir = (char*)PR_Malloc(strlen(pathCopy) + 2);
+ strcpy(startDir, pathCopy);
+ strcat(startDir, "/");
+
+ spec = nsFilePath(startDir, PR_FALSE);
+
+ PR_Free(startDir);
+ }
+ else
+ {
+ // move after server name and share name in UNC path
+ if (pathCopy[0] == '/' &&
+ currentEnd == currentStart+kSkipFirst)
+ {
+ *currentEnd = '/';
+ currentStart = strchr(pathCopy+2, kSeparator);
+ currentStart = strchr(currentStart+1, kSeparator);
+ currentEnd = strchr(currentStart+1, kSeparator);
+ if (currentEnd)
+ *currentEnd = '\0';
+ }
+ spec = nsFilePath(pathCopy, PR_FALSE);
+ }
+#else
+ spec = nsFilePath(pathCopy, PR_FALSE);
+#endif
+ 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);
+
+ currentStart = ++currentEnd;
+ currentEnd = strchr(currentStart, kSeparator);
+ if (!currentEnd)
+ break;
+
+ *currentEnd = '\0';
+
+ spec += currentStart; // "lengthen" the path, adding the next node.
+ } while (currentEnd);
+ }
+ nsCRT::free(pathCopy);
+} // nsFileSpecHelpers::MakeAllDirectories
+
+#endif // XP_UNIX || XP_WIN || XP_OS2 || XP_BEOS
+
+#if 0
+#pragma mark -
+#endif
+
+#if defined(XP_WIN)
+#include "nsFileSpecWin.cpp" // Windows-specific implementations
+#elif defined(XP_MAC)
+//#include "nsFileSpecMac.cpp" // Macintosh-specific implementations
+// we include the .cpp file in the project now.
+#elif defined(XP_BEOS)
+#include "nsFileSpecBeOS.cpp" // BeOS-specific implementations
+#elif defined(XP_UNIX) || defined(XP_MACOSX)
+#include "nsFileSpecUnix.cpp" // Unix-specific implementations
+#elif defined(XP_OS2)
+#include "nsFileSpecOS2.cpp" // OS/2-specific implementations
+#endif
+
+//========================================================================================
+// nsFileURL implementation
+//========================================================================================
+
+#if !defined(XP_MAC)
+//----------------------------------------------------------------------------------------
+nsFileURL::nsFileURL(const char* inString, PRBool inCreateDirs)
+//----------------------------------------------------------------------------------------
+{
+ if (!inString)
+ return;
+ NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!");
+ // Make canonical and absolute. Since it's a parameter to this constructor,
+ // inString is escaped. We want to make an nsFilePath, which requires
+ // an unescaped string.
+ nsSimpleCharString unescapedPath(inString + kFileURLPrefixLength);
+ unescapedPath.Unescape();
+ nsFilePath path(unescapedPath, inCreateDirs);
+ *this = path;
+} // nsFileURL::nsFileURL
+#endif
+
+#if !defined(XP_MAC)
+//----------------------------------------------------------------------------------------
+nsFileURL::nsFileURL(const nsString& inString, PRBool inCreateDirs)
+//----------------------------------------------------------------------------------------
+{
+ NS_LossyConvertUCS2toASCII cstring(inString);
+ if (!inString.Length())
+ return;
+ NS_ASSERTION(strstr(cstring.get(), kFileURLPrefix) == cstring.get(),
+ "Not a URL!");
+ // Make canonical and absolute. Since it's a parameter to this constructor,
+ // inString is escaped. We want to make an nsFilePath, which requires
+ // an unescaped string.
+ nsSimpleCharString unescapedPath(cstring.get() + kFileURLPrefixLength);
+ unescapedPath.Unescape();
+ nsFilePath path(unescapedPath, inCreateDirs);
+ *this = path;
+} // nsFileURL::nsFileURL
+#endif
+
+//----------------------------------------------------------------------------------------
+nsFileURL::nsFileURL(const nsFileURL& inOther)
+//----------------------------------------------------------------------------------------
+: mURL(inOther.mURL)
+#if defined(XP_MAC)
+, mFileSpec(inOther.GetFileSpec())
+#endif
+{
+} // nsFileURL::nsFileURL
+
+#if !defined(XP_MAC)
+//----------------------------------------------------------------------------------------
+nsFileURL::nsFileURL(const nsFilePath& inOther)
+//----------------------------------------------------------------------------------------
+{
+ *this = inOther;
+} // nsFileURL::nsFileURL
+#endif
+
+#if !defined(XP_MAC)
+//----------------------------------------------------------------------------------------
+nsFileURL::nsFileURL(const nsFileSpec& inOther)
+//----------------------------------------------------------------------------------------
+{
+ *this = inOther;
+} // nsFileURL::nsFileURL
+#endif
+
+//----------------------------------------------------------------------------------------
+nsFileURL::~nsFileURL()
+//----------------------------------------------------------------------------------------
+{
+}
+
+#if !defined(XP_MAC)
+//----------------------------------------------------------------------------------------
+void nsFileURL::operator = (const char* inString)
+//----------------------------------------------------------------------------------------
+{
+ // XXX is this called by nsFileSpecImpl.cpp::SetURLString?
+ // if so, there's a bug...
+
+ mURL = inString;
+ NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!");
+} // nsFileURL::operator =
+#endif
+
+//----------------------------------------------------------------------------------------
+void nsFileURL::operator +=(const char* inRelativeUnixPath)
+//----------------------------------------------------------------------------------------
+{
+ char* escapedPath = nsEscape(inRelativeUnixPath, url_Path);
+ mURL += escapedPath;
+ nsCRT::free(escapedPath);
+#if defined(XP_MAC)
+ mFileSpec += inRelativeUnixPath;
+#endif
+} // nsFileURL::operator +=
+
+//----------------------------------------------------------------------------------------
+nsFileURL nsFileURL::operator +(const char* inRelativeUnixPath) const
+//----------------------------------------------------------------------------------------
+{
+ nsFileURL result(*this);
+ result += inRelativeUnixPath;
+ return result;
+} // nsFileURL::operator +
+
+//----------------------------------------------------------------------------------------
+void nsFileURL::operator = (const nsFileURL& inOther)
+//----------------------------------------------------------------------------------------
+{
+ mURL = inOther.mURL;
+#if defined(XP_MAC)
+ mFileSpec = inOther.GetFileSpec();
+#endif
+} // nsFileURL::operator =
+
+#if !defined(XP_MAC)
+//----------------------------------------------------------------------------------------
+void nsFileURL::operator = (const nsFilePath& inOther)
+//----------------------------------------------------------------------------------------
+{
+ mURL = kFileURLPrefix;
+ char* original = (char*)(const char*)inOther; // we shall modify, but restore.
+ if (!original || !*original) return;
+#if defined(XP_WIN) || defined(XP_OS2)
+ // because we don't want to escape the '|' character, change it to a letter.
+ // Note that a UNC path will not have a '|' character.
+ char oldchar = original[2];
+ original[2] = 'x';
+ char* escapedPath = nsEscape(original, url_Path);
+ original[2] = escapedPath[2] = oldchar; // restore it
+#else
+ char* escapedPath = nsEscape(original, url_Path);
+#endif
+ if (escapedPath)
+ mURL += escapedPath;
+ nsCRT::free(escapedPath);
+} // nsFileURL::operator =
+#endif
+
+#if !defined(XP_MAC)
+//----------------------------------------------------------------------------------------
+void nsFileURL::operator = (const nsFileSpec& inOther)
+//----------------------------------------------------------------------------------------
+{
+ *this = nsFilePath(inOther);
+ if (mURL[mURL.Length() - 1] != '/' && inOther.IsDirectory())
+ mURL += "/";
+} // nsFileURL::operator =
+#endif
+
+#if 0
+#pragma mark -
+#endif
+
+//========================================================================================
+// nsFilePath implementation
+//========================================================================================
+
+//----------------------------------------------------------------------------------------
+nsFilePath::nsFilePath(const nsFilePath& inPath)
+//----------------------------------------------------------------------------------------
+ : mPath(inPath.mPath)
+#if defined(XP_MAC)
+ , mFileSpec(inPath.mFileSpec)
+#endif
+{
+}
+
+#if !defined(XP_MAC)
+//----------------------------------------------------------------------------------------
+nsFilePath::nsFilePath(const char* inString, PRBool inCreateDirs)
+//----------------------------------------------------------------------------------------
+: mPath(inString)
+{
+ if (mPath.IsEmpty())
+ return;
+
+ NS_ASSERTION(strstr(inString, kFileURLPrefix) != inString, "URL passed as path");
+
+#if defined(XP_WIN) || defined(XP_OS2)
+ nsFileSpecHelpers::UnixToNative(mPath);
+#endif
+ // Make canonical and absolute.
+ nsFileSpecHelpers::Canonify(mPath, inCreateDirs);
+#if defined(XP_WIN) || defined(XP_OS2)
+ // Assert native path is of one of these forms:
+ // - regular: X:\some\path
+ // - UNC: \\some_machine\some\path
+ NS_ASSERTION( mPath[1] == ':' || (mPath[0] == '\\' && mPath[1] == '\\'),
+ "unexpected canonical path" );
+ nsFileSpecHelpers::NativeToUnix(mPath);
+#endif
+}
+#endif
+
+#if !defined(XP_MAC)
+//----------------------------------------------------------------------------------------
+nsFilePath::nsFilePath(const nsString& inString, PRBool inCreateDirs)
+//----------------------------------------------------------------------------------------
+: mPath(inString)
+{
+ if (mPath.IsEmpty())
+ return;
+
+ NS_ASSERTION(strstr((const char*)mPath, kFileURLPrefix) != (const char*)mPath, "URL passed as path");
+#if defined(XP_WIN) || defined(XP_OS2)
+ nsFileSpecHelpers::UnixToNative(mPath);
+#endif
+ // Make canonical and absolute.
+ nsFileSpecHelpers::Canonify(mPath, inCreateDirs);
+#if defined(XP_WIN) || defined(XP_OS2)
+ NS_ASSERTION( mPath[1] == ':' || (mPath[0] == '\\' && mPath[1] == '\\'),
+ "unexpected canonical path" );
+ nsFileSpecHelpers::NativeToUnix(mPath);
+#endif
+}
+#endif
+
+#if !defined(XP_MAC)
+//----------------------------------------------------------------------------------------
+nsFilePath::nsFilePath(const nsFileURL& inOther)
+//----------------------------------------------------------------------------------------
+{
+ mPath = (const char*)inOther.mURL + kFileURLPrefixLength;
+ mPath.Unescape();
+}
+#endif
+
+#if (defined XP_UNIX || defined XP_BEOS)
+//----------------------------------------------------------------------------------------
+nsFilePath::nsFilePath(const nsFileSpec& inOther)
+//----------------------------------------------------------------------------------------
+: mPath(inOther.mPath)
+{
+}
+#endif // XP_UNIX
+
+//----------------------------------------------------------------------------------------
+nsFilePath::~nsFilePath()
+//----------------------------------------------------------------------------------------
+{
+}
+
+#if (defined XP_UNIX || defined XP_BEOS)
+//----------------------------------------------------------------------------------------
+void nsFilePath::operator = (const nsFileSpec& inOther)
+//----------------------------------------------------------------------------------------
+{
+ // XXX bug here, again if.
+
+ mPath = inOther.mPath;
+}
+#endif // XP_UNIX
+
+#if !defined(XP_MAC)
+//----------------------------------------------------------------------------------------
+void nsFilePath::operator = (const char* inString)
+//----------------------------------------------------------------------------------------
+{
+
+ NS_ASSERTION(strstr(inString, kFileURLPrefix) != inString, "URL passed as path");
+ mPath = inString;
+ if (mPath.IsEmpty())
+ return;
+#if defined(XP_WIN) || defined(XP_OS2)
+ nsFileSpecHelpers::UnixToNative(mPath);
+#endif
+ // Make canonical and absolute.
+ nsFileSpecHelpers::Canonify(mPath, PR_FALSE /* XXX? */);
+#if defined(XP_WIN) || defined(XP_OS2)
+ nsFileSpecHelpers::NativeToUnix(mPath);
+#endif
+}
+#endif // XP_MAC
+
+#if !defined(XP_MAC)
+//----------------------------------------------------------------------------------------
+void nsFilePath::operator = (const nsFileURL& inOther)
+//----------------------------------------------------------------------------------------
+{
+ mPath = (const char*)nsFilePath(inOther);
+}
+#endif
+
+//----------------------------------------------------------------------------------------
+void nsFilePath::operator = (const nsFilePath& inOther)
+//----------------------------------------------------------------------------------------
+{
+ mPath = inOther.mPath;
+#if defined(XP_MAC)
+ mFileSpec = inOther.GetFileSpec();
+#endif
+}
+
+//----------------------------------------------------------------------------------------
+void nsFilePath::operator +=(const char* inRelativeUnixPath)
+//----------------------------------------------------------------------------------------
+{
+ NS_ASSERTION(inRelativeUnixPath, "Attempt append relative path with null path");
+
+ char* escapedPath = nsEscape(inRelativeUnixPath, url_Path);
+ mPath += escapedPath;
+ nsCRT::free(escapedPath);
+#if defined(XP_MAC)
+ mFileSpec += inRelativeUnixPath;
+#endif
+} // nsFilePath::operator +=
+
+//----------------------------------------------------------------------------------------
+nsFilePath nsFilePath::operator +(const char* inRelativeUnixPath) const
+//----------------------------------------------------------------------------------------
+{
+ NS_ASSERTION(inRelativeUnixPath, "Attempt append relative path with null path");
+
+ nsFilePath resultPath(*this);
+ resultPath += inRelativeUnixPath;
+ return resultPath;
+} // nsFilePath::operator +
+
+
+#if 0
+#pragma mark -
+#endif
+
+//========================================================================================
+// nsFileSpec implementation
+//========================================================================================
+
+#if !defined(XP_MAC)
+//----------------------------------------------------------------------------------------
+nsFileSpec::nsFileSpec()
+//----------------------------------------------------------------------------------------
+: mError(NS_OK) // XXX shouldn't this be NS_ERROR_NOT_INITIALIZED?
+{
+// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!");
+}
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::Clear()
+//----------------------------------------------------------------------------------------
+{
+ mPath.SetToEmpty();
+ mError = NS_ERROR_NOT_INITIALIZED;
+}
+
+#endif
+
+//----------------------------------------------------------------------------------------
+nsFileSpec::~nsFileSpec()
+//----------------------------------------------------------------------------------------
+{
+ // mPath cleans itself up
+}
+
+//----------------------------------------------------------------------------------------
+nsFileSpec::nsFileSpec(const nsPersistentFileDescriptor& inDescriptor)
+//----------------------------------------------------------------------------------------
+{
+ *this = inDescriptor;
+}
+
+//----------------------------------------------------------------------------------------
+nsFileSpec::nsFileSpec(const nsFileURL& inURL)
+//----------------------------------------------------------------------------------------
+{
+ *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 = nsCRT::strdup(lastDot); // include '.'
+ *lastDot = '\0'; // strip suffix and dot.
+ }
+ const int kMaxRootLength
+ = nsFileSpecHelpers::kMaxCoreLeafNameLength - strlen(suffix) - 1;
+ if ((int)strlen(leafName) > (int)kMaxRootLength)
+ leafName[kMaxRootLength] = '\0';
+ for (short indx = 1; indx < 1000 && Exists(); indx++)
+ {
+ // start with "Picture-1.jpg" after "Picture.jpg" exists
+ char newName[nsFileSpecHelpers::kMaxFilenameLength + 1];
+ sprintf(newName, "%s-%d%s", leafName, indx, suffix);
+ SetLeafName(newName);
+ }
+ if (*suffix)
+ nsCRT::free(suffix);
+ nsCRT::free(leafName);
+} // nsFileSpec::MakeUnique
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::operator = (const nsFileURL& inURL)
+//----------------------------------------------------------------------------------------
+{
+ *this = nsFilePath(inURL); // convert to unix path first
+}
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::operator = (const nsPersistentFileDescriptor& inDescriptor)
+//----------------------------------------------------------------------------------------
+{
+
+ nsCAutoString data;
+ inDescriptor.GetData(data);
+
+#if defined (XP_MAC) || defined(XP_MACOSX)
+ // Decode descriptor into a Handle (which is actually an AliasHandle)
+ char* decodedData = PL_Base64Decode(data.get(), data.Length(), nsnull);
+ Handle aliasH = nsnull;
+ mError = NS_FILE_RESULT(::PtrToHand(decodedData, &aliasH, (data.Length() * 3) / 4));
+ PR_Free(decodedData);
+ if (NS_FAILED(mError))
+ return; // not enough memory?
+#endif
+
+#if defined(XP_MAC)
+ Boolean changed;
+ mError = NS_FILE_RESULT(::ResolveAlias(nsnull, (AliasHandle)aliasH, &mSpec, &changed));
+ DisposeHandle((Handle) aliasH);
+ mPath.SetToEmpty();
+#elif defined(XP_MACOSX)
+ Boolean changed;
+ FSRef fileRef;
+ mError = NS_FILE_RESULT(::FSResolveAlias(nsnull, (AliasHandle)aliasH, &fileRef, &changed));
+ ::DisposeHandle(aliasH);
+
+ UInt8 pathBuf[PATH_MAX];
+ mError = NS_FILE_RESULT(::FSRefMakePath(&fileRef, pathBuf, PATH_MAX));
+ if (NS_FAILED(mError))
+ return;
+ mPath = (const char*)pathBuf;
+#else
+ mPath = data.get();
+ mError = NS_OK;
+#endif
+}
+
+//========================================================================================
+// UNIX & WIN nsFileSpec implementation
+//========================================================================================
+
+#if (defined XP_UNIX || defined XP_BEOS)
+//----------------------------------------------------------------------------------------
+nsFileSpec::nsFileSpec(const nsFilePath& inPath)
+//----------------------------------------------------------------------------------------
+: mPath((const char*)inPath)
+, mError(NS_OK)
+{
+// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!");
+}
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::operator = (const nsFilePath& inPath)
+//----------------------------------------------------------------------------------------
+{
+ mPath = (const char*)inPath;
+ mError = NS_OK;
+}
+#endif //XP_UNIX
+
+#if (defined(XP_UNIX) || defined(XP_WIN) || defined(XP_OS2) || defined(XP_BEOS))
+//----------------------------------------------------------------------------------------
+nsFileSpec::nsFileSpec(const nsFileSpec& inSpec)
+//----------------------------------------------------------------------------------------
+: mPath(inSpec.mPath)
+, mError(NS_OK)
+{
+// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!");
+}
+
+//----------------------------------------------------------------------------------------
+nsFileSpec::nsFileSpec(const char* inString, PRBool inCreateDirs)
+//----------------------------------------------------------------------------------------
+: mPath(inString)
+, mError(NS_OK)
+{
+// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!");
+ // Make canonical and absolute.
+ nsFileSpecHelpers::Canonify(mPath, inCreateDirs);
+}
+
+//----------------------------------------------------------------------------------------
+nsFileSpec::nsFileSpec(const nsString& inString, PRBool inCreateDirs)
+//----------------------------------------------------------------------------------------
+: mPath(inString)
+, mError(NS_OK)
+{
+// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!");
+ // Make canonical and absolute.
+ nsFileSpecHelpers::Canonify(mPath, inCreateDirs);
+}
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::operator = (const nsFileSpec& inSpec)
+//----------------------------------------------------------------------------------------
+{
+ mPath = inSpec.mPath;
+ mError = inSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::operator = (const char* inString)
+//----------------------------------------------------------------------------------------
+{
+ mPath = inString;
+ // Make canonical and absolute.
+ nsFileSpecHelpers::Canonify(mPath, PR_FALSE /* XXX? */);
+ mError = NS_OK;
+}
+#endif //XP_UNIX,XP_WIN,XP_OS2,XP_BEOS
+
+//----------------------------------------------------------------------------------------
+nsFileSpec nsFileSpec::operator + (const char* inRelativePath) const
+//----------------------------------------------------------------------------------------
+{
+ NS_ASSERTION(inRelativePath, "Attempt to append name with a null string");
+
+ nsFileSpec resultSpec = *this;
+ resultSpec += inRelativePath;
+ return resultSpec;
+} // nsFileSpec::operator +
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::operator == (const nsFileSpec& inOther) const
+//----------------------------------------------------------------------------------------
+{
+
+#if defined(XP_MAC)
+ if ( inOther.mSpec.vRefNum == mSpec.vRefNum &&
+ inOther.mSpec.parID == mSpec.parID &&
+ EqualString(inOther.mSpec.name, mSpec.name, false, true))
+ return PR_TRUE;
+#else
+ PRBool amEmpty = mPath.IsEmpty();
+ PRBool heEmpty = inOther.mPath.IsEmpty();
+ if (amEmpty) // we're the same if he's empty...
+ return heEmpty;
+ if (heEmpty) // ('cuz I'm not...)
+ return PR_FALSE;
+
+ nsSimpleCharString str = mPath;
+ nsSimpleCharString inStr = inOther.mPath;
+
+ // Length() is size of buffer, not length of string
+ PRUint32 strLast = str.Length() - 1, inLast = inStr.Length() - 1;
+#if defined(XP_WIN) || defined(XP_OS2)
+#define DIR_SEPARATOR '\\' // XXX doesn't NSPR have this?
+ /* windows does not care about case. */
+#ifdef XP_OS2
+#define DIR_STRCMP strcmp
+#else
+#define DIR_STRCMP _stricmp
+#endif
+#else
+#define DIR_SEPARATOR '/'
+#if defined(VMS)
+#define DIR_STRCMP strcasecmp
+#else
+#define DIR_STRCMP strcmp
+#endif
+#endif
+
+ if(str[strLast] == DIR_SEPARATOR)
+ str[strLast] = '\0';
+
+ if(inStr[inLast] == DIR_SEPARATOR)
+ inStr[inLast] = '\0';
+
+ if (DIR_STRCMP(str, inStr ) == 0)
+ return PR_TRUE;
+#undef DIR_SEPARATOR
+#undef DIR_STRCMP
+#endif
+ return PR_FALSE;
+}
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::operator != (const nsFileSpec& inOther) const
+//----------------------------------------------------------------------------------------
+{
+ return (! (*this == inOther) );
+}
+
+#if !defined(XP_MAC)
+//----------------------------------------------------------------------------------------
+// This is the only automatic conversion to const char*
+// that is provided, and it allows the
+// path to be "passed" to NSPR file routines. This practice
+// is VERY EVIL and should only be used to support legacy
+// code. Using it guarantees bugs on Macintosh. The path is NOT allocated, so do
+// not even think of deleting (or freeing) it.
+const char* nsFileSpec::GetCString() const
+//----------------------------------------------------------------------------------------
+{
+ return mPath;
+}
+#endif
+
+//----------------------------------------------------------------------------------------
+// Is our spec a child of the provided parent?
+PRBool nsFileSpec::IsChildOf(nsFileSpec &possibleParent)
+//----------------------------------------------------------------------------------------
+{
+ nsFileSpec iter = *this, parent;
+#ifdef DEBUG
+ int depth = 0;
+#endif
+ while (1) {
+#ifdef DEBUG
+ // sanity
+ NS_ASSERTION(depth < 100, "IsChildOf has lost its little mind");
+ if (depth > 100)
+ return PR_FALSE;
+#endif
+ if (iter == possibleParent)
+ return PR_TRUE;
+
+ iter.GetParent(parent); // shouldn't this be an error on parent?
+ if (iter.Failed())
+ return PR_FALSE;
+
+ if (iter == parent) // hit bottom
+ return PR_FALSE;
+
+ iter = parent;
+#ifdef DEBUG
+ depth++;
+#endif
+ }
+
+ // not reached, but I bet some compiler will whine
+ return PR_FALSE;
+}
+
+#if 0
+#pragma mark -
+#endif
+
+//========================================================================================
+// class nsPersistentFileDescriptor
+//========================================================================================
+
+//----------------------------------------------------------------------------------------
+nsPersistentFileDescriptor::nsPersistentFileDescriptor(const nsPersistentFileDescriptor& inDesc)
+//----------------------------------------------------------------------------------------
+ : mDescriptorString(inDesc.mDescriptorString)
+{
+} // nsPersistentFileDescriptor::nsPersistentFileDescriptor
+
+//----------------------------------------------------------------------------------------
+void nsPersistentFileDescriptor::operator = (const nsPersistentFileDescriptor& inDesc)
+//----------------------------------------------------------------------------------------
+{
+ mDescriptorString = inDesc.mDescriptorString;
+} // nsPersistentFileDescriptor::operator =
+
+//----------------------------------------------------------------------------------------
+nsPersistentFileDescriptor::nsPersistentFileDescriptor(const nsFileSpec& inSpec)
+//----------------------------------------------------------------------------------------
+{
+ *this = inSpec;
+} // nsPersistentFileDescriptor::nsPersistentFileDescriptor
+
+//----------------------------------------------------------------------------------------
+void nsPersistentFileDescriptor::operator = (const nsFileSpec& inSpec)
+//----------------------------------------------------------------------------------------
+{
+#if defined(XP_MAC)
+ if (inSpec.Error())
+ return;
+ AliasHandle aliasH;
+ OSErr err = NewAlias(nil, inSpec.GetFSSpecPtr(), &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);
+
+ mDescriptorString = buf;
+ PR_Free(buf);
+#elif defined(XP_MACOSX)
+ if (inSpec.Error())
+ return;
+
+ FSRef fileRef;
+ Boolean isDir;
+ OSErr err = ::FSPathMakeRef((const UInt8*)inSpec.GetCString(), &fileRef, &isDir);
+ if (err != noErr)
+ return;
+
+ AliasHandle aliasH;
+ err = ::FSNewAlias(nsnull, &fileRef, &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);
+
+ mDescriptorString = buf;
+ PR_Free(buf);
+#else
+ mDescriptorString = inSpec.GetCString();
+#endif // XP_MAC
+} // nsPersistentFileDescriptor::operator =
+
+//----------------------------------------------------------------------------------------
+nsPersistentFileDescriptor::~nsPersistentFileDescriptor()
+//----------------------------------------------------------------------------------------
+{
+} // nsPersistentFileDescriptor::~nsPersistentFileDescriptor
+
+//----------------------------------------------------------------------------------------
+void nsPersistentFileDescriptor::GetData(nsAFlatCString& outData) const
+//----------------------------------------------------------------------------------------
+{
+ outData.Assign(mDescriptorString, mDescriptorString.Length());
+}
+
+//----------------------------------------------------------------------------------------
+void nsPersistentFileDescriptor::SetData(const nsAFlatCString& inData)
+//----------------------------------------------------------------------------------------
+{
+ mDescriptorString.CopyFrom(inData.get(), inData.Length());
+}
+
+//----------------------------------------------------------------------------------------
+void nsPersistentFileDescriptor::SetData(const char* inData, PRInt32 inSize)
+//----------------------------------------------------------------------------------------
+{
+ mDescriptorString.CopyFrom(inData, inSize);
+}
+
+//========================================================================================
+// class nsNSPRPath
+//========================================================================================
+
+//----------------------------------------------------------------------------------------
+nsNSPRPath::operator const char*() const
+// NSPR expects a UNIX path on unix and Macintosh, but a native path on windows. NSPR
+// cannot be changed, so we have to do the dirty work.
+//----------------------------------------------------------------------------------------
+{
+#if defined(XP_WIN) || defined(XP_OS2)
+ if (!modifiedNSPRPath)
+ {
+ // If this is the first call, initialize modifiedNSPRPath. Start by cloning
+ // mFilePath, but strip the leading separator, if present
+ const char* unixPath = (const char*)mFilePath;
+ if (!unixPath)
+ return nsnull;
+
+ ((nsNSPRPath*)this)->modifiedNSPRPath
+ = nsCRT::strdup(*unixPath == '/' ? unixPath + 1: unixPath);
+
+ // Replace the bar
+ if (modifiedNSPRPath[1] == '|')
+ modifiedNSPRPath[1] = ':';
+
+ // Remove the ending separator only if it is not the last separator
+ int len = strlen(modifiedNSPRPath);
+ if (modifiedNSPRPath[len - 1 ] == '/' && modifiedNSPRPath[len - 2 ] != ':')
+ modifiedNSPRPath[len - 1 ] = '\0';
+ }
+ return modifiedNSPRPath;
+#else
+ return (const char*)mFilePath;
+#endif
+}
+
+//----------------------------------------------------------------------------------------
+nsNSPRPath::~nsNSPRPath()
+//----------------------------------------------------------------------------------------
+{
+#if defined(XP_WIN) || defined(XP_OS2)
+ if (modifiedNSPRPath)
+ nsCRT::free(modifiedNSPRPath);
+#endif
+}
+
+
+nsresult
+NS_FileSpecToIFile(nsFileSpec* fileSpec, nsILocalFile* *result)
+{
+ nsresult rv;
+
+ nsCOMPtr<nsILocalFile> file(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID));
+
+ if (!file) return NS_ERROR_FAILURE;
+
+#if defined(XP_MAC)
+ {
+ FSSpec spec = fileSpec->GetFSSpec();
+ nsCOMPtr<nsILocalFileMac> psmAppMacFile = do_QueryInterface(file, &rv);
+ if (NS_FAILED(rv)) return rv;
+ rv = psmAppMacFile->InitWithFSSpec(&spec);
+ if (NS_FAILED(rv)) return rv;
+ file = do_QueryInterface(psmAppMacFile, &rv);
+ }
+#else
+ // XP_MACOSX: do this for OS X to preserve long filenames
+ rv = file->InitWithNativePath(nsDependentCString(fileSpec->GetNativePathCString()));
+#endif
+ if (NS_FAILED(rv)) return rv;
+
+ *result = file;
+ NS_ADDREF(*result);
+ return NS_OK;
+}
+
+
+
+
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpec.h b/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpec.h
new file mode 100644
index 00000000..53fa6c1a
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpec.h
@@ -0,0 +1,782 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ THESE CLASSES ARE DEPRECATED AND UNSUPPORTED! USE |nsIFile| and |nsILocalFile|.
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+
+
+
+
+
+
+
+
+
+// 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
+// nsDirectoryIterator.
+//
+// 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(nsFileSpec(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
+//
+// nsFileURL fileURL("file:///Development/MPW/MPW%20Shell");
+//
+// Initialize a Unix-style path from a URL
+//
+// nsFilePath filePath(fileURL);
+//
+// Initialize a file spec from a URL
+//
+// nsFileSpec fileSpec(fileURL);
+//
+// Make the spec unique.
+//
+// fileSpec.MakeUnique();
+//
+// Assign the spec to a URL (causing conversion)
+//
+// fileURL = fileSpec;
+//
+// Assign a unix path using a string
+//
+// filePath = "/Development/MPW/SysErrs.err";
+//
+// Assign to a file spec using a unix path (causing conversion).
+//
+// fileSpec = filePath;
+//
+// Make this unique.
+//
+// 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.
+//
+//========================================================================================
+
+#ifndef _FILESPEC_H_
+#define _FILESPEC_H_
+
+#include "xpcomobsolete.h"
+#include "nsError.h"
+#include "nsString.h"
+#include "nsReadableUtils.h"
+#include "nsCRT.h"
+#include "prtypes.h"
+
+//========================================================================================
+// Compiler-specific macros, as needed
+//========================================================================================
+#if !defined(NS_USING_NAMESPACE) && (defined(__MWERKS__) || defined(_MSC_VER))
+#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 ===============================
+
+#include "nsILocalFile.h"
+#include "nsCOMPtr.h"
+
+#if defined(XP_MAC)
+#include <Files.h>
+#include "nsILocalFileMac.h"
+#elif defined(XP_UNIX) || defined(XP_BEOS)
+#include <dirent.h>
+#elif defined(XP_WIN)
+
+// This clashes with some of the Win32 system headers (specifically,
+// winbase.h). Hopefully they'll have been included first; else we may
+// have problems. We could include winbase.h before doing this;
+// unfortunately, it's bring in too much crap and'd slow stuff down
+// more than it's worth doing.
+#ifdef CreateDirectory
+#undef CreateDirectory
+#endif
+
+#include "prio.h"
+#elif defined(XP_OS2)
+#define INCL_DOS
+#define INCL_DOSERRORS
+#define INCL_WIN
+#define INCL_GPI
+#include <os2.h>
+#include "prio.h"
+#endif
+
+//========================================================================================
+// Here are the allowable ways to describe a file.
+//========================================================================================
+
+class nsFileSpec; // Preferred. For i/o use nsInputFileStream, nsOutputFileStream
+class nsFilePath;
+class nsFileURL;
+class nsNSPRPath; // This can be passed to NSPR file I/O routines, if you must.
+class nsPersistentFileDescriptor; // Used for storage across program launches.
+
+#define kFileURLPrefix "file://"
+#define kFileURLPrefixLength (7)
+
+class nsOutputStream;
+class nsInputStream;
+class nsIOutputStream;
+class nsIInputStream;
+class nsOutputFileStream;
+class nsInputFileStream;
+class nsOutputConsoleStream;
+
+class nsIUnicodeEncoder;
+class nsIUnicodeDecoder;
+
+//========================================================================================
+// 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 nsSimpleCharString
+// An envelope for char*: reference counted. Used internally by all the nsFileSpec
+// classes below.
+//========================================================================================
+{
+public:
+ nsSimpleCharString();
+ nsSimpleCharString(const char*);
+ nsSimpleCharString(const nsString&);
+ nsSimpleCharString(const nsSimpleCharString&);
+ nsSimpleCharString(const char* inData, PRUint32 inLength);
+
+ ~nsSimpleCharString();
+
+ void operator = (const char*);
+ void operator = (const nsString&);
+ void operator = (const nsSimpleCharString&);
+
+ operator const char*() const { return mData ? mData->mString : 0; }
+ operator char* ()
+ {
+ ReallocData(Length()); // requires detaching if shared...
+ return mData ? mData->mString : 0;
+ }
+ PRBool operator == (const char*);
+ PRBool operator == (const nsString&);
+ PRBool operator == (const nsSimpleCharString&);
+
+ void operator += (const char* inString);
+ nsSimpleCharString operator + (const char* inString) const;
+
+ char operator [](int i) const { return mData ? mData->mString[i] : '\0'; }
+ char& operator [](int i)
+ {
+ if (i >= (int)Length())
+ ReallocData((PRUint32)i + 1);
+ return mData->mString[i]; // caveat appelator
+ }
+ char& operator [](unsigned int i) { return (*this)[(int)i]; }
+
+ void Catenate(const char* inString1, const char* inString2);
+
+ void SetToEmpty();
+ PRBool IsEmpty() const { return Length() == 0; }
+
+ PRUint32 Length() const { return mData ? mData->mLength : 0; }
+ void SetLength(PRUint32 inLength) { ReallocData(inLength); }
+ void CopyFrom(const char* inData, PRUint32 inLength);
+ void LeafReplace(char inSeparator, const char* inLeafName);
+ char* GetLeaf(char inSeparator) const; // use PR_Free()
+ void Unescape();
+
+protected:
+
+ void AddRefData();
+ void ReleaseData();
+ void ReallocData(PRUint32 inLength);
+
+ //--------------------------------------------------
+ // Data
+ //--------------------------------------------------
+
+protected:
+
+ struct Data {
+ int mRefCount;
+ PRUint32 mLength;
+ char mString[1];
+ };
+ Data* mData;
+}; // class nsSimpleCharString
+
+//========================================================================================
+class NS_COM_OBSOLETE nsFileSpec
+// This is whatever each platform really prefers to describe files as. Declared first
+// because the other two types have an embedded nsFileSpec object.
+//========================================================================================
+{
+ public:
+ nsFileSpec();
+
+ // These two meathods take *native* file paths.
+ NS_EXPLICIT nsFileSpec(const char* inNativePath, PRBool inCreateDirs = PR_FALSE);
+ NS_EXPLICIT nsFileSpec(const nsString& inNativePath, PRBool inCreateDirs = PR_FALSE);
+
+
+ NS_EXPLICIT nsFileSpec(const nsFilePath& inPath);
+ NS_EXPLICIT nsFileSpec(const nsFileURL& inURL);
+ nsFileSpec(const nsFileSpec& inPath);
+ virtual ~nsFileSpec();
+
+ // These two operands take *native* file paths.
+ void operator = (const char* inNativePath);
+
+ void operator = (const nsFilePath& inPath);
+ void operator = (const nsFileURL& inURL);
+ void operator = (const nsFileSpec& inOther);
+ void operator = (const nsPersistentFileDescriptor& inOther);
+
+ PRBool operator ==(const nsFileSpec& inOther) const;
+ PRBool operator !=(const nsFileSpec& inOther) const;
+
+
+ // Returns a native path, and allows the
+ // path to be "passed" to legacy code. This practice
+ // is VERY EVIL and should only be used to support legacy
+ // code. Using it guarantees bugs on Macintosh.
+ // The path is cached and freed by the nsFileSpec destructor
+ // so do not delete (or free) it. See also nsNSPRPath below,
+ // if you really must pass a string to PR_OpenFile().
+ // Doing so will introduce two automatic bugs.
+ const char* GetCString() const;
+
+ // Same as GetCString (please read the comments).
+ // Do not try to free this!
+ operator const char* () const { return GetCString(); }
+
+ // Same as GetCString (please read the comments).
+ // Do not try to free this!
+ const char* GetNativePathCString() const { return GetCString(); }
+
+ PRBool IsChildOf(nsFileSpec &possibleParent);
+
+#if defined(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,
+ PRBool resolveAlias = PR_TRUE);
+
+ nsFileSpec(const FSSpec& inSpec, PRBool resolveAlias = PR_TRUE);
+ void operator = (const FSSpec& inSpec);
+
+ operator FSSpec* () { return &mSpec; }
+ operator const FSSpec* const () { return &mSpec; }
+ operator FSSpec& () { return mSpec; }
+ operator const FSSpec& () const { return mSpec; }
+
+ const FSSpec& GetFSSpec() const { return mSpec; }
+ FSSpec& GetFSSpec() { return mSpec; }
+ ConstFSSpecPtr GetFSSpecPtr() const { return &mSpec; }
+ FSSpecPtr GetFSSpecPtr() { return &mSpec; }
+ void MakeAliasSafe();
+ void MakeUnique(ConstStr255Param inSuggestedLeafName);
+ StringPtr GetLeafPName() { return mSpec.name; }
+ ConstStr255Param GetLeafPName() const { return mSpec.name; }
+
+ OSErr GetCatInfo(CInfoPBRec& outInfo) const;
+
+ OSErr SetFileTypeAndCreator(OSType type, OSType creator);
+ OSErr GetFileTypeAndCreator(OSType* type, OSType* creator);
+
+#endif // end of Macintosh utility methods.
+
+ PRBool Valid() const { return NS_SUCCEEDED(Error()); }
+ nsresult Error() const
+ {
+#if !defined(XP_MAC)
+ if (mPath.IsEmpty() && NS_SUCCEEDED(mError))
+ ((nsFileSpec*)this)->mError = NS_ERROR_NOT_INITIALIZED;
+#endif
+ return mError;
+ }
+ PRBool Failed() const { return (PRBool)NS_FAILED(Error()); }
+
+ //--------------------------------------------------
+ // Queries and path algebra. These do not modify the disk.
+ //--------------------------------------------------
+
+ char* GetLeafName() const; // Allocated. Use nsCRT::free().
+ // inLeafName can be a relative path, so this allows
+ // one kind of concatenation of "paths".
+ void SetLeafName(const char* inLeafName);
+
+ // 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 --() ?
+ void GetParent(nsFileSpec& outSpec) const;
+
+
+ // ie nsFileSpec::TimeStamp. This is 32 bits now,
+ // but might change, eg, to a 64-bit class. So use the
+ // typedef, and use a streaming operator to convert
+ // to a string, so that your code won't break. It's
+ // none of your business what the number means. Don't
+ // rely on the implementation.
+ typedef PRUint32 TimeStamp;
+
+ // This will return different values on different
+ // platforms, even for the same file (eg, on a server).
+ // But if the platform is constant, it will increase after
+ // every file modification.
+ void GetModDate(TimeStamp& outStamp) const;
+
+ PRBool ModDateChanged(const TimeStamp& oldStamp) const
+ {
+ TimeStamp newStamp;
+ GetModDate(newStamp);
+ return newStamp != oldStamp;
+ }
+
+ PRUint32 GetFileSize() const;
+ PRInt64 GetDiskSpaceAvailable() const;
+
+ nsFileSpec operator + (const char* inRelativeUnixPath) const;
+
+ // 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 operator += (const char* inRelativeUnixPath);
+
+
+ void MakeUnique();
+ void MakeUnique(const char* inSuggestedLeafName);
+
+
+ PRBool IsDirectory() const; // More stringent than Exists()
+ PRBool IsFile() const; // More stringent than Exists()
+ PRBool Exists() const;
+
+ PRBool IsHidden() const;
+
+ PRBool IsSymlink() const;
+
+ //--------------------------------------------------
+ // Creation and deletion of objects. These can modify the disk.
+ //--------------------------------------------------
+
+ // Called for the spec of an alias. Modifies the spec to
+ // point to the original. Sets mError.
+ nsresult ResolveSymlink(PRBool& wasSymlink);
+
+ void CreateDirectory(int mode = 0775 /* for unix */);
+ void CreateDir(int mode = 0775) { CreateDirectory(mode); }
+ // workaround for yet another VC++ bug with long identifiers.
+ void Delete(PRBool inRecursive) const;
+ nsresult Truncate(PRInt32 aNewLength) const;
+ void RecursiveCopy(nsFileSpec newDir) const;
+
+ nsresult Rename(const char* inNewName); // not const: gets updated
+ nsresult CopyToDir(const nsFileSpec& inNewParentDirectory) const;
+ nsresult MoveToDir(const nsFileSpec& inNewParentDirectory);
+ nsresult Execute(const char* args) const;
+
+ protected:
+
+ //--------------------------------------------------
+ // Data
+ //--------------------------------------------------
+
+ protected:
+
+ // Clear the nsFileSpec contents, resetting it
+ // to the uninitialized state;
+ void Clear();
+
+ friend class nsFilePath;
+ friend class nsFileURL;
+ friend class nsDirectoryIterator;
+#if defined(XP_MAC)
+ FSSpec mSpec;
+#endif
+ nsSimpleCharString mPath;
+ nsresult mError;
+
+private:
+ NS_EXPLICIT nsFileSpec(const nsPersistentFileDescriptor& inURL);
+
+}; // class nsFileSpec
+
+// FOR HISTORICAL REASONS:
+
+typedef nsFileSpec nsNativeFileSpec;
+
+//========================================================================================
+class NS_COM_OBSOLETE 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* inURLString, PRBool inCreateDirs = PR_FALSE);
+ NS_EXPLICIT nsFileURL(const nsString& inURLString, 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* inURLString);
+ void operator = (const nsString& inURLString)
+ {
+ *this = NS_LossyConvertUCS2toASCII(inURLString).get();
+ }
+ void operator = (const nsFilePath& inOther);
+ void operator = (const nsFileSpec& inOther);
+
+ void operator +=(const char* inRelativeUnixPath);
+ nsFileURL operator +(const char* inRelativeUnixPath) const;
+ operator const char* () const { return (const char*)mURL; } // deprecated.
+ const char* GetURLString() const { return (const char*)mURL; }
+ // Not allocated, so don't free it.
+ const char* GetAsString() const { return (const char*)mURL; }
+ // Not allocated, so don't free it.
+
+#if defined(XP_MAC)
+ // Accessor to allow quick assignment to a mFileSpec
+ const nsFileSpec& GetFileSpec() const { return mFileSpec; }
+#endif
+
+ //--------------------------------------------------
+ // Data
+ //--------------------------------------------------
+
+ protected:
+ friend class nsFilePath; // to allow construction of nsFilePath
+ nsSimpleCharString mURL;
+
+#if defined(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_COM_OBSOLETE nsFilePath
+// This is a string that looks like "/foo/bar/mumble fish". Same as nsFileURL, but
+// without the "file:// prefix", and NOT %20 ENCODED! Strings passed in must be
+// valid unix-style paths in this format.
+//========================================================================================
+{
+ public:
+ nsFilePath(const nsFilePath& inPath);
+ NS_EXPLICIT nsFilePath(const char* inUnixPathString, PRBool inCreateDirs = PR_FALSE);
+ NS_EXPLICIT nsFilePath(const nsString& inUnixPathString, 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 will return a UNIX string. If you
+ // need a string that can be passed into
+ // NSPR, take a look at the nsNSPRPath class.
+
+ void operator = (const nsFilePath& inPath);
+ void operator = (const char* inUnixPathString);
+ void operator = (const nsString& inUnixPathString)
+ {
+ *this = NS_LossyConvertUCS2toASCII(inUnixPathString).get();
+ }
+ void operator = (const nsFileURL& inURL);
+ void operator = (const nsFileSpec& inOther);
+
+ void operator +=(const char* inRelativeUnixPath);
+ nsFilePath operator +(const char* inRelativeUnixPath) const;
+
+#if defined(XP_MAC)
+ public:
+ // Accessor to allow quick assignment to a mFileSpec
+ const nsFileSpec& GetFileSpec() const { return mFileSpec; }
+#endif
+
+ //--------------------------------------------------
+ // Data
+ //--------------------------------------------------
+
+ private:
+
+ nsSimpleCharString mPath;
+#if defined(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 nsPersistentFileDescriptor
+// To save information about a file's location in another file, initialize
+// one of these from your nsFileSpec, and then write this out to your output stream.
+// To retrieve the info, create one of these, read its value from an input stream.
+// and then make an nsFileSpec from it.
+//========================================================================================
+{
+ public:
+ nsPersistentFileDescriptor() {}
+ // For use prior to reading in from a stream
+ nsPersistentFileDescriptor(const nsPersistentFileDescriptor& inEncodedData);
+ virtual ~nsPersistentFileDescriptor();
+ void operator = (const nsPersistentFileDescriptor& inEncodedData);
+
+ // Conversions
+ NS_EXPLICIT nsPersistentFileDescriptor(const nsFileSpec& inSpec);
+ void operator = (const nsFileSpec& inSpec);
+
+ // The following four functions are declared here (as friends). Their implementations
+ // are in mozilla/base/src/nsFileSpecStreaming.cpp.
+
+ friend nsresult Read(nsIInputStream* aStream, nsPersistentFileDescriptor&);
+ friend nsresult Write(nsIOutputStream* aStream, const nsPersistentFileDescriptor&);
+ // writes the data to a file
+ friend NS_COM_OBSOLETE nsInputStream& operator >> (nsInputStream&, nsPersistentFileDescriptor&);
+ // reads the data from a file
+ friend NS_COM_OBSOLETE nsOutputStream& operator << (nsOutputStream&, const nsPersistentFileDescriptor&);
+ // writes the data to a file
+ friend class nsFileSpec;
+
+ void GetData(nsAFlatCString& outData) const;
+ void SetData(const nsAFlatCString& inData);
+ void SetData(const char* inData, PRInt32 inSize);
+
+ //--------------------------------------------------
+ // Data
+ //--------------------------------------------------
+
+ protected:
+
+ nsSimpleCharString mDescriptorString;
+
+}; // class nsPersistentFileDescriptor
+
+//========================================================================================
+class NS_COM_OBSOLETE nsDirectoryIterator
+// Example:
+//
+// nsFileSpec parentDir(...); // directory over whose children we shall iterate
+// for (nsDirectoryIterator i(parentDir, PR_FALSE); i.Exists(); i++)
+// {
+// // do something with i.Spec()
+// }
+//
+// - or -
+//
+// for (nsDirectoryIterator i(parentDir, PR_TRUE); i.Exists(); i--)
+// {
+// // do something with i.Spec()
+// }
+// This one passed the PR_TRUE flag which will resolve any symlink encountered.
+//========================================================================================
+{
+ public:
+ nsDirectoryIterator( const nsFileSpec& parent,
+ PRBool resoveSymLinks);
+#if !defined(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; }
+
+ nsFileSpec& Spec() { return mCurrent; }
+
+ private:
+
+#if defined(XP_MAC)
+ OSErr SetToIndex();
+#endif
+
+ //--------------------------------------------------
+ // Data
+ //--------------------------------------------------
+
+ private:
+
+ nsFileSpec mCurrent;
+ PRBool mExists;
+ PRBool mResoveSymLinks;
+
+#if (defined(XP_UNIX) || defined(XP_BEOS) || defined (XP_WIN) || defined(XP_OS2))
+ nsFileSpec mStarting;
+#endif
+
+#if defined(XP_MAC)
+ short mVRefNum;
+ long mParID;
+ short mIndex;
+ short mMaxIndex;
+#elif defined(XP_UNIX) || defined(XP_BEOS)
+ DIR* mDir;
+#elif defined(XP_WIN) || defined(XP_OS2)
+ PRDir* mDir; // XXX why not use PRDir for Unix too?
+#endif
+}; // class nsDirectoryIterator
+
+//========================================================================================
+class NS_COM_OBSOLETE nsNSPRPath
+// This class will allow you to pass any one of the nsFile* classes directly into NSPR
+// without the need to worry about whether you have the right kind of filepath or not.
+// It will also take care of cleaning up any allocated memory.
+//========================================================================================
+{
+public:
+ NS_EXPLICIT nsNSPRPath(const nsFileSpec& inSpec)
+ : mFilePath(inSpec), modifiedNSPRPath(nsnull) {}
+ NS_EXPLICIT nsNSPRPath(const nsFileURL& inURL)
+ : mFilePath(inURL), modifiedNSPRPath(nsnull) {}
+ NS_EXPLICIT nsNSPRPath(const nsFilePath& inUnixPath)
+ : mFilePath(inUnixPath), modifiedNSPRPath(nsnull) {}
+
+ virtual ~nsNSPRPath();
+
+ operator const char*() const;
+ // Returns the path
+ // that NSPR file routines expect on each platform.
+ // Concerning constness, this can modify
+ // modifiedNSPRPath, but it's really just "mutable".
+
+ //--------------------------------------------------
+ // Data
+ //--------------------------------------------------
+
+private:
+
+ nsFilePath mFilePath;
+ char* modifiedNSPRPath; // Currently used only on XP_WIN,XP_OS2
+}; // class nsNSPRPath
+
+
+NS_COM_OBSOLETE nsresult NS_FileSpecToIFile(nsFileSpec* fileSpec, nsILocalFile* *result);
+
+#endif // _FILESPEC_H_
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecBeOS.cpp b/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecBeOS.cpp
new file mode 100644
index 00000000..20a38f5e
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecBeOS.cpp
@@ -0,0 +1,547 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// 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 <limits.h>
+#include "nsError.h"
+#include "prio.h" /* for PR_Rename */
+
+// BeOS specific headers
+#include <Entry.h>
+#include <Path.h>
+#include <Volume.h>
+
+//----------------------------------------------------------------------------------------
+void nsFileSpecHelpers::Canonify(nsSimpleCharString& ioPath, PRBool inMakeDirs)
+// Canonify, make absolute, and check whether directories exist
+//----------------------------------------------------------------------------------------
+{
+ if (ioPath.IsEmpty())
+ return;
+ if (inMakeDirs)
+ {
+ const mode_t mode = 0700;
+ nsFileSpecHelpers::MakeAllDirectories((const char*)ioPath, mode);
+ }
+ char buffer[MAXPATHLEN];
+ errno = 0;
+ *buffer = '\0';
+ BEntry e((const char *)ioPath, true);
+ BPath p;
+ e.GetPath(&p);
+ ioPath = p.Path();
+} // nsFileSpecHelpers::Canonify
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::SetLeafName(const char* inLeafName)
+//----------------------------------------------------------------------------------------
+{
+ mPath.LeafReplace('/', inLeafName);
+} // nsFileSpec::SetLeafName
+
+//----------------------------------------------------------------------------------------
+char* nsFileSpec::GetLeafName() const
+//----------------------------------------------------------------------------------------
+{
+ return mPath.GetLeaf('/');
+} // nsFileSpec::GetLeafName
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::Exists() const
+//----------------------------------------------------------------------------------------
+{
+ struct stat st;
+ return !mPath.IsEmpty() && 0 == stat(mPath, &st);
+} // nsFileSpec::Exists
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::GetModDate(TimeStamp& outStamp) const
+//----------------------------------------------------------------------------------------
+{
+ struct stat st;
+ if (!mPath.IsEmpty() && stat(mPath, &st) == 0)
+ outStamp = st.st_mtime;
+ else
+ outStamp = 0;
+} // nsFileSpec::GetModDate
+
+//----------------------------------------------------------------------------------------
+PRUint32 nsFileSpec::GetFileSize() const
+//----------------------------------------------------------------------------------------
+{
+ struct stat st;
+ if (!mPath.IsEmpty() && stat(mPath, &st) == 0)
+ return (PRUint32)st.st_size;
+ return 0;
+} // nsFileSpec::GetFileSize
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::IsFile() const
+//----------------------------------------------------------------------------------------
+{
+ struct stat st;
+ return !mPath.IsEmpty() && stat(mPath, &st) == 0 && S_ISREG(st.st_mode);
+} // nsFileSpec::IsFile
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::IsDirectory() const
+//----------------------------------------------------------------------------------------
+{
+ struct stat st;
+ return !mPath.IsEmpty() && 0 == stat(mPath, &st) && S_ISDIR(st.st_mode);
+} // nsFileSpec::IsDirectory
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::IsHidden() const
+//----------------------------------------------------------------------------------------
+{
+ PRBool hidden = PR_TRUE;
+ char *leafname = GetLeafName();
+ if (nsnull != leafname)
+ {
+ if ((!strcmp(leafname, ".")) || (!strcmp(leafname, "..")))
+ {
+ hidden = PR_FALSE;
+ }
+ nsCRT::free(leafname);
+ }
+ return hidden;
+} // nsFileSpec::IsHidden
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::IsSymlink() const
+//----------------------------------------------------------------------------------------
+{
+ struct stat st;
+ if (!mPath.IsEmpty() && stat(mPath, &st) == 0 && S_ISLNK(st.st_mode))
+ return PR_TRUE;
+
+ return PR_FALSE;
+} // nsFileSpec::IsSymlink
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::ResolveSymlink(PRBool& wasAliased)
+//----------------------------------------------------------------------------------------
+{
+ wasAliased = PR_FALSE;
+
+ char resolvedPath[MAXPATHLEN];
+ int charCount = readlink(mPath, (char*)&resolvedPath, MAXPATHLEN);
+ if (0 < charCount)
+ {
+ if (MAXPATHLEN > charCount)
+ resolvedPath[charCount] = '\0';
+
+ wasAliased = PR_TRUE;
+ /* if it's not an absolute path,
+ replace the leaf with what got resolved */
+ if (resolvedPath[0] != '/') {
+ SetLeafName(resolvedPath);
+ }
+ else {
+ mPath = (char*)resolvedPath;
+ }
+
+ BEntry e((const char *)mPath, true); // traverse symlink
+ BPath p;
+ status_t err;
+ err = e.GetPath(&p);
+ NS_ASSERTION(err == B_OK, "realpath failed");
+
+ const char* canonicalPath = p.Path();
+ if(err == B_OK)
+ mPath = (char*)canonicalPath;
+ else
+ return NS_ERROR_FAILURE;
+ }
+ return NS_OK;
+} // nsFileSpec::ResolveSymlink
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::GetParent(nsFileSpec& outSpec) const
+//----------------------------------------------------------------------------------------
+{
+ outSpec.mPath = mPath;
+ char* chars = (char*)outSpec.mPath;
+ chars[outSpec.mPath.Length() - 1] = '\0'; // avoid trailing separator, if any
+ char* cp = strrchr(chars, '/');
+ if (cp++)
+ outSpec.mPath.SetLength(cp - chars); // truncate.
+} // nsFileSpec::GetParent
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::operator += (const char* inRelativePath)
+//----------------------------------------------------------------------------------------
+{
+ if (!inRelativePath || mPath.IsEmpty())
+ return;
+
+ char endChar = mPath[(int)(strlen(mPath) - 1)];
+ if (endChar == '/')
+ mPath += "x";
+ else
+ mPath += "/x";
+ SetLeafName(inRelativePath);
+} // nsFileSpec::operator +=
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::CreateDirectory(int mode)
+//----------------------------------------------------------------------------------------
+{
+ // Note that mPath is canonical!
+ if (mPath.IsEmpty())
+ return;
+ mkdir(mPath, mode);
+} // nsFileSpec::CreateDirectory
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::Delete(PRBool inRecursive) const
+// To check if this worked, call Exists() afterwards, see?
+//----------------------------------------------------------------------------------------
+{
+ if (IsDirectory())
+ {
+ if (inRecursive)
+ {
+ for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++)
+ {
+ nsFileSpec& child = (nsFileSpec&)i;
+ child.Delete(inRecursive);
+ }
+ }
+ rmdir(mPath);
+ }
+ else if (!mPath.IsEmpty())
+ remove(mPath);
+} // nsFileSpec::Delete
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::RecursiveCopy(nsFileSpec newDir) const
+//----------------------------------------------------------------------------------------
+{
+ if (IsDirectory())
+ {
+ if (!(newDir.Exists()))
+ {
+ newDir.CreateDirectory();
+ }
+
+ for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++)
+ {
+ nsFileSpec& child = (nsFileSpec&)i;
+
+ if (child.IsDirectory())
+ {
+ nsFileSpec tmpDirSpec(newDir);
+
+ char *leafname = child.GetLeafName();
+ tmpDirSpec += leafname;
+ nsCRT::free(leafname);
+
+ child.RecursiveCopy(tmpDirSpec);
+ }
+ else
+ {
+ child.RecursiveCopy(newDir);
+ }
+ }
+ }
+ else if (!mPath.IsEmpty())
+ {
+ nsFileSpec& filePath = (nsFileSpec&) *this;
+
+ if (!(newDir.Exists()))
+ {
+ newDir.CreateDirectory();
+ }
+
+ filePath.CopyToDir(newDir);
+ }
+} // nsFileSpec::RecursiveCopy
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::Truncate(PRInt32 offset) const
+//----------------------------------------------------------------------------------------
+{
+ char* Path = nsCRT::strdup(mPath);
+
+ int rv = truncate(Path, offset) ;
+
+ nsCRT::free(Path) ;
+
+ if(!rv)
+ return NS_OK ;
+ else
+ return NS_ERROR_FAILURE ;
+} // nsFileSpec::Truncate
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::Rename(const char* inNewName)
+//----------------------------------------------------------------------------------------
+{
+ // This function should not be used to move a file on disk.
+ if (mPath.IsEmpty() || strchr(inNewName, '/'))
+ return NS_FILE_FAILURE;
+
+ char* oldPath = nsCRT::strdup(mPath);
+
+ SetLeafName(inNewName);
+
+ if (PR_Rename(oldPath, mPath) != NS_OK)
+ {
+ // Could not rename, set back to the original.
+ mPath = oldPath;
+ return NS_FILE_FAILURE;
+ }
+
+ nsCRT::free(oldPath);
+
+ 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::CopyToDir(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();
+ nsSimpleCharString destPath(inParentDirectory.GetCString());
+ destPath += "/";
+ destPath += leafname;
+ nsCRT::free(leafname);
+ result = NS_FILE_RESULT(CrudeFileCopy(GetCString(), destPath));
+ }
+ return result;
+} // nsFileSpec::CopyToDir
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::MoveToDir(const nsFileSpec& inNewParentDirectory)
+//----------------------------------------------------------------------------------------
+{
+ // 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();
+ nsSimpleCharString destPath(inNewParentDirectory.GetCString());
+ destPath += "/";
+ destPath += leafname;
+ nsCRT::free(leafname);
+
+ result = NS_FILE_RESULT(CrudeFileCopy(GetCString(), (const char*)destPath));
+ if (result == NS_OK)
+ {
+ // cast to fix const-ness
+ ((nsFileSpec*)this)->Delete(PR_FALSE);
+
+ *this = inNewParentDirectory + GetLeafName();
+ }
+ }
+ return result;
+}
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::Execute(const char* inArgs ) const
+//----------------------------------------------------------------------------------------
+{
+ nsresult result = NS_FILE_FAILURE;
+
+ if (!mPath.IsEmpty() && !IsDirectory())
+ {
+ nsSimpleCharString fileNameWithArgs = mPath + " " + inArgs;
+ result = NS_FILE_RESULT(system(fileNameWithArgs));
+ }
+
+ return result;
+
+} // nsFileSpec::Execute
+
+//----------------------------------------------------------------------------------------
+PRInt64 nsFileSpec::GetDiskSpaceAvailable() const
+//----------------------------------------------------------------------------------------
+{
+ char curdir [MAXPATHLEN];
+ if (!mPath || !*mPath)
+ {
+ (void) getcwd(curdir, MAXPATHLEN);
+ if (!curdir)
+ return ULONGLONG_MAX; /* hope for the best as we did in cheddar */
+ }
+ else
+ sprintf(curdir, "%.200s", (const char*)mPath);
+
+ BEntry e(curdir);
+ if(e.InitCheck() != B_OK)
+ return ULONGLONG_MAX; /* hope for the best as we did in cheddar */
+ entry_ref ref;
+ e.GetRef(&ref);
+ BVolume v(ref.device);
+
+#ifdef DEBUG_DISK_SPACE
+ printf("DiskSpaceAvailable: %d bytes\n", space);
+#endif
+ return v.FreeBytes();
+} // nsFileSpec::GetDiskSpace()
+
+//========================================================================================
+// nsDirectoryIterator
+//========================================================================================
+
+//----------------------------------------------------------------------------------------
+nsDirectoryIterator::nsDirectoryIterator(
+ const nsFileSpec& inDirectory
+, PRBool resolveSymlinks)
+//----------------------------------------------------------------------------------------
+ : mCurrent(inDirectory)
+ , mStarting(inDirectory)
+ , mExists(PR_FALSE)
+ , mDir(nsnull)
+ , mResoveSymLinks(resolveSymlinks)
+{
+ mStarting += "sysygy"; // save off the starting directory
+ 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 = PR_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 = PR_TRUE;
+ mCurrent = mStarting; // restore mCurrent to be the starting directory. ResolveSymlink() may have taken us to another directory
+ mCurrent.SetLeafName(entry->d_name);
+ if (mResoveSymLinks)
+ {
+ PRBool ignore;
+ mCurrent.ResolveSymlink(ignore);
+ }
+ }
+ return *this;
+} // nsDirectoryIterator::operator ++
+
+//----------------------------------------------------------------------------------------
+nsDirectoryIterator& nsDirectoryIterator::operator -- ()
+//----------------------------------------------------------------------------------------
+{
+ return ++(*this); // can't do it backwards.
+} // nsDirectoryIterator::operator --
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecImpl.cpp b/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecImpl.cpp
new file mode 100644
index 00000000..b0e3cc15
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecImpl.cpp
@@ -0,0 +1,879 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Pierre Phaneuf <pp@ludusdesign.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsFileSpecImpl.h"// Always first, to ensure that it compiles alone.
+
+#include "nsIFileStream.h"
+#include "nsFileStream.h"
+
+#include "nsILocalFile.h"
+#include "nsNativeCharsetUtils.h"
+
+#include "prmem.h"
+
+NS_IMPL_THREADSAFE_ISUPPORTS1(nsFileSpecImpl, nsIFileSpec)
+
+#ifdef NS_DEBUG
+#define TEST_OUT_PTR(p) \
+ if (!(p)) \
+ return NS_ERROR_NULL_POINTER;
+#else
+#define TEST_OUT_PTR(p)
+#endif
+
+//----------------------------------------------------------------------------------------
+nsFileSpecImpl::nsFileSpecImpl()
+//----------------------------------------------------------------------------------------
+ : mInputStream(nsnull)
+ , mOutputStream(nsnull)
+{
+// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!");
+
+}
+
+//----------------------------------------------------------------------------------------
+nsFileSpecImpl::nsFileSpecImpl(const nsFileSpec& inSpec)
+//----------------------------------------------------------------------------------------
+ : mFileSpec(inSpec)
+ , mInputStream(nsnull)
+ , mOutputStream(nsnull)
+{
+// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!");
+
+}
+
+//----------------------------------------------------------------------------------------
+nsFileSpecImpl::~nsFileSpecImpl()
+//----------------------------------------------------------------------------------------
+{
+ CloseStream();
+}
+
+//----------------------------------------------------------------------------------------
+/* static */
+nsresult nsFileSpecImpl::MakeInterface(const nsFileSpec& inSpec, nsIFileSpec** result)
+//----------------------------------------------------------------------------------------
+{
+ nsFileSpecImpl* it = new nsFileSpecImpl(inSpec);
+ if (!it)
+ return NS_ERROR_OUT_OF_MEMORY;
+ return it->QueryInterface(NS_GET_IID(nsIFileSpec), (void **) result);
+} // nsFileSpecImpl::MakeInterface
+
+#define FILESPEC(ifilespec) ((nsFileSpecImpl*)ifilespec)->mFileSpec
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::FromFileSpec(const nsIFileSpec *original)
+//----------------------------------------------------------------------------------------
+{
+ if (original) {
+ nsresult rv = ((nsIFileSpec *)original)->GetFileSpec( &mFileSpec);
+ if (NS_SUCCEEDED( rv))
+ return mFileSpec.Error();
+ else
+ return( rv);
+ }
+ else
+ return( NS_ERROR_FAILURE);
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::IsChildOf(nsIFileSpec *possibleParent,
+ PRBool *_retval)
+{
+ *_retval = mFileSpec.IsChildOf(FILESPEC(possibleParent));
+ return mFileSpec.Error();
+}
+//----------------------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetURLString(char * *aURLString)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(aURLString)
+ if (mFileSpec.Failed())
+ return mFileSpec.Error();
+ nsFileURL url(mFileSpec);
+ *aURLString = nsCRT::strdup(url.GetURLString());
+ if (!*aURLString)
+ return NS_ERROR_OUT_OF_MEMORY;
+ return NS_OK;
+} // nsFileSpecImpl::GetURLString
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::SetURLString(const char * aURLString)
+//----------------------------------------------------------------------------------------
+{
+ mFileSpec = nsFileURL(aURLString);
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetUnixStyleFilePath(char * *aUnixStyleFilePath)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(aUnixStyleFilePath)
+ if (mFileSpec.Failed())
+ return mFileSpec.Error();
+ nsFilePath path(mFileSpec);
+ *aUnixStyleFilePath = nsCRT::strdup((const char*) path);
+ if (!*aUnixStyleFilePath)
+ return NS_ERROR_OUT_OF_MEMORY;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::SetUnixStyleFilePath(const char * aUnixStyleFilePath)
+//----------------------------------------------------------------------------------------
+{
+ mFileSpec = nsFilePath(aUnixStyleFilePath);
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetPersistentDescriptorString(char * *aPersistentDescriptorString)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(aPersistentDescriptorString)
+ if (mFileSpec.Failed())
+ return mFileSpec.Error();
+ nsPersistentFileDescriptor desc(mFileSpec);
+ nsCAutoString data;
+ desc.GetData(data);
+ *aPersistentDescriptorString = ToNewCString(data);
+ if (!*aPersistentDescriptorString)
+ return NS_ERROR_OUT_OF_MEMORY;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::SetPersistentDescriptorString(const char * aPersistentDescriptorString)
+//----------------------------------------------------------------------------------------
+{
+ nsPersistentFileDescriptor desc(mFileSpec);
+ desc.SetData(nsDependentCString(aPersistentDescriptorString));
+ mFileSpec = desc;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetNativePath(char * *aNativePath)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(aNativePath)
+ if (mFileSpec.Failed())
+ return mFileSpec.Error();
+ *aNativePath = nsCRT::strdup(mFileSpec.GetNativePathCString());
+ if (!*aNativePath)
+ return NS_ERROR_OUT_OF_MEMORY;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::SetNativePath(const char * aNativePath)
+//----------------------------------------------------------------------------------------
+{
+ mFileSpec = aNativePath;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetUnicodePath(nsAString & aUnicodePath)
+//----------------------------------------------------------------------------------------
+{
+ nsCAutoString native;
+ native = mFileSpec.GetNativePathCString();
+ NS_CopyNativeToUnicode(native, aUnicodePath);
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::SetUnicodePath(const nsAString & aUnicodePath)
+//----------------------------------------------------------------------------------------
+{
+ nsCAutoString native;
+
+ NS_CopyUnicodeToNative(aUnicodePath, native);
+ mFileSpec = native.get();
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetNSPRPath(char * *aNSPRPath)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(aNSPRPath)
+ if (mFileSpec.Failed())
+ return mFileSpec.Error();
+ nsNSPRPath path(mFileSpec);
+ *aNSPRPath = nsCRT::strdup((const char*) path);
+ if (!*aNSPRPath)
+ return NS_ERROR_OUT_OF_MEMORY;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Error()
+//----------------------------------------------------------------------------------------
+{
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::IsValid(PRBool *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ *_retval = mFileSpec.Valid();
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Failed(PRBool *_retval)
+//----------------------------------------------------------------------------------------
+{
+ *_retval = mFileSpec.Failed();
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetLeafName(char * *aLeafName)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(aLeafName)
+ *aLeafName = mFileSpec.GetLeafName();
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::SetLeafName(const char * aLeafName)
+//----------------------------------------------------------------------------------------
+{
+ mFileSpec.SetLeafName(aLeafName);
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetParent(nsIFileSpec * *aParent)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(aParent)
+ nsFileSpec parent;
+ mFileSpec.GetParent(parent);
+ return MakeInterface(parent, aParent);
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::MakeUnique()
+//----------------------------------------------------------------------------------------
+{
+ mFileSpec.MakeUnique();
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::MakeUniqueWithSuggestedName(const char *suggestedName)
+//----------------------------------------------------------------------------------------
+{
+ mFileSpec.MakeUnique(suggestedName);
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetModDate(PRUint32 *aModDate)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(aModDate)
+ nsFileSpec::TimeStamp stamp;
+ mFileSpec.GetModDate(stamp);
+ *aModDate = stamp;
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::ModDateChanged(PRUint32 oldStamp, PRBool *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ *_retval = mFileSpec.ModDateChanged(oldStamp);
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::IsDirectory(PRBool *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ *_retval = mFileSpec.IsDirectory();
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::IsFile(PRBool *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ *_retval = mFileSpec.IsFile();
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Exists(PRBool *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ *_retval = mFileSpec.Exists();
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::IsHidden(PRBool *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ *_retval = mFileSpec.IsHidden();
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::IsSymlink(PRBool *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ *_retval = mFileSpec.IsSymlink();
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::ResolveSymlink()
+//----------------------------------------------------------------------------------------
+{
+ PRBool ignore;
+ return mFileSpec.ResolveSymlink(ignore);
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetFileSize(PRUint32 *aFileSize)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(aFileSize)
+ *aFileSize = mFileSpec.GetFileSize();
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetDiskSpaceAvailable(PRInt64 *aDiskSpaceAvailable)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(aDiskSpaceAvailable)
+ *aDiskSpaceAvailable = mFileSpec.GetDiskSpaceAvailable();
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::AppendRelativeUnixPath(const char *relativePath)
+//----------------------------------------------------------------------------------------
+{
+ mFileSpec += relativePath;
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Touch()
+//----------------------------------------------------------------------------------------
+{
+ // create an empty file, like the UNIX touch command.
+ nsresult rv;
+ rv = OpenStreamForWriting();
+ if (NS_FAILED(rv)) return rv;
+ rv = CloseStream();
+ return rv;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::CreateDir()
+//----------------------------------------------------------------------------------------
+{
+ mFileSpec.CreateDir();
+ return mFileSpec.Error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Delete(PRBool aRecursive)
+//----------------------------------------------------------------------------------------
+{
+ mFileSpec.Delete(aRecursive);
+ return mFileSpec.Error();
+}
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Truncate(PRInt32 aNewLength)
+//----------------------------------------------------------------------------------------
+{
+ return mFileSpec.Truncate(aNewLength);
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Rename(const char *newLeafName)
+//----------------------------------------------------------------------------------------
+{
+ return mFileSpec.Rename(newLeafName);
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::CopyToDir(const nsIFileSpec *newParentDir)
+//----------------------------------------------------------------------------------------
+{
+ return mFileSpec.CopyToDir(FILESPEC(newParentDir));
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::MoveToDir(const nsIFileSpec *newParentDir)
+//----------------------------------------------------------------------------------------
+{
+ return mFileSpec.MoveToDir(FILESPEC(newParentDir));
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Execute(const char *args)
+//----------------------------------------------------------------------------------------
+{
+ return mFileSpec.Execute(args);
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::OpenStreamForReading()
+//----------------------------------------------------------------------------------------
+{
+ if (mInputStream || mOutputStream)
+ return NS_ERROR_FAILURE;
+ return NS_NewTypicalInputFileStream((nsISupports**)&mInputStream, mFileSpec);
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::OpenStreamForWriting()
+//----------------------------------------------------------------------------------------
+{
+ if (mInputStream || mOutputStream)
+ return NS_ERROR_FAILURE;
+ return NS_NewTypicalOutputFileStream((nsISupports**)&mOutputStream, mFileSpec);
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::OpenStreamForReadingAndWriting()
+//----------------------------------------------------------------------------------------
+{
+ if (mInputStream || mOutputStream)
+ return NS_ERROR_FAILURE;
+ nsresult result = NS_NewTypicalInputFileStream((nsISupports**)&mInputStream, mFileSpec);
+ if (NS_SUCCEEDED(result))
+ result = NS_NewTypicalOutputFileStream((nsISupports**)&mOutputStream, mFileSpec);
+ return result;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::CloseStream()
+//----------------------------------------------------------------------------------------
+{
+ NS_IF_RELEASE(mInputStream);
+ NS_IF_RELEASE(mOutputStream);
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::IsStreamOpen(PRBool *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ *_retval = (mInputStream || mOutputStream);
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetInputStream(nsIInputStream** _retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ if (!mInputStream) {
+ nsresult rv = OpenStreamForReading();
+ if (NS_FAILED(rv)) return rv;
+ }
+ *_retval = mInputStream;
+ NS_IF_ADDREF(mInputStream);
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetOutputStream(nsIOutputStream** _retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ if (!mOutputStream) {
+ nsresult rv = OpenStreamForWriting();
+ if (NS_FAILED(rv)) return rv;
+ }
+ *_retval = mOutputStream;
+ NS_IF_ADDREF(mOutputStream);
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::SetFileContents(const char* inString)
+//----------------------------------------------------------------------------------------
+{
+ nsresult rv = OpenStreamForWriting();
+ if (NS_FAILED(rv)) return rv;
+ PRInt32 count;
+ rv = Write(inString, PL_strlen(inString), &count);
+ nsresult rv2 = CloseStream();
+ return NS_FAILED(rv) ? rv : rv2;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetFileContents(char** _retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ *_retval = nsnull;
+ nsresult rv = OpenStreamForReading();
+ if (NS_FAILED(rv)) return rv;
+ PRInt32 theSize;
+ rv = GetFileSize((PRUint32*)&theSize);
+ if (NS_SUCCEEDED(rv))
+ rv = Read(_retval, theSize, &theSize);
+ if (NS_SUCCEEDED(rv))
+ (*_retval)[theSize] = 0;
+ nsresult rv2 = CloseStream();
+ return NS_FAILED(rv) ? rv : rv2;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::GetFileSpec(nsFileSpec *aFileSpec)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(aFileSpec)
+ *aFileSpec = mFileSpec;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Equals(nsIFileSpec *spec, PRBool *result)
+//----------------------------------------------------------------------------------------
+{
+ nsresult rv;
+
+ if (!result || !spec) return NS_ERROR_NULL_POINTER;
+
+ nsFileSpec otherSpec;
+
+ rv = spec->GetFileSpec(&otherSpec);
+ if (NS_FAILED(rv)) return rv;
+
+ if (mFileSpec == otherSpec) {
+ *result = PR_TRUE;
+ }
+ else {
+ *result = PR_FALSE;
+ }
+
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::SetFromFileSpec(const nsFileSpec& aFileSpec)
+//----------------------------------------------------------------------------------------
+{
+ mFileSpec = aFileSpec;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Eof(PRBool *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ if (!mInputStream)
+ return NS_ERROR_NULL_POINTER;
+ nsInputFileStream s(mInputStream);
+ *_retval = s.eof();
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Read(char** buffer, PRInt32 requestedCount, PRInt32 *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ TEST_OUT_PTR(buffer)
+ if (!mInputStream) {
+ nsresult rv = OpenStreamForReading();
+ if (NS_FAILED(rv)) return rv;
+ }
+ if (!*buffer)
+ *buffer = (char*)PR_Malloc(requestedCount + 1);
+ if (!mInputStream)
+ return NS_ERROR_NULL_POINTER;
+ nsInputFileStream s(mInputStream);
+ *_retval = s.read(*buffer, requestedCount);
+ return s.error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::ReadLine(char** line, PRInt32 bufferSize, PRBool *wasTruncated)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(wasTruncated)
+ TEST_OUT_PTR(line)
+ if (!mInputStream) {
+ nsresult rv = OpenStreamForReading();
+ if (NS_FAILED(rv)) return rv;
+ }
+ if (!*line)
+ *line = (char*)PR_Malloc(bufferSize + 1);
+ if (!mInputStream)
+ return NS_ERROR_NULL_POINTER;
+ nsInputFileStream s(mInputStream);
+ *wasTruncated = !s.readline(*line, bufferSize);
+ return s.error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Write(const char * data, PRInt32 requestedCount, PRInt32 *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ //if (!mOutputStream)
+ // return NS_ERROR_NULL_POINTER;
+ if (!mOutputStream) {
+ nsresult rv = OpenStreamForWriting();
+ if (NS_FAILED(rv))
+ return rv;
+ }
+ nsOutputFileStream s(mOutputStream);
+ *_retval = s.write(data, requestedCount);
+ return s.error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Flush()
+//----------------------------------------------------------------------------------------
+{
+ if (!mOutputStream)
+ return NS_ERROR_NULL_POINTER;
+ nsOutputFileStream s(mOutputStream);
+ s.flush();
+ return s.error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Seek(PRInt32 offset)
+//----------------------------------------------------------------------------------------
+{
+ nsresult result = NS_OK;
+ if (mOutputStream)
+ {
+ nsOutputFileStream os(mOutputStream);
+ os.seek(offset);
+ result = os.error();
+ }
+ if (NS_SUCCEEDED(result) && mInputStream)
+ {
+ nsInputFileStream is(mInputStream);
+ is.seek(offset);
+ result = is.error();
+ }
+ return result;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Tell(PRInt32 *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ if (!mInputStream)
+ return NS_ERROR_NULL_POINTER;
+ nsInputFileStream s(mInputStream);
+ *_retval = s.tell();
+ return s.error();
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::EndLine()
+//----------------------------------------------------------------------------------------
+{
+ nsOutputFileStream s(mOutputStream);
+ s << nsEndl;
+ return s.error();
+}
+
+NS_IMPL_ISUPPORTS1(nsDirectoryIteratorImpl, nsIDirectoryIterator)
+
+//----------------------------------------------------------------------------------------
+nsDirectoryIteratorImpl::nsDirectoryIteratorImpl()
+//----------------------------------------------------------------------------------------
+ : mDirectoryIterator(nsnull)
+{
+}
+
+//----------------------------------------------------------------------------------------
+nsDirectoryIteratorImpl::~nsDirectoryIteratorImpl()
+//----------------------------------------------------------------------------------------
+{
+ delete mDirectoryIterator;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsDirectoryIteratorImpl::Init(nsIFileSpec *parent, PRBool resolveSymlink)
+//----------------------------------------------------------------------------------------
+{
+ delete mDirectoryIterator;
+ mDirectoryIterator = new nsDirectoryIterator(FILESPEC(parent), resolveSymlink);
+ if (!mDirectoryIterator)
+ return NS_ERROR_OUT_OF_MEMORY;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsDirectoryIteratorImpl::Exists(PRBool *_retval)
+//----------------------------------------------------------------------------------------
+{
+ TEST_OUT_PTR(_retval)
+ if (!mDirectoryIterator)
+ return NS_ERROR_NULL_POINTER;
+ *_retval = mDirectoryIterator->Exists();
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsDirectoryIteratorImpl::Next()
+//----------------------------------------------------------------------------------------
+{
+ if (!mDirectoryIterator)
+ return NS_ERROR_NULL_POINTER;
+ (*mDirectoryIterator)++;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsDirectoryIteratorImpl::GetCurrentSpec(nsIFileSpec * *aCurrentSpec)
+//----------------------------------------------------------------------------------------
+{
+ if (!mDirectoryIterator)
+ return NS_ERROR_NULL_POINTER;
+ return nsFileSpecImpl::MakeInterface(mDirectoryIterator->Spec(), aCurrentSpec);
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsDirectoryIteratorImpl::Create(nsISupports* outer, const nsIID& aIID, void* *aIFileSpec)
+//----------------------------------------------------------------------------------------
+{
+ if (aIFileSpec == NULL)
+ return NS_ERROR_NULL_POINTER;
+
+ nsDirectoryIteratorImpl* it = new nsDirectoryIteratorImpl;
+ if (!it)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ nsresult rv = it->QueryInterface(aIID, aIFileSpec);
+ if (NS_FAILED(rv))
+ {
+ delete it;
+ return rv;
+ }
+ return rv;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP nsFileSpecImpl::Create(nsISupports* outer, const nsIID& aIID, void* *aIFileSpec)
+//----------------------------------------------------------------------------------------
+{
+ if (aIFileSpec == NULL)
+ return NS_ERROR_NULL_POINTER;
+
+ nsFileSpecImpl* it = new nsFileSpecImpl;
+ if (!it)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ nsresult rv = it->QueryInterface(aIID, aIFileSpec);
+ if (NS_FAILED(rv))
+ {
+ delete it;
+ return rv;
+ }
+ return rv;
+}
+
+//----------------------------------------------------------------------------------------
+nsresult NS_NewFileSpecWithSpec(const nsFileSpec& aSrcFileSpec, nsIFileSpec **result)
+//----------------------------------------------------------------------------------------
+{
+ if (!result)
+ return NS_ERROR_NULL_POINTER;
+
+ return nsFileSpecImpl::MakeInterface(aSrcFileSpec, result);
+}
+
+//----------------------------------------------------------------------------------------
+nsresult NS_NewFileSpec(nsIFileSpec** result)
+//----------------------------------------------------------------------------------------
+{
+ return nsFileSpecImpl::Create(nsnull, NS_GET_IID(nsIFileSpec), (void**)result);
+}
+
+//----------------------------------------------------------------------------------------
+nsresult NS_NewFileSpecFromIFile(nsIFile *aFile, nsIFileSpec **result)
+//----------------------------------------------------------------------------------------
+{
+ nsresult rv = nsFileSpecImpl::Create(nsnull, NS_GET_IID(nsIFileSpec), (void**)result);
+ if (NS_FAILED(rv)) return rv;
+
+ nsCAutoString path;
+ rv = aFile->GetNativePath(path);
+ if (NS_FAILED(rv)) return rv;
+
+ rv = (*result)->SetNativePath(path.get());
+ if (NS_FAILED(rv))
+ NS_RELEASE(*result);
+ return rv;
+}
+
+//----------------------------------------------------------------------------------------
+nsresult NS_NewDirectoryIterator(nsIDirectoryIterator** result)
+//----------------------------------------------------------------------------------------
+{
+ return nsDirectoryIteratorImpl::Create(nsnull, NS_GET_IID(nsIDirectoryIterator), (void**)result);
+}
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecImpl.h b/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecImpl.h
new file mode 100644
index 00000000..811749cb
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecImpl.h
@@ -0,0 +1,116 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef _FILESPECIMPL_H_
+#define _FILESPECIMPL_H_
+
+#include "nscore.h"
+#include "nsIFileSpec.h"
+#include "nsFileSpec.h"
+
+//========================================================================================
+class NS_COM_OBSOLETE nsFileSpecImpl
+//========================================================================================
+ : public nsIFileSpec
+{
+
+ public:
+
+ NS_DECL_ISUPPORTS
+
+ NS_DECL_NSIFILESPEC
+
+ //----------------------
+ // COM Cruft
+ //----------------------
+
+ static NS_METHOD Create(nsISupports* outer, const nsIID& aIID, void* *aIFileSpec);
+
+ //----------------------
+ // Implementation
+ //----------------------
+
+ nsFileSpecImpl();
+ nsFileSpecImpl(const nsFileSpec& inSpec);
+ static nsresult MakeInterface(const nsFileSpec& inSpec, nsIFileSpec** outSpec);
+
+ //----------------------
+ // Data
+ //----------------------
+
+ nsFileSpec mFileSpec;
+ nsIInputStream* mInputStream;
+ nsIOutputStream* mOutputStream;
+
+private:
+ ~nsFileSpecImpl();
+}; // class nsFileSpecImpl
+
+//========================================================================================
+class NS_COM_OBSOLETE nsDirectoryIteratorImpl
+//========================================================================================
+ : public nsIDirectoryIterator
+{
+
+public:
+
+ nsDirectoryIteratorImpl();
+
+ NS_DECL_ISUPPORTS
+
+ NS_IMETHOD Init(nsIFileSpec *parent, PRBool resolveSymlink);
+
+ NS_IMETHOD Exists(PRBool *_retval);
+
+ NS_IMETHOD Next();
+
+ NS_IMETHOD GetCurrentSpec(nsIFileSpec * *aCurrentSpec);
+
+ //----------------------
+ // COM Cruft
+ //----------------------
+
+ static NS_METHOD Create(nsISupports* outer, const nsIID& aIID, void* *aIFileSpec);
+
+private:
+ ~nsDirectoryIteratorImpl();
+
+protected:
+ nsDirectoryIterator* mDirectoryIterator;
+}; // class nsDirectoryIteratorImpl
+
+#endif // _FILESPECIMPL_H_
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecMac.cpp b/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecMac.cpp
new file mode 100644
index 00000000..fd208fb7
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecMac.cpp
@@ -0,0 +1,1471 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// This file is included by nsFile.cp, and includes the Macintosh-specific
+// implementations.
+
+
+#include <string.h>
+
+#include "prtypes.h"
+#include "nscore.h"
+
+#include "FullPath.h"
+#include "FileCopy.h"
+#include "MoreFilesExtras.h"
+
+#include <Aliases.h>
+#include <Folders.h>
+#include <Math64.h>
+#include <TextUtils.h>
+#include <Processes.h>
+#include <limits.h> // ULONG_MAX
+
+#include "nsFileSpec.h"
+#include "nsEscape.h"
+#include "nsXPIDLString.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 FSSpecFromUnixPath(
+ const char * unixPath,
+ FSSpec& ioSpec,
+ Boolean hexDecode,
+ Boolean resolveAlias,
+ Boolean allowPartial = false,
+ Boolean createDirs = false);
+ char* MacPathFromUnixPath(
+ const char* unixPath,
+ Boolean hexDecode);
+ char* EncodeMacPath(
+ char* inPath, // NOT const - gets clobbered
+ Boolean prependSlash,
+ Boolean doEscape );
+ OSErr FSSpecFromPathname(
+ const char* inPathNamePtr,
+ FSSpec& ioSpec,
+ Boolean inCreateDirs);
+ char* PathNameFromFSSpec(
+ const FSSpec& inSpec );
+ 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)
+ {
+ 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, Boolean hexDecode)
+//----------------------------------------------------------------------------------------
+{
+ // 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
+ // REMEMBER: at the end we call SwapSlashColon, so bear that in mind when you see
+ // this code using '/' as a separator in what is supposed to be a Macintosh path!
+ if (result)
+ {
+ char* dst = result;
+ const char* src = unixPath;
+ if (*src == '/') // * full path
+ src++;
+ else if (strchr(src, '/') && *src != '.')
+ {
+ // * partial path, and not just a leaf name. The '.' test is there because
+ // the loop below will add sufficient colons in that case.
+ *dst++ = '/';
+ }
+ // Copy src to dst, but watch out for .. and .
+ char c = '/';
+ do
+ {
+ char cprev = c; // remember the previous char (initially /)
+ c = *src++;
+ if (c == '.' && cprev == '/')
+ {
+ char* dstSaved = dst;
+ // Special cases: "." and "..". Convert to ':' and '::'
+ *dst++ = '/'; // . becomes :
+ c = *src++;
+ if (c == '.')
+ {
+ *dst++ = '/'; // .. becomes ::
+ c = *src++;
+ }
+ if (c == '/')
+ {
+ // ../ becomes :: so just skip the slash
+ // ./ becomes : " " " " "
+ src++;
+ }
+ else if (c)
+ {
+ // Oh. A file called ".foo" or "..foo"
+ // Back up and just do the normal thing.
+ src -= (dst - dstSaved);
+ dst = dstSaved;
+ // Since c is not '/', we won't do this stuff on the
+ // next iteration.
+ }
+ continue;
+ }
+ else if (c == '/' && cprev == '/')
+ {
+ // Hmm. A 'run on' path with two slashes right next to each other.
+ // This is an illegal path, but, hey, we'll be tough and try to
+ // deal with it (especially since '::' has loaded semantics in
+ // a Mac path)
+ continue;
+ }
+ *dst++ = c;
+ } while (c);
+ if (hexDecode)
+ nsUnescape(result); // Hex Decode
+ MacFileHelpers::SwapSlashColon(result);
+ }
+ return result;
+} // MacFileHelpers::MacPathFromUnixPath
+
+//----------------------------------------------------------------------------------------
+OSErr MacFileHelpers::FSSpecFromPathname(
+ const char* inPathNamePtr,
+ FSSpec& ioSpec, // used as in-parameter for a relative path.
+ 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.
+
+ short inVRefNum = ioSpec.vRefNum;
+ long inParID = ioSpec.parID;
+
+ size_t inLength = strlen(inPathNamePtr);
+ bool isRelative = (strchr(inPathNamePtr, ':') == 0 || *inPathNamePtr == ':');
+#ifdef NS_DEBUG
+ // Attempt to catch people sending unix paths in to routines that expect native ones.
+ NS_ASSERTION(strchr(inPathNamePtr, '/') == 0,
+ "Possible unix path where native path is required");
+#endif
+ if (inLength < 255)
+ {
+ Str255 pascalpath;
+ MacFileHelpers::PLstrcpy(pascalpath, inPathNamePtr);
+ if (isRelative)
+ err = ::FSMakeFSSpec(inVRefNum, inParID, pascalpath, &ioSpec);
+ else
+ err = ::FSMakeFSSpec(0, 0, pascalpath, &ioSpec);
+ }
+ else if (!isRelative)
+ err = FSpLocationFromFullPath(inLength, inPathNamePtr, &ioSpec);
+ else
+ err = bdNamErr;
+
+ if ((err == dirNFErr || err == bdNamErr) && inCreateDirs)
+ {
+ const char* path = inPathNamePtr;
+ if (isRelative)
+ {
+ ioSpec.vRefNum = inVRefNum;
+ ioSpec.parID = inParID;
+ }
+ else
+ {
+ ioSpec.vRefNum = 0;
+ ioSpec.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(ioSpec.vRefNum, ioSpec.parID, ppath, &ioSpec);
+
+ // If this was the leaf node, then we are done.
+ if (!*nextColon)
+ break;
+
+ // Since there's more to go, we have to get the directory ID, which becomes
+ // the parID for the next round.
+ if (err == noErr)
+ {
+ // The directory (or perhaps a file) exists. Find its dirID.
+ long dirID;
+ Boolean isDirectory;
+ err = ::FSpGetDirectoryID(&ioSpec, &dirID, &isDirectory);
+ if (!isDirectory)
+ return dupFNErr; // oops! a file exists with that name.
+ if (err)
+ return err;
+ ioSpec.parID = dirID;
+ }
+ else if (err == fnfErr)
+ {
+ // If we got "file not found", then
+ // we need to create a directory.
+ err = ::FSpDirCreate(&ioSpec, smCurrentScript, &ioSpec.parID);
+ // For some reason, this usually returns fnfErr, even though it works.
+ if (err == fnfErr)
+ err = noErr;
+ }
+ if (err != noErr)
+ 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::FSSpecFromUnixPath(
+ const char * unixPath,
+ FSSpec& ioSpec,
+ Boolean hexDecode,
+ 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, hexDecode);
+ if (!macPath)
+ return memFullErr;
+
+ OSErr err = noErr;
+ if (!allowPartial)
+ {
+ NS_ASSERTION(*unixPath == '/' /*full path*/, "Not a full Unix path!");
+ }
+ err = FSSpecFromPathname(macPath, ioSpec, createDirs);
+ if (err == fnfErr)
+ err = noErr;
+ Boolean dummy;
+ if (err == noErr && resolveAlias) // Added
+ err = MacFileHelpers::ResolveAliasFile(ioSpec, 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 )
+// Returns a full pathname to the given file
+// Returned value is allocated with new [], and must be freed with delete []
+// For consistency and to work under OS X this creates an nsILocalFileMac and has it do the work.
+//-----------------------------------
+{
+ char* result = nil;
+ nsresult rv;
+
+ FSSpec nonConstSpec = inSpec;
+ nsCAutoString path;
+ nsCOMPtr<nsILocalFileMac> macFile;
+
+ rv = NS_NewLocalFileWithFSSpec(&nonConstSpec, PR_TRUE, getter_AddRefs(macFile));
+ if (NS_FAILED(rv)) return nsnull;
+ nsCOMPtr<nsILocalFile> localFile(do_QueryInterface(macFile, &rv));
+ if (NS_FAILED(rv)) return nsnull;
+ rv = localFile->GetNativePath(path);
+ if (NS_FAILED(rv)) return nsnull;
+ PRInt32 strLen = path.Length();
+ result = new char [strLen + 1];
+ if (!result) return nsnull;
+ memcpy(result, path.get(), strLen);
+ result[ strLen ] = 0;
+
+ return result;
+} // MacFileHelpers::PathNameFromFSSpec
+
+
+#pragma mark -
+
+//========================================================================================
+// Macintosh nsFileSpec implementation
+//========================================================================================
+
+//----------------------------------------------------------------------------------------
+nsFileSpec::nsFileSpec()
+//----------------------------------------------------------------------------------------
+{
+// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!");
+ Clear();
+}
+
+//----------------------------------------------------------------------------------------
+nsFileSpec::nsFileSpec(const FSSpec& inSpec, PRBool resolveAlias)
+//----------------------------------------------------------------------------------------
+: mSpec(inSpec)
+, mError(NS_OK)
+{
+// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!");
+ if (resolveAlias)
+ {
+ PRBool dummy;
+ ResolveSymlink(dummy);
+ }
+}
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::operator = (const FSSpec& inSpec)
+//----------------------------------------------------------------------------------------
+{
+ mSpec = inSpec;
+ mError = NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+nsFileSpec::nsFileSpec(const nsFileSpec& inSpec)
+//----------------------------------------------------------------------------------------
+: mSpec(inSpec.mSpec)
+, mError(inSpec.Error())
+{
+// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!");
+}
+
+//----------------------------------------------------------------------------------------
+nsFileSpec::nsFileSpec(const char* inNativePathString, PRBool inCreateDirs)
+//----------------------------------------------------------------------------------------
+{
+// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!");
+ Clear(); // this sets mError to NS_ERROR_NOT_INITIALIZED
+
+ if (inNativePathString)
+ {
+ mError = NS_FILE_RESULT(MacFileHelpers::FSSpecFromPathname(
+ inNativePathString, mSpec, inCreateDirs));
+ if (mError == NS_FILE_RESULT(fnfErr))
+ mError = NS_OK;
+ }
+
+} // nsFileSpec::nsFileSpec
+
+//----------------------------------------------------------------------------------------
+nsFileSpec::nsFileSpec(const nsString& inNativePathString, PRBool inCreateDirs)
+//----------------------------------------------------------------------------------------
+{
+// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!");
+ Clear(); // this sets mError to NS_ERROR_NOT_INITIALIZED
+
+ mError = NS_FILE_RESULT(
+ MacFileHelpers::FSSpecFromPathname(
+ NS_LossyConvertUCS2toASCII(inNativePathString).get(),
+ mSpec, inCreateDirs));
+ if (mError == NS_FILE_RESULT(fnfErr))
+ mError = NS_OK;
+
+} // nsFileSpec::nsFileSpec
+
+//----------------------------------------------------------------------------------------
+nsFileSpec::nsFileSpec(short vRefNum, long parID, ConstStr255Param fileName, PRBool resolveAlias)
+//----------------------------------------------------------------------------------------
+{
+// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!");
+ mError = NS_FILE_RESULT(::FSMakeFSSpec(vRefNum, parID, fileName, &mSpec));
+ if (mError == NS_FILE_RESULT(fnfErr))
+ mError = NS_OK;
+
+ if (resolveAlias)
+ {
+ PRBool dummy;
+ ResolveSymlink(dummy);
+ }
+}
+
+//----------------------------------------------------------------------------------------
+nsFileSpec::nsFileSpec(const nsFilePath& inPath)
+//----------------------------------------------------------------------------------------
+{
+// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!");
+ *this = inPath.GetFileSpec();
+}
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::operator = (const char* inString)
+//----------------------------------------------------------------------------------------
+{
+ Clear(); // this sets mError to NS_ERROR_NOT_INITIALIZED
+
+ if (inString)
+ {
+ mError = NS_FILE_RESULT(MacFileHelpers::FSSpecFromPathname(inString, mSpec, true));
+ if (mError == NS_FILE_RESULT(fnfErr))
+ mError = NS_OK;
+ }
+
+} // nsFileSpec::operator =
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::operator = (const nsFileSpec& inSpec)
+//----------------------------------------------------------------------------------------
+{
+ mPath.SetToEmpty();
+ mSpec.vRefNum = inSpec.mSpec.vRefNum;
+ mSpec.parID = inSpec.mSpec.parID;
+
+ PRInt32 copySize = inSpec.mSpec.name[0] + 1;
+ if (copySize > sizeof(inSpec.mSpec.name))
+ copySize = sizeof(inSpec.mSpec.name);
+ memcpy(mSpec.name, inSpec.mSpec.name, copySize);
+ mError = inSpec.Error(); // note that the error is propagated
+} // nsFileSpec::operator =
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::operator = (const nsFilePath& inPath)
+//----------------------------------------------------------------------------------------
+{
+ *this = inPath.GetFileSpec();
+} // nsFileSpec::operator =
+
+//----------------------------------------------------------------------------------------
+inline void nsFileSpec::Clear()
+//----------------------------------------------------------------------------------------
+{
+ mPath.SetToEmpty();
+ mSpec.vRefNum = 0;
+ mSpec.parID = 0;
+ mSpec.name[0] = 0;
+ mError = NS_ERROR_NOT_INITIALIZED;
+}
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::Exists() const
+//----------------------------------------------------------------------------------------
+{
+ if (NS_FAILED(mError)) return PR_FALSE;
+ FSSpec temp;
+ return ::FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, mSpec.name, &temp) == noErr;
+} // nsFileSpec::Exists()
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::GetModDate(TimeStamp& outStamp) const
+//----------------------------------------------------------------------------------------
+{
+ CInfoPBRec pb;
+ if (GetCatInfo(pb) == noErr)
+ outStamp = ((DirInfo*)&pb)->ioDrMdDat; // The mod date is in the same spot for files and dirs.
+ else
+ outStamp = 0;
+} // nsFileSpec::GetModDate
+
+//----------------------------------------------------------------------------------------
+PRUint32 nsFileSpec::GetFileSize() const
+//----------------------------------------------------------------------------------------
+{
+ CInfoPBRec pb;
+ if (noErr == GetCatInfo(pb))
+ return (PRUint32)((HFileInfo*)&pb)->ioFlLgLen;
+ return 0;
+} // nsFileSpec::GetFileSize
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::SetLeafName(const char* inLeafName)
+// In leaf name can actually be a partial path...
+//----------------------------------------------------------------------------------------
+{
+ NS_ASSERTION(inLeafName, "Attempt to set leaf name with a null string");
+
+ mPath.SetToEmpty();
+
+ if (inLeafName)
+ {
+ // what about long relative paths? Hmm? We don't have a routine for this anywhere.
+ Str255 partialPath;
+ MacFileHelpers::PLstrcpy(partialPath, inLeafName);
+ mError = NS_FILE_RESULT(
+ ::FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, partialPath, &mSpec));
+ if (mError == NS_FILE_RESULT(fnfErr))
+ mError = NS_OK;
+ }
+
+} // nsFileSpec::SetLeafName
+
+//----------------------------------------------------------------------------------------
+char* nsFileSpec::GetLeafName() const
+// Result needs to be nsCRT::free()ed.
+//----------------------------------------------------------------------------------------
+{
+ char leaf[sizeof(mSpec.name)];
+ memcpy(leaf, &mSpec.name[1], mSpec.name[0]);
+ leaf[mSpec.name[0]] = '\0';
+ return nsCRT::strdup(leaf);
+} // nsFileSpec::GetLeafName
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::MakeAliasSafe()
+//----------------------------------------------------------------------------------------
+{
+ mPath.SetToEmpty();
+ mError = NS_FILE_RESULT(MacFileHelpers::MakeAliasSafe(mSpec));
+} // nsFileSpec::MakeAliasSafe
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::MakeUnique(ConstStr255Param inSuggestedLeafName)
+//----------------------------------------------------------------------------------------
+{
+ mPath.SetToEmpty();
+ if (inSuggestedLeafName[0] > 0)
+ MacFileHelpers::PLstrcpy(mSpec.name, inSuggestedLeafName);
+
+ MakeUnique();
+} // nsFileSpec::MakeUnique
+
+//----------------------------------------------------------------------------------------
+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
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::IsHidden() const
+//----------------------------------------------------------------------------------------
+{
+ CInfoPBRec cInfo;
+ PRBool hidden = PR_FALSE;
+
+ if (noErr == GetCatInfo(cInfo))
+ if (cInfo.hFileInfo.ioFlFndrInfo.fdFlags & kIsInvisible)
+ hidden = PR_TRUE;
+
+ return hidden;
+} // nsFileSpec::IsHidden
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::IsSymlink() const
+//----------------------------------------------------------------------------------------
+{
+ CInfoPBRec cInfo;
+ PRBool hidden = PR_FALSE;
+
+ if (noErr == GetCatInfo(cInfo))
+ if (cInfo.hFileInfo.ioFlFndrInfo.fdFlags & kIsAlias)
+ hidden = PR_TRUE;
+
+ return hidden;
+} // nsFileSpec::IsSymlink
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::ResolveSymlink(PRBool& wasAliased)
+//----------------------------------------------------------------------------------------
+{
+ Boolean wasAliased2; // Type conversion Boolean <--> PRBool
+ OSErr err = MacFileHelpers::ResolveAliasFile(mSpec, wasAliased2);
+ if (wasAliased2)
+ {
+ mError = NS_FILE_RESULT(err);
+ wasAliased = PR_TRUE;
+ }
+ else
+ wasAliased = PR_FALSE;
+
+ return mError;
+} // nsFileSpec::ResolveSymlink
+
+//----------------------------------------------------------------------------------------
+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)
+//----------------------------------------------------------------------------------------
+{
+ NS_ASSERTION(inRelativePath, "Attempt to append relative path with null path");
+
+ // Invalidate the path cache string, since we're changing ourselves.
+ mPath.SetToEmpty();
+
+ // if we are already bad, don't allow appendage
+ if (NS_FAILED(Error()))
+ {
+ NS_WARNING("trying to append to a bad nsFileSpec");
+ return;
+ }
+
+ // Find the dirID of the directory described by this spec
+ long dirID;
+ Boolean isDirectory;
+ mError = NS_FILE_RESULT(::FSpGetDirectoryID(&mSpec, &dirID, &isDirectory));
+ if (NS_FAILED(mError) || !isDirectory || !inRelativePath)
+ return;
+ // mSpec.vRefNum is already correct.
+ mSpec.parID = dirID;
+
+ // Next, determine if it is a UNIX or Mac style path. Now, Macintosh relative paths
+ // are either leaf names (in which the distinction between unix and macintosh
+ // relative paths disappears) or they start with a colon. If we find an initial colon,
+ // then assume it's a macintosh path.
+ // If it is a UNIX path (including just a leaf name), we will also look for ':' and
+ // assert if we find one.
+ if (*inRelativePath != ':')
+ {
+ // Looks like a UNIX path (including possibly just a leaf name)
+ NS_ASSERTION(strchr(inRelativePath, ':') == nsnull, "Can not determine path type");
+ // Convert unix path (which is unencoded) to a spec
+ mError = NS_FILE_RESULT(
+ MacFileHelpers::FSSpecFromUnixPath(inRelativePath, mSpec, false, false, true, true));
+ }
+ else
+ {
+ // We must be a mac path!
+ mError = NS_FILE_RESULT(MacFileHelpers::FSSpecFromPathname(inRelativePath, mSpec, true));
+ }
+ if (mError == NS_FILE_RESULT(fnfErr))
+ mError = NS_OK;
+
+} // nsFileSpec::operator +=
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::CreateDirectory(int /* unix mode */)
+//----------------------------------------------------------------------------------------
+{
+ long ignoredDirID;
+ OSErr err = ::FSpDirCreate(&mSpec, smCurrentScript, &ignoredDirID);
+ // it's OK if the dir already exists
+ if (err != noErr && IsDirectory())
+ err = noErr;
+
+ mError = NS_FILE_RESULT(err);
+
+} // nsFileSpec::CreateDirectory
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::Delete(PRBool inRecursive) const
+//----------------------------------------------------------------------------------------
+{
+ OSErr anErr;
+
+ nsresult& mutableError = const_cast<nsFileSpec*>(this)->mError;
+ if (inRecursive)
+ {
+ // MoreFilesExtras
+ anErr = ::DeleteDirectory(
+ mSpec.vRefNum,
+ mSpec.parID,
+ const_cast<unsigned char*>(mSpec.name));
+ }
+ else
+ anErr = ::FSpDelete(&mSpec);
+
+ if (anErr == fnfErr) // deleting a file that doesn't exist isn't an error!
+ anErr = noErr;
+
+ mutableError = NS_FILE_RESULT(anErr);
+
+} // nsFileSpec::Delete
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::RecursiveCopy(nsFileSpec newDir) const
+//----------------------------------------------------------------------------------------
+{
+ if (IsDirectory())
+ {
+ if (!(newDir.Exists()))
+ {
+ newDir.CreateDirectory();
+ }
+
+ for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++)
+ {
+ nsFileSpec& child = (nsFileSpec&)i;
+
+ if (child.IsDirectory())
+ {
+ nsFileSpec tmpDirSpec(newDir);
+
+ char *leafname = child.GetLeafName();
+ tmpDirSpec += leafname;
+ nsCRT::free(leafname);
+
+ child.RecursiveCopy(tmpDirSpec);
+ }
+ else
+ {
+ child.RecursiveCopy(newDir);
+ }
+ }
+ }
+ else
+ {
+ nsFileSpec& filePath = (nsFileSpec&) *this;
+
+ if (!(newDir.Exists()))
+ {
+ newDir.CreateDirectory();
+ }
+
+ filePath.CopyToDir(newDir);
+ }
+} // nsFileSpec::RecursiveCopy
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::Truncate(PRInt32 aNewLength) const
+//----------------------------------------------------------------------------------------
+{
+ short refNum;
+ OSErr err;
+
+ // First see if we have an internal error set
+ if (NS_FAILED(mError))
+ return mError;
+
+ // Need to open the file to trunc
+ if (::FSpOpenDF(&mSpec, fsWrPerm, &refNum) != noErr)
+ return NS_FILE_FAILURE;
+
+ err = ::SetEOF(refNum, aNewLength);
+
+ // Close the file unless we got an error that it was already closed
+ if (err != fnOpnErr)
+ (void)::FSClose(refNum);
+
+ if (err != noErr)
+ return NS_FILE_FAILURE;
+
+ return NS_OK;
+} // nsFileSpec::Truncate
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::Rename(const char* inNewName)
+//----------------------------------------------------------------------------------------
+{
+ NS_ASSERTION(inNewName, "Attempt to rename with null new name");
+
+ if (strchr(inNewName, '/'))
+ return NS_FILE_FAILURE; // no relative paths here!
+
+ Str255 pName;
+ MacFileHelpers::PLstrcpy(pName, inNewName);
+ if (::FSpRename(&mSpec, pName) != noErr)
+ return NS_FILE_FAILURE;
+ SetLeafName(inNewName);
+ return NS_OK;
+} // nsFileSpec::Rename
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::CopyToDir(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 rv = NS_FILE_RESULT(::FSpFileCopy(&mSpec,
+ &newParentDir.mSpec,
+ const_cast<StringPtr>(GetLeafPName()),
+ nsnull,
+ 0,
+ true));
+
+ return rv;
+
+} // nsFileSpec::CopyToDir
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::MoveToDir(const nsFileSpec& newParentDir)
+//----------------------------------------------------------------------------------------
+{
+ // 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())));
+
+ if ( NS_SUCCEEDED(result) )
+ {
+ char* leafName = GetLeafName();
+ *this = newParentDir + leafName;
+ nsCRT::free(leafName);
+ }
+ return result;
+} // nsFileSpec::MoveToDir
+
+//----------------------------------------------------------------------------------------
+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
+
+//----------------------------------------------------------------------------------------
+OSErr nsFileSpec::GetCatInfo(CInfoPBRec& outInfo) const
+//----------------------------------------------------------------------------------------
+{
+ DirInfo *dipb=(DirInfo *)&outInfo;
+ dipb->ioCompletion = nsnull;
+ dipb->ioFDirIndex = 0; // use dirID and name
+ dipb->ioVRefNum = mSpec.vRefNum;
+ dipb->ioDrDirID = mSpec.parID;
+ dipb->ioNamePtr = const_cast<nsFileSpec*>(this)->mSpec.name;
+ return PBGetCatInfoSync(&outInfo);
+} // nsFileSpec::GetCatInfo()
+
+//----------------------------------------------------------------------------------------
+OSErr nsFileSpec::SetFileTypeAndCreator(OSType type, OSType creator)
+//----------------------------------------------------------------------------------------
+{
+ FInfo info;
+ OSErr err = ::FSpGetFInfo(&mSpec, &info);
+ if (err != noErr)
+ return err;
+ info.fdType = type;
+ info.fdCreator = creator;
+ err = ::FSpSetFInfo(&mSpec, &info);
+ return err;
+}
+
+//----------------------------------------------------------------------------------------
+OSErr nsFileSpec::GetFileTypeAndCreator(OSType* type, OSType* creator)
+//----------------------------------------------------------------------------------------
+{
+ FInfo info;
+ OSErr err = ::FSpGetFInfo(&mSpec, &info);
+ if (err != noErr)
+ return err;
+ *type = info.fdType;
+ *creator = info.fdCreator;
+ return noErr;
+}
+
+//----------------------------------------------------------------------------------------
+PRInt64 nsFileSpec::GetDiskSpaceAvailable() const
+//----------------------------------------------------------------------------------------
+{
+ PRInt64 space64Bits;
+
+ LL_I2L(space64Bits , LONG_MAX);
+
+ XVolumeParam pb;
+ pb.ioCompletion = nsnull;
+ pb.ioVolIndex = 0;
+ pb.ioNamePtr = nsnull;
+ pb.ioVRefNum = mSpec.vRefNum;
+
+ // PBXGetVolInfoSync works on HFS+ volumes too!
+ OSErr err = ::PBXGetVolInfoSync(&pb);
+
+ if (err == noErr)
+ {
+#ifdef HAVE_LONG_LONG
+ space64Bits = pb.ioVFreeBytes;
+#else
+ const UnsignedWide& freeBytes = UInt64ToUnsignedWide(pb.ioVFreeBytes);
+ space64Bits.lo = freeBytes.lo;
+ space64Bits.hi = freeBytes.hi;
+#endif
+ }
+
+ return space64Bits;
+} // nsFileSpec::GetDiskSpace()
+
+//----------------------------------------------------------------------------------------
+const char* nsFileSpec::GetCString() const
+// This is the only conversion to const char* that is provided, and it allows the
+// path to be "passed" to NSPR file routines. This practice is VERY EVIL and should only
+// be used to support legacy code. Using it guarantees bugs on Macintosh. The string is
+// cached and freed by the nsFileSpec destructor, so do not delete (or free) it.
+//----------------------------------------------------------------------------------------
+{
+ if (mPath.IsEmpty())
+ {
+ char* path = MacFileHelpers::PathNameFromFSSpec(mSpec);
+ if (path != NULL) {
+ const_cast<nsFileSpec*>(this)->mPath = path; // operator =() copies the string!!!
+ delete[] path;
+ } else {
+ const_cast<nsFileSpec*>(this)->mError = NS_ERROR_OUT_OF_MEMORY;
+ }
+ }
+ return mPath;
+}
+
+#pragma mark -
+
+//========================================================================================
+// Macintosh nsFilePath implementation
+//========================================================================================
+
+//----------------------------------------------------------------------------------------
+static void AssignFromPath(nsFilePath& ioPath, const char* inString, PRBool inCreateDirs)
+//----------------------------------------------------------------------------------------
+{
+ NS_ASSERTION(inString, "AssignFromPath called with null inString");
+ NS_ASSERTION(strstr(inString, kFileURLPrefix) != inString, "URL passed as path");
+
+ FSSpec spec;
+ spec.vRefNum = 0;
+ spec.parID = 0;
+ spec.name[0] = 0;
+ MacFileHelpers::FSSpecFromUnixPath(
+ inString,
+ spec,
+ false,
+ true, // resolve alias
+ true,
+ inCreateDirs);
+ // Now we have a spec,
+ // Invoke operator = (const nsFileSpec&) to do the rest.
+ // Why didn't we just say mPath = inString to get the path? Well, we want it to be
+ // canonical and absolute.
+ ioPath = spec;
+}
+
+//----------------------------------------------------------------------------------------
+nsFilePath::nsFilePath(const char* inString, PRBool inCreateDirs)
+//----------------------------------------------------------------------------------------
+{
+ AssignFromPath(*this, inString, inCreateDirs);
+} //nsFilePath::nsFilePath
+
+//----------------------------------------------------------------------------------------
+nsFilePath::nsFilePath(const nsString& inString, PRBool inCreateDirs)
+//----------------------------------------------------------------------------------------
+{
+ AssignFromPath(*this, NS_LossyConvertUCS2toASCII(inString).get(),
+ inCreateDirs);
+}
+
+//----------------------------------------------------------------------------------------
+void nsFilePath::operator = (const char* inString)
+//----------------------------------------------------------------------------------------
+{
+ AssignFromPath(*this, inString, PR_FALSE);
+}
+
+//----------------------------------------------------------------------------------------
+nsFilePath::nsFilePath(const nsFileSpec& inSpec)
+//----------------------------------------------------------------------------------------
+{
+ *this = inSpec;
+}
+
+//----------------------------------------------------------------------------------------
+nsFilePath::nsFilePath(const nsFileURL& inOther)
+//----------------------------------------------------------------------------------------
+{
+ *this = inOther;
+}
+
+//----------------------------------------------------------------------------------------
+void nsFilePath::operator = (const nsFileSpec& inSpec)
+//----------------------------------------------------------------------------------------
+{
+ char * path = MacFileHelpers::PathNameFromFSSpec(inSpec);
+ path = MacFileHelpers::EncodeMacPath(path, true, false);
+ mPath = path;
+ nsCRT::free(path);
+ mFileSpec = inSpec;
+} // nsFilePath::operator =
+
+//----------------------------------------------------------------------------------------
+void nsFilePath::operator = (const nsFileURL& inOther)
+//----------------------------------------------------------------------------------------
+{
+ char * path = MacFileHelpers::PathNameFromFSSpec(inOther.mFileSpec);
+ path = MacFileHelpers::EncodeMacPath(path, true, false);
+ mPath = path;
+ nsCRT::free(path);
+ mFileSpec = inOther.GetFileSpec();
+}
+
+#pragma mark -
+
+//========================================================================================
+// nsFileURL implementation
+//========================================================================================
+
+//----------------------------------------------------------------------------------------
+nsFileURL::nsFileURL(const char* inString, PRBool inCreateDirs)
+//----------------------------------------------------------------------------------------
+: mURL(inString)
+{
+ NS_ASSERTION(inString, "nsFileURL constructed with null inString");
+ NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!");
+ mFileSpec.mError = NS_FILE_RESULT(MacFileHelpers::FSSpecFromUnixPath(
+ inString + kFileURLPrefixLength,
+ mFileSpec.mSpec,
+ true, // need to decode
+ false, // resolve alias
+ false, // must be a full path
+ inCreateDirs));
+ if (mFileSpec.mError == NS_FILE_RESULT(fnfErr))
+ mFileSpec.mError = NS_OK;
+} // nsFileURL::nsFileURL
+
+//----------------------------------------------------------------------------------------
+nsFileURL::nsFileURL(const nsString& inString, PRBool inCreateDirs)
+//----------------------------------------------------------------------------------------
+: mURL(nsnull)
+{
+ NS_LossyConvertUCS2toASCII cstring(inString);
+ mURL = cstring.get();
+ NS_ASSERTION(strstr(cstring.get(), kFileURLPrefix) == cstring.get(),
+ "Not a URL!");
+ mFileSpec.mError = NS_FILE_RESULT(MacFileHelpers::FSSpecFromUnixPath(
+ cstring.get() + kFileURLPrefixLength,
+ mFileSpec.mSpec,
+ true, // need to decode
+ false, // resolve alias
+ false, // must be a full path
+ inCreateDirs));
+ if (mFileSpec.mError == NS_FILE_RESULT(fnfErr))
+ mFileSpec.mError = NS_OK;
+} // nsFileURL::nsFileURL
+
+//----------------------------------------------------------------------------------------
+nsFileURL::nsFileURL(const nsFilePath& inOther)
+//----------------------------------------------------------------------------------------
+{
+ *this = inOther.GetFileSpec();
+} // nsFileURL::nsFileURL
+
+//----------------------------------------------------------------------------------------
+nsFileURL::nsFileURL(const nsFileSpec& inOther)
+//----------------------------------------------------------------------------------------
+{
+ *this = inOther;
+} // nsFileURL::nsFileURL
+
+//----------------------------------------------------------------------------------------
+void nsFileURL::operator = (const nsFilePath& inOther)
+//----------------------------------------------------------------------------------------
+{
+ *this = inOther.GetFileSpec();
+} // nsFileURL::operator =
+
+//----------------------------------------------------------------------------------------
+void nsFileURL::operator = (const nsFileSpec& inOther)
+//----------------------------------------------------------------------------------------
+{
+ mFileSpec = inOther;
+ char* path = MacFileHelpers::PathNameFromFSSpec( mFileSpec );
+ char* encodedPath = MacFileHelpers::EncodeMacPath(path, true, true);
+ nsSimpleCharString encodedURL(kFileURLPrefix);
+ encodedURL += encodedPath;
+ nsCRT::free(encodedPath);
+ mURL = encodedURL;
+ if (encodedURL[encodedURL.Length() - 1] != '/' && inOther.IsDirectory())
+ mURL += "/";
+} // nsFileURL::operator =
+
+//----------------------------------------------------------------------------------------
+void nsFileURL::operator = (const char* inString)
+//----------------------------------------------------------------------------------------
+{
+ NS_ASSERTION(inString, "nsFileURL operator= constructed with null inString");
+
+ mURL = inString;
+ NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!");
+ mFileSpec.mError = NS_FILE_RESULT(MacFileHelpers::FSSpecFromUnixPath(
+ inString + kFileURLPrefixLength,
+ mFileSpec.mSpec,
+ true, // need to decode
+ true, // resolve alias
+ false, // must be a full path
+ false)); // don't create dirs.
+ if (mFileSpec.mError == NS_FILE_RESULT(fnfErr))
+ mFileSpec.mError = NS_OK;
+} // nsFileURL::operator =
+
+#pragma mark -
+
+//========================================================================================
+// nsDirectoryIterator
+//========================================================================================
+
+//----------------------------------------------------------------------------------------
+nsDirectoryIterator::nsDirectoryIterator(
+ const nsFileSpec& inDirectory
+, PRBool resolveSymLinks)
+//----------------------------------------------------------------------------------------
+ : mCurrent(inDirectory)
+ , mExists(false)
+ , mResoveSymLinks(resolveSymLinks)
+ , mIndex(-1)
+{
+ CInfoPBRec pb;
+ OSErr err = inDirectory.GetCatInfo(pb);
+
+ // test that we have got a directory back, not a file
+ DirInfo* dipb = (DirInfo*)&pb;
+ 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&();
+ mVRefNum = currentSpec.vRefNum;
+ mParID = dipb->ioDrDirID;
+ mMaxIndex = pb.dirInfo.ioDrNmFls;
+ mIndex = 0; // ready to increment
+ ++(*this); // the pre-increment 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 = mVRefNum; /* Might need to use vRefNum, not sure*/
+ dipb->ioDrDirID = mParID;
+ dipb->ioNamePtr = objectName;
+ OSErr err = PBGetCatInfoSync(&cipb);
+ FSSpec temp;
+ if (err == noErr)
+ err = FSMakeFSSpec(mVRefNum, mParID, objectName, &temp);
+ mCurrent = temp; // use the operator: it clears the string cache.
+ mExists = err == noErr;
+
+ if (mExists && mResoveSymLinks)
+ {
+ PRBool ignore;
+ mCurrent.ResolveSymlink(ignore);
+ }
+ 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 ++
+
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecOS2.cpp b/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecOS2.cpp
new file mode 100644
index 00000000..4621d8b8
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecOS2.cpp
@@ -0,0 +1,840 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla OS/2 libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * John Fairhurst, <john_fairhurst@iname.com>.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Henry Sobotka <sobotka@axess.com>
+ * 00/01/06: general review and update against Win/Unix versions;
+ * replaced nsFileSpec::Execute implementation with system() call
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK *****
+ *
+ * This Original Code has been modified by IBM Corporation.
+ * Modifications made by IBM described herein are
+ * Copyright (c) International Business Machines
+ * Corporation, 2000
+ *
+ * Modifications to Mozilla code or documentation
+ * identified per MPL Section 3.3
+ *
+ * Date Modified by Description of modification
+ * 03/23/2000 IBM Corp. Fixed bug where 2 char or less profile names treated as drive letters.
+ * 06/20/2000 IBM Corp. Make it more like Windows version.
+ */
+
+#define INCL_DOSERRORS
+#define INCL_DOS
+#define INCL_WINWORKPLACE
+#include <os2.h>
+
+#ifdef XP_OS2_VACPP
+#include <direct.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <ctype.h>
+#include <io.h>
+
+//----------------------------------------------------------------------------------------
+void nsFileSpecHelpers::Canonify(nsSimpleCharString& 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.IsEmpty())
+ return;
+
+ NS_ASSERTION(strchr((const char*)ioPath, '/') == 0,
+ "This smells like a Unix path. Native path expected! "
+ "Please fix.");
+ if (inMakeDirs)
+ {
+ const int mode = 0700;
+ nsSimpleCharString unixStylePath = ioPath;
+ nsFileSpecHelpers::NativeToUnix(unixStylePath);
+ nsFileSpecHelpers::MakeAllDirectories((const char*)unixStylePath, mode);
+ }
+ char buffer[_MAX_PATH];
+ errno = 0;
+ *buffer = '\0';
+#ifdef XP_OS2
+ PRBool removedBackslash = PR_FALSE;
+ PRUint32 lenstr = ioPath.Length();
+ char &lastchar = ioPath[lenstr -1];
+
+ // Strip off any trailing backslash UNLESS it's the backslash that
+ // comes after "X:". Note also that "\" is valid. Sheesh.
+ //
+ if( lastchar == '\\' && (lenstr != 3 || ioPath[1] != ':') && lenstr != 1)
+ {
+ lastchar = '\0';
+ removedBackslash = PR_TRUE;
+ }
+
+ char canonicalPath[CCHMAXPATH] = "";
+
+ DosQueryPathInfo( (char*) ioPath,
+ FIL_QUERYFULLNAME,
+ canonicalPath,
+ CCHMAXPATH);
+#else
+ char* canonicalPath = _fullpath(buffer, ioPath, _MAX_PATH);
+#endif
+
+ if (canonicalPath)
+ {
+ NS_ASSERTION( canonicalPath[0] != '\0', "Uh oh...couldn't convert" );
+ if (canonicalPath[0] == '\0')
+ return;
+#ifdef XP_OS2
+ // If we removed that backslash, add it back onto the fullpath
+ if (removedBackslash)
+ strcat( canonicalPath, "\\");
+#endif
+ }
+ ioPath = canonicalPath;
+} // nsFileSpecHelpers::Canonify
+
+//----------------------------------------------------------------------------------------
+void nsFileSpecHelpers::UnixToNative(nsSimpleCharString& 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.IsEmpty())
+ return;
+
+ // Strip initial slash for an absolute path
+ char* src = (char*)ioPath;
+ if (*src == '/') {
+ if (!src[1]) {
+ // allocate new string by copying from ioPath[1]
+ nsSimpleCharString temp = src + 1;
+ ioPath = temp;
+ return;
+ }
+ // Since it was an absolute path, check for the drive letter
+ char* colonPointer = src + 2;
+ if (strstr(src, "|/") == colonPointer)
+ *colonPointer = ':';
+ // allocate new string by copying from ioPath[1]
+ nsSimpleCharString temp = src + 1;
+ ioPath = temp;
+ }
+
+ src = (char*)ioPath;
+
+ if (*src) {
+ // Convert '/' to '\'.
+ while (*++src)
+ {
+ if (*src == '/')
+ *src = '\\';
+ }
+ }
+} // nsFileSpecHelpers::UnixToNative
+
+//----------------------------------------------------------------------------------------
+void nsFileSpecHelpers::NativeToUnix(nsSimpleCharString& 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.IsEmpty())
+ return;
+
+ // Convert the drive-letter separator, if present
+ nsSimpleCharString temp("/");
+
+ char* cp = (char*)ioPath + 1;
+ if (strstr(cp, ":\\") == cp)
+ *cp = '|'; // absolute path
+ else
+ temp[0] = '\0'; // relative path
+
+ // Convert '\' to '/'
+ for (; *cp; cp++)
+ {
+#ifdef XP_OS2
+ // OS2TODO - implement equivalent of IsDBCSLeadByte
+#else
+ if(IsDBCSLeadByte(*cp) && *(cp+1) != nsnull)
+ {
+ cp++;
+ continue;
+ }
+#endif
+ if (*cp == '\\')
+ *cp = '/';
+ }
+ // Add the slash in front.
+ temp += ioPath;
+ ioPath = temp;
+}
+
+//----------------------------------------------------------------------------------------
+nsFileSpec::nsFileSpec(const nsFilePath& inPath)
+//----------------------------------------------------------------------------------------
+{
+// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!");
+ *this = inPath;
+}
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::operator = (const nsFilePath& inPath)
+//----------------------------------------------------------------------------------------
+{
+ mPath = (const char*)inPath;
+ nsFileSpecHelpers::UnixToNative(mPath);
+ mError = NS_OK;
+} // nsFileSpec::operator =
+
+//----------------------------------------------------------------------------------------
+nsFilePath::nsFilePath(const nsFileSpec& inSpec)
+//----------------------------------------------------------------------------------------
+{
+ *this = inSpec;
+} // nsFilePath::nsFilePath
+
+//----------------------------------------------------------------------------------------
+void nsFilePath::operator = (const nsFileSpec& inSpec)
+//----------------------------------------------------------------------------------------
+{
+ mPath = inSpec.mPath;
+ nsFileSpecHelpers::NativeToUnix(mPath);
+} // nsFilePath::operator =
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::SetLeafName(const char* inLeafName)
+//----------------------------------------------------------------------------------------
+{
+ NS_ASSERTION(inLeafName, "Attempt to SetLeafName with a null string");
+ mPath.LeafReplace('\\', inLeafName);
+} // nsFileSpec::SetLeafName
+
+//----------------------------------------------------------------------------------------
+char* nsFileSpec::GetLeafName() const
+//----------------------------------------------------------------------------------------
+{
+ return mPath.GetLeaf('\\');
+} // nsFileSpec::GetLeafName
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::Exists() const
+//----------------------------------------------------------------------------------------
+{
+ struct stat st;
+ return !mPath.IsEmpty() && 0 == stat(nsNSPRPath(*this), &st);
+} // nsFileSpec::Exists
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::GetModDate(TimeStamp& outStamp) const
+//----------------------------------------------------------------------------------------
+{
+ struct stat st;
+ if (!mPath.IsEmpty() && stat(nsNSPRPath(*this), &st) == 0)
+ outStamp = st.st_mtime;
+ else
+ outStamp = 0;
+} // nsFileSpec::GetModDate
+
+//----------------------------------------------------------------------------------------
+PRUint32 nsFileSpec::GetFileSize() const
+//----------------------------------------------------------------------------------------
+{
+ struct stat st;
+ if (!mPath.IsEmpty() && stat(nsNSPRPath(*this), &st) == 0)
+ return (PRUint32)st.st_size;
+ return 0;
+} // nsFileSpec::GetFileSize
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::IsFile() const
+//----------------------------------------------------------------------------------------
+{
+ struct stat st;
+#ifdef XP_OS2
+ return !mPath.IsEmpty() && 0 == stat(nsNSPRPath(*this), &st) && ( S_IFREG & st.st_mode);
+#else
+ return !mPath.IsEmpty() && 0 == stat(nsNSPRPath(*this), &st) && (_S_IFREG & st.st_mode);
+#endif
+} // nsFileSpec::IsFile
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::IsDirectory() const
+//----------------------------------------------------------------------------------------
+{
+ struct stat st;
+#ifdef XP_OS2
+ return !mPath.IsEmpty() && 0 == stat(nsNSPRPath(*this), &st) && ( S_IFDIR & st.st_mode);
+#else
+ return !mPath.IsEmpty() && 0 == stat(nsNSPRPath(*this), &st) && (_S_IFDIR & st.st_mode);
+#endif
+} // nsFileSpec::IsDirectory
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::IsHidden() const
+//----------------------------------------------------------------------------------------
+{
+ PRBool hidden = PR_FALSE;
+ if (!mPath.IsEmpty())
+ {
+#ifdef XP_OS2
+ FILESTATUS3 fs3;
+ APIRET rc;
+
+ rc = DosQueryPathInfo( mPath,
+ FIL_STANDARD,
+ &fs3,
+ sizeof fs3);
+ if(!rc)
+ hidden = fs3.attrFile & FILE_HIDDEN ? PR_TRUE : PR_FALSE;
+#else
+ DWORD attr = GetFileAttributes(mPath);
+ if (FILE_ATTRIBUTE_HIDDEN & attr)
+ hidden = PR_TRUE;
+#endif
+ }
+ return hidden;
+}
+// nsFileSpec::IsHidden
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::IsSymlink() const
+//----------------------------------------------------------------------------------------
+{
+#ifdef XP_OS2
+ return PR_FALSE; // No symlinks on OS/2
+#else
+ HRESULT hres;
+ IShellLink* psl;
+
+ PRBool isSymlink = PR_FALSE;
+
+ CoInitialize(NULL);
+ // Get a pointer to the IShellLink interface.
+ hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&psl);
+ if (SUCCEEDED(hres))
+ {
+ IPersistFile* ppf;
+
+ // Get a pointer to the IPersistFile interface.
+ hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
+
+ if (SUCCEEDED(hres))
+ {
+ WORD wsz[MAX_PATH];
+ // Ensure that the string is Unicode.
+ MultiByteToWideChar(CP_ACP, 0, mPath, -1, wsz, MAX_PATH);
+
+ // Load the shortcut.
+ hres = ppf->Load(wsz, STGM_READ);
+ if (SUCCEEDED(hres))
+ {
+ isSymlink = PR_TRUE;
+ }
+
+ // Release the pointer to the IPersistFile interface.
+ ppf->Release();
+ }
+
+ // Release the pointer to the IShellLink interface.
+ psl->Release();
+ }
+
+ CoUninitialize();
+
+ return isSymlink;
+#endif
+}
+
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::ResolveSymlink(PRBool& wasSymlink)
+//----------------------------------------------------------------------------------------
+{
+#ifdef XP_OS2
+ return NS_OK; // no symlinks on OS/2
+#else
+ wasSymlink = PR_FALSE; // assume failure
+
+ if (Exists())
+ return NS_OK;
+
+
+ HRESULT hres;
+ IShellLink* psl;
+
+ CoInitialize(NULL);
+
+ // Get a pointer to the IShellLink interface.
+ hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&psl);
+ if (SUCCEEDED(hres))
+ {
+ IPersistFile* ppf;
+
+ // Get a pointer to the IPersistFile interface.
+ hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
+
+ if (SUCCEEDED(hres))
+ {
+ WORD wsz[MAX_PATH];
+ // Ensure that the string is Unicode.
+ MultiByteToWideChar(CP_ACP, 0, mPath, -1, wsz, MAX_PATH);
+
+ // Load the shortcut.
+ hres = ppf->Load(wsz, STGM_READ);
+ if (SUCCEEDED(hres))
+ {
+ wasSymlink = PR_TRUE;
+
+ // Resolve the link.
+ hres = psl->Resolve(nsnull, SLR_NO_UI );
+ if (SUCCEEDED(hres))
+ {
+ char szGotPath[MAX_PATH];
+ WIN32_FIND_DATA wfd;
+
+ // Get the path to the link target.
+ hres = psl->GetPath( szGotPath, MAX_PATH, &wfd, SLGP_UNCPRIORITY );
+
+ if (SUCCEEDED(hres))
+ {
+ // Here we modify the nsFileSpec;
+ mPath = szGotPath;
+ mError = NS_OK;
+ }
+ }
+ }
+ else {
+ // It wasn't a shortcut. Oh well. Leave it like it was.
+ hres = 0;
+ }
+
+ // Release the pointer to the IPersistFile interface.
+ ppf->Release();
+ }
+ // Release the pointer to the IShellLink interface.
+ psl->Release();
+ }
+
+ CoUninitialize();
+
+ if (SUCCEEDED(hres))
+ return NS_OK;
+
+ return NS_FILE_FAILURE;
+#endif
+}
+
+
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::GetParent(nsFileSpec& outSpec) const
+//----------------------------------------------------------------------------------------
+{
+ outSpec.mPath = mPath;
+ char* chars = (char*)outSpec.mPath;
+ chars[outSpec.mPath.Length() - 1] = '\0'; // avoid trailing separator, if any
+ char* cp = strrchr(chars, '\\');
+ if (cp++)
+ outSpec.mPath.SetLength(cp - chars); // truncate.
+} // nsFileSpec::GetParent
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::operator += (const char* inRelativePath)
+//----------------------------------------------------------------------------------------
+{
+ NS_ASSERTION(inRelativePath, "Attempt to do += with a null string");
+
+ if (!inRelativePath || mPath.IsEmpty())
+ return;
+
+ if (mPath[mPath.Length() - 1] == '\\')
+ mPath += "x";
+ else
+ mPath += "\\x";
+
+ // If it's a (unix) relative path, make it native
+ nsSimpleCharString dosPath = inRelativePath;
+ nsFileSpecHelpers::UnixToNative(dosPath);
+ SetLeafName(dosPath);
+} // nsFileSpec::operator +=
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::CreateDirectory(int /*mode*/)
+//----------------------------------------------------------------------------------------
+{
+ // Note that mPath is canonical!
+ if (!mPath.IsEmpty())
+#ifdef XP_OS2
+ // OS2TODO - vacpp complains about mkdir but PR_MkDir should be ok?
+ PR_MkDir(nsNSPRPath(*this), PR_CREATE_FILE);
+#else
+ mkdir(nsNSPRPath(*this));
+#endif
+} // nsFileSpec::CreateDirectory
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::Delete(PRBool inRecursive) const
+//----------------------------------------------------------------------------------------
+{
+ if (IsDirectory())
+ {
+ if (inRecursive)
+ {
+ for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++)
+ {
+ nsFileSpec& child = i.Spec();
+ child.Delete(inRecursive);
+ }
+ }
+#ifdef XP_OS2
+ // OS2TODO - vacpp complains if use rmdir but PR_RmDir should be ok?
+ PR_RmDir(nsNSPRPath(*this));
+#else
+ rmdir(nsNSPRPath(*this));
+#endif
+ }
+ else if (!mPath.IsEmpty())
+ {
+ remove(nsNSPRPath(*this));
+ }
+} // nsFileSpec::Delete
+
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::RecursiveCopy(nsFileSpec newDir) const
+//----------------------------------------------------------------------------------------
+{
+ if (IsDirectory())
+ {
+ if (!(newDir.Exists()))
+ {
+ newDir.CreateDirectory();
+ }
+
+ for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++)
+ {
+ nsFileSpec& child = i.Spec();
+
+ if (child.IsDirectory())
+ {
+ nsFileSpec tmpDirSpec(newDir);
+
+ char *leafname = child.GetLeafName();
+ tmpDirSpec += leafname;
+ nsCRT::free(leafname);
+
+ child.RecursiveCopy(tmpDirSpec);
+ }
+ else
+ {
+ child.RecursiveCopy(newDir);
+ }
+ }
+ }
+ else if (!mPath.IsEmpty())
+ {
+ nsFileSpec& filePath = (nsFileSpec&) *this;
+
+ if (!(newDir.Exists()))
+ {
+ newDir.CreateDirectory();
+ }
+
+ filePath.CopyToDir(newDir);
+ }
+} // nsFileSpec::RecursiveCopy
+
+//----------------------------------------------------------------------------------------
+nsresult
+nsFileSpec::Truncate(PRInt32 aNewFileLength) const
+//----------------------------------------------------------------------------------------
+{
+#ifdef XP_OS2
+ APIRET rc;
+ HFILE hFile;
+ ULONG actionTaken;
+
+ rc = DosOpen(mPath,
+ &hFile,
+ &actionTaken,
+ 0,
+ FILE_NORMAL,
+ OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
+ OPEN_SHARE_DENYREADWRITE | OPEN_ACCESS_READWRITE,
+ NULL);
+
+ if (rc != NO_ERROR)
+ return NS_FILE_FAILURE;
+
+ rc = DosSetFileSize(hFile, aNewFileLength);
+
+ if (rc == NO_ERROR)
+ DosClose(hFile);
+ else
+ goto error;
+#else
+ DWORD status;
+ HANDLE hFile;
+
+ // Leave it to Microsoft to open an existing file with a function
+ // named "CreateFile".
+ hFile = CreateFile(mPath,
+ GENERIC_WRITE,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ return NS_FILE_FAILURE;
+
+ // Seek to new, desired end of file
+ status = SetFilePointer(hFile, aNewFileLength, NULL, FILE_BEGIN);
+ if (status == 0xffffffff)
+ goto error;
+
+ // Truncate file at current cursor position
+ if (!SetEndOfFile(hFile))
+ goto error;
+
+ if (!CloseHandle(hFile))
+ return NS_FILE_FAILURE;
+#endif
+
+ return NS_OK;
+
+ error:
+#ifdef XP_OS2
+ DosClose(hFile);
+#else
+ CloseHandle(hFile);
+#endif
+ return NS_FILE_FAILURE;
+
+} // nsFileSpec::Truncate
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::Rename(const char* inNewName)
+//----------------------------------------------------------------------------------------
+{
+ NS_ASSERTION(inNewName, "Attempt to Rename with a null string");
+
+ // This function should not be used to move a file on disk.
+ if (strchr(inNewName, '/'))
+ return NS_FILE_FAILURE;
+
+ char* oldPath = nsCRT::strdup(mPath);
+
+ SetLeafName(inNewName);
+
+ if (PR_Rename(oldPath, mPath) != NS_OK)
+ {
+ // Could not rename, set back to the original.
+ mPath = oldPath;
+ return NS_FILE_FAILURE;
+ }
+
+ nsCRT::free(oldPath);
+
+ return NS_OK;
+} // nsFileSpec::Rename
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::CopyToDir(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();
+ nsSimpleCharString destPath(inParentDirectory.GetCString());
+ destPath += "\\";
+ destPath += leafname;
+ nsCRT::free(leafname);
+
+ // CopyFile returns non-zero if succeeds
+#ifdef XP_OS2
+ APIRET rc;
+ PRBool copyOK;
+
+ rc = DosCopy(GetCString(), (PSZ)destPath, DCPY_EXISTING);
+
+ if (rc == NO_ERROR)
+ copyOK = PR_TRUE;
+ else
+ copyOK = PR_FALSE;
+#else
+ int copyOK = CopyFile(GetCString(), destPath, PR_TRUE);
+#endif
+ if (copyOK)
+ return NS_OK;
+ }
+ return NS_FILE_FAILURE;
+} // nsFileSpec::CopyToDir
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::MoveToDir(const nsFileSpec& inNewParentDirectory)
+//----------------------------------------------------------------------------------------
+{
+ // We can only copy into a directory, and (for now) can not copy entire directories
+ if (inNewParentDirectory.IsDirectory() && (! IsDirectory() ) )
+ {
+ char *leafname = GetLeafName();
+ nsSimpleCharString destPath(inNewParentDirectory.GetCString());
+ destPath += "\\";
+ destPath += leafname;
+ nsCRT::free(leafname);
+
+ if (DosMove(GetCString(), destPath) == NO_ERROR)
+ {
+ *this = inNewParentDirectory + GetLeafName();
+ return NS_OK;
+ }
+
+ }
+ return NS_FILE_FAILURE;
+} // nsFileSpec::MoveToDir
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::Execute(const char* inArgs ) const
+//----------------------------------------------------------------------------------------
+{
+ if (!IsDirectory())
+ {
+#ifdef XP_OS2
+ nsresult result = NS_FILE_FAILURE;
+
+ if (!mPath.IsEmpty())
+ {
+ nsSimpleCharString fileNameWithArgs = mPath + " " + inArgs;
+ result = NS_FILE_RESULT(system(fileNameWithArgs));
+ }
+ return result;
+#else
+ nsSimpleCharString fileNameWithArgs = "\"";
+ fileNameWithArgs += mPath + "\" " + inArgs;
+ int execResult = WinExec( fileNameWithArgs, SW_NORMAL );
+ if (execResult > 31)
+ return NS_OK;
+#endif
+ }
+ return NS_FILE_FAILURE;
+} // nsFileSpec::Execute
+
+
+//----------------------------------------------------------------------------------------
+PRInt64 nsFileSpec::GetDiskSpaceAvailable() const
+//----------------------------------------------------------------------------------------
+{
+ PRInt64 nBytes = 0;
+ ULONG ulDriveNo = toupper(mPath[0]) + 1 - 'A';
+ FSALLOCATE fsAllocate;
+ APIRET rc = DosQueryFSInfo(ulDriveNo,
+ FSIL_ALLOC,
+ &fsAllocate,
+ sizeof(fsAllocate));
+
+ if (rc == NO_ERROR) {
+ nBytes = fsAllocate.cUnitAvail;
+ nBytes *= fsAllocate.cSectorUnit;
+ nBytes *= fsAllocate.cbSector;
+ }
+
+ return nBytes;
+}
+
+
+
+//========================================================================================
+// nsDirectoryIterator
+//========================================================================================
+
+//----------------------------------------------------------------------------------------
+nsDirectoryIterator::nsDirectoryIterator(const nsFileSpec& inDirectory, PRBool resolveSymlink)
+//----------------------------------------------------------------------------------------
+ : mCurrent(inDirectory)
+ , mDir(nsnull)
+ , mStarting(inDirectory)
+ , mExists(PR_FALSE)
+ , mResoveSymLinks(resolveSymlink)
+{
+ mDir = PR_OpenDir(inDirectory);
+ mCurrent += "dummy";
+ mStarting += "dummy";
+ ++(*this);
+} // nsDirectoryIterator::nsDirectoryIterator
+
+//----------------------------------------------------------------------------------------
+nsDirectoryIterator::~nsDirectoryIterator()
+//----------------------------------------------------------------------------------------
+{
+ if (mDir)
+ PR_CloseDir(mDir);
+} // nsDirectoryIterator::nsDirectoryIterator
+
+//----------------------------------------------------------------------------------------
+nsDirectoryIterator& nsDirectoryIterator::operator ++ ()
+//----------------------------------------------------------------------------------------
+{
+ mExists = PR_FALSE;
+ if (!mDir)
+ return *this;
+ PRDirEntry* entry = PR_ReadDir(mDir, PR_SKIP_BOTH); // Ignore '.' && '..'
+ if (entry)
+ {
+ mExists = PR_TRUE;
+ mCurrent = mStarting;
+ mCurrent.SetLeafName(entry->name);
+ if (mResoveSymLinks)
+ {
+ PRBool ignore;
+ mCurrent.ResolveSymlink(ignore);
+ }
+ }
+ return *this;
+} // nsDirectoryIterator::operator ++
+
+//----------------------------------------------------------------------------------------
+nsDirectoryIterator& nsDirectoryIterator::operator -- ()
+//----------------------------------------------------------------------------------------
+{
+ return ++(*this); // can't do it backwards.
+} // nsDirectoryIterator::operator --
+
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecUnix.cpp b/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecUnix.cpp
new file mode 100644
index 00000000..8acb6330
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecUnix.cpp
@@ -0,0 +1,703 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Henry Sobotka <sobotka@axess.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// 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 <limits.h>
+#include "xpcom-private.h"
+#include "nsError.h"
+#include "prio.h" /* for PR_Rename */
+#include "nsAutoBuffer.h"
+
+#if defined(_SCO_DS)
+#define _SVID3 /* for statvfs.h */
+#endif
+
+#ifdef HAVE_SYS_STATVFS_H
+#include <sys/statvfs.h>
+#endif
+
+#ifdef HAVE_SYS_VFS_H
+#include <sys/vfs.h>
+#endif
+
+#ifdef HAVE_SYS_STATFS_H
+#include <sys/statfs.h>
+#endif
+
+#ifdef HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#undef Free
+#endif
+
+#ifdef HAVE_STATVFS
+#define STATFS statvfs
+#else
+#define STATFS statfs
+#endif
+
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 1024 /* Guessing this is okay. Works for SCO. */
+#endif
+
+#if defined(__QNX__)
+#include <unix.h> /* for realpath */
+#define f_bavail f_bfree
+extern "C" int truncate(const char *, off_t);
+#endif
+
+#if defined(SUNOS4)
+extern "C" int statfs(char *, struct statfs *);
+#endif
+
+#if defined(OSF1)
+extern "C" int statvfs(const char *, struct statvfs *);
+#endif
+
+#ifdef XP_MACOSX
+static void CopyUTF8toUTF16NFC(const nsACString& aSrc, nsAString& aResult);
+#endif
+
+//----------------------------------------------------------------------------------------
+void nsFileSpecHelpers::Canonify(nsSimpleCharString& ioPath, PRBool inMakeDirs)
+// Canonify, make absolute, and check whether directories exist
+//----------------------------------------------------------------------------------------
+{
+ if (ioPath.IsEmpty())
+ return;
+ if (inMakeDirs)
+ {
+ const mode_t mode = 0700;
+ nsFileSpecHelpers::MakeAllDirectories((const char*)ioPath, mode);
+ }
+
+ errno = 0; // needed?
+
+ if (ioPath[0] != '/')
+ {
+ // the ioPath that was passed in is relative. We must cat it to the cwd.
+ char buffer[MAXPATHLEN];
+
+ (void) getcwd(buffer, MAXPATHLEN);
+
+ strcat(buffer, "/");
+ strcat(buffer, ioPath);
+
+ ioPath = buffer;
+ }
+} // nsFileSpecHelpers::Canonify
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::SetLeafName(const char* inLeafName)
+//----------------------------------------------------------------------------------------
+{
+ mPath.LeafReplace('/', inLeafName);
+} // nsFileSpec::SetLeafName
+
+//----------------------------------------------------------------------------------------
+char* nsFileSpec::GetLeafName() const
+//----------------------------------------------------------------------------------------
+{
+#ifndef XP_MACOSX
+ return mPath.GetLeaf('/');
+#else
+ char *name = mPath.GetLeaf('/');
+ if (!name || !*name)
+ return name;
+ nsAutoString nameInNFC;
+ CopyUTF8toUTF16NFC(nsDependentCString(name), nameInNFC);
+ nsCRT::free(name);
+ return nsCRT::strdup(NS_ConvertUTF16toUTF8(nameInNFC).get());
+#endif
+} // nsFileSpec::GetLeafName
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::Exists() const
+//----------------------------------------------------------------------------------------
+{
+ struct stat st;
+ return !mPath.IsEmpty() && 0 == stat(mPath, &st);
+} // nsFileSpec::Exists
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::GetModDate(TimeStamp& outStamp) const
+//----------------------------------------------------------------------------------------
+{
+ struct stat st;
+ if (!mPath.IsEmpty() && stat(mPath, &st) == 0)
+ outStamp = st.st_mtime;
+ else
+ outStamp = 0;
+} // nsFileSpec::GetModDate
+
+//----------------------------------------------------------------------------------------
+PRUint32 nsFileSpec::GetFileSize() const
+//----------------------------------------------------------------------------------------
+{
+ struct stat st;
+ if (!mPath.IsEmpty() && stat(mPath, &st) == 0)
+ return (PRUint32)st.st_size;
+ return 0;
+} // nsFileSpec::GetFileSize
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::IsFile() const
+//----------------------------------------------------------------------------------------
+{
+ struct stat st;
+ return !mPath.IsEmpty() && stat(mPath, &st) == 0 && S_ISREG(st.st_mode);
+} // nsFileSpec::IsFile
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::IsDirectory() const
+//----------------------------------------------------------------------------------------
+{
+ struct stat st;
+ return !mPath.IsEmpty() && 0 == stat(mPath, &st) && S_ISDIR(st.st_mode);
+} // nsFileSpec::IsDirectory
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::IsHidden() const
+//----------------------------------------------------------------------------------------
+{
+ PRBool hidden = PR_FALSE;
+ char *leafname = GetLeafName();
+ if (nsnull != leafname)
+ {
+ // rjc: don't return ".", "..", or any file/directory that begins with a "."
+
+ /* if ((!strcmp(leafname, ".")) || (!strcmp(leafname, ".."))) */
+ if (leafname[0] == '.')
+ {
+ hidden = PR_TRUE;
+ }
+ nsCRT::free(leafname);
+ }
+ return hidden;
+} // nsFileSpec::IsHidden
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::IsSymlink() const
+//----------------------------------------------------------------------------------------
+{
+ struct stat st;
+ if (!mPath.IsEmpty() && stat(mPath, &st) == 0 && S_ISLNK(st.st_mode))
+ return PR_TRUE;
+
+ return PR_FALSE;
+} // nsFileSpec::IsSymlink
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::ResolveSymlink(PRBool& wasAliased)
+//----------------------------------------------------------------------------------------
+{
+ wasAliased = PR_FALSE;
+
+ char resolvedPath[MAXPATHLEN];
+ int charCount = readlink(mPath, (char*)&resolvedPath, MAXPATHLEN);
+ if (0 < charCount)
+ {
+ if (MAXPATHLEN > charCount)
+ resolvedPath[charCount] = '\0';
+
+ wasAliased = PR_TRUE;
+
+ /* if it's not an absolute path,
+ replace the leaf with what got resolved */
+ if (resolvedPath[0] != '/') {
+ SetLeafName(resolvedPath);
+ }
+ else {
+ mPath = (char*)&resolvedPath;
+ }
+
+ char* canonicalPath = realpath((const char *)mPath, resolvedPath);
+ NS_ASSERTION(canonicalPath, "realpath failed");
+ if (canonicalPath) {
+ mPath = (char*)&resolvedPath;
+ }
+ else {
+ return NS_ERROR_FAILURE;
+ }
+ }
+
+ return NS_OK;
+} // nsFileSpec::ResolveSymlink
+
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::GetParent(nsFileSpec& outSpec) const
+//----------------------------------------------------------------------------------------
+{
+ outSpec.mPath = mPath;
+ char* chars = (char*)outSpec.mPath;
+ chars[outSpec.mPath.Length() - 1] = '\0'; // avoid trailing separator, if any
+ char* cp = strrchr(chars, '/');
+ if (cp++)
+ outSpec.mPath.SetLength(cp - chars); // truncate.
+} // nsFileSpec::GetParent
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::operator += (const char* inRelativePath)
+//----------------------------------------------------------------------------------------
+{
+ NS_ASSERTION(inRelativePath, "Attempt to do += with a null string");
+
+ if (!inRelativePath || mPath.IsEmpty())
+ return;
+
+ char endChar = mPath[(int)(strlen(mPath) - 1)];
+ if (endChar == '/')
+ mPath += "x";
+ else
+ mPath += "/x";
+ SetLeafName(inRelativePath);
+} // nsFileSpec::operator +=
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::CreateDirectory(int mode)
+//----------------------------------------------------------------------------------------
+{
+ // Note that mPath is canonical!
+ if (mPath.IsEmpty())
+ return;
+ mkdir(mPath, mode);
+} // nsFileSpec::CreateDirectory
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::Delete(PRBool inRecursive) const
+// To check if this worked, call Exists() afterwards, see?
+//----------------------------------------------------------------------------------------
+{
+ if (IsDirectory())
+ {
+ if (inRecursive)
+ {
+ for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++)
+ {
+ nsFileSpec& child = (nsFileSpec&)i;
+ child.Delete(inRecursive);
+ }
+ }
+ rmdir(mPath);
+ }
+ else if (!mPath.IsEmpty())
+ remove(mPath);
+} // nsFileSpec::Delete
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::RecursiveCopy(nsFileSpec newDir) const
+//----------------------------------------------------------------------------------------
+{
+ if (IsDirectory())
+ {
+ if (!(newDir.Exists()))
+ {
+ newDir.CreateDirectory();
+ }
+
+ for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++)
+ {
+ nsFileSpec& child = (nsFileSpec&)i;
+
+ if (child.IsDirectory())
+ {
+ nsFileSpec tmpDirSpec(newDir);
+
+ char *leafname = child.GetLeafName();
+ tmpDirSpec += leafname;
+ nsCRT::free(leafname);
+
+ child.RecursiveCopy(tmpDirSpec);
+ }
+ else
+ {
+ child.RecursiveCopy(newDir);
+ }
+ }
+ }
+ else if (!mPath.IsEmpty())
+ {
+ nsFileSpec& filePath = (nsFileSpec&) *this;
+
+ if (!(newDir.Exists()))
+ {
+ newDir.CreateDirectory();
+ }
+
+ filePath.CopyToDir(newDir);
+ }
+} // nsFileSpec::RecursiveCopy
+
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::Truncate(PRInt32 offset) const
+//----------------------------------------------------------------------------------------
+{
+ char* Path = nsCRT::strdup(mPath);
+
+ int rv = truncate(Path, offset) ;
+
+ nsCRT::free(Path) ;
+
+ if(!rv)
+ return NS_OK ;
+ else
+ return NS_ERROR_FAILURE ;
+} // nsFileSpec::Truncate
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::Rename(const char* inNewName)
+//----------------------------------------------------------------------------------------
+{
+ NS_ASSERTION(inNewName, "Attempt to Rename with a null string");
+
+ // This function should not be used to move a file on disk.
+ if (mPath.IsEmpty() || strchr(inNewName, '/'))
+ return NS_FILE_FAILURE;
+
+ char* oldPath = nsCRT::strdup(mPath);
+
+ SetLeafName(inNewName);
+
+ if (PR_Rename(oldPath, mPath) != NS_OK)
+ {
+ // Could not rename, set back to the original.
+ mPath = oldPath;
+ return NS_FILE_FAILURE;
+ }
+
+ nsCRT::free(oldPath);
+
+ 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::CopyToDir(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();
+ nsSimpleCharString destPath(inParentDirectory.GetCString());
+ destPath += "/";
+ destPath += leafname;
+ nsCRT::free(leafname);
+ result = NS_FILE_RESULT(CrudeFileCopy(GetCString(), destPath));
+ }
+ return result;
+} // nsFileSpec::CopyToDir
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::MoveToDir(const nsFileSpec& inNewParentDirectory)
+//----------------------------------------------------------------------------------------
+{
+ // 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();
+ nsSimpleCharString destPath(inNewParentDirectory.GetCString());
+ destPath += "/";
+ destPath += leafname;
+ nsCRT::free(leafname);
+
+ result = NS_FILE_RESULT(CrudeFileCopy(GetCString(), (const char*)destPath));
+ if (result == NS_OK)
+ {
+ // cast to fix const-ness
+ ((nsFileSpec*)this)->Delete(PR_FALSE);
+
+ *this = inNewParentDirectory + GetLeafName();
+ }
+ }
+ return result;
+}
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::Execute(const char* inArgs ) const
+//----------------------------------------------------------------------------------------
+{
+ nsresult result = NS_FILE_FAILURE;
+
+ if (!mPath.IsEmpty() && !IsDirectory())
+ {
+ nsSimpleCharString fileNameWithArgs = mPath + " " + inArgs;
+ result = NS_FILE_RESULT(system(fileNameWithArgs));
+ }
+
+ return result;
+
+} // nsFileSpec::Execute
+
+//----------------------------------------------------------------------------------------
+PRInt64 nsFileSpec::GetDiskSpaceAvailable() const
+//----------------------------------------------------------------------------------------
+{
+ PRInt64 bytes; /* XXX dougt needs to fix this */
+ LL_I2L(bytes , LONG_MAX); // initialize to all the space in the world?
+
+
+#if defined(HAVE_SYS_STATFS_H) || defined(HAVE_SYS_STATVFS_H)
+
+ char curdir [MAXPATHLEN];
+ if (mPath.IsEmpty())
+ {
+ (void) getcwd(curdir, MAXPATHLEN);
+ if (!curdir)
+ return bytes; /* hope for the best as we did in cheddar */
+ }
+ else
+ sprintf(curdir, "%.200s", (const char*)mPath);
+
+ struct STATFS fs_buf;
+#if defined(__QNX__) && !defined(HAVE_STATVFS) /* Maybe this should be handled differently? */
+ if (STATFS(curdir, &fs_buf, 0, 0) < 0)
+#else
+ if (STATFS(curdir, &fs_buf) < 0)
+#endif
+ return bytes; /* hope for the best as we did in cheddar */
+
+#ifdef DEBUG_DISK_SPACE
+ printf("DiskSpaceAvailable: %d bytes\n",
+ fs_buf.f_bsize * (fs_buf.f_bavail - 1));
+#endif
+
+ PRInt64 bsize,bavail;
+ LL_I2L( bsize, fs_buf.f_bsize );
+ LL_I2L( bavail, fs_buf.f_bavail - 1 );
+ LL_MUL( bytes, bsize, bavail );
+ return bytes;
+
+#else
+ /*
+ ** This platform doesn't have statfs or statvfs, so we don't have much
+ ** choice but to "hope for the best as we did in cheddar".
+ */
+ return bytes;
+#endif /* HAVE_SYS_STATFS_H or HAVE_SYS_STATVFS_H */
+
+} // nsFileSpec::GetDiskSpace()
+
+//========================================================================================
+// nsDirectoryIterator
+//========================================================================================
+
+//----------------------------------------------------------------------------------------
+nsDirectoryIterator::nsDirectoryIterator(const nsFileSpec& inDirectory, PRBool resolveSymLinks)
+//----------------------------------------------------------------------------------------
+ : mCurrent(inDirectory)
+ , mExists(PR_FALSE)
+ , mResoveSymLinks(resolveSymLinks)
+ , mStarting(inDirectory)
+ , mDir(nsnull)
+
+{
+ mStarting += "sysygy"; // save off the starting directory
+ 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 = PR_FALSE;
+ if (!mDir)
+ return *this;
+ const char dot[] = ".";
+ const 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 = PR_TRUE;
+ mCurrent = mStarting; // restore mCurrent to be the starting directory. ResolveSymlink() may have taken us to another directory
+ mCurrent.SetLeafName(entry->d_name);
+ if (mResoveSymLinks)
+ {
+ PRBool ignore;
+ mCurrent.ResolveSymlink(ignore);
+ }
+ }
+ return *this;
+} // nsDirectoryIterator::operator ++
+
+//----------------------------------------------------------------------------------------
+nsDirectoryIterator& nsDirectoryIterator::operator -- ()
+//----------------------------------------------------------------------------------------
+{
+ return ++(*this); // can't do it backwards.
+} // nsDirectoryIterator::operator --
+
+// Convert a UTF-8 string to a UTF-16 string while normalizing to
+// Normalization Form C (composed Unicode). We need this because
+// Mac OS X file system uses NFD (Normalization Form D : decomposed Unicode)
+// while most other OS', server-side programs usually expect NFC.
+
+#ifdef XP_MACOSX
+typedef void (*UnicodeNormalizer) (CFMutableStringRef, CFStringNormalizationForm);
+static void CopyUTF8toUTF16NFC(const nsACString& aSrc, nsAString& aResult)
+{
+ static PRBool sChecked = PR_FALSE;
+ static UnicodeNormalizer sUnicodeNormalizer = NULL;
+
+ // CFStringNormalize was not introduced until Mac OS 10.2
+ if (!sChecked) {
+ CFBundleRef carbonBundle =
+ CFBundleGetBundleWithIdentifier(CFSTR("com.apple.Carbon"));
+ if (carbonBundle)
+ sUnicodeNormalizer = (UnicodeNormalizer)
+ ::CFBundleGetFunctionPointerForName(carbonBundle,
+ CFSTR("CFStringNormalize"));
+ sChecked = PR_TRUE;
+ }
+
+ if (!sUnicodeNormalizer) { // OS X 10.1 or earlier
+ CopyUTF8toUTF16(aSrc, aResult);
+ return;
+ }
+
+ const nsAFlatCString &inFlatSrc = PromiseFlatCString(aSrc);
+
+ // The number of 16bit code units in a UTF-16 string will never be
+ // larger than the number of bytes in the corresponding UTF-8 string.
+ CFMutableStringRef inStr =
+ ::CFStringCreateMutable(NULL, inFlatSrc.Length());
+
+ if (!inStr) {
+ CopyUTF8toUTF16(aSrc, aResult);
+ return;
+ }
+
+ ::CFStringAppendCString(inStr, inFlatSrc.get(), kCFStringEncodingUTF8);
+
+ sUnicodeNormalizer(inStr, kCFStringNormalizationFormC);
+
+ CFIndex length = CFStringGetLength(inStr);
+ const UniChar* chars = CFStringGetCharactersPtr(inStr);
+
+ if (chars)
+ aResult.Assign(chars, length);
+ else {
+ nsAutoBuffer<UniChar, 512> buffer;
+ if (buffer.EnsureElemCapacity(length)) {
+ CFStringGetCharacters(inStr, CFRangeMake(0, length), buffer.get());
+ aResult.Assign(buffer.get(), length);
+ }
+ else
+ CopyUTF8toUTF16(aSrc, aResult);
+ }
+ CFRelease(inStr);
+}
+#endif
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecWin.cpp b/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecWin.cpp
new file mode 100644
index 00000000..7d7e863d
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecWin.cpp
@@ -0,0 +1,766 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// This file is included by nsFileSpec.cp, and includes the Windows-specific
+// implementations.
+
+#include <sys/stat.h>
+#include <direct.h>
+#include <limits.h>
+#include <stdlib.h>
+#include "prio.h"
+#include "nsError.h"
+
+#include <windows.h>
+
+#if (_MSC_VER == 1100) || defined(__GNUC__)
+#define INITGUID
+#include <objbase.h>
+DEFINE_OLEGUID(IID_IPersistFile, 0x0000010BL, 0, 0);
+#endif
+
+#include <shlobj.h>
+#include <shellapi.h>
+#include <shlguid.h>
+
+#ifdef UNICODE
+#define CreateDirectoryW CreateDirectory
+#else
+#define CreateDirectoryA CreateDirectory
+#endif
+
+//----------------------------------------------------------------------------------------
+void nsFileSpecHelpers::Canonify(nsSimpleCharString& 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.IsEmpty())
+ return;
+
+ NS_ASSERTION(strchr((const char*)ioPath, '/') == 0,
+ "This smells like a Unix path. Native path expected! "
+ "Please fix.");
+ if (inMakeDirs)
+ {
+ const int mode = 0755;
+ nsSimpleCharString unixStylePath = ioPath;
+ nsFileSpecHelpers::NativeToUnix(unixStylePath);
+ nsFileSpecHelpers::MakeAllDirectories((const char*)unixStylePath, mode);
+ }
+ char buffer[_MAX_PATH];
+ errno = 0;
+ *buffer = '\0';
+ char* canonicalPath = _fullpath(buffer, ioPath, _MAX_PATH);
+
+ if (canonicalPath)
+ {
+ NS_ASSERTION( canonicalPath[0] != '\0', "Uh oh...couldn't convert" );
+ if (canonicalPath[0] == '\0')
+ return;
+ }
+ ioPath = canonicalPath;
+} // nsFileSpecHelpers::Canonify
+
+//----------------------------------------------------------------------------------------
+void nsFileSpecHelpers::UnixToNative(nsSimpleCharString& 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.IsEmpty())
+ return;
+
+ // Strip initial slash for an absolute path
+ char* src = (char*)ioPath;
+ if (*src == '/') {
+ if (!src[1]) {
+ // allocate new string by copying from ioPath[1]
+ nsSimpleCharString temp = src + 1;
+ ioPath = temp;
+ return;
+ }
+ // Since it was an absolute path, check for the drive letter
+ char* colonPointer = src + 2;
+ if (strstr(src, "|/") == colonPointer)
+ *colonPointer = ':';
+ // allocate new string by copying from ioPath[1]
+ nsSimpleCharString temp = src + 1;
+ ioPath = temp;
+ }
+
+ // Convert '/' to '\'. (Must check EVERY character: consider UNC path
+ // case.)
+ for (src = (char*)ioPath; *src; ++src)
+ {
+ if (*src == '/')
+ *src = '\\';
+ }
+
+} // nsFileSpecHelpers::UnixToNative
+
+//----------------------------------------------------------------------------------------
+void nsFileSpecHelpers::NativeToUnix(nsSimpleCharString& 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.IsEmpty())
+ return;
+
+ // Convert the drive-letter separator, if present
+ nsSimpleCharString temp("/");
+
+ char* cp = (char*)ioPath + 1;
+ if (strstr(cp, ":\\") == cp)
+ *cp = '|'; // absolute path
+ else
+ if (cp[0] == '\\') // unc path
+ cp--;
+ else
+ temp[0] = '\0'; // relative path
+
+ // Convert '\' to '/'
+ for (; *cp; cp++)
+ {
+ if(IsDBCSLeadByte(*cp) && *(cp+1) != nsnull)
+ {
+ cp++;
+ continue;
+ }
+ if (*cp == '\\')
+ *cp = '/';
+ }
+ // Add the slash in front.
+ temp += ioPath;
+ ioPath = temp;
+}
+
+//----------------------------------------------------------------------------------------
+nsFileSpec::nsFileSpec(const nsFilePath& inPath)
+//----------------------------------------------------------------------------------------
+{
+// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!");
+ *this = inPath;
+}
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::operator = (const nsFilePath& inPath)
+//----------------------------------------------------------------------------------------
+{
+ mPath = (const char*)inPath;
+ nsFileSpecHelpers::UnixToNative(mPath);
+ mError = NS_OK;
+} // nsFileSpec::operator =
+
+//----------------------------------------------------------------------------------------
+nsFilePath::nsFilePath(const nsFileSpec& inSpec)
+//----------------------------------------------------------------------------------------
+{
+ *this = inSpec;
+} // nsFilePath::nsFilePath
+
+//----------------------------------------------------------------------------------------
+void nsFilePath::operator = (const nsFileSpec& inSpec)
+//----------------------------------------------------------------------------------------
+{
+ mPath = inSpec.mPath;
+ nsFileSpecHelpers::NativeToUnix(mPath);
+} // nsFilePath::operator =
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::SetLeafName(const char* inLeafName)
+//----------------------------------------------------------------------------------------
+{
+ NS_ASSERTION(inLeafName, "Attempt to SetLeafName with a null string");
+ mPath.LeafReplace('\\', inLeafName);
+} // nsFileSpec::SetLeafName
+
+//----------------------------------------------------------------------------------------
+char* nsFileSpec::GetLeafName() const
+//----------------------------------------------------------------------------------------
+{
+ return mPath.GetLeaf('\\');
+} // nsFileSpec::GetLeafName
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::Exists() const
+//----------------------------------------------------------------------------------------
+{
+ struct stat st;
+ return !mPath.IsEmpty() && 0 == stat(nsNSPRPath(*this), &st);
+} // nsFileSpec::Exists
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::GetModDate(TimeStamp& outStamp) const
+//----------------------------------------------------------------------------------------
+{
+ struct stat st;
+ if (!mPath.IsEmpty() && stat(nsNSPRPath(*this), &st) == 0)
+ outStamp = st.st_mtime;
+ else
+ outStamp = 0;
+} // nsFileSpec::GetModDate
+
+//----------------------------------------------------------------------------------------
+PRUint32 nsFileSpec::GetFileSize() const
+//----------------------------------------------------------------------------------------
+{
+ struct stat st;
+ if (!mPath.IsEmpty() && stat(nsNSPRPath(*this), &st) == 0)
+ return (PRUint32)st.st_size;
+ return 0;
+} // nsFileSpec::GetFileSize
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::IsFile() const
+//----------------------------------------------------------------------------------------
+{
+ struct stat st;
+ return !mPath.IsEmpty() && 0 == stat(nsNSPRPath(*this), &st) && (_S_IFREG & st.st_mode);
+} // nsFileSpec::IsFile
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::IsDirectory() const
+//----------------------------------------------------------------------------------------
+{
+ struct stat st;
+ return !mPath.IsEmpty() && 0 == stat(nsNSPRPath(*this), &st) && (_S_IFDIR & st.st_mode);
+} // nsFileSpec::IsDirectory
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::IsHidden() const
+//----------------------------------------------------------------------------------------
+{
+ PRBool hidden = PR_FALSE;
+ if (!mPath.IsEmpty())
+ {
+ DWORD attr = GetFileAttributes(mPath);
+ if (FILE_ATTRIBUTE_HIDDEN & attr)
+ hidden = PR_TRUE;
+ }
+ return hidden;
+}
+// nsFileSpec::IsHidden
+
+//----------------------------------------------------------------------------------------
+PRBool nsFileSpec::IsSymlink() const
+//----------------------------------------------------------------------------------------
+{
+ HRESULT hres;
+ IShellLink* psl;
+
+ PRBool isSymlink = PR_FALSE;
+
+ CoInitialize(NULL);
+ // Get a pointer to the IShellLink interface.
+ hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&psl);
+ if (SUCCEEDED(hres))
+ {
+ IPersistFile* ppf;
+
+ // Get a pointer to the IPersistFile interface.
+ hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
+
+ if (SUCCEEDED(hres))
+ {
+ WCHAR wsz[MAX_PATH];
+ // Ensure that the string is Unicode.
+ MultiByteToWideChar(CP_ACP, 0, mPath, -1, wsz, MAX_PATH);
+
+ // Load the shortcut.
+ hres = ppf->Load(wsz, STGM_READ);
+ if (SUCCEEDED(hres))
+ {
+ isSymlink = PR_TRUE;
+ }
+
+ // Release the pointer to the IPersistFile interface.
+ ppf->Release();
+ }
+
+ // Release the pointer to the IShellLink interface.
+ psl->Release();
+ }
+
+ CoUninitialize();
+
+ return isSymlink;
+}
+
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::ResolveSymlink(PRBool& wasSymlink)
+//----------------------------------------------------------------------------------------
+{
+ wasSymlink = PR_FALSE; // assume failure
+
+ if (Exists())
+ return NS_OK;
+
+
+ HRESULT hres;
+ IShellLink* psl;
+
+ CoInitialize(NULL);
+
+ // Get a pointer to the IShellLink interface.
+ hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&psl);
+ if (SUCCEEDED(hres))
+ {
+ IPersistFile* ppf;
+
+ // Get a pointer to the IPersistFile interface.
+ hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
+
+ if (SUCCEEDED(hres))
+ {
+ WCHAR wsz[MAX_PATH];
+ // Ensure that the string is Unicode.
+ MultiByteToWideChar(CP_ACP, 0, mPath, -1, wsz, MAX_PATH);
+
+ // Load the shortcut.
+ hres = ppf->Load(wsz, STGM_READ);
+ if (SUCCEEDED(hres))
+ {
+ wasSymlink = PR_TRUE;
+
+ // Resolve the link.
+ hres = psl->Resolve(nsnull, SLR_NO_UI );
+ if (SUCCEEDED(hres))
+ {
+ char szGotPath[MAX_PATH];
+ WIN32_FIND_DATA wfd;
+
+ // Get the path to the link target.
+ hres = psl->GetPath( szGotPath, MAX_PATH, &wfd, SLGP_UNCPRIORITY );
+
+ if (SUCCEEDED(hres))
+ {
+ // Here we modify the nsFileSpec;
+ mPath = szGotPath;
+ mError = NS_OK;
+ }
+ }
+ }
+ else {
+ // It wasn't a shortcut. Oh well. Leave it like it was.
+ hres = 0;
+ }
+
+ // Release the pointer to the IPersistFile interface.
+ ppf->Release();
+ }
+ // Release the pointer to the IShellLink interface.
+ psl->Release();
+ }
+
+ CoUninitialize();
+
+ if (SUCCEEDED(hres))
+ return NS_OK;
+
+ return NS_FILE_FAILURE;
+}
+
+
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::GetParent(nsFileSpec& outSpec) const
+//----------------------------------------------------------------------------------------
+{
+ outSpec.mPath = mPath;
+ char* chars = (char*)outSpec.mPath;
+ chars[outSpec.mPath.Length() - 1] = '\0'; // avoid trailing separator, if any
+ char* cp = strrchr(chars, '\\');
+ if (cp++)
+ outSpec.mPath.SetLength(cp - chars); // truncate.
+} // nsFileSpec::GetParent
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::operator += (const char* inRelativePath)
+//----------------------------------------------------------------------------------------
+{
+ NS_ASSERTION(inRelativePath, "Attempt to do += with a null string");
+
+ if (!inRelativePath || mPath.IsEmpty())
+ return;
+
+ if (mPath[mPath.Length() - 1] == '\\')
+ mPath += "x";
+ else
+ mPath += "\\x";
+
+ // If it's a (unix) relative path, make it native
+ nsSimpleCharString dosPath = inRelativePath;
+ nsFileSpecHelpers::UnixToNative(dosPath);
+ SetLeafName(dosPath);
+} // nsFileSpec::operator +=
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::CreateDirectory(int /*mode*/)
+//----------------------------------------------------------------------------------------
+{
+ // Note that mPath is canonical!
+ if (!mPath.IsEmpty())
+ mkdir(nsNSPRPath(*this));
+} // nsFileSpec::CreateDirectory
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::Delete(PRBool inRecursive) const
+//----------------------------------------------------------------------------------------
+{
+ if (IsDirectory())
+ {
+ if (inRecursive)
+ {
+ for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++)
+ {
+ nsFileSpec& child = (nsFileSpec&)i;
+ child.Delete(inRecursive);
+ }
+ }
+ rmdir(nsNSPRPath(*this));
+ }
+ else if (!mPath.IsEmpty())
+ {
+ remove(nsNSPRPath(*this));
+ }
+} // nsFileSpec::Delete
+
+
+//----------------------------------------------------------------------------------------
+void nsFileSpec::RecursiveCopy(nsFileSpec newDir) const
+//----------------------------------------------------------------------------------------
+{
+ if (IsDirectory())
+ {
+ if (!(newDir.Exists()))
+ {
+ newDir.CreateDirectory();
+ }
+
+ for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++)
+ {
+ nsFileSpec& child = (nsFileSpec&)i;
+
+ if (child.IsDirectory())
+ {
+ nsFileSpec tmpDirSpec(newDir);
+
+ char *leafname = child.GetLeafName();
+ tmpDirSpec += leafname;
+ nsCRT::free(leafname);
+
+ child.RecursiveCopy(tmpDirSpec);
+ }
+ else
+ {
+ child.RecursiveCopy(newDir);
+ }
+ }
+ }
+ else if (!mPath.IsEmpty())
+ {
+ nsFileSpec& filePath = (nsFileSpec&) *this;
+
+ if (!(newDir.Exists()))
+ {
+ newDir.CreateDirectory();
+ }
+
+ filePath.CopyToDir(newDir);
+ }
+} // nsFileSpec::RecursiveCopy
+
+//----------------------------------------------------------------------------------------
+nsresult
+nsFileSpec::Truncate(PRInt32 aNewFileLength) const
+//----------------------------------------------------------------------------------------
+{
+ DWORD status;
+ HANDLE hFile;
+
+ // Leave it to Microsoft to open an existing file with a function
+ // named "CreateFile".
+ hFile = CreateFile(mPath,
+ GENERIC_WRITE,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ return NS_FILE_FAILURE;
+
+ // Seek to new, desired end of file
+ status = SetFilePointer(hFile, aNewFileLength, NULL, FILE_BEGIN);
+ if (status == 0xffffffff)
+ goto error;
+
+ // Truncate file at current cursor position
+ if (!SetEndOfFile(hFile))
+ goto error;
+
+ if (!CloseHandle(hFile))
+ return NS_FILE_FAILURE;
+
+ return NS_OK;
+
+ error:
+ CloseHandle(hFile);
+ return NS_FILE_FAILURE;
+
+} // nsFileSpec::Truncate
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::Rename(const char* inNewName)
+//----------------------------------------------------------------------------------------
+{
+ NS_ASSERTION(inNewName, "Attempt to Rename with a null string");
+
+ // This function should not be used to move a file on disk.
+ if (strchr(inNewName, '/'))
+ return NS_FILE_FAILURE;
+
+ char* oldPath = nsCRT::strdup(mPath);
+
+ SetLeafName(inNewName);
+
+ if (PR_Rename(oldPath, mPath) != NS_OK)
+ {
+ // Could not rename, set back to the original.
+ mPath = oldPath;
+ return NS_FILE_FAILURE;
+ }
+
+ nsCRT::free(oldPath);
+
+ return NS_OK;
+} // nsFileSpec::Rename
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::CopyToDir(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();
+ nsSimpleCharString destPath(inParentDirectory.GetCString());
+ destPath += "\\";
+ destPath += leafname;
+ nsCRT::free(leafname);
+
+ // CopyFile returns non-zero if succeeds
+ int copyOK = CopyFile(GetCString(), destPath, PR_TRUE);
+ if (copyOK)
+ return NS_OK;
+ }
+ return NS_FILE_FAILURE;
+} // nsFileSpec::CopyToDir
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::MoveToDir(const nsFileSpec& inNewParentDirectory)
+//----------------------------------------------------------------------------------------
+{
+ // We can only copy into a directory, and (for now) can not copy entire directories
+ if (inNewParentDirectory.IsDirectory() && (! IsDirectory() ) )
+ {
+ char *leafname = GetLeafName();
+ nsSimpleCharString destPath(inNewParentDirectory.GetCString());
+ destPath += "\\";
+ destPath += leafname;
+ nsCRT::free(leafname);
+
+ // MoveFile returns non-zero if succeeds
+ int copyOK = MoveFile(GetCString(), destPath);
+
+ if (copyOK)
+ {
+ *this = inNewParentDirectory + GetLeafName();
+ return NS_OK;
+ }
+
+ }
+ return NS_FILE_FAILURE;
+} // nsFileSpec::MoveToDir
+
+//----------------------------------------------------------------------------------------
+nsresult nsFileSpec::Execute(const char* inArgs ) const
+//----------------------------------------------------------------------------------------
+{
+ if (!IsDirectory())
+ {
+ nsSimpleCharString fileNameWithArgs = "\"";
+ fileNameWithArgs += mPath + "\" " + inArgs;
+ int execResult = WinExec( fileNameWithArgs, SW_NORMAL );
+ if (execResult > 31)
+ return NS_OK;
+ }
+ return NS_FILE_FAILURE;
+} // nsFileSpec::Execute
+
+
+//----------------------------------------------------------------------------------------
+PRInt64 nsFileSpec::GetDiskSpaceAvailable() const
+//----------------------------------------------------------------------------------------
+{
+ PRInt64 int64;
+
+ LL_I2L(int64 , LONG_MAX);
+
+ char aDrive[_MAX_DRIVE + 2];
+ _splitpath( (const char*)mPath, aDrive, NULL, NULL, NULL);
+
+ if (aDrive[0] == '\0')
+ {
+ // The back end is always trying to pass us paths that look
+ // like /c|/netscape/mail. See if we've got one of them
+ if (mPath.Length() > 2 && mPath[0] == '/' && mPath[2] == '|')
+ {
+ aDrive[0] = mPath[1];
+ aDrive[1] = ':';
+ aDrive[2] = '\0';
+ }
+ else
+ {
+ // Return bogus large number and hope for the best
+ return int64;
+ }
+ }
+
+ strcat(aDrive, "\\");
+
+ // Check disk space
+ DWORD dwSecPerClus, dwBytesPerSec, dwFreeClus, dwTotalClus;
+ ULARGE_INTEGER liFreeBytesAvailableToCaller, liTotalNumberOfBytes, liTotalNumberOfFreeBytes;
+ double nBytes = 0;
+
+ BOOL (WINAPI* getDiskFreeSpaceExA)(LPCTSTR lpDirectoryName,
+ PULARGE_INTEGER lpFreeBytesAvailableToCaller,
+ PULARGE_INTEGER lpTotalNumberOfBytes,
+ PULARGE_INTEGER lpTotalNumberOfFreeBytes) = NULL;
+
+ HINSTANCE hInst = LoadLibrary("KERNEL32.DLL");
+ NS_ASSERTION(hInst != NULL, "COULD NOT LOAD KERNEL32.DLL");
+ if (hInst != NULL)
+ {
+ getDiskFreeSpaceExA = (BOOL (WINAPI*)(LPCTSTR lpDirectoryName,
+ PULARGE_INTEGER lpFreeBytesAvailableToCaller,
+ PULARGE_INTEGER lpTotalNumberOfBytes,
+ PULARGE_INTEGER lpTotalNumberOfFreeBytes))
+ GetProcAddress(hInst, "GetDiskFreeSpaceExA");
+ FreeLibrary(hInst);
+ }
+
+ if (getDiskFreeSpaceExA && (*getDiskFreeSpaceExA)(aDrive,
+ &liFreeBytesAvailableToCaller,
+ &liTotalNumberOfBytes,
+ &liTotalNumberOfFreeBytes))
+ {
+ nBytes = (double)(signed __int64)liFreeBytesAvailableToCaller.QuadPart;
+ }
+ else if ( GetDiskFreeSpace(aDrive, &dwSecPerClus, &dwBytesPerSec, &dwFreeClus, &dwTotalClus))
+ {
+ nBytes = (double)dwFreeClus*(double)dwSecPerClus*(double) dwBytesPerSec;
+ }
+ return (PRInt64)nBytes;
+}
+
+
+
+//========================================================================================
+// nsDirectoryIterator
+//========================================================================================
+
+//----------------------------------------------------------------------------------------
+nsDirectoryIterator::nsDirectoryIterator(const nsFileSpec& inDirectory, PRBool resolveSymlink)
+//----------------------------------------------------------------------------------------
+ : mCurrent(inDirectory)
+ , mDir(nsnull)
+ , mStarting(inDirectory)
+ , mExists(PR_FALSE)
+ , mResoveSymLinks(resolveSymlink)
+{
+ mDir = PR_OpenDir(inDirectory);
+ mCurrent += "dummy";
+ mStarting += "dummy";
+ ++(*this);
+} // nsDirectoryIterator::nsDirectoryIterator
+
+//----------------------------------------------------------------------------------------
+nsDirectoryIterator::~nsDirectoryIterator()
+//----------------------------------------------------------------------------------------
+{
+ if (mDir)
+ PR_CloseDir(mDir);
+} // nsDirectoryIterator::nsDirectoryIterator
+
+//----------------------------------------------------------------------------------------
+nsDirectoryIterator& nsDirectoryIterator::operator ++ ()
+//----------------------------------------------------------------------------------------
+{
+ mExists = PR_FALSE;
+ if (!mDir)
+ return *this;
+ PRDirEntry* entry = PR_ReadDir(mDir, PR_SKIP_BOTH); // Ignore '.' && '..'
+ if (entry)
+ {
+ mExists = PR_TRUE;
+ mCurrent = mStarting;
+ mCurrent.SetLeafName(entry->name);
+ if (mResoveSymLinks)
+ {
+ PRBool ignore;
+ mCurrent.ResolveSymlink(ignore);
+ }
+ }
+ return *this;
+} // nsDirectoryIterator::operator ++
+
+//----------------------------------------------------------------------------------------
+nsDirectoryIterator& nsDirectoryIterator::operator -- ()
+//----------------------------------------------------------------------------------------
+{
+ return ++(*this); // can't do it backwards.
+} // nsDirectoryIterator::operator --
+
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/nsFileStream.cpp b/src/libs/xpcom18a4/xpcom/obsolete/nsFileStream.cpp
new file mode 100644
index 00000000..f20c60e3
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/nsFileStream.cpp
@@ -0,0 +1,392 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// 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 "nsFileSpec.h"
+#include "nsIFileSpec.h"
+#include "nsIStringStream.h"
+#include "nsInt64.h"
+#include <string.h>
+#include <stdio.h>
+
+
+//========================================================================================
+// nsInputStream
+//========================================================================================
+
+//----------------------------------------------------------------------------------------
+nsInputStream::~nsInputStream()
+//----------------------------------------------------------------------------------------
+{
+}
+
+//----------------------------------------------------------------------------------------
+char nsInputStream::get()
+//----------------------------------------------------------------------------------------
+{
+ char c;
+ if (read(&c, sizeof(c)) == sizeof(c))
+ return c;
+ return 0;
+}
+
+//----------------------------------------------------------------------------------------
+PRInt32 nsInputStream::read(void* s, PRInt32 n)
+//----------------------------------------------------------------------------------------
+{
+ if (!mInputStream)
+ return 0;
+ PRInt32 result = 0;
+ mInputStream->Read((char*)s, n, (PRUint32*)&result);
+ if (result == 0)
+ set_at_eof(PR_TRUE);
+ return result;
+} // nsInputStream::read
+
+//----------------------------------------------------------------------------------------
+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()
+//----------------------------------------------------------------------------------------
+{
+}
+
+//----------------------------------------------------------------------------------------
+void nsOutputStream::put(char c)
+//----------------------------------------------------------------------------------------
+{
+ write(&c, sizeof(c));
+}
+
+//----------------------------------------------------------------------------------------
+PRInt32 nsOutputStream::write(const void* s, PRInt32 n)
+//----------------------------------------------------------------------------------------
+{
+ if (!mOutputStream)
+ return 0;
+ PRInt32 result = 0;
+ mWriteStatus = mOutputStream->Write((char*)s, n, (PRUint32*)&result);
+ return result;
+} // nsOutputStream::write
+
+//----------------------------------------------------------------------------------------
+nsresult nsOutputStream::flush()
+//----------------------------------------------------------------------------------------
+{
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+nsresult nsOutputStream::lastWriteStatus()
+//----------------------------------------------------------------------------------------
+{
+ return mWriteStatus;
+}
+
+//----------------------------------------------------------------------------------------
+nsOutputStream& nsOutputStream::operator << (char c)
+//----------------------------------------------------------------------------------------
+{
+ put(c);
+ return *this;
+}
+
+//----------------------------------------------------------------------------------------
+nsOutputStream& nsOutputStream::operator << (const char* s)
+//----------------------------------------------------------------------------------------
+{
+ if (s)
+ write(s, strlen(s));
+ return *this;
+}
+
+//----------------------------------------------------------------------------------------
+nsOutputStream& nsOutputStream::operator << (short val)
+//----------------------------------------------------------------------------------------
+{
+ char buf[30];
+ sprintf(buf, "%hd", val);
+ return (*this << buf);
+}
+
+//----------------------------------------------------------------------------------------
+nsOutputStream& nsOutputStream::operator << (unsigned short val)
+//----------------------------------------------------------------------------------------
+{
+ char buf[30];
+ sprintf(buf, "%hu", 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, "%lu", val);
+ return (*this << buf);
+}
+
+//----------------------------------------------------------------------------------------
+nsOutputStream& nsOutputStream::operator << (int val)
+//----------------------------------------------------------------------------------------
+{
+ char buf[30];
+ sprintf(buf, "%d", val);
+ return (*this << buf);
+}
+
+//----------------------------------------------------------------------------------------
+nsOutputStream& nsOutputStream::operator << (unsigned int val)
+//----------------------------------------------------------------------------------------
+{
+ char buf[30];
+ sprintf(buf, "%u", val);
+ return (*this << buf);
+}
+
+//========================================================================================
+// nsRandomAccessInputStream
+//========================================================================================
+
+//----------------------------------------------------------------------------------------
+PRBool nsRandomAccessInputStream::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;
+
+ nsInt64 position = tell();
+ const nsInt64 zero(0);
+ if (position < zero)
+ 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() && n-1 == bytesRead)
+ bufferLargeEnough = PR_FALSE;
+ position += bytesRead;
+ seek(position);
+ return bufferLargeEnough;
+} // nsRandomAccessInputStream::readline
+
+//========================================================================================
+// nsInputStringStream
+//========================================================================================
+
+//----------------------------------------------------------------------------------------
+nsInputStringStream::nsInputStringStream(const char* stringToRead)
+//----------------------------------------------------------------------------------------
+{
+ nsCOMPtr<nsIInputStream> stream;
+ if (NS_FAILED(NS_NewCharInputStream(getter_AddRefs(stream), stringToRead)))
+ return;
+ mInputStream = stream;
+ mStore = do_QueryInterface(stream);
+}
+
+//----------------------------------------------------------------------------------------
+nsInputStringStream::nsInputStringStream(const nsString& stringToRead)
+//----------------------------------------------------------------------------------------
+{
+ if (NS_FAILED(NS_NewStringInputStream(getter_AddRefs(mInputStream), stringToRead)))
+ return;
+ mStore = do_QueryInterface(mInputStream);
+}
+
+
+//========================================================================================
+// nsInputFileStream
+//========================================================================================
+
+//----------------------------------------------------------------------------------------
+nsInputFileStream::nsInputFileStream(
+ const nsFileSpec& inFile,
+ int nsprMode,
+ PRIntn accessMode)
+//----------------------------------------------------------------------------------------
+{
+ nsISupports* stream;
+ if (NS_FAILED(NS_NewIOFileStream(&stream, inFile, nsprMode, accessMode)))
+ return;
+ AssignFrom(stream);
+ NS_RELEASE(stream);
+} // nsInputFileStream::nsInputFileStream
+
+//----------------------------------------------------------------------------------------
+nsInputFileStream::nsInputFileStream(nsIFileSpec* inSpec)
+//----------------------------------------------------------------------------------------
+{
+ nsIInputStream* stream;
+ if (NS_FAILED(inSpec->GetInputStream(&stream)))
+ return;
+ AssignFrom(stream);
+ NS_RELEASE(stream);
+} // nsInputFileStream::nsInputFileStream
+
+//----------------------------------------------------------------------------------------
+nsInputFileStream::~nsInputFileStream()
+//----------------------------------------------------------------------------------------
+{
+// if (is_open())
+// close();
+}
+
+//----------------------------------------------------------------------------------------
+void nsInputFileStream::AssignFrom(nsISupports* stream)
+//----------------------------------------------------------------------------------------
+{
+ mFile = do_QueryInterface(stream);
+ mInputStream = do_QueryInterface(stream);
+ mStore = do_QueryInterface(stream);
+ mFileInputStream = do_QueryInterface(stream);
+}
+
+//========================================================================================
+// nsOutputFileStream
+//========================================================================================
+
+//----------------------------------------------------------------------------------------
+nsOutputFileStream::nsOutputFileStream(nsIFileSpec* inSpec)
+//----------------------------------------------------------------------------------------
+{
+ if (!inSpec)
+ return;
+ nsIOutputStream* stream;
+ if (NS_FAILED(inSpec->GetOutputStream(&stream)))
+ return;
+ AssignFrom(stream);
+ NS_RELEASE(stream);
+}
+
+//----------------------------------------------------------------------------------------
+nsOutputFileStream::~nsOutputFileStream()
+//----------------------------------------------------------------------------------------
+{
+// if (is_open())
+// close();
+}
+//----------------------------------------------------------------------------------------
+void nsOutputFileStream::AssignFrom(nsISupports* stream)
+//----------------------------------------------------------------------------------------
+{
+ mFile = do_QueryInterface(stream);
+ mOutputStream = do_QueryInterface(stream);
+ mStore = do_QueryInterface(stream);
+ mFileOutputStream = do_QueryInterface(stream);
+}
+
+//----------------------------------------------------------------------------------------
+nsresult nsOutputFileStream::flush()
+//----------------------------------------------------------------------------------------
+{
+ if (mFileOutputStream)
+ mFileOutputStream->Flush();
+ return error();
+}
+
+//----------------------------------------------------------------------------------------
+void nsOutputFileStream::abort()
+//----------------------------------------------------------------------------------------
+{
+ mResult = NS_FILE_FAILURE;
+ close();
+}
+
+//========================================================================================
+// Manipulators
+//========================================================================================
+
+//----------------------------------------------------------------------------------------
+nsOutputStream& nsEndl(nsOutputStream& os)
+//----------------------------------------------------------------------------------------
+{
+#if defined(XP_WIN) || defined(XP_OS2)
+ os.write("\r\n", 2);
+#elif defined (XP_MAC)
+ os.put('\r');
+#else
+ os.put('\n');
+#endif
+ //os.flush();
+ return os;
+} // nsEndl
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/nsFileStream.h b/src/libs/xpcom18a4/xpcom/obsolete/nsFileStream.h
new file mode 100644
index 00000000..b0cd5e8a
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/nsFileStream.h
@@ -0,0 +1,772 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// 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 wrappers for the file-related
+// versions of the above.
+// nsIOFileStream
+// An input and output file stream attached to the same file.
+//
+// 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 "xpcomobsolete.h"
+#include "nsStringFwd.h"
+
+#ifdef XP_MAC
+#include "pprio.h" // To get PR_ImportFile
+#else
+#include "prio.h"
+#endif
+
+#include "nsCOMPtr.h"
+#include "nsIFileStream.h"
+
+// Defined elsewhere
+class nsFileSpec;
+class nsIInputStream;
+class nsIOutputStream;
+class nsIFileSpec;
+
+//========================================================================================
+// Compiler-specific macros, as needed
+//========================================================================================
+#if !defined(NS_USING_NAMESPACE) && (defined(__MWERKS__) || defined(_MSC_VER))
+#define NS_USING_NAMESPACE
+#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
+
+#if !defined(XP_MAC) && !defined(__KCC)
+// 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_COM_OBSOLETE 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;
+ }
+ PRBool eof() const { return get_at_eof(); }
+ char get();
+ nsresult close()
+ {
+ NS_ASSERTION(mInputStream, "mInputStream is null!");
+ if (mInputStream) {
+ return mInputStream->Close();
+ }
+ return NS_OK;
+ }
+ PRInt32 read(void* s, PRInt32 n);
+
+ // 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);
+ }
+
+protected:
+
+ // These certainly need to be overridden, they give the best shot we can at detecting
+ // eof in a simple nsIInputStream.
+ virtual void set_at_eof(PRBool atEnd)
+ {
+ mEOF = atEnd;
+ }
+ virtual PRBool get_at_eof() const
+ {
+ return mEOF;
+ }
+private:
+
+ nsInputStream& operator >> (char* buf); // TOO DANGEROUS. DON'T DEFINE.
+
+ // private and unimplemented to disallow copies and assigns
+ nsInputStream(const nsInputStream& rhs);
+ nsInputStream& operator=(const nsInputStream& rhs);
+
+// DATA
+protected:
+ nsCOMPtr<nsIInputStream> mInputStream;
+ PRBool mEOF;
+}; // class nsInputStream
+
+typedef nsInputStream nsBasicInStream; // historic support for this name
+
+//========================================================================================
+class NS_COM_OBSOLETE 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;
+ }
+ nsresult close()
+ {
+ if (mOutputStream)
+ return mOutputStream->Close();
+ return NS_OK;
+ }
+ void put(char c);
+ PRInt32 write(const void* s, PRInt32 n);
+ virtual nsresult flush();
+ nsresult lastWriteStatus();
+
+ // 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);
+ nsOutputStream& operator << (int val);
+ nsOutputStream& operator << (unsigned int val);
+
+ // Support manipulators
+ nsOutputStream& operator << (nsOutputStream& (*pf)(nsOutputStream&))
+ {
+ return pf(*this);
+ }
+
+private:
+
+ // private and unimplemented to disallow copies and assigns
+ nsOutputStream(const nsOutputStream& rhs);
+ nsOutputStream& operator=(const nsOutputStream& rhs);
+
+ nsresult mWriteStatus;
+
+// DATA
+protected:
+ nsCOMPtr<nsIOutputStream> mOutputStream;
+}; // class nsOutputStream
+
+typedef nsOutputStream nsBasicOutStream; // Historic support for this name
+
+//========================================================================================
+class NS_COM_OBSOLETE nsErrorProne
+// Common (virtual) base class for remembering errors on demand
+//========================================================================================
+{
+public:
+ nsErrorProne() // for delayed opening
+ : mResult(NS_OK)
+ {
+ }
+ PRBool failed() const
+ {
+ return NS_FAILED(mResult);
+ }
+ nsresult error() const
+ {
+ return mResult;
+ }
+
+// DATA
+protected:
+ nsresult mResult;
+}; // class nsErrorProne
+
+//========================================================================================
+class NS_COM_OBSOLETE 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 virtual nsErrorProne
+{
+public:
+ nsFileClient(const nsCOMPtr<nsIOpenFile>& inFile)
+ : mFile(do_QueryInterface(inFile))
+ {
+ }
+ virtual ~nsFileClient() {}
+
+ 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 is_file() const
+ {
+ return mFile ? PR_TRUE : PR_FALSE;
+ }
+
+protected:
+
+ nsFileClient() // for delayed opening
+ {
+ }
+// DATA
+protected:
+ nsCOMPtr<nsIOpenFile> mFile;
+}; // class nsFileClient
+
+//========================================================================================
+class NS_COM_OBSOLETE nsRandomAccessStoreClient
+// 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 virtual nsErrorProne
+{
+public:
+ nsRandomAccessStoreClient() // for delayed opening
+ {
+ }
+ nsRandomAccessStoreClient(const nsCOMPtr<nsIRandomAccessStore>& inStore)
+ : mStore(do_QueryInterface(inStore))
+ {
+ }
+ virtual ~nsRandomAccessStoreClient() {}
+
+ void seek(PRInt64 offset)
+ {
+ seek(PR_SEEK_SET, offset);
+ }
+
+ void seek(PRSeekWhence whence, PRInt64 offset)
+ {
+ set_at_eof(PR_FALSE);
+ if (mStore)
+ mResult = mStore->Seek(whence, offset);
+ }
+ PRInt64 tell()
+ {
+ PRInt64 result;
+ LL_I2L(result, -1);
+ if (mStore)
+ mResult = mStore->Tell(&result);
+ return result;
+ }
+
+protected:
+
+ virtual PRBool get_at_eof() const
+ {
+ PRBool result = PR_TRUE;
+ if (mStore)
+ mStore->GetAtEOF(&result);
+ return result;
+ }
+
+ virtual void set_at_eof(PRBool atEnd)
+ {
+ if (mStore)
+ mStore->SetAtEOF(atEnd);
+ }
+
+private:
+
+ // private and unimplemented to disallow copies and assigns
+ nsRandomAccessStoreClient(const nsRandomAccessStoreClient& rhs);
+ nsRandomAccessStoreClient& operator=(const nsRandomAccessStoreClient& rhs);
+
+// DATA
+protected:
+ nsCOMPtr<nsIRandomAccessStore> mStore;
+}; // class nsRandomAccessStoreClient
+
+//========================================================================================
+class NS_COM_OBSOLETE nsRandomAccessInputStream
+// Please read the comments at the top of this file
+//========================================================================================
+: public nsRandomAccessStoreClient
+, public nsInputStream
+{
+public:
+ nsRandomAccessInputStream(nsIInputStream* inStream)
+ : nsRandomAccessStoreClient(do_QueryInterface(inStream))
+ , nsInputStream(inStream)
+ {
+ }
+ 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).
+
+ // Input streamers. Unfortunately, they don't inherit!
+ nsInputStream& operator >> (char& ch)
+ { return nsInputStream::operator >>(ch); }
+ nsInputStream& operator >> (nsInputStream& (*pf)(nsInputStream&))
+ { return nsInputStream::operator >>(pf); }
+
+protected:
+ nsRandomAccessInputStream()
+ : nsInputStream(nsnull)
+ {
+ }
+
+ virtual PRBool get_at_eof() const
+ {
+ return nsRandomAccessStoreClient::get_at_eof();
+ }
+
+ virtual void set_at_eof(PRBool atEnd)
+ {
+ nsRandomAccessStoreClient::set_at_eof(atEnd);
+ }
+
+private:
+
+ // private and unimplemented to disallow copies and assigns
+ nsRandomAccessInputStream(const nsRandomAccessInputStream& rhs);
+ nsRandomAccessInputStream& operator=(const nsRandomAccessInputStream& rhs);
+
+}; // class nsRandomAccessInputStream
+
+//========================================================================================
+class NS_COM_OBSOLETE nsInputStringStream
+//========================================================================================
+: public nsRandomAccessInputStream
+{
+public:
+ nsInputStringStream(const char* stringToRead);
+ nsInputStringStream(const nsString& stringToRead);
+
+ // Input streamers. Unfortunately, they don't inherit!
+ nsInputStream& operator >> (char& ch)
+ { return nsInputStream::operator >>(ch); }
+ nsInputStream& operator >> (nsInputStream& (*pf)(nsInputStream&))
+ { return nsInputStream::operator >>(pf); }
+
+
+private:
+
+ // private and unimplemented to disallow copies and assigns
+ nsInputStringStream(const nsInputStringStream& rhs);
+ nsInputStringStream& operator=(const nsInputStringStream& rhs);
+
+
+}; // class nsInputStringStream
+
+//========================================================================================
+class NS_COM_OBSOLETE nsInputFileStream
+// Please read the comments at the top of this file
+//========================================================================================
+: public nsRandomAccessInputStream
+, public nsFileClient
+{
+public:
+ enum { kDefaultMode = PR_RDONLY };
+ nsInputFileStream(nsIInputStream* inStream)
+ : nsRandomAccessInputStream(inStream)
+ , nsFileClient(do_QueryInterface(inStream))
+ , mFileInputStream(do_QueryInterface(inStream))
+ {
+ }
+ nsInputFileStream(
+ const nsFileSpec& inFile,
+ int nsprMode = kDefaultMode,
+ PRIntn accessMode = 00666);
+ nsInputFileStream(nsIFileSpec* inFile);
+ virtual ~nsInputFileStream();
+
+ void Open(
+ const nsFileSpec& inFile,
+ int nsprMode = kDefaultMode,
+ PRIntn accessMode = 00666)
+ {
+ 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); }
+
+protected:
+ void AssignFrom(nsISupports* stream);
+
+private:
+
+ // private and unimplemented to disallow copies and assigns
+ nsInputFileStream(const nsInputFileStream& rhs);
+ nsInputFileStream& operator=(const nsInputFileStream& rhs);
+
+// DATA
+protected:
+ nsCOMPtr<nsIFileSpecInputStream> mFileInputStream;
+}; // class nsInputFileStream
+
+//========================================================================================
+class NS_COM_OBSOLETE nsRandomAccessOutputStream
+// Please read the comments at the top of this file
+//========================================================================================
+: public nsRandomAccessStoreClient
+, public nsOutputStream
+{
+public:
+ nsRandomAccessOutputStream(nsIOutputStream* inStream)
+ : nsRandomAccessStoreClient(do_QueryInterface(inStream))
+ , nsOutputStream(inStream)
+ {
+ }
+
+ // 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 << (int val)
+ { return nsOutputStream::operator << (val); }
+ nsOutputStream& operator << (unsigned int val)
+ { return nsOutputStream::operator << (val); }
+ nsOutputStream& operator << (nsOutputStream& (*pf)(nsOutputStream&))
+ { return nsOutputStream::operator << (pf); }
+
+protected:
+ nsRandomAccessOutputStream()
+ : nsOutputStream(nsnull)
+ {
+ }
+
+private:
+
+ // private and unimplemented to disallow copies and assigns
+ nsRandomAccessOutputStream(const nsRandomAccessOutputStream& rhs);
+ nsRandomAccessOutputStream& operator=(const nsRandomAccessOutputStream& rhs);
+
+}; // class nsRandomAccessOutputStream
+
+//========================================================================================
+class NS_COM_OBSOLETE nsOutputFileStream
+// Please read the comments at the top of this file
+//========================================================================================
+: public nsRandomAccessOutputStream
+, public nsFileClient
+{
+public:
+ enum { kDefaultMode = (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE) };
+
+ nsOutputFileStream() {}
+ nsOutputFileStream(nsIOutputStream* inStream)
+ {
+ AssignFrom(inStream);
+ }
+ nsOutputFileStream(
+ const nsFileSpec& inFile,
+ int nsprMode = kDefaultMode,
+ PRIntn accessMode = 00666)
+ {
+ nsISupports* stream;
+ if (NS_FAILED(NS_NewIOFileStream(
+ &stream,
+ inFile, nsprMode, accessMode)))
+ return;
+ AssignFrom(stream);
+ NS_RELEASE(stream);
+ }
+ nsOutputFileStream(nsIFileSpec* inFile);
+ virtual ~nsOutputFileStream();
+
+ virtual nsresult flush();
+ virtual void abort();
+
+ // 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 << (int val)
+ { return nsOutputStream::operator << (val); }
+ nsOutputStream& operator << (unsigned int val)
+ { return nsOutputStream::operator << (val); }
+ nsOutputStream& operator << (nsOutputStream& (*pf)(nsOutputStream&))
+ { return nsOutputStream::operator << (pf); }
+
+protected:
+ void AssignFrom(nsISupports* stream);
+
+private:
+
+ // private and unimplemented to disallow copies and assigns
+ nsOutputFileStream(const nsOutputFileStream& rhs);
+ nsOutputFileStream& operator=(const nsOutputFileStream& rhs);
+
+// DATA
+protected:
+ nsCOMPtr<nsIFileSpecOutputStream> mFileOutputStream;
+}; // class nsOutputFileStream
+
+
+//========================================================================================
+class 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 = 00666)
+ : nsInputFileStream((nsIInputStream*)nsnull)
+ , nsOutputStream(nsnull)
+ {
+ nsISupports* stream;
+ if (NS_FAILED(NS_NewIOFileStream(
+ &stream,
+ inFile, nsprMode, accessMode)))
+ return;
+ mFile = do_QueryInterface(stream);
+ mStore = do_QueryInterface(stream);
+ mInputStream = do_QueryInterface(stream);
+ mOutputStream = do_QueryInterface(stream);
+ mFileInputStream = do_QueryInterface(stream);
+ mFileOutputStream = do_QueryInterface(stream);
+ NS_RELEASE(stream);
+ }
+
+ virtual nsresult close()
+ {
+ // Doesn't matter which of the two we close:
+ // they're hooked up to the same file.
+ return nsInputFileStream::close();
+ }
+
+ // 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 << (int val)
+ { return nsOutputStream::operator << (val); }
+ nsOutputStream& operator << (unsigned int 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); }
+
+ virtual nsresult flush() {if (mFileOutputStream) mFileOutputStream->Flush(); return error(); }
+
+
+private:
+
+ // private and unimplemented to disallow copies and assigns
+ nsIOFileStream(const nsIOFileStream& rhs);
+ nsIOFileStream& operator=(const nsIOFileStream& rhs);
+
+ // DATA
+protected:
+ nsCOMPtr<nsIFileSpecOutputStream> mFileOutputStream;
+}; // class nsIOFileStream
+
+//========================================================================================
+// Manipulators
+//========================================================================================
+
+NS_COM_OBSOLETE nsOutputStream& nsEndl(nsOutputStream& os); // outputs and FLUSHES.
+
+//========================================================================================
+#endif /* _FILESTREAM_H_ */
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/nsIFileSpec.idl b/src/libs/xpcom18a4/xpcom/obsolete/nsIFileSpec.idl
new file mode 100644
index 00000000..78abd9e7
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/nsIFileSpec.idl
@@ -0,0 +1,204 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ THIS INTERFACE IS DEPRECATED AND UNSUPPORTED! USE |nsIFile| and |nsILocalFile|.
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+
+// This is the only correct cross-platform way to specify a file.
+// Strings are not such a way. If you grew up on windows or unix, you
+// may think they are. Welcome to reality.
+
+#include "nsISupports.idl"
+
+%{C++
+#include "nsFileSpec.h" // for factory method
+%}
+
+interface nsIFileURL;
+interface nsIFilePath;
+interface nsIOutputStream;
+interface nsIInputStream;
+
+// Define Contractid and CID
+%{C++
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ THIS INTERFACE IS DEPRECATED AND UNSUPPORTED! USE |nsIFile| and |nsILocalFile|.
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+// {A5740FA2-146E-11d3-B00D-00C04FC2E79B}
+#define NS_FILESPEC_CID \
+{ 0xa5740fa2, 0x146e, 0x11d3, { 0xb0, 0xd, 0x0, 0xc0, 0x4f, 0xc2, 0xe7, 0x9b } }
+
+#define NS_FILESPEC_CONTRACTID "@mozilla.org/filespec;1"
+#define NS_FILESPEC_CLASSNAME "File Spec"
+
+%}
+
+ native nsFileSpec(nsFileSpec);
+[ref] native nsFileSpecRef(nsFileSpec);
+[ptr] native nsFileSpecPtr(nsFileSpec);
+
+[scriptable, uuid(d8c0a080-0868-11d3-915f-d9d889d48e3c)]
+interface nsIFileSpec : nsISupports
+{
+ void fromFileSpec([const] in nsIFileSpec original);
+
+ attribute string URLString;
+ attribute string unixStyleFilePath;
+ attribute string persistentDescriptorString;
+ attribute string nativePath;
+
+ readonly attribute string NSPRPath;
+
+ void error();
+
+ boolean isValid();
+ boolean failed();
+
+ attribute string leafName;
+
+ readonly attribute nsIFileSpec parent;
+ readonly attribute nsIInputStream inputStream;
+ readonly attribute nsIOutputStream outputStream;
+ boolean isChildOf(in nsIFileSpec possibleParent);
+ [noscript] readonly attribute nsFileSpec fileSpec;
+ [noscript] void setFromFileSpec([const] in nsFileSpecRef spec);
+
+ attribute string fileContents;
+
+ void makeUnique();
+ void makeUniqueWithSuggestedName(in string suggestedName);
+
+ readonly attribute unsigned long modDate;
+ boolean modDateChanged(in unsigned long oldStamp);
+
+ boolean isDirectory();
+ boolean isFile();
+ boolean exists();
+ boolean isHidden();
+
+ boolean equals(in nsIFileSpec spec);
+
+ readonly attribute unsigned long fileSize;
+ readonly attribute long long diskSpaceAvailable;
+
+ void appendRelativeUnixPath(in string relativePath);
+
+ void createDir();
+ void touch();
+
+ boolean isSymlink();
+ void resolveSymlink();
+
+ void delete(in boolean recursive);
+ void truncate(in long aNewLength);
+ void rename([const] in string newLeafName);
+ void copyToDir([const] in nsIFileSpec newParentDir);
+ void moveToDir([const] in nsIFileSpec newParentDir);
+ void execute([const] in string args);
+
+ void openStreamForReading();
+ void openStreamForWriting();
+ void openStreamForReadingAndWriting();
+ void closeStream();
+ boolean isStreamOpen();
+
+ boolean eof();
+ long read(inout string buffer, in long requestedCount);
+ void readLine(inout string line, in long bufferSize, out boolean wasTruncated);
+
+ /** Check eof() before each call.
+ * CAUTION: false result only indicates line was truncated
+ * to fit buffer, or an error occurred (OTHER THAN eof).
+ */
+ long write(in string data, in long requestedCount);
+ void flush();
+
+ void seek(in long offset);
+ long tell();
+ void endLine();
+ attribute AString unicodePath;
+
+};
+
+// Define Contractid and CID
+%{C++
+// {a3020981-2018-11d3-915f-a957795b7ebc}
+#define NS_DIRECTORYITERATOR_CID \
+{ 0xa3020981, 0x2018, 0x11d3, { 0x91, 0x5f, 0xa9, 0x57, 0x79, 0x5b, 0x7e, 0xbc } }
+
+#define NS_DIRECTORYITERATOR_CONTRACTID "@mozilla.org/directoryiterator;1"
+#define NS_DIRECTORYITERATOR_CLASSNAME "nsIDirectoryIterator"
+%}
+
+[scriptable, uuid(d8c0a083-0868-11d3-915f-d9d889d48e3c)]
+interface nsIDirectoryIterator : nsISupports
+{
+ void init(in nsIFileSpec parent, in boolean resolveSymlink);
+ boolean exists();
+ void next();
+ readonly attribute nsIFileSpec currentSpec;
+};
+
+%{C++
+// Factory methods if you link with xpcom
+NS_COM_OBSOLETE nsresult NS_NewFileSpecWithSpec(const nsFileSpec& aSrcFileSpec, nsIFileSpec **result);
+NS_COM_OBSOLETE nsresult NS_NewFileSpec(nsIFileSpec** result);
+NS_COM_OBSOLETE nsresult NS_NewDirectoryIterator(nsIDirectoryIterator** result);
+
+// Convert from nsIFile to nsIFileSpec
+//
+// XXX This function is here only to assist with the migration from nsIFileSpec
+// to nsIFile. This function will dissappear in future mozilla releases.
+//
+// ...ripped from nsPrefService.cpp:
+//
+// "So discouraged is the use of nsIFileSpec, nobody wanted to have this routine be
+// public - It might lead to continued use of nsIFileSpec. Right now, [mozilla] has
+// such a need for it, here it is. Let's stop having to use it though."
+//
+NS_COM_OBSOLETE nsresult NS_NewFileSpecFromIFile(nsIFile *aFile, nsIFileSpec **result);
+
+#define NS_BOOL_ACCESSOR(_method) { PRBool yes; return NS_SUCCEEDED(f->_method(&yes)) && yes; }
+inline PRBool Exists(nsIFileSpec* f) NS_BOOL_ACCESSOR(Exists)
+inline PRBool Exists(nsIDirectoryIterator* f) NS_BOOL_ACCESSOR(Exists)
+inline PRBool IsDirectory(nsIFileSpec* f) NS_BOOL_ACCESSOR(IsDirectory)
+
+%}
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/nsIFileStream.cpp b/src/libs/xpcom18a4/xpcom/obsolete/nsIFileStream.cpp
new file mode 100644
index 00000000..011bcdaa
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/nsIFileStream.cpp
@@ -0,0 +1,727 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Pierre Phaneuf <pp@ludusdesign.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsIFileStream.h"
+#include "nsFileSpec.h"
+#include "nsCOMPtr.h"
+
+#include "prerror.h"
+
+#include "nsSegmentedBuffer.h"
+#include "nsInt64.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 nsIRandomAccessStore
+ , public nsIFileSpecOutputStream
+ , public nsIFileSpecInputStream
+ , public nsIOpenFile
+//========================================================================================
+{
+ public:
+ FileImpl(PRFileDesc* inDesc);
+ FileImpl(const nsFileSpec& inFile, int nsprMode, PRIntn accessMode);
+
+ // nsISupports interface
+ NS_DECL_ISUPPORTS
+
+ // nsIOpenFile interface
+ NS_IMETHOD Open(const nsFileSpec& inFile, int nsprMode, PRIntn accessMode);
+ NS_IMETHOD Close();
+ NS_IMETHOD GetIsOpen(PRBool* outOpen);
+
+ // nsIInputStream interface
+ NS_IMETHOD Available(PRUint32 *aLength);
+ NS_IMETHOD Read(char* aBuf, PRUint32 aCount, PRUint32 *aReadCount);
+ NS_IMETHOD ReadSegments(nsWriteSegmentFun writer, void * closure, PRUint32 count, PRUint32 *_retval);
+ NS_IMETHOD IsNonBlocking(PRBool *aNonBlocking);
+
+ // nsIOutputStream interface
+ NS_IMETHOD Write(const char* aBuf, PRUint32 aCount, PRUint32 *aWriteCount);
+ NS_IMETHOD Flush();
+ NS_IMETHOD WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *_retval);
+ NS_IMETHOD WriteSegments(nsReadSegmentFun reader, void * closure, PRUint32 count, PRUint32 *_retval);
+
+ // nsIRandomAccessStore interface
+ NS_DECL_NSISEEKABLESTREAM
+ NS_IMETHOD GetAtEOF(PRBool* outAtEOF);
+ NS_IMETHOD SetAtEOF(PRBool inAtEOF);
+
+ private:
+
+ ~FileImpl();
+
+ protected:
+
+ enum {
+ kOuputBufferSegmentSize = 4096,
+ kOuputBufferMaxSize = 4096
+ };
+
+ nsresult InternalFlush(PRBool syncFile);
+ nsresult AllocateBuffers(PRUint32 segmentSize, PRUint32 maxSize);
+
+ PRFileDesc* mFileDesc;
+ int mNSPRMode;
+ PRBool mFailed;
+ PRBool mEOF;
+ PRInt32 mLength;
+
+ PRBool mGotBuffers;
+ nsSegmentedBuffer mOutBuffer;
+ char* mWriteCursor;
+ char* mWriteLimit;
+
+}; // class FileImpl
+
+NS_IMPL_RELEASE(FileImpl)
+NS_IMPL_ADDREF(FileImpl)
+
+NS_IMPL_QUERY_HEAD(FileImpl)
+ NS_IMPL_QUERY_BODY(nsIOpenFile)
+ NS_IMPL_QUERY_BODY(nsISeekableStream)
+ NS_IMPL_QUERY_BODY(nsIRandomAccessStore)
+ NS_IMPL_QUERY_BODY(nsIOutputStream)
+ NS_IMPL_QUERY_BODY(nsIInputStream)
+ NS_IMPL_QUERY_BODY(nsIFileSpecInputStream)
+ NS_IMPL_QUERY_BODY(nsIFileSpecOutputStream)
+NS_IMPL_QUERY_TAIL(nsIOutputStream)
+
+
+//----------------------------------------------------------------------------------------
+FileImpl::FileImpl(PRFileDesc* inDesc)
+//----------------------------------------------------------------------------------------
+: mFileDesc(inDesc)
+, mNSPRMode(0)
+, mFailed(PR_FALSE)
+, mEOF(PR_FALSE)
+, mLength(-1)
+, mGotBuffers(PR_FALSE)
+{
+ mWriteCursor = nsnull;
+ mWriteLimit = nsnull;
+}
+
+
+//----------------------------------------------------------------------------------------
+FileImpl::FileImpl(const nsFileSpec& inFile, int nsprMode, PRIntn accessMode)
+//----------------------------------------------------------------------------------------
+: mFileDesc(nsnull)
+, mNSPRMode(-1)
+, mEOF(PR_FALSE)
+, mLength(-1)
+, mGotBuffers(PR_FALSE)
+{
+ mWriteCursor = nsnull;
+ mWriteLimit = nsnull;
+
+ nsresult rv = Open(inFile, nsprMode, accessMode); // this sets nsprMode
+
+ if (NS_FAILED(rv))
+ {
+ mFailed = PR_TRUE;
+#if DEBUG
+ char *fileName = inFile.GetLeafName();
+ printf("Opening file %s failed\n", fileName);
+ nsCRT::free(fileName);
+#endif
+ }
+ else
+ {
+ mFailed = PR_FALSE;
+ }
+}
+
+//----------------------------------------------------------------------------------------
+FileImpl::~FileImpl()
+//----------------------------------------------------------------------------------------
+{
+ nsresult rv = Close();
+ NS_ASSERTION(NS_SUCCEEDED(rv), "Close failed");
+}
+
+
+//----------------------------------------------------------------------------------------
+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;
+ OSErr err = inFile.Error();
+ if (err != noErr)
+ if (err != fnfErr || !(nsprMode & PR_CREATE_FILE))
+ return NS_FILE_RESULT(inFile.Error());
+ 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.ResolveSymlink(ignoredResult);
+ const FSSpec& spec = original.operator const FSSpec&();
+ if (nsprMode & PR_CREATE_FILE) {
+ // In order to get the right file type/creator, do it with an nsILocalFileMac
+ // Don't propagate any errors in doing this. If any error, just use FSpCreate.
+ FSSpec nonConstSpec = spec;
+ nsCOMPtr<nsILocalFileMac> macFile;
+ nsresult res = NS_NewLocalFileWithFSSpec(&nonConstSpec, PR_FALSE, getter_AddRefs(macFile));
+ if (NS_SUCCEEDED(res)) {
+ nsCOMPtr<nsIFile> asFile(do_QueryInterface(macFile, &res));
+ if (NS_SUCCEEDED(res)) {
+ res = asFile->Create(nsIFile::NORMAL_FILE_TYPE, 0);
+ if (res == NS_ERROR_FILE_ALREADY_EXISTS)
+ res = NS_OK;
+ }
+ }
+ if (NS_FAILED(res))
+ 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::Available(PRUint32 *aLength)
+//----------------------------------------------------------------------------------------
+{
+ NS_PRECONDITION(aLength != nsnull, "null ptr");
+ if (!aLength)
+ return NS_ERROR_NULL_POINTER;
+ if (mLength < 0)
+ return NS_ERROR_UNEXPECTED;
+ *aLength = mLength;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP FileImpl::GetIsOpen(PRBool* outOpen)
+//----------------------------------------------------------------------------------------
+{
+ *outOpen = (mFileDesc != nsnull && !mFailed);
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP FileImpl::Seek(PRInt32 whence, PRInt64 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.
+
+ // To avoid corruption, we flush during a seek. see bug number 18949
+ InternalFlush(PR_FALSE);
+
+ nsInt64 position = PR_Seek64(mFileDesc, 0, PR_SEEK_CUR);
+ nsInt64 available = PR_Available64(mFileDesc);
+ nsInt64 fileSize = position + available;
+ nsInt64 newPosition = offset;
+ switch (whence)
+ {
+ case NS_SEEK_CUR: newPosition += position; break;
+ case NS_SEEK_SET: ; break;
+ case NS_SEEK_END: newPosition += fileSize; break;
+ }
+ const nsInt64 zero = 0;
+ if (newPosition < zero)
+ {
+ newPosition = 0;
+ mFailed = PR_TRUE;
+ }
+ if (newPosition >= fileSize) // nb: not "else if".
+ {
+ newPosition = fileSize;
+ mEOF = PR_TRUE;
+ }
+ if (PR_Seek64(mFileDesc, newPosition, PR_SEEK_SET) < 0)
+ mFailed = PR_TRUE;
+ return NS_OK;
+} // FileImpl::Seek
+
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP FileImpl::Read(char* aBuf, 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;
+ PRInt32 bytesRead = PR_Read(mFileDesc, aBuf, aCount);
+ if (bytesRead < 0)
+ {
+ *aReadCount = 0;
+ mFailed = PR_TRUE;
+ return NS_FILE_RESULT(PR_GetError());
+ }
+ else if (bytesRead == 0)
+ {
+ mEOF = PR_TRUE;
+ }
+ *aReadCount = bytesRead;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+FileImpl::ReadSegments(nsWriteSegmentFun writer, void * closure, PRUint32 count, PRUint32 *_retval)
+{
+ NS_NOTREACHED("ReadSegments");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP FileImpl::Write(const char* aBuf, PRUint32 aCount, PRUint32 *aWriteCount)
+//----------------------------------------------------------------------------------------
+{
+ NS_PRECONDITION(aBuf != nsnull, "null ptr");
+ NS_PRECONDITION(aWriteCount != nsnull, "null ptr");
+
+ *aWriteCount = 0;
+
+#ifdef XP_MAC
+ // Calling PR_Write on stdout is sure suicide.
+ if (mFileDesc == PR_STDOUT || mFileDesc == PR_STDERR)
+ {
+ std::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 (!mGotBuffers)
+ {
+ nsresult rv = AllocateBuffers(kOuputBufferSegmentSize, kOuputBufferMaxSize);
+ if (NS_FAILED(rv))
+ return rv; // try to write non-buffered?
+ }
+
+ PRUint32 bufOffset = 0;
+ PRUint32 currentWrite = 0;
+ while (aCount > 0)
+ {
+ if (mWriteCursor == nsnull || mWriteCursor == mWriteLimit)
+ {
+ char* seg = mOutBuffer.AppendNewSegment();
+ if (seg == nsnull)
+ {
+ // buffer is full, try again
+ InternalFlush(PR_FALSE);
+ seg = mOutBuffer.AppendNewSegment();
+ if (seg == nsnull)
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ mWriteCursor = seg;
+ mWriteLimit = seg + mOutBuffer.GetSegmentSize();
+ }
+
+ // move
+ currentWrite = mWriteLimit - mWriteCursor;
+
+ if (aCount < currentWrite)
+ currentWrite = aCount;
+
+ memcpy(mWriteCursor, (aBuf + bufOffset), currentWrite);
+
+ mWriteCursor += currentWrite;
+
+ aCount -= currentWrite;
+ bufOffset += currentWrite;
+ *aWriteCount += currentWrite;
+ }
+
+ return NS_OK;
+}
+
+static NS_METHOD
+nsWriteSegmentToFile(nsIInputStream* in,
+ void* closure,
+ const char* fromRawSegment,
+ PRUint32 toOffset,
+ PRUint32 count,
+ PRUint32 *writeCount)
+{
+ NS_NOTREACHED("nsWriteSegmentToFile");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+FileImpl::WriteFrom(nsIInputStream *inStr, PRUint32 count, PRUint32 *result)
+{
+ return inStr->ReadSegments(nsWriteSegmentToFile, nsnull, count, result);
+}
+
+NS_IMETHODIMP
+FileImpl::WriteSegments(nsReadSegmentFun reader, void * closure,
+ PRUint32 count, PRUint32 *result)
+{
+ NS_NOTREACHED("WriteSegments");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+FileImpl::IsNonBlocking(PRBool *aNonBlocking)
+{
+ *aNonBlocking = PR_FALSE;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP FileImpl::Tell(PRInt64* outWhere)
+//----------------------------------------------------------------------------------------
+{
+ if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR || !mFileDesc)
+ return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
+ *outWhere = PR_Seek64(mFileDesc, 0, PR_SEEK_CUR);
+ return NS_OK;
+} // FileImpl::Tell
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP FileImpl::Close()
+//----------------------------------------------------------------------------------------
+{
+ if ((mNSPRMode & PR_RDONLY) == 0)
+ InternalFlush(PR_FALSE);
+
+ 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()
+//----------------------------------------------------------------------------------------
+{
+ // for external callers, this will do a Sync as well as flush buffers.
+ return InternalFlush(PR_TRUE);
+} // FileImpl::flush
+
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP FileImpl::GetAtEOF(PRBool* outAtEOF)
+//----------------------------------------------------------------------------------------
+{
+ *outAtEOF = mEOF;
+ return NS_OK;
+}
+
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP FileImpl::SetAtEOF(PRBool inAtEOF)
+//----------------------------------------------------------------------------------------
+{
+ mEOF = inAtEOF;
+ return NS_OK;
+}
+
+//----------------------------------------------------------------------------------------
+NS_IMETHODIMP FileImpl::SetEOF()
+//----------------------------------------------------------------------------------------
+{
+ NS_NOTYETIMPLEMENTED("FileImpl::SetEOF");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+//----------------------------------------------------------------------------------------
+nsresult FileImpl::AllocateBuffers(PRUint32 segmentSize, PRUint32 maxBufSize)
+//----------------------------------------------------------------------------------------
+{
+ nsresult rv = mOutBuffer.Init(segmentSize, maxBufSize);
+ if (NS_SUCCEEDED(rv))
+ mGotBuffers = PR_TRUE;
+
+ return rv;
+}
+
+// external callers of Flush will have sync get called,
+// but internal callers just want to flush the buffers to disk.
+nsresult FileImpl::InternalFlush(PRBool syncFile)
+{
+#ifdef XP_MAC
+ if (mFileDesc == PR_STDOUT || mFileDesc == PR_STDERR)
+ {
+ std::cout.flush();
+ return NS_OK;
+ }
+#endif
+ if (!mFileDesc)
+ return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
+
+ PRInt32 segCount = mOutBuffer.GetSegmentCount();
+ PRUint32 segSize = mOutBuffer.GetSegmentSize();
+
+ for (PRInt32 i = 0; i < segCount; i++)
+ {
+ char* seg = mOutBuffer.GetSegment(i);
+
+ // if it is the last buffer, it may not be completely full.
+ if(i == (segCount-1))
+ segSize = (mWriteCursor - seg);
+
+ PRInt32 bytesWrit = PR_Write(mFileDesc, seg, segSize);
+ if (bytesWrit != (PRInt32)segSize)
+ {
+ mFailed = PR_TRUE;
+ return NS_FILE_RESULT(PR_GetError());
+ }
+ }
+
+ if (mGotBuffers)
+ mOutBuffer.Empty();
+ mWriteCursor = nsnull;
+ mWriteLimit = nsnull;
+
+ // On unix, it seems to fail always.
+ if (syncFile && PR_Sync(mFileDesc) != PR_SUCCESS)
+ mFailed = PR_TRUE;
+
+ return NS_OK;
+}
+//----------------------------------------------------------------------------------------
+nsresult NS_NewTypicalInputFileStream(
+ nsISupports** aResult,
+ const nsFileSpec& inFile
+ /*Default nsprMode == PR_RDONLY*/
+ /*Default accessmode = 0666 (octal)*/)
+// Factory method to get an nsInputStream from a file, using most common options
+//----------------------------------------------------------------------------------------
+{
+ // This QueryInterface was needed because NS_NewIOFileStream
+ // does a cast from (void *) to (nsISupports *) thus causing a
+ // vtable problem on Windows, where we really didn't have the proper pointer
+ // to an nsIInputStream, this ensures that we do
+ nsISupports * supports;
+ nsIInputStream * inStr;
+
+ nsresult rv = NS_NewIOFileStream(&supports, inFile, PR_RDONLY, 0666);
+
+ *aResult = nsnull;
+ if (NS_SUCCEEDED(rv)) {
+ if (NS_SUCCEEDED(supports->QueryInterface(NS_GET_IID(nsIInputStream), (void**)&inStr))) {
+ *aResult = inStr;
+ }
+ NS_RELEASE(supports);
+ }
+ return rv;
+}
+
+//----------------------------------------------------------------------------------------
+nsresult NS_NewTypicalOutputFileStream(
+ nsISupports** aResult,
+ const nsFileSpec& inFile
+ /*default nsprMode= (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE)*/
+ /*Default accessMode= 0666 (octal)*/)
+// Factory method to get an nsOutputStream to a file - most common case.
+//----------------------------------------------------------------------------------------
+{
+ // This QueryInterface was needed because NS_NewIOFileStream
+ // does a cast from (void *) to (nsISupports *) thus causing a
+ // vtable problem on Windows, where we really didn't have the proper pointer
+ // to an nsIOutputStream, this ensures that we do
+#if 1
+/* nsISupports * supports;
+ nsIOutputStream * outStr;
+
+ nsresult rv = NS_NewIOFileStream(
+ &supports,
+ inFile,
+ (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE),
+ 0666);
+
+ *aResult = nsnull;
+ if (NS_SUCCEEDED(rv)) {
+ if (NS_SUCCEEDED(supports->QueryInterface(NS_GET_IID(nsIOutputStream), (void**)&outStr))) {
+ *aResult = outStr;
+ }
+ NS_RELEASE(supports);
+ }
+ return rv;
+ */
+
+ nsCOMPtr<nsISupports> supports;
+ nsIOutputStream * outStr;
+
+ nsresult rv = NS_NewIOFileStream(
+ getter_AddRefs(supports),
+ inFile,
+ (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE),
+ 0666);
+
+ *aResult = nsnull;
+ if (NS_SUCCEEDED(rv)) {
+ if (NS_SUCCEEDED(supports->QueryInterface(NS_GET_IID(nsIOutputStream), (void**)&outStr))) {
+ *aResult = outStr;
+ }
+ }
+ return rv;
+#else
+ return NS_NewIOFileStream(
+ aResult,
+ inFile,
+ (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE),
+ 0666);
+#endif
+}
+
+//----------------------------------------------------------------------------------------
+NS_COM_OBSOLETE nsresult NS_NewIOFileStream(
+ nsISupports** aResult,
+ const nsFileSpec& inFile,
+ PRInt32 nsprMode /*default = (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE)*/,
+ PRInt32 accessMode /*Default = 0666 (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);
+ PRBool isOpened = PR_FALSE;
+ stream->GetIsOpen(&isOpened);
+ if (!isOpened)
+ {
+ NS_RELEASE(stream);
+ return NS_ERROR_FAILURE;
+ }
+
+ *aResult = (nsISupports*)(void*)stream;
+ return NS_OK;
+}
+
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/nsIFileStream.h b/src/libs/xpcom18a4/xpcom/obsolete/nsIFileStream.h
new file mode 100644
index 00000000..251b3ffc
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/nsIFileStream.h
@@ -0,0 +1,157 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#ifndef nsIFileStream_h___
+#define nsIFileStream_h___
+
+#include "xpcomobsolete.h"
+#include "nsIInputStream.h"
+#include "nsIOutputStream.h"
+#include "nsISeekableStream.h"
+#include "prio.h"
+
+class nsFileSpec;
+
+/* a6cf90e8-15b3-11d2-932e-00805f8add32 */
+#define NS_IOPENFILE_IID \
+{ 0xa6cf90e8, 0x15b3, 0x11d2, \
+ {0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
+
+//========================================================================================
+class nsIOpenFile
+// Represents a file, and supports Open.
+//========================================================================================
+: public nsISupports
+{
+public:
+ NS_DEFINE_STATIC_IID_ACCESSOR(NS_IOPENFILE_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 GetIsOpen(PRBool* outOpen) = 0;
+
+}; // class nsIOpenFile
+
+/* a6cf90e8-15b3-11d2-932e-00805f8add32 */
+#define NS_IRANDOMACCESS_IID \
+{ 0xa6cf90eb, 0x15b3, 0x11d2, \
+ {0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
+
+//========================================================================================
+class nsIRandomAccessStore
+// Supports Seek, Tell etc.
+//========================================================================================
+: public nsISeekableStream
+{
+public:
+ NS_DEFINE_STATIC_IID_ACCESSOR(NS_IRANDOMACCESS_IID)
+
+/* "PROTECTED" */
+ NS_IMETHOD GetAtEOF(PRBool* outAtEOF) = 0;
+ NS_IMETHOD SetAtEOF(PRBool inAtEOF) = 0;
+}; // class nsIRandomAccessStore
+
+
+#ifndef NO_XPCOM_FILE_STREAMS // hack to work around duplicate class definitions in here
+ // and mozilla/netwerks/base/nsIFileStreams.idl
+
+/* a6cf90e6-15b3-11d2-932e-00805f8add32 */
+#define NS_IFILESPECINPUTSTREAM_IID \
+{ 0xa6cf90e6, 0x15b3, 0x11d2, \
+ {0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
+
+//========================================================================================
+class nsIFileSpecInputStream
+// These are additional file-specific methods that files have, above what
+// nsIInputStream supports. The current implementation supports both
+// interfaces.
+//========================================================================================
+: public nsIInputStream
+{
+public:
+ NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFILESPECINPUTSTREAM_IID)
+}; // class nsIFileSpecInputStream
+
+/* a6cf90e7-15b3-11d2-932e-00805f8add32 */
+#define NS_IFILESPECOUTPUTSTREAM_IID \
+{ 0xa6cf90e7, 0x15b3, 0x11d2, \
+ {0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
+
+//========================================================================================
+class nsIFileSpecOutputStream
+// These are additional file-specific methods that files have, above what
+// nsIOutputStream supports. The current implementation supports both
+// interfaces.
+//========================================================================================
+: public nsIOutputStream
+{
+public:
+ NS_DEFINE_STATIC_IID_ACCESSOR(NS_IFILESPECOUTPUTSTREAM_IID)
+}; // class nsIFileSpecOutputStream
+
+#endif // NO_XPCOM_FILE_STREAMS
+
+//----------------------------------------------------------------------------------------
+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
+
+//----------------------------------------------------------------------------------------
+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_COM_OBSOLETE 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 /* nsIFileSpecStream_h___ */
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/nsIRegistry.idl b/src/libs/xpcom18a4/xpcom/obsolete/nsIRegistry.idl
new file mode 100644
index 00000000..bc9990e2
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/nsIRegistry.idl
@@ -0,0 +1,186 @@
+/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org Code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#include "nsISupports.idl"
+#include "nsIEnumerator.idl"
+
+interface nsIFile;
+
+typedef PRUint32 nsRegistryKey;
+typedef long nsWellKnownRegistry;
+
+[scriptable,uuid(5D41A440-8E37-11d2-8059-00600811A9C3)]
+interface nsIRegistry : nsISupports
+{
+ const long None = 0;
+ const long Users = 1;
+ const long Common = 2;
+ const long CurrentUser = 3;
+
+ const long ApplicationComponentRegistry = 1;
+ const long ApplicationRegistry = 2;
+
+ // Dont use this one. This for internal use only.
+ const long ApplicationCustomRegistry = -1;
+
+ void open(in nsIFile regFile);
+ void openWellKnownRegistry(in nsWellKnownRegistry regid);
+
+ void flush();
+ boolean isOpen();
+
+ nsRegistryKey addKey(in nsRegistryKey baseKey, in wstring keyname);
+ nsRegistryKey getKey(in nsRegistryKey baseKey, in wstring keyname);
+ void removeKey(in nsRegistryKey baseKey, in wstring keyname);
+
+ wstring getString(in nsRegistryKey baseKey, in wstring valname);
+ void setString(in nsRegistryKey baseKey, in wstring valname, in wstring value);
+
+ string getStringUTF8(in nsRegistryKey baseKey, in string path);
+ void setStringUTF8(in nsRegistryKey baseKey, in string path, in string value);
+
+ void getBytesUTF8(in nsRegistryKey baseKey, in string path, out PRUint32 length, [retval, array, size_is(length)] out PRUint8 valueArray);
+ void setBytesUTF8(in nsRegistryKey baseKey, in string path, in PRUint32 length, [array, size_is(length)] in PRUint8 valueArray);
+ PRInt32 getInt(in nsRegistryKey baseKey, in string path);
+ void setInt(in nsRegistryKey baseKey, in string path, in PRInt32 value);
+ PRInt64 getLongLong(in nsRegistryKey baseKey, in string path);
+ void setLongLong(in nsRegistryKey baseKey, in string path, inout PRInt64 value);
+
+ /**
+ * addSubtree() and friends need to be renamed to addKeyUTF8().
+ * If you are using these forms make sure you pass UTF8 data
+ */
+ nsRegistryKey addSubtree(in nsRegistryKey baseKey, in string path);
+ void removeSubtree(in nsRegistryKey baseKey, in string path);
+ nsRegistryKey getSubtree(in nsRegistryKey baseKey, in string path);
+
+ nsRegistryKey addSubtreeRaw(in nsRegistryKey baseKey, in string path);
+ void removeSubtreeRaw(in nsRegistryKey baseKey, in string path);
+ nsRegistryKey getSubtreeRaw(in nsRegistryKey baseKey, in string path);
+
+ nsIEnumerator enumerateSubtrees(in nsRegistryKey baseKey);
+ nsIEnumerator enumerateAllSubtrees(in nsRegistryKey baseKey);
+ nsIEnumerator enumerateValues(in nsRegistryKey baseKey);
+
+ const unsigned long String = 1;
+ const unsigned long Int32 = 2;
+ const unsigned long Bytes = 3;
+ const unsigned long File = 4;
+
+ unsigned long getValueType(in nsRegistryKey baseKey, in string path);
+ PRUint32 getValueLength(in nsRegistryKey baseKey, in string path);
+ void deleteValue(in nsRegistryKey baseKey, in string path);
+
+ /**
+ * escapeKey() takes arbitrary binary data and converts it into
+ * valid ASCII which can be used as registry key or value names
+ */
+ void escapeKey([array, size_is(length)] in PRUint8 key, in PRUint32 terminator, inout PRUint32 length, [retval, array, size_is(length)] out PRUint8 escaped);
+ void unescapeKey([array, size_is(length)] in PRUint8 escaped, in PRUint32 terminator, inout PRUint32 length, [retval, array, size_is(length)] out PRUint8 key);
+
+ attribute string currentUserName;
+
+ void pack();
+};
+
+[scriptable, uuid(8cecf236-1dd2-11b2-893c-f9848956eaec)]
+interface nsIRegistryEnumerator : nsIEnumerator
+{
+ void currentItemInPlaceUTF8(out nsRegistryKey key,
+ [shared, retval] out string item);
+};
+
+[scriptable, uuid(D1B54831-AC07-11d2-805E-00600811A9C3)]
+interface nsIRegistryNode : nsISupports
+{
+ readonly attribute string nameUTF8;
+ readonly attribute wstring name;
+ readonly attribute nsRegistryKey key;
+};
+
+[scriptable,uuid(5316C380-B2F8-11d2-A374-0080C6F80E4B)]
+interface nsIRegistryValue : nsISupports
+{
+ readonly attribute wstring name;
+ readonly attribute string nameUTF8;
+ readonly attribute unsigned long type;
+ readonly attribute PRUint32 length;
+};
+
+[uuid(3A15FC88-7A61-4Ab4-8E58-31E95fAB3DA8)]
+/**
+ * It sucks that nsIRegistry has to always allocate and return
+ * strings. nsIRegistryGetter adds in interfaces for non allocating getters
+ * to registry values.
+ */
+interface nsIRegistryGetter : nsISupports
+{
+ /**
+ * Get a string value of attribute valname in widestring or utf8 format
+ *
+ * @return
+ * NS_OK on success.
+ * buf has the string value copied into it. length is NOT changed.
+ * NS_ERROR_REG_BUFFER_TOO_SMALL if not enough buffer space.
+ * length is updated to actual length in chars including
+ * terminating NULL and buf will be unchanged.
+ * NS_ERROR_FAILURE if an unknown error happened. state of buf and
+ * length undefined.
+ * various failure codes otherwise. buf and length wont be updated.
+ */
+ void getStringUTF8IntoBuffer(in nsRegistryKey baseKey, in string path,
+ inout char buf, inout PRUint32 length);
+
+ /**
+ * Get a a byte array value of attribute valname
+ *
+ * @return
+ * NS_OK on success. buf has the string value copied into it.
+ * length is updated to actual number of bytes copied into buf.
+ * NS_ERROR_REG_BUFFER_TOO_SMALL if not enough buffer space.
+ * length is updated to actual length in PRUint8s including
+ * terminating NULL and buf will be unchanged.
+ * NS_ERROR_FAILURE if an unknown error happened. state of buf and
+ * length undefined.
+ * various other failure codes otherwise. buf and length wont be updated.
+ */
+ void getBytesUTF8IntoBuffer(in nsRegistryKey baseKey, in string path,
+ inout PRUint8 buf, inout PRUint32 length);
+};
+
+%{ C++
+#include "nsIRegistryUtils.h"
+%}
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/nsIRegistryUtils.h b/src/libs/xpcom18a4/xpcom/obsolete/nsIRegistryUtils.h
new file mode 100644
index 00000000..a3d74d7a
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/nsIRegistryUtils.h
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+#ifndef __nsIRegistryUtils_h
+#define __nsIRegistryUtils_h
+
+#define NS_REGISTRY_CONTRACTID "@mozilla.org/registry;1"
+#define NS_REGISTRY_CLASSNAME "Mozilla Registry"
+/* be761f00-a3b0-11d2-996c-0080c7cb1081 */
+#define NS_REGISTRY_CID \
+{ \
+ 0xbe761f00, \
+ 0xa3b0, \
+ 0x11d2, \
+ {0x99, 0x6c, 0x00, 0x80, 0xc7, 0xcb, 0x10, 0x81} \
+}
+
+/*------------------------------- Error Codes ----------------------------------
+------------------------------------------------------------------------------*/
+#define NS_ERROR_REG_BADTYPE NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 1 )
+#define NS_ERROR_REG_NO_MORE NS_ERROR_GENERATE_SUCCESS( NS_ERROR_MODULE_REG, 2 )
+#define NS_ERROR_REG_NOT_FOUND NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 3 )
+#define NS_ERROR_REG_NOFILE NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 4 )
+#define NS_ERROR_REG_BUFFER_TOO_SMALL NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 5 )
+#define NS_ERROR_REG_NAME_TOO_LONG NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 6 )
+#define NS_ERROR_REG_NO_PATH NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 7 )
+#define NS_ERROR_REG_READ_ONLY NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 8 )
+#define NS_ERROR_REG_BAD_UTF8 NS_ERROR_GENERATE_FAILURE( NS_ERROR_MODULE_REG, 9 )
+
+#endif
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/nsSpecialSystemDirectory.cpp b/src/libs/xpcom18a4/xpcom/obsolete/nsSpecialSystemDirectory.cpp
new file mode 100644
index 00000000..f120cd43
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/nsSpecialSystemDirectory.cpp
@@ -0,0 +1,1189 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Doug Turner <dougt@netscape.com>
+ * IBM Corp.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsSpecialSystemDirectory.h"
+#include "nsDebug.h"
+
+#ifdef XP_MAC
+#include <Folders.h>
+#include <Files.h>
+#include <Memory.h>
+#include <Processes.h>
+#include <Gestalt.h>
+#include "nsIInternetConfigService.h"
+#ifdef DEBUG
+#include "prenv.h" // For PR_Getenv
+#endif
+#elif defined(XP_WIN)
+#include <windows.h>
+#include <shlobj.h>
+#include <stdlib.h>
+#include <stdio.h>
+#elif defined(XP_OS2)
+#define MAX_PATH _MAX_PATH
+#define INCL_WINWORKPLACE
+#include <os2.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "prenv.h"
+#elif defined(XP_UNIX)
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/param.h>
+#include "prenv.h"
+#elif defined(XP_BEOS)
+#include <FindDirectory.h>
+#include <Path.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/param.h>
+#include <OS.h>
+#include <image.h>
+#include "prenv.h"
+#endif
+
+#if defined(VMS)
+#include <unixlib.h>
+#endif
+
+#include "plstr.h"
+
+#include "nsHashtable.h"
+#include "prlog.h"
+
+#if defined (XP_MAC) && UNIVERSAL_INTERFACES_VERSION < 0x0340
+ enum {
+ kSystemDomain = -32766, /* Read-only system hierarchy.*/
+ kLocalDomain = -32765, /* All users of a single machine have access to these resources.*/
+ kNetworkDomain = -32764, /* All users configured to use a common network server has access to these resources.*/
+ kUserDomain = -32763, /* Read/write. Resources that are private to the user.*/
+ kClassicDomain = -32762, /* Domain referring to the currently configured Classic System Folder*/
+
+ kDomainLibraryFolderType = FOUR_CHAR_CODE('dlib')
+ };
+#endif
+
+
+class SystemDirectoriesKey : public nsHashKey {
+public:
+
+ SystemDirectoriesKey(nsSpecialSystemDirectory::SystemDirectories newKey) : sdKey(newKey) {}
+
+ virtual PRUint32 HashCode(void) const
+ {
+ return PRUint32(sdKey);
+ }
+
+ virtual PRBool Equals(const nsHashKey *aKey) const
+ {
+ nsSpecialSystemDirectory::SystemDirectories other =
+ ((SystemDirectoriesKey*)aKey)->sdKey;
+ return other == sdKey;
+ }
+
+ virtual nsHashKey *Clone(void) const
+ {
+ return new SystemDirectoriesKey(sdKey);
+ }
+
+private:
+ nsSpecialSystemDirectory::SystemDirectories sdKey; // sd for SystemDirectories
+};
+
+PR_STATIC_CALLBACK(PRBool) DeleteSystemDirKeys(nsHashKey *aKey, void *aData, void* closure)
+{
+ delete ((nsFileSpec *)aData);
+ return PR_TRUE;
+}
+
+#define NS_SYSTEMDIR_HASH_NUM (10)
+static nsHashtable *systemDirectoriesLocations = NULL;
+#if defined (XP_WIN)
+typedef BOOL (WINAPI * GetSpecialPathProc) (HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate);
+GetSpecialPathProc gGetSpecialPathProc = NULL;
+static HINSTANCE gShell32DLLInst = NULL;
+#endif
+NS_COM_OBSOLETE void StartupSpecialSystemDirectory()
+{
+#if defined (XP_WIN)
+ /* On windows, the old method to get file locations is incredibly slow.
+ As of this writing, 3 calls to GetWindowsFolder accounts for 3% of mozilla
+ startup. Replacing these older calls with a single call to SHGetSpecialFolderPath
+ effectively removes these calls from the performace radar. We need to
+ support the older way of file location lookup on systems that do not have
+ IE4. (Note: gets the ansi version: SHGetSpecialFolderPathA).
+ */
+ gShell32DLLInst = LoadLibrary("Shell32.dll");
+ if(gShell32DLLInst)
+ {
+ gGetSpecialPathProc = (GetSpecialPathProc) GetProcAddress(gShell32DLLInst,
+ "SHGetSpecialFolderPathA");
+ }
+#endif
+}
+
+NS_COM_OBSOLETE void ShutdownSpecialSystemDirectory()
+{
+ if (systemDirectoriesLocations)
+ {
+ systemDirectoriesLocations->Reset(DeleteSystemDirKeys);
+ delete systemDirectoriesLocations;
+ }
+#if defined (XP_WIN)
+ if (gShell32DLLInst)
+ {
+ FreeLibrary(gShell32DLLInst);
+ gShell32DLLInst = NULL;
+ gGetSpecialPathProc = NULL;
+ }
+#endif
+}
+
+#if defined (XP_WIN)
+
+static PRBool gGlobalOSInitialized = PR_FALSE;
+static PRBool gGlobalDBCSEnabledOS = PR_FALSE;
+
+//----------------------------------------------------------------------------------------
+static char* MakeUpperCase(char* aPath)
+//----------------------------------------------------------------------------------------
+{
+ // check if the Windows is DBCSEnabled once.
+ if (PR_FALSE == gGlobalOSInitialized) {
+ if (GetSystemMetrics(SM_DBCSENABLED))
+ gGlobalDBCSEnabledOS = PR_TRUE;
+ gGlobalOSInitialized = PR_TRUE;
+ }
+
+ // windows does not care about case. pu sh to uppercase:
+ int length = strlen(aPath);
+ int i = 0; /* C++ portability guide #20 */
+ if (!gGlobalDBCSEnabledOS) {
+ // for non-DBCS windows
+ for (i = 0; i < length; i++)
+ if (islower(aPath[i]))
+ aPath[i] = _toupper(aPath[i]);
+ }
+ else {
+ // for DBCS windows
+ for (i = 0; i < length; i++) {
+ if (IsDBCSLeadByte(aPath[i])) {
+ // begining of the double bye char
+ i++;
+ }
+ else {
+ if ( islower(aPath[i]))
+ aPath[i] = _toupper(aPath[i]);
+ }
+ } //end of for loop
+ }
+ return aPath;
+}
+
+//----------------------------------------------------------------------------------------
+static void GetWindowsFolder(int folder, nsFileSpec& outDirectory)
+//----------------------------------------------------------------------------------------
+{
+
+ if (gGetSpecialPathProc) {
+ TCHAR path[MAX_PATH];
+ HRESULT result = gGetSpecialPathProc(NULL, path, folder, true);
+
+ if (!SUCCEEDED(result))
+ return;
+
+ // Append the trailing slash
+ int len = PL_strlen(path);
+ if (len>1 && path[len-1] != '\\')
+ {
+ path[len] = '\\';
+ path[len + 1] = '\0';
+ }
+ outDirectory = path;
+ return;
+ }
+
+ LPMALLOC pMalloc = NULL;
+ LPSTR pBuffer = NULL;
+ LPITEMIDLIST pItemIDList = NULL;
+ int len;
+
+ // Get the shell's allocator.
+ if (!SUCCEEDED(SHGetMalloc(&pMalloc)))
+ return;
+
+ // Allocate a buffer
+ if ((pBuffer = (LPSTR) pMalloc->Alloc(MAX_PATH + 2)) == NULL)
+ return;
+
+ // Get the PIDL for the folder.
+ if (!SUCCEEDED(SHGetSpecialFolderLocation(
+ NULL, folder, &pItemIDList)))
+ goto Clean;
+
+ if (!SUCCEEDED(SHGetPathFromIDList(pItemIDList, pBuffer)))
+ goto Clean;
+
+ // Append the trailing slash
+ len = PL_strlen(pBuffer);
+ pBuffer[len] = '\\';
+ pBuffer[len + 1] = '\0';
+
+ // Assign the directory
+ outDirectory = pBuffer;
+
+Clean:
+ // Clean up.
+ if (pItemIDList)
+ pMalloc->Free(pItemIDList);
+ if (pBuffer)
+ pMalloc->Free(pBuffer);
+
+ pMalloc->Release();
+} // GetWindowsFolder
+#endif // XP_WIN
+
+//----------------------------------------------------------------------------------------
+static void GetCurrentWorkingDirectory(nsFileSpec& aFileSpec)
+//----------------------------------------------------------------------------------------
+{
+ aFileSpec = ".";
+ return;
+} // GetCurrentWorkingDirectory
+
+//----------------------------------------------------------------------------------------
+static void GetCurrentProcessDirectory(nsFileSpec& aFileSpec)
+//----------------------------------------------------------------------------------------
+{
+#if defined (XP_WIN)
+ char buf[MAX_PATH];
+ if ( ::GetModuleFileName(0, buf, sizeof(buf)) ) {
+ // chop of the executable name by finding the rightmost backslash
+ char* lastSlash = PL_strrchr(buf, '\\');
+ if (lastSlash)
+ *(lastSlash + 1) = '\0';
+
+ aFileSpec = buf;
+ return;
+ }
+
+#elif defined(XP_OS2)
+ PPIB ppib;
+ PTIB ptib;
+ char buffer[CCHMAXPATH];
+ DosGetInfoBlocks( &ptib, &ppib);
+ DosQueryModuleName( ppib->pib_hmte, CCHMAXPATH, buffer);
+ *strrchr( buffer, '\\') = '\0'; // XXX DBCS misery
+ aFileSpec = buffer;
+ return;
+
+
+#elif defined(XP_MAC)
+ // get info for the the current process to determine the directory
+ // its located in
+ OSErr err;
+ ProcessSerialNumber psn = {kNoProcess, kCurrentProcess};
+ ProcessInfoRec pInfo;
+ FSSpec tempSpec;
+
+ // initialize ProcessInfoRec before calling
+ // GetProcessInformation() or die horribly.
+ pInfo.processName = nil;
+ pInfo.processAppSpec = &tempSpec;
+ pInfo.processInfoLength = sizeof(ProcessInfoRec);
+
+ if (!(err = GetProcessInformation(&psn, &pInfo)))
+ {
+ FSSpec appFSSpec = *(pInfo.processAppSpec);
+ long theDirID = appFSSpec.parID;
+
+ Str255 name;
+ CInfoPBRec catInfo;
+ catInfo.dirInfo.ioCompletion = NULL;
+ catInfo.dirInfo.ioNamePtr = (StringPtr)&name;
+ catInfo.dirInfo.ioVRefNum = appFSSpec.vRefNum;
+ catInfo.dirInfo.ioDrDirID = theDirID;
+ catInfo.dirInfo.ioFDirIndex = -1; // -1 = query dir in ioDrDirID
+
+ if (!(err = PBGetCatInfoSync(&catInfo)))
+ {
+ aFileSpec = nsFileSpec(appFSSpec.vRefNum,
+ catInfo.dirInfo.ioDrParID,
+ name,
+ PR_TRUE);
+ return;
+ }
+ }
+#if defined(DEBUG)
+ else
+ {
+ // In the absence of a good way to get the executable directory let
+ // us try this for unix:
+ // - if VBOX_XPCOM_HOME is defined, that is it
+ char *moz5 = PR_GetEnv("VBOX_XPCOM_HOME");
+ if (moz5)
+ {
+ printf( "nsSpecialSystemDirectory::VBOX_XPCOM_HOME is set to %s\n", moz5 );
+ aFileSpec = moz5;
+ return;
+ }
+ else
+ {
+ static PRBool firstWarning = PR_TRUE;
+
+ if(firstWarning) {
+ // Warn that VBOX_XPCOM_HOME not set, once.
+ printf("***Warning: VBOX_XPCOM_HOME not set.\n");
+ firstWarning = PR_FALSE;
+ }
+ }
+ }
+#endif /* DEBUG */
+
+#elif defined(XP_UNIX)
+
+ // In the absence of a good way to get the executable directory let
+ // us try this for unix:
+ // - if VBOX_XPCOM_HOME is defined, that is it
+ // - else give the current directory
+ char buf[MAXPATHLEN];
+ char *moz5 = PR_GetEnv("VBOX_XPCOM_HOME");
+ if (moz5)
+ {
+ aFileSpec = moz5;
+ return;
+ }
+ else
+ {
+#if defined(DEBUG)
+ static PRBool firstWarning = PR_TRUE;
+
+ if(firstWarning) {
+ // Warn that VBOX_XPCOM_HOME not set, once.
+ printf("Warning: VBOX_XPCOM_HOME not set.\n");
+ firstWarning = PR_FALSE;
+ }
+#endif /* DEBUG */
+
+ // Fall back to current directory.
+ if (getcwd(buf, sizeof(buf)))
+ {
+ aFileSpec = buf;
+ return;
+ }
+ }
+
+#elif defined(XP_BEOS)
+
+ char *moz5 = getenv("VBOX_XPCOM_HOME");
+ if (moz5)
+ {
+ aFileSpec = moz5;
+ return;
+ }
+ else
+ {
+ static char buf[MAXPATHLEN];
+ int32 cookie = 0;
+ image_info info;
+ char *p;
+ *buf = 0;
+ if(get_next_image_info(0, &cookie, &info) == B_OK)
+ {
+ strcpy(buf, info.name);
+ if((p = strrchr(buf, '/')) != 0)
+ {
+ *p = 0;
+ aFileSpec = buf;
+ return;
+ }
+ }
+ }
+
+#endif
+
+ NS_ERROR("unable to get current process directory");
+} // GetCurrentProcessDirectory()
+
+//nsSpecialSystemDirectory::nsSpecialSystemDirectory()
+//: nsFileSpec(nsnull)
+//{
+//}
+
+//----------------------------------------------------------------------------------------
+nsSpecialSystemDirectory::nsSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory)
+//----------------------------------------------------------------------------------------
+: nsFileSpec(nsnull)
+{
+ *this = aSystemSystemDirectory;
+}
+
+//----------------------------------------------------------------------------------------
+nsSpecialSystemDirectory::~nsSpecialSystemDirectory()
+//----------------------------------------------------------------------------------------
+{
+}
+
+//----------------------------------------------------------------------------------------
+void nsSpecialSystemDirectory::operator = (SystemDirectories aSystemSystemDirectory)
+//----------------------------------------------------------------------------------------
+{
+ SystemDirectoriesKey dirKey(aSystemSystemDirectory);
+ SystemDirectoriesKey mozBinDirKey(Moz_BinDirectory);
+
+ // This flag is used to tell whether or not we need to append something
+ // onto the *this. Search for needToAppend to how it's used.
+ // IT's VERY IMPORTANT that needToAppend is initialized to PR_TRUE.
+ PRBool needToAppend = PR_TRUE;
+
+#ifdef XP_MAC
+ OSErr err;
+ short vRefNum;
+ long dirID;
+#endif
+
+ *this = (const char*)nsnull;
+ switch (aSystemSystemDirectory)
+ {
+
+ case OS_DriveDirectory:
+#if defined (XP_WIN)
+ {
+ char path[_MAX_PATH];
+ PRInt32 len = GetWindowsDirectory( path, _MAX_PATH );
+ if (len)
+ {
+ if ( path[1] == ':' && path[2] == '\\' )
+ path[3] = 0;
+ }
+ *this = MakeUpperCase(path);
+ }
+#elif defined(XP_OS2)
+ {
+ // printf( "*** Warning warning OS_DriveDirectory called for");
+
+ ULONG ulBootDrive = 0;
+ char buffer[] = " :\\OS2\\";
+ DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
+ &ulBootDrive, sizeof ulBootDrive);
+ buffer[0] = 'A' - 1 + ulBootDrive; // duh, 1-based index...
+ *this = buffer;
+#ifdef DEBUG
+ printf( "Got OS_DriveDirectory: %s\n", buffer);
+#endif
+ }
+#elif defined(XP_MAC)
+ {
+ *this = kVolumeRootFolderType;
+ }
+#else
+ *this = "/";
+#endif
+ break;
+
+
+ case OS_TemporaryDirectory:
+#if defined (XP_WIN)
+ {
+ char path[_MAX_PATH];
+ DWORD len = GetTempPath(_MAX_PATH, path);
+ *this = MakeUpperCase(path);
+ }
+#elif defined(XP_OS2)
+ {
+ char buffer[CCHMAXPATH] = "";
+ char *c = getenv( "TMP");
+ if( c) strcpy( buffer, c);
+ else
+ {
+ c = getenv( "TEMP");
+ if( c) strcpy( buffer, c);
+ }
+ if( c) *this = buffer;
+ // use exe's directory if not set
+ else GetCurrentProcessDirectory(*this);
+ }
+#elif defined(XP_MAC)
+ *this = kTemporaryFolderType;
+
+#elif defined(XP_UNIX) || defined(XP_BEOS)
+ {
+ static const char *tPath = nsnull;
+ if (!tPath) {
+ tPath = PR_GetEnv("TMPDIR");
+ if (!tPath || !*tPath) {
+ tPath = PR_GetEnv("TMP");
+ if (!tPath || !*tPath) {
+ tPath = PR_GetEnv("TEMP");
+ if (!tPath || !*tPath) {
+ tPath = "/tmp/";
+ }
+ }
+ }
+ }
+
+ *this = tPath;
+ }
+#endif
+ break;
+
+ case OS_CurrentProcessDirectory:
+ GetCurrentProcessDirectory(*this);
+ break;
+
+ case OS_CurrentWorkingDirectory:
+ GetCurrentWorkingDirectory(*this);
+ break;
+
+ case XPCOM_CurrentProcessComponentRegistry:
+ {
+ nsFileSpec *dirSpec = NULL;
+
+ // if someone has called nsSpecialSystemDirectory::Set()
+ if (systemDirectoriesLocations) {
+ // look for the value for the argument key
+ if (!(dirSpec = (nsFileSpec *)systemDirectoriesLocations->Get(&dirKey))) {
+ // if not found, try Moz_BinDirectory
+ dirSpec = (nsFileSpec *)
+ systemDirectoriesLocations->Get(&mozBinDirKey);
+ }
+ else {
+ // if the value is found for the argument key,
+ // we don't need to append.
+ needToAppend = PR_FALSE;
+ }
+ }
+
+ if (dirSpec)
+ {
+ *this = *dirSpec;
+ }
+ else
+ {
+ GetCurrentProcessDirectory(*this);
+ }
+
+ if (needToAppend) {
+ // XXX We need to unify these names across all platforms
+#if defined(XP_MAC)
+ *this += "Component Registry";
+#else
+ *this += "component.reg";
+#endif /* XP_MAC */
+ }
+ }
+ break;
+
+ case XPCOM_CurrentProcessComponentDirectory:
+ {
+ nsFileSpec *dirSpec = NULL;
+ // if someone has called nsSpecialSystemDirectory::Set()
+ if (systemDirectoriesLocations) {
+ // look for the value for the argument key
+ if (!(dirSpec = (nsFileSpec *)systemDirectoriesLocations->Get(&dirKey))) {
+ // if not found, try Moz_BinDirectory
+ dirSpec = (nsFileSpec *)
+ systemDirectoriesLocations->Get(&mozBinDirKey);
+ }
+ else {
+ // if the value is found for the argument key,
+ // we don't need to append.
+ needToAppend = PR_FALSE;
+ }
+ }
+ if (dirSpec)
+ {
+ *this = *dirSpec;
+ }
+ else
+ {
+ // <exedir>/Components
+ GetCurrentProcessDirectory(*this);
+ }
+
+ if (needToAppend) {
+ // XXX We need to unify these names across all platforms
+#if defined(XP_MAC)
+ *this += "Components";
+#else
+ *this += "components";
+#endif /* XP_MAC */
+ }
+ }
+ break;
+
+ case Moz_BinDirectory:
+ {
+ nsFileSpec *dirSpec = NULL;
+ // if someone has called nsSpecialSystemDirectory::Set()
+ if (systemDirectoriesLocations) {
+ // look for the value for the argument key
+ dirSpec = (nsFileSpec *)
+ systemDirectoriesLocations->Get(&dirKey);
+ }
+ if (dirSpec) {
+ *this = *dirSpec;
+ }
+ else {
+ GetCurrentProcessDirectory(*this);
+ }
+ }
+ break;
+
+#if defined(XP_MAC)
+ case Mac_SystemDirectory:
+ *this = kSystemFolderType;
+ break;
+
+ case Mac_DesktopDirectory:
+ *this = kDesktopFolderType;
+ break;
+
+ case Mac_TrashDirectory:
+ *this = kTrashFolderType;
+ break;
+
+ case Mac_StartupDirectory:
+ *this = kStartupFolderType;
+ break;
+
+ case Mac_ShutdownDirectory:
+ *this = kShutdownFolderType;
+ break;
+
+ case Mac_AppleMenuDirectory:
+ *this = kAppleMenuFolderType;
+ break;
+
+ case Mac_ControlPanelDirectory:
+ *this = kControlPanelFolderType;
+ break;
+
+ case Mac_ExtensionDirectory:
+ *this = kExtensionFolderType;
+ break;
+
+ case Mac_FontsDirectory:
+ *this = kFontsFolderType;
+ break;
+
+ case Mac_ClassicPreferencesDirectory:
+ {
+ // whether Mac OS X or pre-Mac OS X, return Classic's Prefs folder
+ short domain;
+ long response;
+ err = ::Gestalt(gestaltSystemVersion, &response);
+ domain = (!err && response >= 0x00001000) ? kClassicDomain : kOnSystemDisk;
+ err = ::FindFolder(domain, kPreferencesFolderType, true, &vRefNum, &dirID);
+ if (!err) {
+ err = ::FSMakeFSSpec(vRefNum, dirID, "\p", &mSpec);
+ }
+ mError = NS_FILE_RESULT(err);
+ break;
+ }
+
+ case Mac_PreferencesDirectory:
+ {
+ // if Mac OS X, return Mac OS X's Prefs folder
+ // if pre-Mac OS X, return Mac OS's Prefs folder
+ err = ::FindFolder(kOnSystemDisk, kPreferencesFolderType, true, &vRefNum, &dirID);
+ if (!err) {
+ err = ::FSMakeFSSpec(vRefNum, dirID, "\p", &mSpec);
+ }
+ mError = NS_FILE_RESULT(err);
+ break;
+ }
+
+ case Mac_DocumentsDirectory:
+ *this = kDocumentsFolderType;
+ break;
+
+ case Mac_InternetSearchDirectory:
+ *this = kInternetSearchSitesFolderType;
+ break;
+
+ case Mac_DefaultDownloadDirectory:
+ *this = kDefaultDownloadFolderType;
+ break;
+
+ case Mac_UserLibDirectory:
+ {
+ err = ::FindFolder(kUserDomain, kDomainLibraryFolderType, true, &vRefNum, &dirID);
+ if (!err) {
+ err = ::FSMakeFSSpec(vRefNum, dirID, "\p", &mSpec);
+ }
+ mError = NS_FILE_RESULT(err);
+ break;
+ }
+#endif
+
+#if defined (XP_WIN)
+ case Win_SystemDirectory:
+ {
+ char path[_MAX_PATH];
+ PRInt32 len = GetSystemDirectory( path, _MAX_PATH );
+
+ // Need enough space to add the trailing backslash
+ if (len > _MAX_PATH-2)
+ break;
+ path[len] = '\\';
+ path[len+1] = '\0';
+
+ *this = MakeUpperCase(path);
+
+ break;
+ }
+
+ case Win_WindowsDirectory:
+ {
+ char path[_MAX_PATH];
+ PRInt32 len = GetWindowsDirectory( path, _MAX_PATH );
+
+ // Need enough space to add the trailing backslash
+ if (len > _MAX_PATH-2)
+ break;
+
+ path[len] = '\\';
+ path[len+1] = '\0';
+
+ *this = MakeUpperCase(path);
+ break;
+ }
+
+ case Win_HomeDirectory:
+ {
+ char path[_MAX_PATH];
+ if (GetEnvironmentVariable(TEXT("HOME"), path, _MAX_PATH) > 0)
+ {
+ PRInt32 len = PL_strlen(path);
+ // Need enough space to add the trailing backslash
+ if (len > _MAX_PATH - 2)
+ break;
+
+ path[len] = '\\';
+ path[len+1] = '\0';
+
+ *this = MakeUpperCase(path);
+ break;
+ }
+
+ if (GetEnvironmentVariable(TEXT("HOMEDRIVE"), path, _MAX_PATH) > 0)
+ {
+ char temp[_MAX_PATH];
+ if (GetEnvironmentVariable(TEXT("HOMEPATH"), temp, _MAX_PATH) > 0)
+ PL_strcatn(path, _MAX_PATH, temp);
+
+ PRInt32 len = PL_strlen(path);
+
+ // Need enough space to add the trailing backslash
+ if (len > _MAX_PATH - 2)
+ break;
+
+ path[len] = '\\';
+ path[len+1] = '\0';
+
+ *this = MakeUpperCase(path);
+ break;
+ }
+ }
+ case Win_Desktop:
+ {
+ GetWindowsFolder(CSIDL_DESKTOP, *this);
+ break;
+ }
+ case Win_Programs:
+ {
+ GetWindowsFolder(CSIDL_PROGRAMS, *this);
+ break;
+ }
+ case Win_Controls:
+ {
+ GetWindowsFolder(CSIDL_CONTROLS, *this);
+ break;
+ }
+ case Win_Printers:
+ {
+ GetWindowsFolder(CSIDL_PRINTERS, *this);
+ break;
+ }
+ case Win_Personal:
+ {
+ GetWindowsFolder(CSIDL_PERSONAL, *this);
+ break;
+ }
+ case Win_Favorites:
+ {
+ GetWindowsFolder(CSIDL_FAVORITES, *this);
+ break;
+ }
+ case Win_Startup:
+ {
+ GetWindowsFolder(CSIDL_STARTUP, *this);
+ break;
+ }
+ case Win_Recent:
+ {
+ GetWindowsFolder(CSIDL_RECENT, *this);
+ break;
+ }
+ case Win_Sendto:
+ {
+ GetWindowsFolder(CSIDL_SENDTO, *this);
+ break;
+ }
+ case Win_Bitbucket:
+ {
+ GetWindowsFolder(CSIDL_BITBUCKET, *this);
+ break;
+ }
+ case Win_Startmenu:
+ {
+ GetWindowsFolder(CSIDL_STARTMENU, *this);
+ break;
+ }
+ case Win_Desktopdirectory:
+ {
+ GetWindowsFolder(CSIDL_DESKTOPDIRECTORY, *this);
+ break;
+ }
+ case Win_Drives:
+ {
+ GetWindowsFolder(CSIDL_DRIVES, *this);
+ break;
+ }
+ case Win_Network:
+ {
+ GetWindowsFolder(CSIDL_NETWORK, *this);
+ break;
+ }
+ case Win_Nethood:
+ {
+ GetWindowsFolder(CSIDL_NETHOOD, *this);
+ break;
+ }
+ case Win_Fonts:
+ {
+ GetWindowsFolder(CSIDL_FONTS, *this);
+ break;
+ }
+ case Win_Templates:
+ {
+ GetWindowsFolder(CSIDL_TEMPLATES, *this);
+ break;
+ }
+ case Win_Common_Startmenu:
+ {
+ GetWindowsFolder(CSIDL_COMMON_STARTMENU, *this);
+ break;
+ }
+ case Win_Common_Programs:
+ {
+ GetWindowsFolder(CSIDL_COMMON_PROGRAMS, *this);
+ break;
+ }
+ case Win_Common_Startup:
+ {
+ GetWindowsFolder(CSIDL_COMMON_STARTUP, *this);
+ break;
+ }
+ case Win_Common_Desktopdirectory:
+ {
+ GetWindowsFolder(CSIDL_COMMON_DESKTOPDIRECTORY, *this);
+ break;
+ }
+ case Win_Appdata:
+ {
+ GetWindowsFolder(CSIDL_APPDATA, *this);
+ break;
+ }
+ case Win_Printhood:
+ {
+ GetWindowsFolder(CSIDL_PRINTHOOD, *this);
+ break;
+ }
+ case Win_Cookies:
+ {
+ GetWindowsFolder(CSIDL_COOKIES, *this);
+ break;
+ }
+#endif // XP_WIN
+
+#if defined(XP_UNIX)
+ case Unix_LocalDirectory:
+ *this = "/usr/local/netscape/";
+ break;
+
+ case Unix_LibDirectory:
+ *this = "/usr/local/lib/netscape/";
+ break;
+
+ case Unix_HomeDirectory:
+#ifdef VMS
+ {
+ char *pHome;
+ pHome = getenv("HOME");
+ if (*pHome == '/')
+ *this = pHome;
+ else
+ *this = decc$translate_vms(pHome);
+ }
+#else
+ *this = PR_GetEnv("HOME");
+#endif
+ break;
+
+#endif
+
+#ifdef XP_BEOS
+ case BeOS_SettingsDirectory:
+ {
+ char path[MAXPATHLEN];
+ find_directory(B_USER_SETTINGS_DIRECTORY, 0, 0, path, MAXPATHLEN);
+ // Need enough space to add the trailing backslash
+ int len = strlen(path);
+ if (len > MAXPATHLEN-2)
+ break;
+ path[len] = '/';
+ path[len+1] = '\0';
+ *this = path;
+ break;
+ }
+
+ case BeOS_HomeDirectory:
+ {
+ char path[MAXPATHLEN];
+ find_directory(B_USER_DIRECTORY, 0, 0, path, MAXPATHLEN);
+ // Need enough space to add the trailing backslash
+ int len = strlen(path);
+ if (len > MAXPATHLEN-2)
+ break;
+ path[len] = '/';
+ path[len+1] = '\0';
+ *this = path;
+ break;
+ }
+
+ case BeOS_DesktopDirectory:
+ {
+ char path[MAXPATHLEN];
+ find_directory(B_DESKTOP_DIRECTORY, 0, 0, path, MAXPATHLEN);
+ // Need enough space to add the trailing backslash
+ int len = strlen(path);
+ if (len > MAXPATHLEN-2)
+ break;
+ path[len] = '/';
+ path[len+1] = '\0';
+ *this = path;
+ break;
+ }
+
+ case BeOS_SystemDirectory:
+ {
+ char path[MAXPATHLEN];
+ find_directory(B_BEOS_DIRECTORY, 0, 0, path, MAXPATHLEN);
+ // Need enough space to add the trailing backslash
+ int len = strlen(path);
+ if (len > MAXPATHLEN-2)
+ break;
+ path[len] = '/';
+ path[len+1] = '\0';
+ *this = path;
+ break;
+ }
+#endif
+#ifdef XP_OS2
+ case OS2_SystemDirectory:
+ {
+ ULONG ulBootDrive = 0;
+ char buffer[] = " :\\OS2\\System\\";
+ DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
+ &ulBootDrive, sizeof ulBootDrive);
+ buffer[0] = 'A' - 1 + ulBootDrive; // duh, 1-based index...
+ *this = buffer;
+#ifdef DEBUG
+ printf( "Got OS2_SystemDirectory: %s\n", buffer);
+#endif
+ break;
+ }
+
+ case OS2_OS2Directory:
+ {
+ ULONG ulBootDrive = 0;
+ char buffer[] = " :\\OS2\\";
+ DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
+ &ulBootDrive, sizeof ulBootDrive);
+ buffer[0] = 'A' - 1 + ulBootDrive; // duh, 1-based index...
+ *this = buffer;
+#ifdef DEBUG
+ printf( "Got OS2_OS2Directory: %s\n", buffer);
+#endif
+ break;
+ }
+
+ case OS2_HomeDirectory:
+ {
+ char *tPath = PR_GetEnv("MOZILLA_HOME");
+ /* If MOZILLA_HOME is not set, use GetCurrentProcessDirectory */
+ /* To ensure we get a long filename system */
+ if (!tPath || !*tPath)
+ GetCurrentProcessDirectory(*this);
+ else
+ *this = tPath;
+ PrfWriteProfileString(HINI_USERPROFILE, "Mozilla", "Home", *this);
+ break;
+ }
+
+ case OS2_DesktopDirectory:
+ {
+ char szPath[CCHMAXPATH + 1];
+ BOOL fSuccess;
+ fSuccess = WinQueryActiveDesktopPathname (szPath, sizeof(szPath));
+ int len = strlen (szPath);
+ if (len > CCHMAXPATH -1)
+ break;
+ szPath[len] = '\\';
+ szPath[len + 1] = '\0';
+#ifdef DEBUG
+ if (fSuccess) {
+ printf ("Got OS2_DesktopDirectory: %s\n", szPath);
+ } else {
+ printf ("Failed getting OS2_DesktopDirectory: %s\n", szPath);
+ }
+#endif
+ break;
+ }
+
+#endif
+ default:
+ break;
+ }
+}
+
+void
+nsSpecialSystemDirectory::Set(SystemDirectories dirToSet, nsFileSpec *dirSpec)
+{
+ SystemDirectoriesKey dirKey(dirToSet);
+
+ PR_ASSERT(NULL != dirSpec);
+
+ if (NULL == systemDirectoriesLocations) {
+ systemDirectoriesLocations = new nsHashtable(NS_SYSTEMDIR_HASH_NUM);
+ }
+ PR_ASSERT(NULL != systemDirectoriesLocations);
+
+ nsFileSpec *newSpec = new nsFileSpec(*dirSpec);
+ if (NULL != newSpec) {
+ systemDirectoriesLocations->Put(&dirKey, newSpec);
+ }
+
+ return;
+}
+
+#if defined(XP_MAC)
+//----------------------------------------------------------------------------------------
+nsSpecialSystemDirectory::nsSpecialSystemDirectory(OSType folderType)
+//----------------------------------------------------------------------------------------
+{
+ *this = folderType;
+}
+
+//----------------------------------------------------------------------------------------
+void nsSpecialSystemDirectory::operator = (OSType folderType)
+//----------------------------------------------------------------------------------------
+{
+ CInfoPBRec cinfo;
+ DirInfo *dipb=(DirInfo *)&cinfo;
+
+ // hack: first check for kDefaultDownloadFolderType
+ // if it is, get Internet Config Download folder, if that's
+ // not availble use desktop folder
+ if (folderType == kDefaultDownloadFolderType)
+ {
+ nsCOMPtr<nsIInternetConfigService> icService (do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID));
+ if (icService)
+ {
+ if (NS_SUCCEEDED(icService->GetDownloadFolder(&mSpec)))
+ return;
+ else
+ folderType = kDesktopFolderType;
+ }
+ else
+ {
+ folderType = kDesktopFolderType;
+ }
+ }
+ // Call FindFolder to fill in the vrefnum and dirid
+ for (int attempts = 0; attempts < 2; attempts++)
+ {
+ mError = NS_FILE_RESULT(
+ FindFolder(
+ kOnSystemDisk,
+ folderType,
+ true,
+ &dipb->ioVRefNum,
+ &dipb->ioDrDirID));
+ if (NS_SUCCEEDED(mError))
+ break;
+ if (attempts > 0)
+ return;
+ switch (folderType)
+ {
+ case kDocumentsFolderType:
+ // Find folder will find this, as long as it exists.
+ // The "create" parameter, however, is sadly ignored.
+ // How do we internationalize this?
+ *this = kVolumeRootFolderType;
+ *this += "Documents";
+ CreateDirectory();
+ break;
+ } // switch
+ } // for
+ StrFileName filename;
+ filename[0] = '\0';
+ dipb->ioNamePtr = (StringPtr)&filename;
+ dipb->ioFDirIndex = -1;
+
+ mError = NS_FILE_RESULT(PBGetCatInfoSync(&cinfo));
+ if (NS_SUCCEEDED(mError))
+ {
+ mError = NS_FILE_RESULT(FSMakeFSSpec(dipb->ioVRefNum, dipb->ioDrParID, filename, &mSpec));
+ }
+}
+#endif // XP_MAC
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/nsSpecialSystemDirectory.h b/src/libs/xpcom18a4/xpcom/obsolete/nsSpecialSystemDirectory.h
new file mode 100644
index 00000000..577cd0c0
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/nsSpecialSystemDirectory.h
@@ -0,0 +1,167 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Doug Turner <dougt@netscape.com>
+ * IBM Corp.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef _NSSPECIALSYSTEMDIRECTORY_H_
+#define _NSSPECIALSYSTEMDIRECTORY_H_
+
+#include "xpcomobsolete.h"
+#include "nsFileSpec.h"
+
+#if defined(XP_MAC) || defined(XP_MACOSX)
+#include <Types.h>
+#endif
+
+
+extern NS_COM_OBSOLETE void StartupSpecialSystemDirectory();
+extern NS_COM_OBSOLETE void ShutdownSpecialSystemDirectory();
+
+
+// SEE ALSO:
+// mozilla/xpfe/appshell/public/nsFileLocations.h
+
+class NS_COM_OBSOLETE nsSpecialSystemDirectory : public nsFileSpec
+{
+
+ public:
+ enum SystemDirectories
+ {
+ OS_DriveDirectory = 1
+ , OS_TemporaryDirectory = 2
+ , OS_CurrentProcessDirectory= 3
+ , OS_CurrentWorkingDirectory= 4
+
+ , XPCOM_CurrentProcessComponentDirectory= 5
+ , XPCOM_CurrentProcessComponentRegistry= 6
+
+ , Moz_BinDirectory = 10
+
+ , Mac_SystemDirectory = 101
+ , Mac_DesktopDirectory = 102
+ , Mac_TrashDirectory = 103
+ , Mac_StartupDirectory = 104
+ , Mac_ShutdownDirectory = 105
+ , Mac_AppleMenuDirectory = 106
+ , Mac_ControlPanelDirectory = 107
+ , Mac_ExtensionDirectory = 108
+ , Mac_FontsDirectory = 109
+ , Mac_ClassicPreferencesDirectory = 110
+ , Mac_DocumentsDirectory = 111
+ , Mac_InternetSearchDirectory = 112
+ , Mac_DefaultDownloadDirectory = 113
+ , Mac_UserLibDirectory = 114
+ , Mac_PreferencesDirectory = 115
+
+ , Win_SystemDirectory = 201
+ , Win_WindowsDirectory = 202
+
+ , Win_HomeDirectory = 203
+ , Win_Desktop = 204
+ , Win_Programs = 205
+ , Win_Controls = 206
+ , Win_Printers = 207
+ , Win_Personal = 208
+ , Win_Favorites = 209
+ , Win_Startup = 210
+ , Win_Recent = 211
+ , Win_Sendto = 212
+ , Win_Bitbucket = 213
+ , Win_Startmenu = 214
+ , Win_Desktopdirectory = 215
+ , Win_Drives = 216
+ , Win_Network = 217
+ , Win_Nethood = 218
+ , Win_Fonts = 219
+ , Win_Templates = 220
+ , Win_Common_Startmenu = 221
+ , Win_Common_Programs = 222
+ , Win_Common_Startup = 223
+ , Win_Common_Desktopdirectory = 224
+ , Win_Appdata = 225
+ , Win_Printhood = 226
+ , Win_Cookies = 227
+
+ , Unix_LocalDirectory = 301
+ , Unix_LibDirectory = 302
+ , Unix_HomeDirectory = 303
+
+ , BeOS_SettingsDirectory = 401
+ , BeOS_HomeDirectory = 402
+ , BeOS_DesktopDirectory = 403
+ , BeOS_SystemDirectory = 404
+
+ , OS2_SystemDirectory = 501
+ , OS2_OS2Directory = 502
+ , OS2_DesktopDirectory = 503
+ , OS2_HomeDirectory = 504
+ };
+
+ //nsSpecialSystemDirectory();
+ nsSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory);
+
+ virtual ~nsSpecialSystemDirectory();
+
+ void operator = (SystemDirectories aSystemSystemDirectory);
+
+#if defined(XP_MAC) || defined(XP_MACOSX)
+ void operator = (OSType folderType);
+ nsSpecialSystemDirectory(OSType folderType);
+ enum {
+ kDefaultDownloadFolderType = FOUR_CHAR_CODE('DfDÄ') /* Default Download Folder */
+ };
+#endif
+
+ /**
+
+ * @param: dirToSet, the value to set for this safeLocation
+
+ * @param: dirSpec, the directory specified as a filespec
+
+ */
+
+ static void Set(SystemDirectories dirToSet, nsFileSpec *dirSpec);
+
+
+private:
+ void operator = (const char* inPath) { *(nsFileSpec*)this = inPath; }
+
+}; // class NS_COM_OBSOLETE nsSpecialSystemDirectory
+
+
+#endif
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/nsXPCOMObsolete.cpp b/src/libs/xpcom18a4/xpcom/obsolete/nsXPCOMObsolete.cpp
new file mode 100644
index 00000000..45391c0f
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/nsXPCOMObsolete.cpp
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsXPCOM.h"
+#include "nsIGenericFactory.h"
+
+#include "nsFileSpecImpl.h"
+
+#define COMPONENT(NAME, Ctor) \
+ { NS_##NAME##_CLASSNAME, NS_##NAME##_CID, NS_##NAME##_CONTRACTID, Ctor }
+
+
+static const nsModuleComponentInfo components[] =
+{
+ COMPONENT(FILESPEC, nsFileSpecImpl::Create),
+ COMPONENT(DIRECTORYITERATOR, nsDirectoryIteratorImpl::Create),
+};
+
+NS_IMPL_NSGETMODULE(xpcomObsoleteModule, components)
+
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/xpcomobsolete.h b/src/libs/xpcom18a4/xpcom/obsolete/xpcomobsolete.h
new file mode 100644
index 00000000..13914115
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/xpcomobsolete.h
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla.
+ *
+ * The Initial Developer of the Original Code is IBM Corporation.
+ * Portions created by IBM Corporation are Copyright (C) 2003
+ * IBM Corporation. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Darin Fisher <darin@meer.net>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef xpcomobsolete_h___
+#define xpcomobsolete_h___
+
+#include "nscore.h"
+
+#ifdef _IMPL_NS_COM_OBSOLETE
+#define NS_COM_OBSOLETE NS_EXPORT
+#else
+#define NS_COM_OBSOLETE NS_IMPORT
+#endif
+
+#endif /* !defined(xpcomobsolete_h___) */
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/xpcomobsolete.pkg b/src/libs/xpcom18a4/xpcom/obsolete/xpcomobsolete.pkg
new file mode 100644
index 00000000..d44a8939
--- /dev/null
+++ b/src/libs/xpcom18a4/xpcom/obsolete/xpcomobsolete.pkg
@@ -0,0 +1,7 @@
+[gecko xpi-bootstrap]
+#if SHARED_LIBRARY
+dist/bin/@SHARED_LIBRARY@
+#endif
+
+[gecko]
+!xpt dist/bin/components/xpcom_obsolete.xpt