From f8fe689a81f906d1b91bb3220acde2a4ecb14c5b Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 6 May 2024 05:01:46 +0200 Subject: Adding upstream version 6.0.4-dfsg. Signed-off-by: Daniel Baumann --- src/libs/xpcom18a4/xpcom/obsolete/Makefile.in | 130 ++ .../xpcom18a4/xpcom/obsolete/component/Makefile.in | 81 + .../xpcom/obsolete/component/nsFileSpecImpl.cpp | 857 +++++++++ .../xpcom/obsolete/component/nsFileSpecImpl.h | 116 ++ .../xpcom/obsolete/component/nsIRegistry.idl | 186 ++ .../xpcom/obsolete/component/nsIRegistryUtils.h | 63 + .../xpcom/obsolete/component/nsRegistry.cpp | 2019 ++++++++++++++++++++ .../xpcom/obsolete/component/nsRegistry.h | 77 + .../xpcom/obsolete/component/nsXPCOMObsolete.cpp | 57 + .../xpcom/obsolete/component/regExport.cpp | 357 ++++ .../xpcom/obsolete/component/xpcomobsoletec.pkg | 6 + src/libs/xpcom18a4/xpcom/obsolete/dlldeps.cpp | 50 + src/libs/xpcom18a4/xpcom/obsolete/nsFileSpec.cpp | 1367 +++++++++++++ src/libs/xpcom18a4/xpcom/obsolete/nsFileSpec.h | 782 ++++++++ .../xpcom18a4/xpcom/obsolete/nsFileSpecBeOS.cpp | 547 ++++++ .../xpcom18a4/xpcom/obsolete/nsFileSpecImpl.cpp | 879 +++++++++ src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecImpl.h | 116 ++ .../xpcom18a4/xpcom/obsolete/nsFileSpecMac.cpp | 1471 ++++++++++++++ .../xpcom18a4/xpcom/obsolete/nsFileSpecOS2.cpp | 840 ++++++++ .../xpcom18a4/xpcom/obsolete/nsFileSpecUnix.cpp | 703 +++++++ .../xpcom18a4/xpcom/obsolete/nsFileSpecWin.cpp | 766 ++++++++ src/libs/xpcom18a4/xpcom/obsolete/nsFileStream.cpp | 392 ++++ src/libs/xpcom18a4/xpcom/obsolete/nsFileStream.h | 772 ++++++++ src/libs/xpcom18a4/xpcom/obsolete/nsIFileSpec.idl | 204 ++ .../xpcom18a4/xpcom/obsolete/nsIFileStream.cpp | 727 +++++++ src/libs/xpcom18a4/xpcom/obsolete/nsIFileStream.h | 157 ++ src/libs/xpcom18a4/xpcom/obsolete/nsIRegistry.idl | 186 ++ .../xpcom18a4/xpcom/obsolete/nsIRegistryUtils.h | 63 + .../xpcom/obsolete/nsSpecialSystemDirectory.cpp | 1189 ++++++++++++ .../xpcom/obsolete/nsSpecialSystemDirectory.h | 167 ++ .../xpcom18a4/xpcom/obsolete/nsXPCOMObsolete.cpp | 54 + src/libs/xpcom18a4/xpcom/obsolete/xpcomobsolete.h | 50 + .../xpcom18a4/xpcom/obsolete/xpcomobsolete.pkg | 7 + 33 files changed, 15438 insertions(+) create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/Makefile.in create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/component/Makefile.in create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/component/nsFileSpecImpl.cpp create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/component/nsFileSpecImpl.h create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/component/nsIRegistry.idl create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/component/nsIRegistryUtils.h create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/component/nsRegistry.cpp create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/component/nsRegistry.h create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/component/nsXPCOMObsolete.cpp create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/component/regExport.cpp create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/component/xpcomobsoletec.pkg create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/dlldeps.cpp create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/nsFileSpec.cpp create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/nsFileSpec.h create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecBeOS.cpp create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecImpl.cpp create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecImpl.h create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecMac.cpp create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecOS2.cpp create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecUnix.cpp create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecWin.cpp create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/nsFileStream.cpp create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/nsFileStream.h create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/nsIFileSpec.idl create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/nsIFileStream.cpp create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/nsIFileStream.h create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/nsIRegistry.idl create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/nsIRegistryUtils.h create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/nsSpecialSystemDirectory.cpp create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/nsSpecialSystemDirectory.h create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/nsXPCOMObsolete.cpp create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/xpcomobsolete.h create mode 100644 src/libs/xpcom18a4/xpcom/obsolete/xpcomobsolete.pkg (limited to 'src/libs/xpcom18a4/xpcom/obsolete') 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 + * + * 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 +#include +#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 registryLocation; + + PRBool foundReg = PR_FALSE; + nsCAutoString regFile; + + switch ( (nsWellKnownRegistry) regid ) { + case ApplicationComponentRegistry: + NS_WARNING("ApplicationComponentRegistry is unsupported!"); + break; + case ApplicationRegistry: + { + EnsureDefaultRegistryDirectory(); + nsCOMPtr 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 + * + * 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 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 + +#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(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 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 **) ®); + // 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 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 **) ®); + + // 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 \n" ); + } + else if ( rv == NS_OK ) { + + printf( "\n\n\nRegistry %s opened OK.\n", "\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 +#include + +#if defined(XP_WIN) +#include +#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 +#endif + +#if defined(XP_MAC) || defined(XP_MACOSX) +#include +#include +#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 file(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID)); + + if (!file) return NS_ERROR_FAILURE; + +#if defined(XP_MAC) + { + FSSpec spec = fileSpec->GetFSSpec(); + nsCOMPtr 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 +#include "nsILocalFileMac.h" +#elif defined(XP_UNIX) || defined(XP_BEOS) +#include +#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 +#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 +#include +#include +#include +#include +#include +#include +#include "nsError.h" +#include "prio.h" /* for PR_Rename */ + +// BeOS specific headers +#include +#include +#include + +//---------------------------------------------------------------------------------------- +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 + * + * 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 + +#include "prtypes.h" +#include "nscore.h" + +#include "FullPath.h" +#include "FileCopy.h" +#include "MoreFilesExtras.h" + +#include +#include +#include +#include +#include +#include // 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 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 macFile; + + rv = NS_NewLocalFileWithFSSpec(&nonConstSpec, PR_TRUE, getter_AddRefs(macFile)); + if (NS_FAILED(rv)) return nsnull; + nsCOMPtr 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(this)->mError; + if (inRecursive) + { + // MoreFilesExtras + anErr = ::DeleteDirectory( + mSpec.vRefNum, + mSpec.parID, + const_cast(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(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(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(&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(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(this)->mPath = path; // operator =() copies the string!!! + delete[] path; + } else { + const_cast(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, . + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Henry Sobotka + * 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 + +#ifdef XP_OS2_VACPP +#include +#endif + +#include +#include +#include +#include +#include + +//---------------------------------------------------------------------------------------- +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 + * + * 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 +#include +#include +#include +#include +#include +#include +#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 +#endif + +#ifdef HAVE_SYS_VFS_H +#include +#endif + +#ifdef HAVE_SYS_STATFS_H +#include +#endif + +#ifdef HAVE_SYS_MOUNT_H +#include +#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 /* 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 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 +#include +#include +#include +#include "prio.h" +#include "nsError.h" + +#include + +#if (_MSC_VER == 1100) || defined(__GNUC__) +#define INITGUID +#include +DEFINE_OLEGUID(IID_IPersistFile, 0x0000010BL, 0, 0); +#endif + +#include +#include +#include + +#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 +#include + + +//======================================================================================== +// 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 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 +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 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 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 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 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& 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 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& 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 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 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 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 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 + * + * 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 +#include +#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 macFile; + nsresult res = NS_NewLocalFileWithFSSpec(&nonConstSpec, PR_FALSE, getter_AddRefs(macFile)); + if (NS_SUCCEEDED(res)) { + nsCOMPtr 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 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 + * 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 +#include +#include +#include +#include +#include "nsIInternetConfigService.h" +#ifdef DEBUG +#include "prenv.h" // For PR_Getenv +#endif +#elif defined(XP_WIN) +#include +#include +#include +#include +#elif defined(XP_OS2) +#define MAX_PATH _MAX_PATH +#define INCL_WINWORKPLACE +#include +#include +#include +#include "prenv.h" +#elif defined(XP_UNIX) +#include +#include +#include +#include "prenv.h" +#elif defined(XP_BEOS) +#include +#include +#include +#include +#include +#include +#include +#include "prenv.h" +#endif + +#if defined(VMS) +#include +#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 + { + // /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 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 + * 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 +#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 + * + * 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 -- cgit v1.2.3