зеркало из https://github.com/mozilla/pjs.git
first draft of a xpcom obsolete dir. NOT PART OF BUILD
This commit is contained in:
Родитель
93be16ebcd
Коммит
69ac8a028e
|
@ -0,0 +1,97 @@
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the Netscape 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/NPL/
|
||||||
|
#
|
||||||
|
# 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 Netscape are
|
||||||
|
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||||
|
# Rights Reserved.
|
||||||
|
#
|
||||||
|
# Contributor(s):
|
||||||
|
#
|
||||||
|
|
||||||
|
DEPTH = ../..
|
||||||
|
topsrcdir = @top_srcdir@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
|
||||||
|
include $(DEPTH)/config/autoconf.mk
|
||||||
|
|
||||||
|
MODULE = xpcom_obsolete
|
||||||
|
LIBRARY_NAME = xpcom_obsolete
|
||||||
|
|
||||||
|
# Do not set EXPORT_LIBRARY as we do not want xpcom in the static libs list
|
||||||
|
#EXPORT_LIBRARY = 1
|
||||||
|
GRE_MODULE = 1
|
||||||
|
|
||||||
|
REQUIRES = xpcom \
|
||||||
|
string \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
# pull in MoreFiles for MacOSX
|
||||||
|
ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
|
||||||
|
REQUIRES += macmorefiles
|
||||||
|
endif
|
||||||
|
|
||||||
|
CPPSRCS = \
|
||||||
|
nsFileSpec.cpp \
|
||||||
|
nsFileSpecImpl.cpp \
|
||||||
|
nsFileStream.cpp \
|
||||||
|
nsIFileStream.cpp \
|
||||||
|
nsSpecialSystemDirectory.cpp \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
EXPORTS = \
|
||||||
|
nsFileSpec.h \
|
||||||
|
nsFileStream.h \
|
||||||
|
nsIFileStream.h \
|
||||||
|
nsSpecialSystemDirectory.h \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
XPIDLSRCS = nsIFileSpec.idl
|
||||||
|
|
||||||
|
LOCAL_INCLUDES = \
|
||||||
|
-I$(srcdir)/../io \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
# Force use of PIC
|
||||||
|
FORCE_USE_PIC = 1
|
||||||
|
|
||||||
|
FORCE_SHARED_LIB = 1
|
||||||
|
|
||||||
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
|
||||||
|
DEFINES += \
|
||||||
|
-D_IMPL_NS_COM
|
||||||
|
|
||||||
|
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 += shell32.lib ole32.lib
|
||||||
|
ifneq (,$(MOZ_DEBUG)$(NS_TRACE_MALLOC))
|
||||||
|
EXTRA_DSO_LDOPTS += imagehlp.lib
|
||||||
|
endif
|
||||||
|
endif # WINNT
|
||||||
|
|
||||||
|
ifeq ($(OS_ARCH), Linux)
|
||||||
|
DEFINES += -D_BSD_SOURCE
|
||||||
|
endif
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,784 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape 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/NPL/
|
||||||
|
*
|
||||||
|
* 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 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 NPL, 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 NPL, 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 "nscore.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(XP_WIN))
|
||||||
|
#define NS_USING_NAMESPACE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NS_USING_NAMESPACE
|
||||||
|
|
||||||
|
#define NS_NAMESPACE_PROTOTYPE
|
||||||
|
#define NS_NAMESPACE namespace
|
||||||
|
#define NS_NAMESPACE_END
|
||||||
|
#define NS_EXPLICIT explicit
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define NS_NAMESPACE_PROTOTYPE static
|
||||||
|
#define NS_NAMESPACE struct
|
||||||
|
#define NS_NAMESPACE_END ;
|
||||||
|
#define NS_EXPLICIT
|
||||||
|
|
||||||
|
#endif
|
||||||
|
//=========================== End Compiler-specific macros ===============================
|
||||||
|
|
||||||
|
#include "nsILocalFile.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
|
||||||
|
#if defined(XP_MAC)
|
||||||
|
#include <Files.h>
|
||||||
|
#include "nsILocalFileMac.h"
|
||||||
|
#elif defined(XP_UNIX) || defined(XP_BEOS)
|
||||||
|
#include <dirent.h>
|
||||||
|
#elif defined(XP_WIN)
|
||||||
|
|
||||||
|
// This clashes with some of the Win32 system headers (specifically,
|
||||||
|
// winbase.h). Hopefully they'll have been included first; else we may
|
||||||
|
// have problems. We could include winbase.h before doing this;
|
||||||
|
// unfortunately, it's bring in too much crap and'd slow stuff down
|
||||||
|
// more than it's worth doing.
|
||||||
|
#ifdef CreateDirectory
|
||||||
|
#undef CreateDirectory
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "prio.h"
|
||||||
|
#elif defined(XP_OS2)
|
||||||
|
#define INCL_DOS
|
||||||
|
#define INCL_DOSERRORS
|
||||||
|
#define INCL_WIN
|
||||||
|
#define INCL_GPI
|
||||||
|
#include <os2.h>
|
||||||
|
#include "prio.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//========================================================================================
|
||||||
|
// Here are the allowable ways to describe a file.
|
||||||
|
//========================================================================================
|
||||||
|
|
||||||
|
class nsFileSpec; // Preferred. For i/o use nsInputFileStream, nsOutputFileStream
|
||||||
|
class nsFilePath;
|
||||||
|
class nsFileURL;
|
||||||
|
class nsNSPRPath; // This can be passed to NSPR file I/O routines, if you must.
|
||||||
|
class nsPersistentFileDescriptor; // Used for storage across program launches.
|
||||||
|
|
||||||
|
#define kFileURLPrefix "file://"
|
||||||
|
#define kFileURLPrefixLength (7)
|
||||||
|
|
||||||
|
class nsOutputStream;
|
||||||
|
class nsInputStream;
|
||||||
|
class nsIOutputStream;
|
||||||
|
class nsIInputStream;
|
||||||
|
class nsOutputFileStream;
|
||||||
|
class nsInputFileStream;
|
||||||
|
class nsOutputConsoleStream;
|
||||||
|
|
||||||
|
class nsString;
|
||||||
|
|
||||||
|
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 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 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 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 nsInputStream& operator >> (nsInputStream&, nsPersistentFileDescriptor&);
|
||||||
|
// reads the data from a file
|
||||||
|
friend NS_COM 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 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 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 nsresult NS_FileSpecToIFile(nsFileSpec* fileSpec, nsILocalFile* *result);
|
||||||
|
|
||||||
|
#endif // _FILESPEC_H_
|
|
@ -0,0 +1,547 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape 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/NPL/
|
||||||
|
*
|
||||||
|
* 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 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 NPL, 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 NPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
// This file is included by nsFileSpec.cpp, and includes the Unix-specific
|
||||||
|
// implementations.
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include "nsError.h"
|
||||||
|
#include "prio.h" /* for PR_Rename */
|
||||||
|
|
||||||
|
// BeOS specific headers
|
||||||
|
#include <Entry.h>
|
||||||
|
#include <Path.h>
|
||||||
|
#include <Volume.h>
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsFileSpecHelpers::Canonify(nsSimpleCharString& ioPath, PRBool inMakeDirs)
|
||||||
|
// Canonify, make absolute, and check whether directories exist
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
if (ioPath.IsEmpty())
|
||||||
|
return;
|
||||||
|
if (inMakeDirs)
|
||||||
|
{
|
||||||
|
const mode_t mode = 0700;
|
||||||
|
nsFileSpecHelpers::MakeAllDirectories((const char*)ioPath, mode);
|
||||||
|
}
|
||||||
|
char buffer[MAXPATHLEN];
|
||||||
|
errno = 0;
|
||||||
|
*buffer = '\0';
|
||||||
|
BEntry e((const char *)ioPath, true);
|
||||||
|
BPath p;
|
||||||
|
e.GetPath(&p);
|
||||||
|
ioPath = p.Path();
|
||||||
|
} // nsFileSpecHelpers::Canonify
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsFileSpec::SetLeafName(const char* inLeafName)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
mPath.LeafReplace('/', inLeafName);
|
||||||
|
} // nsFileSpec::SetLeafName
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
char* nsFileSpec::GetLeafName() const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
return mPath.GetLeaf('/');
|
||||||
|
} // nsFileSpec::GetLeafName
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
PRBool nsFileSpec::Exists() const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
return !mPath.IsEmpty() && 0 == stat(mPath, &st);
|
||||||
|
} // nsFileSpec::Exists
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsFileSpec::GetModDate(TimeStamp& outStamp) const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
if (!mPath.IsEmpty() && stat(mPath, &st) == 0)
|
||||||
|
outStamp = st.st_mtime;
|
||||||
|
else
|
||||||
|
outStamp = 0;
|
||||||
|
} // nsFileSpec::GetModDate
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
PRUint32 nsFileSpec::GetFileSize() const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
if (!mPath.IsEmpty() && stat(mPath, &st) == 0)
|
||||||
|
return (PRUint32)st.st_size;
|
||||||
|
return 0;
|
||||||
|
} // nsFileSpec::GetFileSize
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
PRBool nsFileSpec::IsFile() const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
return !mPath.IsEmpty() && stat(mPath, &st) == 0 && S_ISREG(st.st_mode);
|
||||||
|
} // nsFileSpec::IsFile
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
PRBool nsFileSpec::IsDirectory() const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
return !mPath.IsEmpty() && 0 == stat(mPath, &st) && S_ISDIR(st.st_mode);
|
||||||
|
} // nsFileSpec::IsDirectory
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
PRBool nsFileSpec::IsHidden() const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
PRBool hidden = PR_TRUE;
|
||||||
|
char *leafname = GetLeafName();
|
||||||
|
if (nsnull != leafname)
|
||||||
|
{
|
||||||
|
if ((!strcmp(leafname, ".")) || (!strcmp(leafname, "..")))
|
||||||
|
{
|
||||||
|
hidden = PR_FALSE;
|
||||||
|
}
|
||||||
|
nsCRT::free(leafname);
|
||||||
|
}
|
||||||
|
return hidden;
|
||||||
|
} // nsFileSpec::IsHidden
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
PRBool nsFileSpec::IsSymlink() const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
if (!mPath.IsEmpty() && stat(mPath, &st) == 0 && S_ISLNK(st.st_mode))
|
||||||
|
return PR_TRUE;
|
||||||
|
|
||||||
|
return PR_FALSE;
|
||||||
|
} // nsFileSpec::IsSymlink
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsresult nsFileSpec::ResolveSymlink(PRBool& wasAliased)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
wasAliased = PR_FALSE;
|
||||||
|
|
||||||
|
char resolvedPath[MAXPATHLEN];
|
||||||
|
int charCount = readlink(mPath, (char*)&resolvedPath, MAXPATHLEN);
|
||||||
|
if (0 < charCount)
|
||||||
|
{
|
||||||
|
if (MAXPATHLEN > charCount)
|
||||||
|
resolvedPath[charCount] = '\0';
|
||||||
|
|
||||||
|
wasAliased = PR_TRUE;
|
||||||
|
/* if it's not an absolute path,
|
||||||
|
replace the leaf with what got resolved */
|
||||||
|
if (resolvedPath[0] != '/') {
|
||||||
|
SetLeafName(resolvedPath);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mPath = (char*)resolvedPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
BEntry e((const char *)mPath, true); // traverse symlink
|
||||||
|
BPath p;
|
||||||
|
status_t err;
|
||||||
|
err = e.GetPath(&p);
|
||||||
|
NS_ASSERTION(err == B_OK, "realpath failed");
|
||||||
|
|
||||||
|
const char* canonicalPath = p.Path();
|
||||||
|
if(err == B_OK)
|
||||||
|
mPath = (char*)canonicalPath;
|
||||||
|
else
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
} // nsFileSpec::ResolveSymlink
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsFileSpec::GetParent(nsFileSpec& outSpec) const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
outSpec.mPath = mPath;
|
||||||
|
char* chars = (char*)outSpec.mPath;
|
||||||
|
chars[outSpec.mPath.Length() - 1] = '\0'; // avoid trailing separator, if any
|
||||||
|
char* cp = strrchr(chars, '/');
|
||||||
|
if (cp++)
|
||||||
|
outSpec.mPath.SetLength(cp - chars); // truncate.
|
||||||
|
} // nsFileSpec::GetParent
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsFileSpec::operator += (const char* inRelativePath)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
if (!inRelativePath || mPath.IsEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
char endChar = mPath[(int)(strlen(mPath) - 1)];
|
||||||
|
if (endChar == '/')
|
||||||
|
mPath += "x";
|
||||||
|
else
|
||||||
|
mPath += "/x";
|
||||||
|
SetLeafName(inRelativePath);
|
||||||
|
} // nsFileSpec::operator +=
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsFileSpec::CreateDirectory(int mode)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
// Note that mPath is canonical!
|
||||||
|
if (mPath.IsEmpty())
|
||||||
|
return;
|
||||||
|
mkdir(mPath, mode);
|
||||||
|
} // nsFileSpec::CreateDirectory
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsFileSpec::Delete(PRBool inRecursive) const
|
||||||
|
// To check if this worked, call Exists() afterwards, see?
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
if (IsDirectory())
|
||||||
|
{
|
||||||
|
if (inRecursive)
|
||||||
|
{
|
||||||
|
for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++)
|
||||||
|
{
|
||||||
|
nsFileSpec& child = (nsFileSpec&)i;
|
||||||
|
child.Delete(inRecursive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rmdir(mPath);
|
||||||
|
}
|
||||||
|
else if (!mPath.IsEmpty())
|
||||||
|
remove(mPath);
|
||||||
|
} // nsFileSpec::Delete
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsFileSpec::RecursiveCopy(nsFileSpec newDir) const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
if (IsDirectory())
|
||||||
|
{
|
||||||
|
if (!(newDir.Exists()))
|
||||||
|
{
|
||||||
|
newDir.CreateDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++)
|
||||||
|
{
|
||||||
|
nsFileSpec& child = (nsFileSpec&)i;
|
||||||
|
|
||||||
|
if (child.IsDirectory())
|
||||||
|
{
|
||||||
|
nsFileSpec tmpDirSpec(newDir);
|
||||||
|
|
||||||
|
char *leafname = child.GetLeafName();
|
||||||
|
tmpDirSpec += leafname;
|
||||||
|
nsCRT::free(leafname);
|
||||||
|
|
||||||
|
child.RecursiveCopy(tmpDirSpec);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
child.RecursiveCopy(newDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!mPath.IsEmpty())
|
||||||
|
{
|
||||||
|
nsFileSpec& filePath = (nsFileSpec&) *this;
|
||||||
|
|
||||||
|
if (!(newDir.Exists()))
|
||||||
|
{
|
||||||
|
newDir.CreateDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
|
filePath.CopyToDir(newDir);
|
||||||
|
}
|
||||||
|
} // nsFileSpec::RecursiveCopy
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsresult nsFileSpec::Truncate(PRInt32 offset) const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
char* Path = nsCRT::strdup(mPath);
|
||||||
|
|
||||||
|
int rv = truncate(Path, offset) ;
|
||||||
|
|
||||||
|
nsCRT::free(Path) ;
|
||||||
|
|
||||||
|
if(!rv)
|
||||||
|
return NS_OK ;
|
||||||
|
else
|
||||||
|
return NS_ERROR_FAILURE ;
|
||||||
|
} // nsFileSpec::Truncate
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsresult nsFileSpec::Rename(const char* inNewName)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
// This function should not be used to move a file on disk.
|
||||||
|
if (mPath.IsEmpty() || strchr(inNewName, '/'))
|
||||||
|
return NS_FILE_FAILURE;
|
||||||
|
|
||||||
|
char* oldPath = nsCRT::strdup(mPath);
|
||||||
|
|
||||||
|
SetLeafName(inNewName);
|
||||||
|
|
||||||
|
if (PR_Rename(oldPath, mPath) != NS_OK)
|
||||||
|
{
|
||||||
|
// Could not rename, set back to the original.
|
||||||
|
mPath = oldPath;
|
||||||
|
return NS_FILE_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCRT::free(oldPath);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
} // nsFileSpec::Rename
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
static int CrudeFileCopy(const char* in, const char* out)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
struct stat in_stat;
|
||||||
|
int stat_result = -1;
|
||||||
|
|
||||||
|
char buf [1024];
|
||||||
|
FILE *ifp, *ofp;
|
||||||
|
int rbytes, wbytes;
|
||||||
|
|
||||||
|
if (!in || !out)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
stat_result = stat (in, &in_stat);
|
||||||
|
|
||||||
|
ifp = fopen (in, "r");
|
||||||
|
if (!ifp)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ofp = fopen (out, "w");
|
||||||
|
if (!ofp)
|
||||||
|
{
|
||||||
|
fclose (ifp);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((rbytes = fread (buf, 1, sizeof(buf), ifp)) > 0)
|
||||||
|
{
|
||||||
|
while (rbytes > 0)
|
||||||
|
{
|
||||||
|
if ( (wbytes = fwrite (buf, 1, rbytes, ofp)) < 0 )
|
||||||
|
{
|
||||||
|
fclose (ofp);
|
||||||
|
fclose (ifp);
|
||||||
|
unlink(out);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
rbytes -= wbytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose (ofp);
|
||||||
|
fclose (ifp);
|
||||||
|
|
||||||
|
if (stat_result == 0)
|
||||||
|
chmod (out, in_stat.st_mode & 0777);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
} // nsFileSpec::Rename
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsresult nsFileSpec::CopyToDir(const nsFileSpec& inParentDirectory) const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
// We can only copy into a directory, and (for now) can not copy entire directories
|
||||||
|
nsresult result = NS_FILE_FAILURE;
|
||||||
|
|
||||||
|
if (inParentDirectory.IsDirectory() && (! IsDirectory() ) )
|
||||||
|
{
|
||||||
|
char *leafname = GetLeafName();
|
||||||
|
nsSimpleCharString destPath(inParentDirectory.GetCString());
|
||||||
|
destPath += "/";
|
||||||
|
destPath += leafname;
|
||||||
|
nsCRT::free(leafname);
|
||||||
|
result = NS_FILE_RESULT(CrudeFileCopy(GetCString(), destPath));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} // nsFileSpec::CopyToDir
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsresult nsFileSpec::MoveToDir(const nsFileSpec& inNewParentDirectory)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
// We can only copy into a directory, and (for now) can not copy entire directories
|
||||||
|
nsresult result = NS_FILE_FAILURE;
|
||||||
|
|
||||||
|
if (inNewParentDirectory.IsDirectory() && !IsDirectory())
|
||||||
|
{
|
||||||
|
char *leafname = GetLeafName();
|
||||||
|
nsSimpleCharString destPath(inNewParentDirectory.GetCString());
|
||||||
|
destPath += "/";
|
||||||
|
destPath += leafname;
|
||||||
|
nsCRT::free(leafname);
|
||||||
|
|
||||||
|
result = NS_FILE_RESULT(CrudeFileCopy(GetCString(), (const char*)destPath));
|
||||||
|
if (result == NS_OK)
|
||||||
|
{
|
||||||
|
// cast to fix const-ness
|
||||||
|
((nsFileSpec*)this)->Delete(PR_FALSE);
|
||||||
|
|
||||||
|
*this = inNewParentDirectory + GetLeafName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsresult nsFileSpec::Execute(const char* inArgs ) const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
nsresult result = NS_FILE_FAILURE;
|
||||||
|
|
||||||
|
if (!mPath.IsEmpty() && !IsDirectory())
|
||||||
|
{
|
||||||
|
nsSimpleCharString fileNameWithArgs = mPath + " " + inArgs;
|
||||||
|
result = NS_FILE_RESULT(system(fileNameWithArgs));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
} // nsFileSpec::Execute
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
PRInt64 nsFileSpec::GetDiskSpaceAvailable() const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
char curdir [MAXPATHLEN];
|
||||||
|
if (!mPath || !*mPath)
|
||||||
|
{
|
||||||
|
(void) getcwd(curdir, MAXPATHLEN);
|
||||||
|
if (!curdir)
|
||||||
|
return ULONGLONG_MAX; /* hope for the best as we did in cheddar */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
sprintf(curdir, "%.200s", (const char*)mPath);
|
||||||
|
|
||||||
|
BEntry e(curdir);
|
||||||
|
if(e.InitCheck() != B_OK)
|
||||||
|
return ULONGLONG_MAX; /* hope for the best as we did in cheddar */
|
||||||
|
entry_ref ref;
|
||||||
|
e.GetRef(&ref);
|
||||||
|
BVolume v(ref.device);
|
||||||
|
|
||||||
|
#ifdef DEBUG_DISK_SPACE
|
||||||
|
printf("DiskSpaceAvailable: %d bytes\n", space);
|
||||||
|
#endif
|
||||||
|
return v.FreeBytes();
|
||||||
|
} // nsFileSpec::GetDiskSpace()
|
||||||
|
|
||||||
|
//========================================================================================
|
||||||
|
// nsDirectoryIterator
|
||||||
|
//========================================================================================
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsDirectoryIterator::nsDirectoryIterator(
|
||||||
|
const nsFileSpec& inDirectory
|
||||||
|
, PRBool resolveSymlinks)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
: mCurrent(inDirectory)
|
||||||
|
, mStarting(inDirectory)
|
||||||
|
, mExists(PR_FALSE)
|
||||||
|
, mDir(nsnull)
|
||||||
|
, mResoveSymLinks(resolveSymlinks)
|
||||||
|
{
|
||||||
|
mStarting += "sysygy"; // save off the starting directory
|
||||||
|
mCurrent += "sysygy"; // prepare the path for SetLeafName
|
||||||
|
mDir = opendir((const char*)nsFilePath(inDirectory));
|
||||||
|
++(*this);
|
||||||
|
} // nsDirectoryIterator::nsDirectoryIterator
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsDirectoryIterator::~nsDirectoryIterator()
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
if (mDir)
|
||||||
|
closedir(mDir);
|
||||||
|
} // nsDirectoryIterator::nsDirectoryIterator
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsDirectoryIterator& nsDirectoryIterator::operator ++ ()
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
mExists = PR_FALSE;
|
||||||
|
if (!mDir)
|
||||||
|
return *this;
|
||||||
|
char* dot = ".";
|
||||||
|
char* dotdot = "..";
|
||||||
|
struct dirent* entry = readdir(mDir);
|
||||||
|
if (entry && strcmp(entry->d_name, dot) == 0)
|
||||||
|
entry = readdir(mDir);
|
||||||
|
if (entry && strcmp(entry->d_name, dotdot) == 0)
|
||||||
|
entry = readdir(mDir);
|
||||||
|
if (entry)
|
||||||
|
{
|
||||||
|
mExists = PR_TRUE;
|
||||||
|
mCurrent = mStarting; // restore mCurrent to be the starting directory. ResolveSymlink() may have taken us to another directory
|
||||||
|
mCurrent.SetLeafName(entry->d_name);
|
||||||
|
if (mResoveSymLinks)
|
||||||
|
{
|
||||||
|
PRBool ignore;
|
||||||
|
mCurrent.ResolveSymlink(ignore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
} // nsDirectoryIterator::operator ++
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsDirectoryIterator& nsDirectoryIterator::operator -- ()
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
return ++(*this); // can't do it backwards.
|
||||||
|
} // nsDirectoryIterator::operator --
|
|
@ -0,0 +1,857 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape 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/NPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is mozilla.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Netscape Communications Corporation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Pierre Phaneuf <pp@ludusdesign.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either 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 NPL, 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 NPL, 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_METHOD 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_METHOD 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);
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape 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/NPL/
|
||||||
|
*
|
||||||
|
* 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 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 NPL, 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 NPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#ifndef _FILESPECIMPL_H_
|
||||||
|
#define _FILESPECIMPL_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);
|
||||||
|
virtual ~nsFileSpecImpl();
|
||||||
|
static nsresult MakeInterface(const nsFileSpec& inSpec, nsIFileSpec** outSpec);
|
||||||
|
|
||||||
|
//----------------------
|
||||||
|
// Data
|
||||||
|
//----------------------
|
||||||
|
|
||||||
|
nsFileSpec mFileSpec;
|
||||||
|
nsIInputStream* mInputStream;
|
||||||
|
nsIOutputStream* mOutputStream;
|
||||||
|
|
||||||
|
}; // class nsFileSpecImpl
|
||||||
|
|
||||||
|
//========================================================================================
|
||||||
|
class nsDirectoryIteratorImpl
|
||||||
|
//========================================================================================
|
||||||
|
: public nsIDirectoryIterator
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
nsDirectoryIteratorImpl();
|
||||||
|
virtual ~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);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
nsDirectoryIterator* mDirectoryIterator;
|
||||||
|
}; // class nsDirectoryIteratorImpl
|
||||||
|
|
||||||
|
#endif // _FILESPECIMPL_H_
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,823 @@
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License
|
||||||
|
* Version 1.1 (the "License"); you may not use this file except in
|
||||||
|
* compliance with the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS"
|
||||||
|
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing rights and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* The Original Code is the Mozilla OS/2 libraries.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is John Fairhurst,
|
||||||
|
* <john_fairhurst@iname.com>. Portions created by John Fairhurst are
|
||||||
|
* Copyright (C) 1998 John Fairhurst. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Henry Sobotka <sobotka@axess.com>
|
||||||
|
* 00/01/06: general review and update against Win/Unix versions;
|
||||||
|
* replaced nsFileSpec::Execute implementation with system() call
|
||||||
|
* which properly launches OS/2 PM|VIO, WinOS2 and DOS programs
|
||||||
|
*
|
||||||
|
* This Original Code has been modified by IBM Corporation.
|
||||||
|
* Modifications made by IBM described herein are
|
||||||
|
* Copyright (c) International Business Machines
|
||||||
|
* Corporation, 2000
|
||||||
|
*
|
||||||
|
* Modifications to Mozilla code or documentation
|
||||||
|
* identified per MPL Section 3.3
|
||||||
|
*
|
||||||
|
* Date Modified by Description of modification
|
||||||
|
* 03/23/2000 IBM Corp. Fixed bug where 2 char or less profile names treated as drive letters.
|
||||||
|
* 06/20/2000 IBM Corp. Make it more like Windows version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define INCL_DOSERRORS
|
||||||
|
#define INCL_DOS
|
||||||
|
#define INCL_WINWORKPLACE
|
||||||
|
#include <os2.h>
|
||||||
|
|
||||||
|
#ifdef XP_OS2_VACPP
|
||||||
|
#include <direct.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <io.h>
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsFileSpecHelpers::Canonify(nsSimpleCharString& ioPath, PRBool inMakeDirs)
|
||||||
|
// Canonify, make absolute, and check whether directories exist. This
|
||||||
|
// takes a (possibly relative) native path and converts it into a
|
||||||
|
// fully qualified native path.
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
if (ioPath.IsEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
NS_ASSERTION(strchr((const char*)ioPath, '/') == 0,
|
||||||
|
"This smells like a Unix path. Native path expected! "
|
||||||
|
"Please fix.");
|
||||||
|
if (inMakeDirs)
|
||||||
|
{
|
||||||
|
const int mode = 0700;
|
||||||
|
nsSimpleCharString unixStylePath = ioPath;
|
||||||
|
nsFileSpecHelpers::NativeToUnix(unixStylePath);
|
||||||
|
nsFileSpecHelpers::MakeAllDirectories((const char*)unixStylePath, mode);
|
||||||
|
}
|
||||||
|
char buffer[_MAX_PATH];
|
||||||
|
errno = 0;
|
||||||
|
*buffer = '\0';
|
||||||
|
#ifdef XP_OS2
|
||||||
|
PRBool removedBackslash = PR_FALSE;
|
||||||
|
PRUint32 lenstr = ioPath.Length();
|
||||||
|
char &lastchar = ioPath[lenstr -1];
|
||||||
|
|
||||||
|
// Strip off any trailing backslash UNLESS it's the backslash that
|
||||||
|
// comes after "X:". Note also that "\" is valid. Sheesh.
|
||||||
|
//
|
||||||
|
if( lastchar == '\\' && (lenstr != 3 || ioPath[1] != ':') && lenstr != 1)
|
||||||
|
{
|
||||||
|
lastchar = '\0';
|
||||||
|
removedBackslash = PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
char canonicalPath[CCHMAXPATH] = "";
|
||||||
|
|
||||||
|
DosQueryPathInfo( (char*) ioPath,
|
||||||
|
FIL_QUERYFULLNAME,
|
||||||
|
canonicalPath,
|
||||||
|
CCHMAXPATH);
|
||||||
|
#else
|
||||||
|
char* canonicalPath = _fullpath(buffer, ioPath, _MAX_PATH);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (canonicalPath)
|
||||||
|
{
|
||||||
|
NS_ASSERTION( canonicalPath[0] != '\0', "Uh oh...couldn't convert" );
|
||||||
|
if (canonicalPath[0] == '\0')
|
||||||
|
return;
|
||||||
|
#ifdef XP_OS2
|
||||||
|
// If we removed that backslash, add it back onto the fullpath
|
||||||
|
if (removedBackslash)
|
||||||
|
strcat( canonicalPath, "\\");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
ioPath = canonicalPath;
|
||||||
|
} // nsFileSpecHelpers::Canonify
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsFileSpecHelpers::UnixToNative(nsSimpleCharString& ioPath)
|
||||||
|
// This just does string manipulation. It doesn't check reality, or canonify, or
|
||||||
|
// anything
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
// Allow for relative or absolute. We can do this in place, because the
|
||||||
|
// native path is never longer.
|
||||||
|
|
||||||
|
if (ioPath.IsEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Strip initial slash for an absolute path
|
||||||
|
char* src = (char*)ioPath;
|
||||||
|
if (*src == '/') {
|
||||||
|
if (!src[1]) {
|
||||||
|
// allocate new string by copying from ioPath[1]
|
||||||
|
nsSimpleCharString temp = src + 1;
|
||||||
|
ioPath = temp;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Since it was an absolute path, check for the drive letter
|
||||||
|
char* colonPointer = src + 2;
|
||||||
|
if (strstr(src, "|/") == colonPointer)
|
||||||
|
*colonPointer = ':';
|
||||||
|
// allocate new string by copying from ioPath[1]
|
||||||
|
nsSimpleCharString temp = src + 1;
|
||||||
|
ioPath = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
src = (char*)ioPath;
|
||||||
|
|
||||||
|
if (*src) {
|
||||||
|
// Convert '/' to '\'.
|
||||||
|
while (*++src)
|
||||||
|
{
|
||||||
|
if (*src == '/')
|
||||||
|
*src = '\\';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // nsFileSpecHelpers::UnixToNative
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsFileSpecHelpers::NativeToUnix(nsSimpleCharString& ioPath)
|
||||||
|
// This just does string manipulation. It doesn't check reality, or canonify, or
|
||||||
|
// anything. The unix path is longer, so we can't do it in place.
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
if (ioPath.IsEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Convert the drive-letter separator, if present
|
||||||
|
nsSimpleCharString temp("/");
|
||||||
|
|
||||||
|
char* cp = (char*)ioPath + 1;
|
||||||
|
if (strstr(cp, ":\\") == cp)
|
||||||
|
*cp = '|'; // absolute path
|
||||||
|
else
|
||||||
|
temp[0] = '\0'; // relative path
|
||||||
|
|
||||||
|
// Convert '\' to '/'
|
||||||
|
for (; *cp; cp++)
|
||||||
|
{
|
||||||
|
#ifdef XP_OS2
|
||||||
|
// OS2TODO - implement equivalent of IsDBCSLeadByte
|
||||||
|
#else
|
||||||
|
if(IsDBCSLeadByte(*cp) && *(cp+1) != nsnull)
|
||||||
|
{
|
||||||
|
cp++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (*cp == '\\')
|
||||||
|
*cp = '/';
|
||||||
|
}
|
||||||
|
// Add the slash in front.
|
||||||
|
temp += ioPath;
|
||||||
|
ioPath = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsFileSpec::nsFileSpec(const nsFilePath& inPath)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!");
|
||||||
|
*this = inPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsFileSpec::operator = (const nsFilePath& inPath)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
mPath = (const char*)inPath;
|
||||||
|
nsFileSpecHelpers::UnixToNative(mPath);
|
||||||
|
mError = NS_OK;
|
||||||
|
} // nsFileSpec::operator =
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsFilePath::nsFilePath(const nsFileSpec& inSpec)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
*this = inSpec;
|
||||||
|
} // nsFilePath::nsFilePath
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsFilePath::operator = (const nsFileSpec& inSpec)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
mPath = inSpec.mPath;
|
||||||
|
nsFileSpecHelpers::NativeToUnix(mPath);
|
||||||
|
} // nsFilePath::operator =
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsFileSpec::SetLeafName(const char* inLeafName)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
NS_ASSERTION(inLeafName, "Attempt to SetLeafName with a null string");
|
||||||
|
mPath.LeafReplace('\\', inLeafName);
|
||||||
|
} // nsFileSpec::SetLeafName
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
char* nsFileSpec::GetLeafName() const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
return mPath.GetLeaf('\\');
|
||||||
|
} // nsFileSpec::GetLeafName
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
PRBool nsFileSpec::Exists() const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
return !mPath.IsEmpty() && 0 == stat(nsNSPRPath(*this), &st);
|
||||||
|
} // nsFileSpec::Exists
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsFileSpec::GetModDate(TimeStamp& outStamp) const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
if (!mPath.IsEmpty() && stat(nsNSPRPath(*this), &st) == 0)
|
||||||
|
outStamp = st.st_mtime;
|
||||||
|
else
|
||||||
|
outStamp = 0;
|
||||||
|
} // nsFileSpec::GetModDate
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
PRUint32 nsFileSpec::GetFileSize() const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
if (!mPath.IsEmpty() && stat(nsNSPRPath(*this), &st) == 0)
|
||||||
|
return (PRUint32)st.st_size;
|
||||||
|
return 0;
|
||||||
|
} // nsFileSpec::GetFileSize
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
PRBool nsFileSpec::IsFile() const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
#ifdef XP_OS2
|
||||||
|
return !mPath.IsEmpty() && 0 == stat(nsNSPRPath(*this), &st) && ( S_IFREG & st.st_mode);
|
||||||
|
#else
|
||||||
|
return !mPath.IsEmpty() && 0 == stat(nsNSPRPath(*this), &st) && (_S_IFREG & st.st_mode);
|
||||||
|
#endif
|
||||||
|
} // nsFileSpec::IsFile
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
PRBool nsFileSpec::IsDirectory() const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
#ifdef XP_OS2
|
||||||
|
return !mPath.IsEmpty() && 0 == stat(nsNSPRPath(*this), &st) && ( S_IFDIR & st.st_mode);
|
||||||
|
#else
|
||||||
|
return !mPath.IsEmpty() && 0 == stat(nsNSPRPath(*this), &st) && (_S_IFDIR & st.st_mode);
|
||||||
|
#endif
|
||||||
|
} // nsFileSpec::IsDirectory
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
PRBool nsFileSpec::IsHidden() const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
PRBool hidden = PR_FALSE;
|
||||||
|
if (!mPath.IsEmpty())
|
||||||
|
{
|
||||||
|
#ifdef XP_OS2
|
||||||
|
FILESTATUS3 fs3;
|
||||||
|
APIRET rc;
|
||||||
|
|
||||||
|
rc = DosQueryPathInfo( mPath,
|
||||||
|
FIL_STANDARD,
|
||||||
|
&fs3,
|
||||||
|
sizeof fs3);
|
||||||
|
if(!rc)
|
||||||
|
hidden = fs3.attrFile & FILE_HIDDEN ? PR_TRUE : PR_FALSE;
|
||||||
|
#else
|
||||||
|
DWORD attr = GetFileAttributes(mPath);
|
||||||
|
if (FILE_ATTRIBUTE_HIDDEN & attr)
|
||||||
|
hidden = PR_TRUE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return hidden;
|
||||||
|
}
|
||||||
|
// nsFileSpec::IsHidden
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
PRBool nsFileSpec::IsSymlink() const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
#ifdef XP_OS2
|
||||||
|
return PR_FALSE; // No symlinks on OS/2
|
||||||
|
#else
|
||||||
|
HRESULT hres;
|
||||||
|
IShellLink* psl;
|
||||||
|
|
||||||
|
PRBool isSymlink = PR_FALSE;
|
||||||
|
|
||||||
|
CoInitialize(NULL);
|
||||||
|
// Get a pointer to the IShellLink interface.
|
||||||
|
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&psl);
|
||||||
|
if (SUCCEEDED(hres))
|
||||||
|
{
|
||||||
|
IPersistFile* ppf;
|
||||||
|
|
||||||
|
// Get a pointer to the IPersistFile interface.
|
||||||
|
hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hres))
|
||||||
|
{
|
||||||
|
WORD wsz[MAX_PATH];
|
||||||
|
// Ensure that the string is Unicode.
|
||||||
|
MultiByteToWideChar(CP_ACP, 0, mPath, -1, wsz, MAX_PATH);
|
||||||
|
|
||||||
|
// Load the shortcut.
|
||||||
|
hres = ppf->Load(wsz, STGM_READ);
|
||||||
|
if (SUCCEEDED(hres))
|
||||||
|
{
|
||||||
|
isSymlink = PR_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release the pointer to the IPersistFile interface.
|
||||||
|
ppf->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release the pointer to the IShellLink interface.
|
||||||
|
psl->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
CoUninitialize();
|
||||||
|
|
||||||
|
return isSymlink;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsresult nsFileSpec::ResolveSymlink(PRBool& wasSymlink)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
#ifdef XP_OS2
|
||||||
|
return NS_OK; // no symlinks on OS/2
|
||||||
|
#else
|
||||||
|
wasSymlink = PR_FALSE; // assume failure
|
||||||
|
|
||||||
|
if (Exists())
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT hres;
|
||||||
|
IShellLink* psl;
|
||||||
|
|
||||||
|
CoInitialize(NULL);
|
||||||
|
|
||||||
|
// Get a pointer to the IShellLink interface.
|
||||||
|
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (void**)&psl);
|
||||||
|
if (SUCCEEDED(hres))
|
||||||
|
{
|
||||||
|
IPersistFile* ppf;
|
||||||
|
|
||||||
|
// Get a pointer to the IPersistFile interface.
|
||||||
|
hres = psl->QueryInterface(IID_IPersistFile, (void**)&ppf);
|
||||||
|
|
||||||
|
if (SUCCEEDED(hres))
|
||||||
|
{
|
||||||
|
WORD wsz[MAX_PATH];
|
||||||
|
// Ensure that the string is Unicode.
|
||||||
|
MultiByteToWideChar(CP_ACP, 0, mPath, -1, wsz, MAX_PATH);
|
||||||
|
|
||||||
|
// Load the shortcut.
|
||||||
|
hres = ppf->Load(wsz, STGM_READ);
|
||||||
|
if (SUCCEEDED(hres))
|
||||||
|
{
|
||||||
|
wasSymlink = PR_TRUE;
|
||||||
|
|
||||||
|
// Resolve the link.
|
||||||
|
hres = psl->Resolve(nsnull, SLR_NO_UI );
|
||||||
|
if (SUCCEEDED(hres))
|
||||||
|
{
|
||||||
|
char szGotPath[MAX_PATH];
|
||||||
|
WIN32_FIND_DATA wfd;
|
||||||
|
|
||||||
|
// Get the path to the link target.
|
||||||
|
hres = psl->GetPath( szGotPath, MAX_PATH, &wfd, SLGP_UNCPRIORITY );
|
||||||
|
|
||||||
|
if (SUCCEEDED(hres))
|
||||||
|
{
|
||||||
|
// Here we modify the nsFileSpec;
|
||||||
|
mPath = szGotPath;
|
||||||
|
mError = NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// It wasn't a shortcut. Oh well. Leave it like it was.
|
||||||
|
hres = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release the pointer to the IPersistFile interface.
|
||||||
|
ppf->Release();
|
||||||
|
}
|
||||||
|
// Release the pointer to the IShellLink interface.
|
||||||
|
psl->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
CoUninitialize();
|
||||||
|
|
||||||
|
if (SUCCEEDED(hres))
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
return NS_FILE_FAILURE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsFileSpec::GetParent(nsFileSpec& outSpec) const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
outSpec.mPath = mPath;
|
||||||
|
char* chars = (char*)outSpec.mPath;
|
||||||
|
chars[outSpec.mPath.Length() - 1] = '\0'; // avoid trailing separator, if any
|
||||||
|
char* cp = strrchr(chars, '\\');
|
||||||
|
if (cp++)
|
||||||
|
outSpec.mPath.SetLength(cp - chars); // truncate.
|
||||||
|
} // nsFileSpec::GetParent
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsFileSpec::operator += (const char* inRelativePath)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
NS_ASSERTION(inRelativePath, "Attempt to do += with a null string");
|
||||||
|
|
||||||
|
if (!inRelativePath || mPath.IsEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (mPath[mPath.Length() - 1] == '\\')
|
||||||
|
mPath += "x";
|
||||||
|
else
|
||||||
|
mPath += "\\x";
|
||||||
|
|
||||||
|
// If it's a (unix) relative path, make it native
|
||||||
|
nsSimpleCharString dosPath = inRelativePath;
|
||||||
|
nsFileSpecHelpers::UnixToNative(dosPath);
|
||||||
|
SetLeafName(dosPath);
|
||||||
|
} // nsFileSpec::operator +=
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsFileSpec::CreateDirectory(int /*mode*/)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
// Note that mPath is canonical!
|
||||||
|
if (!mPath.IsEmpty())
|
||||||
|
#ifdef XP_OS2
|
||||||
|
// OS2TODO - vacpp complains about mkdir but PR_MkDir should be ok?
|
||||||
|
PR_MkDir(nsNSPRPath(*this), PR_CREATE_FILE);
|
||||||
|
#else
|
||||||
|
mkdir(nsNSPRPath(*this));
|
||||||
|
#endif
|
||||||
|
} // nsFileSpec::CreateDirectory
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsFileSpec::Delete(PRBool inRecursive) const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
if (IsDirectory())
|
||||||
|
{
|
||||||
|
if (inRecursive)
|
||||||
|
{
|
||||||
|
for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++)
|
||||||
|
{
|
||||||
|
nsFileSpec& child = i.Spec();
|
||||||
|
child.Delete(inRecursive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef XP_OS2
|
||||||
|
// OS2TODO - vacpp complains if use rmdir but PR_RmDir should be ok?
|
||||||
|
PR_RmDir(nsNSPRPath(*this));
|
||||||
|
#else
|
||||||
|
rmdir(nsNSPRPath(*this));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (!mPath.IsEmpty())
|
||||||
|
{
|
||||||
|
remove(nsNSPRPath(*this));
|
||||||
|
}
|
||||||
|
} // nsFileSpec::Delete
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsFileSpec::RecursiveCopy(nsFileSpec newDir) const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
if (IsDirectory())
|
||||||
|
{
|
||||||
|
if (!(newDir.Exists()))
|
||||||
|
{
|
||||||
|
newDir.CreateDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++)
|
||||||
|
{
|
||||||
|
nsFileSpec& child = i.Spec();
|
||||||
|
|
||||||
|
if (child.IsDirectory())
|
||||||
|
{
|
||||||
|
nsFileSpec tmpDirSpec(newDir);
|
||||||
|
|
||||||
|
char *leafname = child.GetLeafName();
|
||||||
|
tmpDirSpec += leafname;
|
||||||
|
nsCRT::free(leafname);
|
||||||
|
|
||||||
|
child.RecursiveCopy(tmpDirSpec);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
child.RecursiveCopy(newDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!mPath.IsEmpty())
|
||||||
|
{
|
||||||
|
nsFileSpec& filePath = (nsFileSpec&) *this;
|
||||||
|
|
||||||
|
if (!(newDir.Exists()))
|
||||||
|
{
|
||||||
|
newDir.CreateDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
|
filePath.CopyToDir(newDir);
|
||||||
|
}
|
||||||
|
} // nsFileSpec::RecursiveCopy
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsresult
|
||||||
|
nsFileSpec::Truncate(PRInt32 aNewFileLength) const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
#ifdef XP_OS2
|
||||||
|
APIRET rc;
|
||||||
|
HFILE hFile;
|
||||||
|
ULONG actionTaken;
|
||||||
|
|
||||||
|
rc = DosOpen(mPath,
|
||||||
|
&hFile,
|
||||||
|
&actionTaken,
|
||||||
|
0,
|
||||||
|
FILE_NORMAL,
|
||||||
|
OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS,
|
||||||
|
OPEN_SHARE_DENYREADWRITE | OPEN_ACCESS_READWRITE,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (rc != NO_ERROR)
|
||||||
|
return NS_FILE_FAILURE;
|
||||||
|
|
||||||
|
rc = DosSetFileSize(hFile, aNewFileLength);
|
||||||
|
|
||||||
|
if (rc == NO_ERROR)
|
||||||
|
DosClose(hFile);
|
||||||
|
else
|
||||||
|
goto error;
|
||||||
|
#else
|
||||||
|
DWORD status;
|
||||||
|
HANDLE hFile;
|
||||||
|
|
||||||
|
// Leave it to Microsoft to open an existing file with a function
|
||||||
|
// named "CreateFile".
|
||||||
|
hFile = CreateFile(mPath,
|
||||||
|
GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ,
|
||||||
|
NULL,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
NULL);
|
||||||
|
if (hFile == INVALID_HANDLE_VALUE)
|
||||||
|
return NS_FILE_FAILURE;
|
||||||
|
|
||||||
|
// Seek to new, desired end of file
|
||||||
|
status = SetFilePointer(hFile, aNewFileLength, NULL, FILE_BEGIN);
|
||||||
|
if (status == 0xffffffff)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
// Truncate file at current cursor position
|
||||||
|
if (!SetEndOfFile(hFile))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!CloseHandle(hFile))
|
||||||
|
return NS_FILE_FAILURE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
error:
|
||||||
|
#ifdef XP_OS2
|
||||||
|
DosClose(hFile);
|
||||||
|
#else
|
||||||
|
CloseHandle(hFile);
|
||||||
|
#endif
|
||||||
|
return NS_FILE_FAILURE;
|
||||||
|
|
||||||
|
} // nsFileSpec::Truncate
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsresult nsFileSpec::Rename(const char* inNewName)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
NS_ASSERTION(inNewName, "Attempt to Rename with a null string");
|
||||||
|
|
||||||
|
// This function should not be used to move a file on disk.
|
||||||
|
if (strchr(inNewName, '/'))
|
||||||
|
return NS_FILE_FAILURE;
|
||||||
|
|
||||||
|
char* oldPath = nsCRT::strdup(mPath);
|
||||||
|
|
||||||
|
SetLeafName(inNewName);
|
||||||
|
|
||||||
|
if (PR_Rename(oldPath, mPath) != NS_OK)
|
||||||
|
{
|
||||||
|
// Could not rename, set back to the original.
|
||||||
|
mPath = oldPath;
|
||||||
|
return NS_FILE_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsCRT::free(oldPath);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
} // nsFileSpec::Rename
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsresult nsFileSpec::CopyToDir(const nsFileSpec& inParentDirectory) const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
// We can only copy into a directory, and (for now) can not copy entire directories
|
||||||
|
if (inParentDirectory.IsDirectory() && (! IsDirectory() ) )
|
||||||
|
{
|
||||||
|
char *leafname = GetLeafName();
|
||||||
|
nsSimpleCharString destPath(inParentDirectory.GetCString());
|
||||||
|
destPath += "\\";
|
||||||
|
destPath += leafname;
|
||||||
|
nsCRT::free(leafname);
|
||||||
|
|
||||||
|
// CopyFile returns non-zero if succeeds
|
||||||
|
#ifdef XP_OS2
|
||||||
|
APIRET rc;
|
||||||
|
PRBool copyOK;
|
||||||
|
|
||||||
|
rc = DosCopy(GetCString(), (PSZ)destPath, DCPY_EXISTING);
|
||||||
|
|
||||||
|
if (rc == NO_ERROR)
|
||||||
|
copyOK = PR_TRUE;
|
||||||
|
else
|
||||||
|
copyOK = PR_FALSE;
|
||||||
|
#else
|
||||||
|
int copyOK = CopyFile(GetCString(), destPath, PR_TRUE);
|
||||||
|
#endif
|
||||||
|
if (copyOK)
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
return NS_FILE_FAILURE;
|
||||||
|
} // nsFileSpec::CopyToDir
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsresult nsFileSpec::MoveToDir(const nsFileSpec& inNewParentDirectory)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
// We can only copy into a directory, and (for now) can not copy entire directories
|
||||||
|
if (inNewParentDirectory.IsDirectory() && (! IsDirectory() ) )
|
||||||
|
{
|
||||||
|
char *leafname = GetLeafName();
|
||||||
|
nsSimpleCharString destPath(inNewParentDirectory.GetCString());
|
||||||
|
destPath += "\\";
|
||||||
|
destPath += leafname;
|
||||||
|
nsCRT::free(leafname);
|
||||||
|
|
||||||
|
if (DosMove(GetCString(), destPath) == NO_ERROR)
|
||||||
|
{
|
||||||
|
*this = inNewParentDirectory + GetLeafName();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return NS_FILE_FAILURE;
|
||||||
|
} // nsFileSpec::MoveToDir
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsresult nsFileSpec::Execute(const char* inArgs ) const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
if (!IsDirectory())
|
||||||
|
{
|
||||||
|
#ifdef XP_OS2
|
||||||
|
nsresult result = NS_FILE_FAILURE;
|
||||||
|
|
||||||
|
if (!mPath.IsEmpty())
|
||||||
|
{
|
||||||
|
nsSimpleCharString fileNameWithArgs = mPath + " " + inArgs;
|
||||||
|
result = NS_FILE_RESULT(system(fileNameWithArgs));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
#else
|
||||||
|
nsSimpleCharString fileNameWithArgs = "\"";
|
||||||
|
fileNameWithArgs += mPath + "\" " + inArgs;
|
||||||
|
int execResult = WinExec( fileNameWithArgs, SW_NORMAL );
|
||||||
|
if (execResult > 31)
|
||||||
|
return NS_OK;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return NS_FILE_FAILURE;
|
||||||
|
} // nsFileSpec::Execute
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
PRInt64 nsFileSpec::GetDiskSpaceAvailable() const
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
PRInt64 nBytes = 0;
|
||||||
|
ULONG ulDriveNo = toupper(mPath[0]) + 1 - 'A';
|
||||||
|
FSALLOCATE fsAllocate;
|
||||||
|
APIRET rc = DosQueryFSInfo(ulDriveNo,
|
||||||
|
FSIL_ALLOC,
|
||||||
|
&fsAllocate,
|
||||||
|
sizeof(fsAllocate));
|
||||||
|
|
||||||
|
if (rc == NO_ERROR) {
|
||||||
|
nBytes = fsAllocate.cUnitAvail;
|
||||||
|
nBytes *= fsAllocate.cSectorUnit;
|
||||||
|
nBytes *= fsAllocate.cbSector;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//========================================================================================
|
||||||
|
// nsDirectoryIterator
|
||||||
|
//========================================================================================
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsDirectoryIterator::nsDirectoryIterator(const nsFileSpec& inDirectory, PRBool resolveSymlink)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
: mCurrent(inDirectory)
|
||||||
|
, mDir(nsnull)
|
||||||
|
, mStarting(inDirectory)
|
||||||
|
, mExists(PR_FALSE)
|
||||||
|
, mResoveSymLinks(resolveSymlink)
|
||||||
|
{
|
||||||
|
mDir = PR_OpenDir(inDirectory);
|
||||||
|
mCurrent += "dummy";
|
||||||
|
mStarting += "dummy";
|
||||||
|
++(*this);
|
||||||
|
} // nsDirectoryIterator::nsDirectoryIterator
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsDirectoryIterator::~nsDirectoryIterator()
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
if (mDir)
|
||||||
|
PR_CloseDir(mDir);
|
||||||
|
} // nsDirectoryIterator::nsDirectoryIterator
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsDirectoryIterator& nsDirectoryIterator::operator ++ ()
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
mExists = PR_FALSE;
|
||||||
|
if (!mDir)
|
||||||
|
return *this;
|
||||||
|
PRDirEntry* entry = PR_ReadDir(mDir, PR_SKIP_BOTH); // Ignore '.' && '..'
|
||||||
|
if (entry)
|
||||||
|
{
|
||||||
|
mExists = PR_TRUE;
|
||||||
|
mCurrent = mStarting;
|
||||||
|
mCurrent.SetLeafName(entry->name);
|
||||||
|
if (mResoveSymLinks)
|
||||||
|
{
|
||||||
|
PRBool ignore;
|
||||||
|
mCurrent.ResolveSymlink(ignore);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
} // nsDirectoryIterator::operator ++
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsDirectoryIterator& nsDirectoryIterator::operator -- ()
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
return ++(*this); // can't do it backwards.
|
||||||
|
} // nsDirectoryIterator::operator --
|
||||||
|
|
|
@ -0,0 +1,624 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape 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/NPL/
|
||||||
|
*
|
||||||
|
* 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 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 NPL, 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 NPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
// This file is included by nsFileSpec.cpp, and includes the Unix-specific
|
||||||
|
// implementations.
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include "nsError.h"
|
||||||
|
#include "prio.h" /* for PR_Rename */
|
||||||
|
|
||||||
|
#if defined(_SCO_DS)
|
||||||
|
#define _SVID3 /* for statvfs.h */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_STATVFS_H
|
||||||
|
#include <sys/statvfs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_VFS_H
|
||||||
|
#include <sys/vfs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_STATFS_H
|
||||||
|
#include <sys/statfs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_MOUNT_H
|
||||||
|
#include <sys/mount.h>
|
||||||
|
#undef Free
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_STATVFS
|
||||||
|
#define STATFS statvfs
|
||||||
|
#else
|
||||||
|
#define STATFS statfs
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAXPATHLEN
|
||||||
|
#define MAXPATHLEN 1024 /* Guessing this is okay. Works for SCO. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__QNX__)
|
||||||
|
#include <unix.h> /* for realpath */
|
||||||
|
#define f_bavail f_bfree
|
||||||
|
extern "C" int truncate(const char *, off_t);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(SUNOS4)
|
||||||
|
extern "C" int statfs(char *, struct statfs *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(OSF1)
|
||||||
|
extern "C" int statvfs(const char *, struct statvfs *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
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 = 0755;
|
||||||
|
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
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
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_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 --
|
|
@ -0,0 +1,765 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape 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/NPL/
|
||||||
|
*
|
||||||
|
* 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 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 NPL, 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 NPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
// This file is included by nsFileSpec.cp, and includes the Windows-specific
|
||||||
|
// implementations.
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <direct.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "prio.h"
|
||||||
|
#include "nsError.h"
|
||||||
|
|
||||||
|
#include "windows.h"
|
||||||
|
|
||||||
|
#if (_MSC_VER == 1100)
|
||||||
|
#define INITGUID
|
||||||
|
#include "objbase.h"
|
||||||
|
DEFINE_OLEGUID(IID_IPersistFile, 0x0000010BL, 0, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "shlobj.h"
|
||||||
|
#include "shellapi.h"
|
||||||
|
#include "shlguid.h"
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
#define CreateDirectoryW CreateDirectory
|
||||||
|
#else
|
||||||
|
#define CreateDirectoryA CreateDirectory
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsFileSpecHelpers::Canonify(nsSimpleCharString& ioPath, PRBool inMakeDirs)
|
||||||
|
// Canonify, make absolute, and check whether directories exist. This
|
||||||
|
// takes a (possibly relative) native path and converts it into a
|
||||||
|
// fully qualified native path.
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
if (ioPath.IsEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
NS_ASSERTION(strchr((const char*)ioPath, '/') == 0,
|
||||||
|
"This smells like a Unix path. Native path expected! "
|
||||||
|
"Please fix.");
|
||||||
|
if (inMakeDirs)
|
||||||
|
{
|
||||||
|
const int mode = 0755;
|
||||||
|
nsSimpleCharString unixStylePath = ioPath;
|
||||||
|
nsFileSpecHelpers::NativeToUnix(unixStylePath);
|
||||||
|
nsFileSpecHelpers::MakeAllDirectories((const char*)unixStylePath, mode);
|
||||||
|
}
|
||||||
|
char buffer[_MAX_PATH];
|
||||||
|
errno = 0;
|
||||||
|
*buffer = '\0';
|
||||||
|
char* canonicalPath = _fullpath(buffer, ioPath, _MAX_PATH);
|
||||||
|
|
||||||
|
if (canonicalPath)
|
||||||
|
{
|
||||||
|
NS_ASSERTION( canonicalPath[0] != '\0', "Uh oh...couldn't convert" );
|
||||||
|
if (canonicalPath[0] == '\0')
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ioPath = canonicalPath;
|
||||||
|
} // nsFileSpecHelpers::Canonify
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsFileSpecHelpers::UnixToNative(nsSimpleCharString& ioPath)
|
||||||
|
// This just does string manipulation. It doesn't check reality, or canonify, or
|
||||||
|
// anything
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
// Allow for relative or absolute. We can do this in place, because the
|
||||||
|
// native path is never longer.
|
||||||
|
|
||||||
|
if (ioPath.IsEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Strip initial slash for an absolute path
|
||||||
|
char* src = (char*)ioPath;
|
||||||
|
if (*src == '/') {
|
||||||
|
if (!src[1]) {
|
||||||
|
// allocate new string by copying from ioPath[1]
|
||||||
|
nsSimpleCharString temp = src + 1;
|
||||||
|
ioPath = temp;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Since it was an absolute path, check for the drive letter
|
||||||
|
char* colonPointer = src + 2;
|
||||||
|
if (strstr(src, "|/") == colonPointer)
|
||||||
|
*colonPointer = ':';
|
||||||
|
// allocate new string by copying from ioPath[1]
|
||||||
|
nsSimpleCharString temp = src + 1;
|
||||||
|
ioPath = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
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++)
|
||||||
|
{
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
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 --
|
||||||
|
|
|
@ -0,0 +1,392 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape 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/NPL/
|
||||||
|
*
|
||||||
|
* 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 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 NPL, 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 NPL, 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 <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
//========================================================================================
|
||||||
|
// nsInputStream
|
||||||
|
//========================================================================================
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsInputStream::~nsInputStream()
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
char nsInputStream::get()
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
if (read(&c, sizeof(c)) == sizeof(c))
|
||||||
|
return c;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
PRInt32 nsInputStream::read(void* s, PRInt32 n)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
if (!mInputStream)
|
||||||
|
return 0;
|
||||||
|
PRInt32 result = 0;
|
||||||
|
mInputStream->Read((char*)s, n, (PRUint32*)&result);
|
||||||
|
if (result == 0)
|
||||||
|
set_at_eof(PR_TRUE);
|
||||||
|
return result;
|
||||||
|
} // nsInputStream::read
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
static void TidyEndOfLine(char*& cp)
|
||||||
|
// Assumes that cp is pointing at \n or \r. Nulls out the character, checks for
|
||||||
|
// a second terminator (of the opposite persuasion), and returns cp pointing past the
|
||||||
|
// entire eol construct (one or two characters).
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
char ch = *cp;
|
||||||
|
*cp++ = '\0'; // terminate at the newline, then skip past it
|
||||||
|
if ((ch == '\n' && *cp == '\r') || (ch == '\r' && *cp == '\n'))
|
||||||
|
cp++; // possibly a pair.
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsInputStream& nsInputStream::operator >> (char& c)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
c = get();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//========================================================================================
|
||||||
|
// nsOutputStream
|
||||||
|
//========================================================================================
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsOutputStream::~nsOutputStream()
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsOutputStream::put(char c)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
write(&c, sizeof(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
PRInt32 nsOutputStream::write(const void* s, PRInt32 n)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
if (!mOutputStream)
|
||||||
|
return 0;
|
||||||
|
PRInt32 result = 0;
|
||||||
|
mWriteStatus = mOutputStream->Write((char*)s, n, (PRUint32*)&result);
|
||||||
|
return result;
|
||||||
|
} // nsOutputStream::write
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsresult nsOutputStream::flush()
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsresult nsOutputStream::lastWriteStatus()
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
return mWriteStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsOutputStream& nsOutputStream::operator << (char c)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
put(c);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsOutputStream& nsOutputStream::operator << (const char* s)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
if (s)
|
||||||
|
write(s, strlen(s));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsOutputStream& nsOutputStream::operator << (short val)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
char buf[30];
|
||||||
|
sprintf(buf, "%hd", val);
|
||||||
|
return (*this << buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsOutputStream& nsOutputStream::operator << (unsigned short val)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
char buf[30];
|
||||||
|
sprintf(buf, "%hu", val);
|
||||||
|
return (*this << buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsOutputStream& nsOutputStream::operator << (long val)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
char buf[30];
|
||||||
|
sprintf(buf, "%ld", val);
|
||||||
|
return (*this << buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsOutputStream& nsOutputStream::operator << (unsigned long val)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
char buf[30];
|
||||||
|
sprintf(buf, "%lu", val);
|
||||||
|
return (*this << buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsOutputStream& nsOutputStream::operator << (int val)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
char buf[30];
|
||||||
|
sprintf(buf, "%d", val);
|
||||||
|
return (*this << buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsOutputStream& nsOutputStream::operator << (unsigned int val)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
char buf[30];
|
||||||
|
sprintf(buf, "%u", val);
|
||||||
|
return (*this << buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
//========================================================================================
|
||||||
|
// nsRandomAccessInputStream
|
||||||
|
//========================================================================================
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
PRBool nsRandomAccessInputStream::readline(char* s, PRInt32 n)
|
||||||
|
// This will truncate if the buffer is too small. Result will always be null-terminated.
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
PRBool bufferLargeEnough = PR_TRUE; // result
|
||||||
|
if (!s || !n)
|
||||||
|
return PR_TRUE;
|
||||||
|
|
||||||
|
PRIntn position = tell();
|
||||||
|
if (position < 0)
|
||||||
|
return PR_FALSE;
|
||||||
|
PRInt32 bytesRead = read(s, n - 1);
|
||||||
|
if (failed())
|
||||||
|
return PR_FALSE;
|
||||||
|
s[bytesRead] = '\0'; // always terminate at the end of the buffer
|
||||||
|
char* tp = strpbrk(s, "\n\r");
|
||||||
|
if (tp)
|
||||||
|
{
|
||||||
|
TidyEndOfLine(tp);
|
||||||
|
bytesRead = (tp - s);
|
||||||
|
}
|
||||||
|
else if (!eof() && n-1 == bytesRead)
|
||||||
|
bufferLargeEnough = PR_FALSE;
|
||||||
|
position += bytesRead;
|
||||||
|
seek(position);
|
||||||
|
return bufferLargeEnough;
|
||||||
|
} // nsRandomAccessInputStream::readline
|
||||||
|
|
||||||
|
//========================================================================================
|
||||||
|
// nsInputStringStream
|
||||||
|
//========================================================================================
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsInputStringStream::nsInputStringStream(const char* stringToRead)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
nsISupports* stream;
|
||||||
|
if (NS_FAILED(NS_NewCharInputStream(&stream, stringToRead)))
|
||||||
|
return;
|
||||||
|
mInputStream = do_QueryInterface(stream);
|
||||||
|
mStore = do_QueryInterface(stream);
|
||||||
|
NS_RELEASE(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
|
|
@ -0,0 +1,775 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape 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/NPL/
|
||||||
|
*
|
||||||
|
* 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 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 NPL, 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 NPL, 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 "nscore.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 nsString;
|
||||||
|
class nsIInputStream;
|
||||||
|
class nsIOutputStream;
|
||||||
|
class nsIFileSpec;
|
||||||
|
|
||||||
|
//========================================================================================
|
||||||
|
// Compiler-specific macros, as needed
|
||||||
|
//========================================================================================
|
||||||
|
#if !defined(NS_USING_NAMESPACE) && (defined(__MWERKS__) || defined(XP_WIN))
|
||||||
|
#define NS_USING_NAMESPACE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(NS_USING_STL) && (defined(__MWERKS__) || defined(XP_WIN))
|
||||||
|
#define NS_USING_STL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NS_USING_NAMESPACE
|
||||||
|
|
||||||
|
#define NS_NAMESPACE_PROTOTYPE
|
||||||
|
#define NS_NAMESPACE namespace
|
||||||
|
#define NS_NAMESPACE_END
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define NS_NAMESPACE_PROTOTYPE static
|
||||||
|
#define NS_NAMESPACE struct
|
||||||
|
#define NS_NAMESPACE_END ;
|
||||||
|
|
||||||
|
#endif // NS_USING_NAMESPACE
|
||||||
|
|
||||||
|
#if !defined(XP_MAC) && !defined(__KCC)
|
||||||
|
// PR_STDOUT and PR_STDIN are fatal on Macintosh. So for console i/o, we must use the std
|
||||||
|
// stream stuff instead. However, we have to require that cout and cin are passed in
|
||||||
|
// to the constructor because in the current build, there is a copy in the base.shlb,
|
||||||
|
// and another in the caller's file. Passing it in as a parameter ensures that the
|
||||||
|
// caller and this library are using the same global object. Groan.
|
||||||
|
//
|
||||||
|
// Unix currently does not support iostreams at all. Their compilers do not support
|
||||||
|
// ANSI C++, or even ARM C++.
|
||||||
|
//
|
||||||
|
// Windows supports them, but only if you turn on the -GX compile flag, to support
|
||||||
|
// exceptions.
|
||||||
|
|
||||||
|
// Catch 22.
|
||||||
|
#define NS_USE_PR_STDIO
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NS_USE_PR_STDIO
|
||||||
|
class istream;
|
||||||
|
class ostream;
|
||||||
|
#define CONSOLE_IN 0
|
||||||
|
#define CONSOLE_OUT 0
|
||||||
|
#else
|
||||||
|
#include <iostream>
|
||||||
|
using std::istream;
|
||||||
|
using std::ostream;
|
||||||
|
#define CONSOLE_IN &std::cin
|
||||||
|
#define CONSOLE_OUT &std::cout
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//=========================== End Compiler-specific macros ===============================
|
||||||
|
|
||||||
|
//========================================================================================
|
||||||
|
class NS_COM nsInputStream
|
||||||
|
// This is a convenience class, for use on the STACK ("new" junkies: get detoxed first).
|
||||||
|
// Given a COM-style stream, this allows you to use the >> operators. It also acquires and
|
||||||
|
// reference counts its stream.
|
||||||
|
// Please read the comments at the top of this file
|
||||||
|
//========================================================================================
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nsInputStream(nsIInputStream* inStream)
|
||||||
|
: mInputStream(do_QueryInterface(inStream))
|
||||||
|
, mEOF(PR_FALSE)
|
||||||
|
{}
|
||||||
|
virtual ~nsInputStream();
|
||||||
|
|
||||||
|
nsCOMPtr<nsIInputStream> GetIStream() const
|
||||||
|
{
|
||||||
|
return mInputStream;
|
||||||
|
}
|
||||||
|
PRBool eof() const { return get_at_eof(); }
|
||||||
|
char get();
|
||||||
|
nsresult close()
|
||||||
|
{
|
||||||
|
NS_ASSERTION(mInputStream, "mInputStream is null!");
|
||||||
|
if (mInputStream) {
|
||||||
|
return mInputStream->Close();
|
||||||
|
}
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
PRInt32 read(void* s, PRInt32 n);
|
||||||
|
|
||||||
|
// Input streamers. Add more as needed (int&, unsigned int& etc). (but you have to
|
||||||
|
// add delegators to the derived classes, too, because these operators don't inherit).
|
||||||
|
nsInputStream& operator >> (char& ch);
|
||||||
|
|
||||||
|
// Support manipulators
|
||||||
|
nsInputStream& operator >> (nsInputStream& (*pf)(nsInputStream&))
|
||||||
|
{
|
||||||
|
return pf(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// These certainly need to be overridden, they give the best shot we can at detecting
|
||||||
|
// eof in a simple nsIInputStream.
|
||||||
|
virtual void set_at_eof(PRBool atEnd)
|
||||||
|
{
|
||||||
|
mEOF = atEnd;
|
||||||
|
}
|
||||||
|
virtual PRBool get_at_eof() const
|
||||||
|
{
|
||||||
|
return mEOF;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
|
||||||
|
nsInputStream& operator >> (char* buf); // TOO DANGEROUS. DON'T DEFINE.
|
||||||
|
|
||||||
|
// private and unimplemented to disallow copies and assigns
|
||||||
|
nsInputStream(const nsInputStream& rhs);
|
||||||
|
nsInputStream& operator=(const nsInputStream& rhs);
|
||||||
|
|
||||||
|
// DATA
|
||||||
|
protected:
|
||||||
|
nsCOMPtr<nsIInputStream> mInputStream;
|
||||||
|
PRBool mEOF;
|
||||||
|
}; // class nsInputStream
|
||||||
|
|
||||||
|
typedef nsInputStream nsBasicInStream; // historic support for this name
|
||||||
|
|
||||||
|
//========================================================================================
|
||||||
|
class NS_COM nsOutputStream
|
||||||
|
// This is a convenience class, for use on the STACK ("new" junkies, get detoxed first).
|
||||||
|
// Given a COM-style stream, this allows you to use the << operators. It also acquires and
|
||||||
|
// reference counts its stream.
|
||||||
|
// Please read the comments at the top of this file
|
||||||
|
//========================================================================================
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nsOutputStream() {}
|
||||||
|
nsOutputStream(nsIOutputStream* inStream)
|
||||||
|
: mOutputStream(do_QueryInterface(inStream))
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual ~nsOutputStream();
|
||||||
|
|
||||||
|
nsCOMPtr<nsIOutputStream> GetIStream() const
|
||||||
|
{
|
||||||
|
return mOutputStream;
|
||||||
|
}
|
||||||
|
nsresult close()
|
||||||
|
{
|
||||||
|
if (mOutputStream)
|
||||||
|
return mOutputStream->Close();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
void put(char c);
|
||||||
|
PRInt32 write(const void* s, PRInt32 n);
|
||||||
|
virtual nsresult flush();
|
||||||
|
nsresult lastWriteStatus();
|
||||||
|
|
||||||
|
// Output streamers. Add more as needed (but you have to add delegators to the derived
|
||||||
|
// classes, too, because these operators don't inherit).
|
||||||
|
nsOutputStream& operator << (const char* buf);
|
||||||
|
nsOutputStream& operator << (char ch);
|
||||||
|
nsOutputStream& operator << (short val);
|
||||||
|
nsOutputStream& operator << (unsigned short val);
|
||||||
|
nsOutputStream& operator << (long val);
|
||||||
|
nsOutputStream& operator << (unsigned long val);
|
||||||
|
nsOutputStream& operator << (int val);
|
||||||
|
nsOutputStream& operator << (unsigned int val);
|
||||||
|
|
||||||
|
// Support manipulators
|
||||||
|
nsOutputStream& operator << (nsOutputStream& (*pf)(nsOutputStream&))
|
||||||
|
{
|
||||||
|
return pf(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// private and unimplemented to disallow copies and assigns
|
||||||
|
nsOutputStream(const nsOutputStream& rhs);
|
||||||
|
nsOutputStream& operator=(const nsOutputStream& rhs);
|
||||||
|
|
||||||
|
nsresult mWriteStatus;
|
||||||
|
|
||||||
|
// DATA
|
||||||
|
protected:
|
||||||
|
nsCOMPtr<nsIOutputStream> mOutputStream;
|
||||||
|
}; // class nsOutputStream
|
||||||
|
|
||||||
|
typedef nsOutputStream nsBasicOutStream; // Historic support for this name
|
||||||
|
|
||||||
|
//========================================================================================
|
||||||
|
class NS_COM 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 nsFileClient
|
||||||
|
// Because COM does not allow us to write functions which return a boolean value etc,
|
||||||
|
// this class is here to take care of the tedious "declare variable then call with
|
||||||
|
// the address of the variable" chores.
|
||||||
|
//========================================================================================
|
||||||
|
: public virtual nsErrorProne
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nsFileClient(const nsCOMPtr<nsIOpenFile>& inFile)
|
||||||
|
: mFile(do_QueryInterface(inFile))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual ~nsFileClient() {}
|
||||||
|
|
||||||
|
void open(
|
||||||
|
const nsFileSpec& inFile,
|
||||||
|
int nsprMode,
|
||||||
|
PRIntn accessMode)
|
||||||
|
{
|
||||||
|
if (mFile)
|
||||||
|
mResult = mFile->Open(inFile, nsprMode, accessMode);
|
||||||
|
}
|
||||||
|
PRBool is_open() const
|
||||||
|
{
|
||||||
|
PRBool result = PR_FALSE;
|
||||||
|
if (mFile)
|
||||||
|
mFile->GetIsOpen(&result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
PRBool is_file() const
|
||||||
|
{
|
||||||
|
return mFile ? PR_TRUE : PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
nsFileClient() // for delayed opening
|
||||||
|
{
|
||||||
|
}
|
||||||
|
// DATA
|
||||||
|
protected:
|
||||||
|
nsCOMPtr<nsIOpenFile> mFile;
|
||||||
|
}; // class nsFileClient
|
||||||
|
|
||||||
|
//========================================================================================
|
||||||
|
class NS_COM nsRandomAccessStoreClient
|
||||||
|
// Because COM does not allow us to write functions which return a boolean value etc,
|
||||||
|
// this class is here to take care of the tedious "declare variable then call with
|
||||||
|
// the address of the variable" chores.
|
||||||
|
//========================================================================================
|
||||||
|
: public virtual nsErrorProne
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
nsRandomAccessStoreClient() // for delayed opening
|
||||||
|
{
|
||||||
|
}
|
||||||
|
nsRandomAccessStoreClient(const nsCOMPtr<nsIRandomAccessStore>& inStore)
|
||||||
|
: mStore(do_QueryInterface(inStore))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual ~nsRandomAccessStoreClient() {}
|
||||||
|
|
||||||
|
void seek(PRInt32 offset)
|
||||||
|
{
|
||||||
|
seek(PR_SEEK_SET, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void seek(PRSeekWhence whence, PRInt32 offset)
|
||||||
|
{
|
||||||
|
set_at_eof(PR_FALSE);
|
||||||
|
if (mStore)
|
||||||
|
mResult = mStore->Seek(whence, offset);
|
||||||
|
}
|
||||||
|
PRIntn tell()
|
||||||
|
{
|
||||||
|
PRIntn result = -1;
|
||||||
|
if (mStore)
|
||||||
|
mResult = mStore->Tell((PRUint32 *)&result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual PRBool get_at_eof() const
|
||||||
|
{
|
||||||
|
PRBool result = PR_TRUE;
|
||||||
|
if (mStore)
|
||||||
|
mStore->GetAtEOF(&result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void set_at_eof(PRBool atEnd)
|
||||||
|
{
|
||||||
|
if (mStore)
|
||||||
|
mStore->SetAtEOF(atEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// private and unimplemented to disallow copies and assigns
|
||||||
|
nsRandomAccessStoreClient(const nsRandomAccessStoreClient& rhs);
|
||||||
|
nsRandomAccessStoreClient& operator=(const nsRandomAccessStoreClient& rhs);
|
||||||
|
|
||||||
|
// DATA
|
||||||
|
protected:
|
||||||
|
nsCOMPtr<nsIRandomAccessStore> mStore;
|
||||||
|
}; // class nsRandomAccessStoreClient
|
||||||
|
|
||||||
|
//========================================================================================
|
||||||
|
class NS_COM 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 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 nsInputFileStream
|
||||||
|
// Please read the comments at the top of this file
|
||||||
|
//========================================================================================
|
||||||
|
: public nsRandomAccessInputStream
|
||||||
|
, public nsFileClient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum { kDefaultMode = PR_RDONLY };
|
||||||
|
nsInputFileStream(nsIInputStream* inStream)
|
||||||
|
: nsRandomAccessInputStream(inStream)
|
||||||
|
, nsFileClient(do_QueryInterface(inStream))
|
||||||
|
, mFileInputStream(do_QueryInterface(inStream))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
nsInputFileStream(
|
||||||
|
const nsFileSpec& inFile,
|
||||||
|
int nsprMode = kDefaultMode,
|
||||||
|
PRIntn accessMode = 00666);
|
||||||
|
nsInputFileStream(nsIFileSpec* inFile);
|
||||||
|
virtual ~nsInputFileStream();
|
||||||
|
|
||||||
|
void Open(
|
||||||
|
const nsFileSpec& inFile,
|
||||||
|
int nsprMode = kDefaultMode,
|
||||||
|
PRIntn accessMode = 00666)
|
||||||
|
{
|
||||||
|
if (mFile)
|
||||||
|
mFile->Open(inFile, nsprMode, accessMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input streamers. Unfortunately, they don't inherit!
|
||||||
|
nsInputStream& operator >> (char& ch)
|
||||||
|
{ return nsInputStream::operator >>(ch); }
|
||||||
|
nsInputStream& operator >> (nsInputStream& (*pf)(nsInputStream&))
|
||||||
|
{ return nsInputStream::operator >>(pf); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void AssignFrom(nsISupports* stream);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// private and unimplemented to disallow copies and assigns
|
||||||
|
nsInputFileStream(const nsInputFileStream& rhs);
|
||||||
|
nsInputFileStream& operator=(const nsInputFileStream& rhs);
|
||||||
|
|
||||||
|
// DATA
|
||||||
|
protected:
|
||||||
|
nsCOMPtr<nsIFileSpecInputStream> mFileInputStream;
|
||||||
|
}; // class nsInputFileStream
|
||||||
|
|
||||||
|
//========================================================================================
|
||||||
|
class NS_COM 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 nsOutputFileStream
|
||||||
|
// Please read the comments at the top of this file
|
||||||
|
//========================================================================================
|
||||||
|
: public nsRandomAccessOutputStream
|
||||||
|
, public nsFileClient
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum { kDefaultMode = (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE) };
|
||||||
|
|
||||||
|
nsOutputFileStream() {}
|
||||||
|
nsOutputFileStream(nsIOutputStream* inStream)
|
||||||
|
{
|
||||||
|
AssignFrom(inStream);
|
||||||
|
}
|
||||||
|
nsOutputFileStream(
|
||||||
|
const nsFileSpec& inFile,
|
||||||
|
int nsprMode = kDefaultMode,
|
||||||
|
PRIntn accessMode = 00666)
|
||||||
|
{
|
||||||
|
nsISupports* stream;
|
||||||
|
if (NS_FAILED(NS_NewIOFileStream(
|
||||||
|
&stream,
|
||||||
|
inFile, nsprMode, accessMode)))
|
||||||
|
return;
|
||||||
|
AssignFrom(stream);
|
||||||
|
NS_RELEASE(stream);
|
||||||
|
}
|
||||||
|
nsOutputFileStream(nsIFileSpec* inFile);
|
||||||
|
virtual ~nsOutputFileStream();
|
||||||
|
|
||||||
|
virtual nsresult flush();
|
||||||
|
virtual void abort();
|
||||||
|
|
||||||
|
// Output streamers. Unfortunately, they don't inherit!
|
||||||
|
nsOutputStream& operator << (const char* buf)
|
||||||
|
{ return nsOutputStream::operator << (buf); }
|
||||||
|
nsOutputStream& operator << (char ch)
|
||||||
|
{ return nsOutputStream::operator << (ch); }
|
||||||
|
nsOutputStream& operator << (short val)
|
||||||
|
{ return nsOutputStream::operator << (val); }
|
||||||
|
nsOutputStream& operator << (unsigned short val)
|
||||||
|
{ return nsOutputStream::operator << (val); }
|
||||||
|
nsOutputStream& operator << (long val)
|
||||||
|
{ return nsOutputStream::operator << (val); }
|
||||||
|
nsOutputStream& operator << (unsigned long val)
|
||||||
|
{ return nsOutputStream::operator << (val); }
|
||||||
|
nsOutputStream& operator << (int val)
|
||||||
|
{ return nsOutputStream::operator << (val); }
|
||||||
|
nsOutputStream& operator << (unsigned int val)
|
||||||
|
{ return nsOutputStream::operator << (val); }
|
||||||
|
nsOutputStream& operator << (nsOutputStream& (*pf)(nsOutputStream&))
|
||||||
|
{ return nsOutputStream::operator << (pf); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void AssignFrom(nsISupports* stream);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// private and unimplemented to disallow copies and assigns
|
||||||
|
nsOutputFileStream(const nsOutputFileStream& rhs);
|
||||||
|
nsOutputFileStream& operator=(const nsOutputFileStream& rhs);
|
||||||
|
|
||||||
|
// DATA
|
||||||
|
protected:
|
||||||
|
nsCOMPtr<nsIFileSpecOutputStream> mFileOutputStream;
|
||||||
|
}; // class nsOutputFileStream
|
||||||
|
|
||||||
|
|
||||||
|
//========================================================================================
|
||||||
|
class NS_COM nsIOFileStream
|
||||||
|
// Please read the comments at the top of this file
|
||||||
|
//========================================================================================
|
||||||
|
: public nsInputFileStream
|
||||||
|
, public nsOutputStream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum { kDefaultMode = (PR_RDWR | PR_CREATE_FILE) };
|
||||||
|
|
||||||
|
nsIOFileStream(
|
||||||
|
nsIInputStream* inInputStream
|
||||||
|
, nsIOutputStream* inOutputStream)
|
||||||
|
: nsInputFileStream(inInputStream)
|
||||||
|
, nsOutputStream(inOutputStream)
|
||||||
|
, mFileOutputStream(do_QueryInterface(inOutputStream))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
nsIOFileStream(
|
||||||
|
const nsFileSpec& inFile,
|
||||||
|
int nsprMode = kDefaultMode,
|
||||||
|
PRIntn accessMode = 00666)
|
||||||
|
: nsInputFileStream((nsIInputStream*)nsnull)
|
||||||
|
, nsOutputStream(nsnull)
|
||||||
|
{
|
||||||
|
nsISupports* stream;
|
||||||
|
if (NS_FAILED(NS_NewIOFileStream(
|
||||||
|
&stream,
|
||||||
|
inFile, nsprMode, accessMode)))
|
||||||
|
return;
|
||||||
|
mFile = do_QueryInterface(stream);
|
||||||
|
mStore = do_QueryInterface(stream);
|
||||||
|
mInputStream = do_QueryInterface(stream);
|
||||||
|
mOutputStream = do_QueryInterface(stream);
|
||||||
|
mFileInputStream = do_QueryInterface(stream);
|
||||||
|
mFileOutputStream = do_QueryInterface(stream);
|
||||||
|
NS_RELEASE(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual nsresult close()
|
||||||
|
{
|
||||||
|
// Doesn't matter which of the two we close:
|
||||||
|
// they're hooked up to the same file.
|
||||||
|
return nsInputFileStream::close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output streamers. Unfortunately, they don't inherit!
|
||||||
|
nsOutputStream& operator << (const char* buf)
|
||||||
|
{ return nsOutputStream::operator << (buf); }
|
||||||
|
nsOutputStream& operator << (char ch)
|
||||||
|
{ return nsOutputStream::operator << (ch); }
|
||||||
|
nsOutputStream& operator << (short val)
|
||||||
|
{ return nsOutputStream::operator << (val); }
|
||||||
|
nsOutputStream& operator << (unsigned short val)
|
||||||
|
{ return nsOutputStream::operator << (val); }
|
||||||
|
nsOutputStream& operator << (long val)
|
||||||
|
{ return nsOutputStream::operator << (val); }
|
||||||
|
nsOutputStream& operator << (unsigned long val)
|
||||||
|
{ return nsOutputStream::operator << (val); }
|
||||||
|
nsOutputStream& operator << (int val)
|
||||||
|
{ return nsOutputStream::operator << (val); }
|
||||||
|
nsOutputStream& operator << (unsigned int val)
|
||||||
|
{ return nsOutputStream::operator << (val); }
|
||||||
|
nsOutputStream& operator << (nsOutputStream& (*pf)(nsOutputStream&))
|
||||||
|
{ return nsOutputStream::operator << (pf); }
|
||||||
|
|
||||||
|
// Input streamers. Unfortunately, they don't inherit!
|
||||||
|
nsInputStream& operator >> (char& ch)
|
||||||
|
{ return nsInputStream::operator >>(ch); }
|
||||||
|
nsInputStream& operator >> (nsInputStream& (*pf)(nsInputStream&))
|
||||||
|
{ return nsInputStream::operator >>(pf); }
|
||||||
|
|
||||||
|
virtual nsresult flush() {if (mFileOutputStream) mFileOutputStream->Flush(); return error(); }
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// private and unimplemented to disallow copies and assigns
|
||||||
|
nsIOFileStream(const nsIOFileStream& rhs);
|
||||||
|
nsIOFileStream& operator=(const nsIOFileStream& rhs);
|
||||||
|
|
||||||
|
// DATA
|
||||||
|
protected:
|
||||||
|
nsCOMPtr<nsIFileSpecOutputStream> mFileOutputStream;
|
||||||
|
}; // class nsIOFileStream
|
||||||
|
|
||||||
|
//========================================================================================
|
||||||
|
// Manipulators
|
||||||
|
//========================================================================================
|
||||||
|
|
||||||
|
NS_COM nsOutputStream& nsEndl(nsOutputStream& os); // outputs and FLUSHES.
|
||||||
|
|
||||||
|
//========================================================================================
|
||||||
|
#endif /* _FILESTREAM_H_ */
|
|
@ -0,0 +1,203 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape 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/NPL/
|
||||||
|
*
|
||||||
|
* 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 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 NPL, 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 NPL, 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();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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 nsresult NS_NewFileSpecWithSpec(const nsFileSpec& aSrcFileSpec, nsIFileSpec **result);
|
||||||
|
NS_COM nsresult NS_NewFileSpec(nsIFileSpec** result);
|
||||||
|
NS_COM 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 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)
|
||||||
|
|
||||||
|
%}
|
|
@ -0,0 +1,724 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape 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/NPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is mozilla.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Netscape Communications Corporation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Pierre Phaneuf <pp@ludusdesign.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either 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 NPL, 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 NPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include "nsIFileStream.h"
|
||||||
|
#include "nsFileSpec.h"
|
||||||
|
#include "nsCOMPtr.h"
|
||||||
|
|
||||||
|
#include "prerror.h"
|
||||||
|
|
||||||
|
#include "nsSegmentedBuffer.h"
|
||||||
|
|
||||||
|
#ifdef XP_MAC
|
||||||
|
#include "pprio.h" // To get PR_ImportFile
|
||||||
|
#else
|
||||||
|
#include "prio.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef XP_MAC
|
||||||
|
#include <Errors.h>
|
||||||
|
#include <iostream>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//========================================================================================
|
||||||
|
class FileImpl
|
||||||
|
: public nsIRandomAccessStore
|
||||||
|
, public nsIFileSpecOutputStream
|
||||||
|
, public nsIFileSpecInputStream
|
||||||
|
, public nsIOpenFile
|
||||||
|
//========================================================================================
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FileImpl(PRFileDesc* inDesc);
|
||||||
|
FileImpl(const nsFileSpec& inFile, int nsprMode, PRIntn accessMode);
|
||||||
|
|
||||||
|
virtual ~FileImpl();
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kOuputBufferSegmentSize = 4096,
|
||||||
|
kOuputBufferMaxSize = 4096
|
||||||
|
};
|
||||||
|
|
||||||
|
nsresult InternalFlush(PRBool syncFile);
|
||||||
|
nsresult AllocateBuffers(PRUint32 segmentSize, PRUint32 maxSize);
|
||||||
|
|
||||||
|
PRFileDesc* mFileDesc;
|
||||||
|
int mNSPRMode;
|
||||||
|
PRBool mFailed;
|
||||||
|
PRBool mEOF;
|
||||||
|
PRInt32 mLength;
|
||||||
|
|
||||||
|
PRBool mGotBuffers;
|
||||||
|
nsSegmentedBuffer mOutBuffer;
|
||||||
|
char* mWriteCursor;
|
||||||
|
char* mWriteLimit;
|
||||||
|
|
||||||
|
}; // class FileImpl
|
||||||
|
|
||||||
|
NS_IMPL_RELEASE(FileImpl)
|
||||||
|
NS_IMPL_ADDREF(FileImpl)
|
||||||
|
|
||||||
|
NS_IMPL_QUERY_HEAD(FileImpl)
|
||||||
|
NS_IMPL_QUERY_BODY(nsIOpenFile)
|
||||||
|
NS_IMPL_QUERY_BODY(nsISeekableStream)
|
||||||
|
NS_IMPL_QUERY_BODY(nsIRandomAccessStore)
|
||||||
|
NS_IMPL_QUERY_BODY(nsIOutputStream)
|
||||||
|
NS_IMPL_QUERY_BODY(nsIInputStream)
|
||||||
|
NS_IMPL_QUERY_BODY(nsIFileSpecInputStream)
|
||||||
|
NS_IMPL_QUERY_BODY(nsIFileSpecOutputStream)
|
||||||
|
NS_IMPL_QUERY_TAIL(nsIOutputStream)
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
FileImpl::FileImpl(PRFileDesc* inDesc)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
: mFileDesc(inDesc)
|
||||||
|
, mNSPRMode(0)
|
||||||
|
, mFailed(PR_FALSE)
|
||||||
|
, mEOF(PR_FALSE)
|
||||||
|
, mLength(-1)
|
||||||
|
, mGotBuffers(PR_FALSE)
|
||||||
|
{
|
||||||
|
mWriteCursor = nsnull;
|
||||||
|
mWriteLimit = nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
FileImpl::FileImpl(const nsFileSpec& inFile, int nsprMode, PRIntn accessMode)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
: mFileDesc(nsnull)
|
||||||
|
, mNSPRMode(-1)
|
||||||
|
, mEOF(PR_FALSE)
|
||||||
|
, mLength(-1)
|
||||||
|
, mGotBuffers(PR_FALSE)
|
||||||
|
{
|
||||||
|
mWriteCursor = nsnull;
|
||||||
|
mWriteLimit = nsnull;
|
||||||
|
|
||||||
|
nsresult rv = Open(inFile, nsprMode, accessMode); // this sets nsprMode
|
||||||
|
|
||||||
|
if (NS_FAILED(rv))
|
||||||
|
{
|
||||||
|
mFailed = PR_TRUE;
|
||||||
|
#if DEBUG
|
||||||
|
char *fileName = inFile.GetLeafName();
|
||||||
|
printf("Opening file %s failed\n", fileName);
|
||||||
|
nsCRT::free(fileName);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mFailed = PR_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
FileImpl::~FileImpl()
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
nsresult rv = Close();
|
||||||
|
NS_ASSERTION(NS_SUCCEEDED(rv), "Close failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
NS_IMETHODIMP FileImpl::Open(
|
||||||
|
const nsFileSpec& inFile,
|
||||||
|
int nsprMode,
|
||||||
|
PRIntn accessMode)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
if (mFileDesc)
|
||||||
|
if ((nsprMode & mNSPRMode) == nsprMode)
|
||||||
|
return NS_OK;
|
||||||
|
else
|
||||||
|
return NS_FILE_RESULT(PR_ILLEGAL_ACCESS_ERROR);
|
||||||
|
|
||||||
|
const int nspr_modes[]={
|
||||||
|
PR_WRONLY | PR_CREATE_FILE,
|
||||||
|
PR_WRONLY | PR_CREATE_FILE | PR_APPEND,
|
||||||
|
PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
|
||||||
|
PR_RDONLY,
|
||||||
|
PR_RDONLY | PR_APPEND,
|
||||||
|
PR_RDWR | PR_CREATE_FILE,
|
||||||
|
PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE,
|
||||||
|
// "wb",
|
||||||
|
// "ab",
|
||||||
|
// "wb",
|
||||||
|
// "rb",
|
||||||
|
// "r+b",
|
||||||
|
// "w+b",
|
||||||
|
0 };
|
||||||
|
const int* currentLegalMode = nspr_modes;
|
||||||
|
while (*currentLegalMode && nsprMode != *currentLegalMode)
|
||||||
|
++currentLegalMode;
|
||||||
|
if (!*currentLegalMode)
|
||||||
|
return NS_FILE_RESULT(PR_ILLEGAL_ACCESS_ERROR);
|
||||||
|
|
||||||
|
#ifdef XP_MAC
|
||||||
|
// Use the file spec to open the file, because one path can be common to
|
||||||
|
// several files on the Macintosh (you can have several volumes with the
|
||||||
|
// same name, see).
|
||||||
|
mFileDesc = 0;
|
||||||
|
OSErr err = inFile.Error();
|
||||||
|
if (err != noErr)
|
||||||
|
if (err != fnfErr || !(nsprMode & PR_CREATE_FILE))
|
||||||
|
return NS_FILE_RESULT(inFile.Error());
|
||||||
|
err = noErr;
|
||||||
|
#if DEBUG
|
||||||
|
const OSType kCreator = 'CWIE';
|
||||||
|
#else
|
||||||
|
const OSType kCreator = 'MOSS';
|
||||||
|
#endif
|
||||||
|
// Resolve the alias to the original file.
|
||||||
|
nsFileSpec original = inFile;
|
||||||
|
PRBool ignoredResult;
|
||||||
|
original.ResolveSymlink(ignoredResult);
|
||||||
|
const FSSpec& spec = original.operator const FSSpec&();
|
||||||
|
if (nsprMode & PR_CREATE_FILE) {
|
||||||
|
// In order to get the right file type/creator, do it with an nsILocalFileMac
|
||||||
|
// Don't propagate any errors in doing this. If any error, just use FSpCreate.
|
||||||
|
FSSpec nonConstSpec = spec;
|
||||||
|
nsCOMPtr<nsILocalFileMac> macFile;
|
||||||
|
nsresult res = NS_NewLocalFileWithFSSpec(&nonConstSpec, PR_FALSE, getter_AddRefs(macFile));
|
||||||
|
if (NS_SUCCEEDED(res)) {
|
||||||
|
nsCOMPtr<nsIFile> asFile(do_QueryInterface(macFile, &res));
|
||||||
|
if (NS_SUCCEEDED(res)) {
|
||||||
|
res = asFile->Create(nsIFile::NORMAL_FILE_TYPE, 0);
|
||||||
|
if (res == NS_ERROR_FILE_ALREADY_EXISTS)
|
||||||
|
res = NS_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (NS_FAILED(res))
|
||||||
|
err = FSpCreate(&spec, kCreator, 'TEXT', 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err == dupFNErr)
|
||||||
|
err = noErr;
|
||||||
|
if (err != noErr)
|
||||||
|
return NS_FILE_RESULT(err);
|
||||||
|
|
||||||
|
SInt8 perm;
|
||||||
|
if (nsprMode & PR_RDWR)
|
||||||
|
perm = fsRdWrPerm;
|
||||||
|
else if (nsprMode & PR_WRONLY)
|
||||||
|
perm = fsWrPerm;
|
||||||
|
else
|
||||||
|
perm = fsRdPerm;
|
||||||
|
|
||||||
|
short refnum;
|
||||||
|
err = FSpOpenDF(&spec, perm, &refnum);
|
||||||
|
|
||||||
|
if (err == noErr && (nsprMode & PR_TRUNCATE))
|
||||||
|
err = ::SetEOF(refnum, 0);
|
||||||
|
if (err == noErr && (nsprMode & PR_APPEND))
|
||||||
|
err = SetFPos(refnum, fsFromLEOF, 0);
|
||||||
|
if (err != noErr)
|
||||||
|
return NS_FILE_RESULT(err);
|
||||||
|
|
||||||
|
if ((mFileDesc = PR_ImportFile(refnum)) == 0)
|
||||||
|
return NS_FILE_RESULT(PR_GetError());
|
||||||
|
#else
|
||||||
|
// Platforms other than Macintosh...
|
||||||
|
// Another bug in NSPR: Mac PR_Open assumes a unix style path, but Win PR_Open assumes
|
||||||
|
// a windows path.
|
||||||
|
if ((mFileDesc = PR_Open((const char*)nsFileSpec(inFile), nsprMode, accessMode)) == 0)
|
||||||
|
return NS_FILE_RESULT(PR_GetError());
|
||||||
|
#endif
|
||||||
|
mNSPRMode = nsprMode;
|
||||||
|
mLength = PR_Available(mFileDesc);
|
||||||
|
return NS_OK;
|
||||||
|
} // FileImpl::Open
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
NS_IMETHODIMP FileImpl::Available(PRUint32 *aLength)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
NS_PRECONDITION(aLength != nsnull, "null ptr");
|
||||||
|
if (!aLength)
|
||||||
|
return NS_ERROR_NULL_POINTER;
|
||||||
|
if (mLength < 0)
|
||||||
|
return NS_ERROR_UNEXPECTED;
|
||||||
|
*aLength = mLength;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
NS_IMETHODIMP FileImpl::GetIsOpen(PRBool* outOpen)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
*outOpen = (mFileDesc != nsnull && !mFailed);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
NS_IMETHODIMP FileImpl::Seek(PRInt32 whence, PRInt32 offset)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR || !mFileDesc)
|
||||||
|
return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
|
||||||
|
mFailed = PR_FALSE; // reset on a seek.
|
||||||
|
mEOF = PR_FALSE; // reset on a seek.
|
||||||
|
|
||||||
|
// To avoid corruption, we flush during a seek. see bug number 18949
|
||||||
|
InternalFlush(PR_FALSE);
|
||||||
|
|
||||||
|
PRInt32 position = PR_Seek(mFileDesc, 0, PR_SEEK_CUR);
|
||||||
|
PRInt32 available = PR_Available(mFileDesc);
|
||||||
|
PRInt32 fileSize = position + available;
|
||||||
|
PRInt32 newPosition = 0;
|
||||||
|
switch (whence)
|
||||||
|
{
|
||||||
|
case NS_SEEK_CUR: newPosition = position + offset; break;
|
||||||
|
case NS_SEEK_SET: newPosition = offset; break;
|
||||||
|
case NS_SEEK_END: newPosition = fileSize + offset; break;
|
||||||
|
}
|
||||||
|
if (newPosition < 0)
|
||||||
|
{
|
||||||
|
newPosition = 0;
|
||||||
|
mFailed = PR_TRUE;
|
||||||
|
}
|
||||||
|
if (newPosition >= fileSize) // nb: not "else if".
|
||||||
|
{
|
||||||
|
newPosition = fileSize;
|
||||||
|
mEOF = PR_TRUE;
|
||||||
|
}
|
||||||
|
if (PR_Seek(mFileDesc, newPosition, PR_SEEK_SET) < 0)
|
||||||
|
mFailed = PR_TRUE;
|
||||||
|
return NS_OK;
|
||||||
|
} // FileImpl::Seek
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
NS_IMETHODIMP FileImpl::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(PRUint32* outWhere)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR || !mFileDesc)
|
||||||
|
return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
|
||||||
|
*outWhere = PR_Seek(mFileDesc, 0, PR_SEEK_CUR);
|
||||||
|
return NS_OK;
|
||||||
|
} // FileImpl::Tell
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
NS_IMETHODIMP FileImpl::Close()
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
if ((mNSPRMode & PR_RDONLY) == 0)
|
||||||
|
InternalFlush(PR_FALSE);
|
||||||
|
|
||||||
|
if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR || !mFileDesc)
|
||||||
|
return NS_OK;
|
||||||
|
if (PR_Close(mFileDesc) == PR_SUCCESS)
|
||||||
|
mFileDesc = 0;
|
||||||
|
else
|
||||||
|
return NS_FILE_RESULT(PR_GetError());
|
||||||
|
return NS_OK;
|
||||||
|
} // FileImpl::close
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
NS_IMETHODIMP FileImpl::Flush()
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
// for external callers, this will do a Sync as well as flush buffers.
|
||||||
|
return InternalFlush(PR_TRUE);
|
||||||
|
} // FileImpl::flush
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
NS_IMETHODIMP FileImpl::GetAtEOF(PRBool* outAtEOF)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
*outAtEOF = mEOF;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
NS_IMETHODIMP FileImpl::SetAtEOF(PRBool inAtEOF)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
mEOF = inAtEOF;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
NS_IMETHODIMP FileImpl::SetEOF()
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
NS_NOTYETIMPLEMENTED("FileImpl::SetEOF");
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsresult FileImpl::AllocateBuffers(PRUint32 segmentSize, PRUint32 maxBufSize)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
nsresult rv = mOutBuffer.Init(segmentSize, maxBufSize);
|
||||||
|
if (NS_SUCCEEDED(rv))
|
||||||
|
mGotBuffers = PR_TRUE;
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
// external callers of Flush will have sync get called,
|
||||||
|
// but internal callers just want to flush the buffers to disk.
|
||||||
|
nsresult FileImpl::InternalFlush(PRBool syncFile)
|
||||||
|
{
|
||||||
|
#ifdef XP_MAC
|
||||||
|
if (mFileDesc == PR_STDOUT || mFileDesc == PR_STDERR)
|
||||||
|
{
|
||||||
|
std::cout.flush();
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!mFileDesc)
|
||||||
|
return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
|
||||||
|
|
||||||
|
PRInt32 segCount = mOutBuffer.GetSegmentCount();
|
||||||
|
PRUint32 segSize = mOutBuffer.GetSegmentSize();
|
||||||
|
|
||||||
|
for (PRInt32 i = 0; i < segCount; i++)
|
||||||
|
{
|
||||||
|
char* seg = mOutBuffer.GetSegment(i);
|
||||||
|
|
||||||
|
// if it is the last buffer, it may not be completely full.
|
||||||
|
if(i == (segCount-1))
|
||||||
|
segSize = (mWriteCursor - seg);
|
||||||
|
|
||||||
|
PRInt32 bytesWrit = PR_Write(mFileDesc, seg, segSize);
|
||||||
|
if (bytesWrit != (PRInt32)segSize)
|
||||||
|
{
|
||||||
|
mFailed = PR_TRUE;
|
||||||
|
return NS_FILE_RESULT(PR_GetError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mGotBuffers)
|
||||||
|
mOutBuffer.Empty();
|
||||||
|
mWriteCursor = nsnull;
|
||||||
|
mWriteLimit = nsnull;
|
||||||
|
|
||||||
|
// On unix, it seems to fail always.
|
||||||
|
if (syncFile && PR_Sync(mFileDesc) != PR_SUCCESS)
|
||||||
|
mFailed = PR_TRUE;
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsresult NS_NewTypicalInputFileStream(
|
||||||
|
nsISupports** aResult,
|
||||||
|
const nsFileSpec& inFile
|
||||||
|
/*Default nsprMode == PR_RDONLY*/
|
||||||
|
/*Default accessmode = 0666 (octal)*/)
|
||||||
|
// Factory method to get an nsInputStream from a file, using most common options
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
// This QueryInterface was needed because NS_NewIOFileStream
|
||||||
|
// does a cast from (void *) to (nsISupports *) thus causing a
|
||||||
|
// vtable problem on Windows, where we really didn't have the proper pointer
|
||||||
|
// to an nsIInputStream, this ensures that we do
|
||||||
|
nsISupports * supports;
|
||||||
|
nsIInputStream * inStr;
|
||||||
|
|
||||||
|
nsresult rv = NS_NewIOFileStream(&supports, inFile, PR_RDONLY, 0666);
|
||||||
|
|
||||||
|
*aResult = nsnull;
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
if (NS_SUCCEEDED(supports->QueryInterface(NS_GET_IID(nsIInputStream), (void**)&inStr))) {
|
||||||
|
*aResult = inStr;
|
||||||
|
}
|
||||||
|
NS_RELEASE(supports);
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsresult NS_NewTypicalOutputFileStream(
|
||||||
|
nsISupports** aResult,
|
||||||
|
const nsFileSpec& inFile
|
||||||
|
/*default nsprMode= (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE)*/
|
||||||
|
/*Default accessMode= 0666 (octal)*/)
|
||||||
|
// Factory method to get an nsOutputStream to a file - most common case.
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
// This QueryInterface was needed because NS_NewIOFileStream
|
||||||
|
// does a cast from (void *) to (nsISupports *) thus causing a
|
||||||
|
// vtable problem on Windows, where we really didn't have the proper pointer
|
||||||
|
// to an nsIOutputStream, this ensures that we do
|
||||||
|
#if 1
|
||||||
|
/* nsISupports * supports;
|
||||||
|
nsIOutputStream * outStr;
|
||||||
|
|
||||||
|
nsresult rv = NS_NewIOFileStream(
|
||||||
|
&supports,
|
||||||
|
inFile,
|
||||||
|
(PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE),
|
||||||
|
0666);
|
||||||
|
|
||||||
|
*aResult = nsnull;
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
if (NS_SUCCEEDED(supports->QueryInterface(NS_GET_IID(nsIOutputStream), (void**)&outStr))) {
|
||||||
|
*aResult = outStr;
|
||||||
|
}
|
||||||
|
NS_RELEASE(supports);
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
*/
|
||||||
|
|
||||||
|
nsCOMPtr<nsISupports> supports;
|
||||||
|
nsIOutputStream * outStr;
|
||||||
|
|
||||||
|
nsresult rv = NS_NewIOFileStream(
|
||||||
|
getter_AddRefs(supports),
|
||||||
|
inFile,
|
||||||
|
(PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE),
|
||||||
|
0666);
|
||||||
|
|
||||||
|
*aResult = nsnull;
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
if (NS_SUCCEEDED(supports->QueryInterface(NS_GET_IID(nsIOutputStream), (void**)&outStr))) {
|
||||||
|
*aResult = outStr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
#else
|
||||||
|
return NS_NewIOFileStream(
|
||||||
|
aResult,
|
||||||
|
inFile,
|
||||||
|
(PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE),
|
||||||
|
0666);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
NS_COM 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;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PRBool isOpened = PR_FALSE;
|
||||||
|
stream->GetIsOpen(&isOpened);
|
||||||
|
if (!isOpened)
|
||||||
|
{
|
||||||
|
delete stream;
|
||||||
|
return NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ADDREF(stream);
|
||||||
|
*aResult = (nsISupports*)(void*)stream;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,156 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape 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/NPL/
|
||||||
|
*
|
||||||
|
* 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 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 NPL, 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 NPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
#ifndef nsIFileStream_h___
|
||||||
|
#define nsIFileStream_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 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___ */
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,152 @@
|
||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/*
|
||||||
|
* The contents of this file are subject to the Netscape Public
|
||||||
|
* License Version 1.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/NPL/
|
||||||
|
*
|
||||||
|
* 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 Netscape are
|
||||||
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||||
|
* Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Doug Turner <dougt@netscape.com>
|
||||||
|
* IBM Corp.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _NSSPECIALSYSTEMDIRECTORY_H_
|
||||||
|
#define _NSSPECIALSYSTEMDIRECTORY_H_
|
||||||
|
|
||||||
|
#include "nscore.h"
|
||||||
|
#include "nsFileSpec.h"
|
||||||
|
|
||||||
|
#if defined(XP_MAC) || defined(XP_MACOSX)
|
||||||
|
#include <Types.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
extern NS_COM void StartupSpecialSystemDirectory();
|
||||||
|
extern NS_COM void ShutdownSpecialSystemDirectory();
|
||||||
|
|
||||||
|
|
||||||
|
// SEE ALSO:
|
||||||
|
// mozilla/xpfe/appshell/public/nsFileLocations.h
|
||||||
|
|
||||||
|
class NS_COM 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 nsSpecialSystemDirectory
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,97 @@
|
||||||
|
#
|
||||||
|
# The contents of this file are subject to the Netscape 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/NPL/
|
||||||
|
#
|
||||||
|
# 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 Netscape are
|
||||||
|
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||||
|
# Rights Reserved.
|
||||||
|
#
|
||||||
|
# Contributor(s):
|
||||||
|
#
|
||||||
|
|
||||||
|
DEPTH = ../..
|
||||||
|
topsrcdir = @top_srcdir@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
|
||||||
|
include $(DEPTH)/config/autoconf.mk
|
||||||
|
|
||||||
|
MODULE = xpcom_obsolete
|
||||||
|
LIBRARY_NAME = xpcom_obsolete
|
||||||
|
|
||||||
|
# Do not set EXPORT_LIBRARY as we do not want xpcom in the static libs list
|
||||||
|
#EXPORT_LIBRARY = 1
|
||||||
|
GRE_MODULE = 1
|
||||||
|
|
||||||
|
REQUIRES = xpcom \
|
||||||
|
string \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
# pull in MoreFiles for MacOSX
|
||||||
|
ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
|
||||||
|
REQUIRES += macmorefiles
|
||||||
|
endif
|
||||||
|
|
||||||
|
CPPSRCS = \
|
||||||
|
nsFileSpec.cpp \
|
||||||
|
nsFileSpecImpl.cpp \
|
||||||
|
nsFileStream.cpp \
|
||||||
|
nsIFileStream.cpp \
|
||||||
|
nsSpecialSystemDirectory.cpp \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
EXPORTS = \
|
||||||
|
nsFileSpec.h \
|
||||||
|
nsFileStream.h \
|
||||||
|
nsIFileStream.h \
|
||||||
|
nsSpecialSystemDirectory.h \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
XPIDLSRCS = nsIFileSpec.idl
|
||||||
|
|
||||||
|
LOCAL_INCLUDES = \
|
||||||
|
-I$(srcdir)/../io \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
# Force use of PIC
|
||||||
|
FORCE_USE_PIC = 1
|
||||||
|
|
||||||
|
FORCE_SHARED_LIB = 1
|
||||||
|
|
||||||
|
include $(topsrcdir)/config/rules.mk
|
||||||
|
|
||||||
|
DEFINES += \
|
||||||
|
-D_IMPL_NS_COM
|
||||||
|
|
||||||
|
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 += shell32.lib ole32.lib
|
||||||
|
ifneq (,$(MOZ_DEBUG)$(NS_TRACE_MALLOC))
|
||||||
|
EXTRA_DSO_LDOPTS += imagehlp.lib
|
||||||
|
endif
|
||||||
|
endif # WINNT
|
||||||
|
|
||||||
|
ifeq ($(OS_ARCH), Linux)
|
||||||
|
DEFINES += -D_BSD_SOURCE
|
||||||
|
endif
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,857 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape 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/NPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Original Code is mozilla.org code.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Netscape Communications Corporation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Pierre Phaneuf <pp@ludusdesign.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either 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 NPL, 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 NPL, 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_METHOD 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_METHOD 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);
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape 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/NPL/
|
||||||
|
*
|
||||||
|
* 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 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 NPL, 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 NPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#ifndef _FILESPECIMPL_H_
|
||||||
|
#define _FILESPECIMPL_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);
|
||||||
|
virtual ~nsFileSpecImpl();
|
||||||
|
static nsresult MakeInterface(const nsFileSpec& inSpec, nsIFileSpec** outSpec);
|
||||||
|
|
||||||
|
//----------------------
|
||||||
|
// Data
|
||||||
|
//----------------------
|
||||||
|
|
||||||
|
nsFileSpec mFileSpec;
|
||||||
|
nsIInputStream* mInputStream;
|
||||||
|
nsIOutputStream* mOutputStream;
|
||||||
|
|
||||||
|
}; // class nsFileSpecImpl
|
||||||
|
|
||||||
|
//========================================================================================
|
||||||
|
class nsDirectoryIteratorImpl
|
||||||
|
//========================================================================================
|
||||||
|
: public nsIDirectoryIterator
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
nsDirectoryIteratorImpl();
|
||||||
|
virtual ~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);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
nsDirectoryIterator* mDirectoryIterator;
|
||||||
|
}; // class nsDirectoryIteratorImpl
|
||||||
|
|
||||||
|
#endif // _FILESPECIMPL_H_
|
|
@ -0,0 +1,624 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape 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/NPL/
|
||||||
|
*
|
||||||
|
* 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 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 NPL, 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 NPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
// This file is included by nsFileSpec.cpp, and includes the Unix-specific
|
||||||
|
// implementations.
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include "nsError.h"
|
||||||
|
#include "prio.h" /* for PR_Rename */
|
||||||
|
|
||||||
|
#if defined(_SCO_DS)
|
||||||
|
#define _SVID3 /* for statvfs.h */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_STATVFS_H
|
||||||
|
#include <sys/statvfs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_VFS_H
|
||||||
|
#include <sys/vfs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_STATFS_H
|
||||||
|
#include <sys/statfs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_MOUNT_H
|
||||||
|
#include <sys/mount.h>
|
||||||
|
#undef Free
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_STATVFS
|
||||||
|
#define STATFS statvfs
|
||||||
|
#else
|
||||||
|
#define STATFS statfs
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAXPATHLEN
|
||||||
|
#define MAXPATHLEN 1024 /* Guessing this is okay. Works for SCO. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__QNX__)
|
||||||
|
#include <unix.h> /* for realpath */
|
||||||
|
#define f_bavail f_bfree
|
||||||
|
extern "C" int truncate(const char *, off_t);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(SUNOS4)
|
||||||
|
extern "C" int statfs(char *, struct statfs *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(OSF1)
|
||||||
|
extern "C" int statvfs(const char *, struct statvfs *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
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 = 0755;
|
||||||
|
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
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
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_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 --
|
|
@ -0,0 +1,765 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape 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/NPL/
|
||||||
|
*
|
||||||
|
* 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 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 NPL, 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 NPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
// This file is included by nsFileSpec.cp, and includes the Windows-specific
|
||||||
|
// implementations.
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <direct.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "prio.h"
|
||||||
|
#include "nsError.h"
|
||||||
|
|
||||||
|
#include "windows.h"
|
||||||
|
|
||||||
|
#if (_MSC_VER == 1100)
|
||||||
|
#define INITGUID
|
||||||
|
#include "objbase.h"
|
||||||
|
DEFINE_OLEGUID(IID_IPersistFile, 0x0000010BL, 0, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "shlobj.h"
|
||||||
|
#include "shellapi.h"
|
||||||
|
#include "shlguid.h"
|
||||||
|
|
||||||
|
#ifdef UNICODE
|
||||||
|
#define CreateDirectoryW CreateDirectory
|
||||||
|
#else
|
||||||
|
#define CreateDirectoryA CreateDirectory
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsFileSpecHelpers::Canonify(nsSimpleCharString& ioPath, PRBool inMakeDirs)
|
||||||
|
// Canonify, make absolute, and check whether directories exist. This
|
||||||
|
// takes a (possibly relative) native path and converts it into a
|
||||||
|
// fully qualified native path.
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
if (ioPath.IsEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
NS_ASSERTION(strchr((const char*)ioPath, '/') == 0,
|
||||||
|
"This smells like a Unix path. Native path expected! "
|
||||||
|
"Please fix.");
|
||||||
|
if (inMakeDirs)
|
||||||
|
{
|
||||||
|
const int mode = 0755;
|
||||||
|
nsSimpleCharString unixStylePath = ioPath;
|
||||||
|
nsFileSpecHelpers::NativeToUnix(unixStylePath);
|
||||||
|
nsFileSpecHelpers::MakeAllDirectories((const char*)unixStylePath, mode);
|
||||||
|
}
|
||||||
|
char buffer[_MAX_PATH];
|
||||||
|
errno = 0;
|
||||||
|
*buffer = '\0';
|
||||||
|
char* canonicalPath = _fullpath(buffer, ioPath, _MAX_PATH);
|
||||||
|
|
||||||
|
if (canonicalPath)
|
||||||
|
{
|
||||||
|
NS_ASSERTION( canonicalPath[0] != '\0', "Uh oh...couldn't convert" );
|
||||||
|
if (canonicalPath[0] == '\0')
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ioPath = canonicalPath;
|
||||||
|
} // nsFileSpecHelpers::Canonify
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsFileSpecHelpers::UnixToNative(nsSimpleCharString& ioPath)
|
||||||
|
// This just does string manipulation. It doesn't check reality, or canonify, or
|
||||||
|
// anything
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
// Allow for relative or absolute. We can do this in place, because the
|
||||||
|
// native path is never longer.
|
||||||
|
|
||||||
|
if (ioPath.IsEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Strip initial slash for an absolute path
|
||||||
|
char* src = (char*)ioPath;
|
||||||
|
if (*src == '/') {
|
||||||
|
if (!src[1]) {
|
||||||
|
// allocate new string by copying from ioPath[1]
|
||||||
|
nsSimpleCharString temp = src + 1;
|
||||||
|
ioPath = temp;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Since it was an absolute path, check for the drive letter
|
||||||
|
char* colonPointer = src + 2;
|
||||||
|
if (strstr(src, "|/") == colonPointer)
|
||||||
|
*colonPointer = ':';
|
||||||
|
// allocate new string by copying from ioPath[1]
|
||||||
|
nsSimpleCharString temp = src + 1;
|
||||||
|
ioPath = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
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++)
|
||||||
|
{
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
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))
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
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 --
|
||||||
|
|
|
@ -0,0 +1,392 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* ***** BEGIN LICENSE BLOCK *****
|
||||||
|
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Netscape 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/NPL/
|
||||||
|
*
|
||||||
|
* 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 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 NPL, 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 NPL, 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 <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
//========================================================================================
|
||||||
|
// nsInputStream
|
||||||
|
//========================================================================================
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsInputStream::~nsInputStream()
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
char nsInputStream::get()
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
if (read(&c, sizeof(c)) == sizeof(c))
|
||||||
|
return c;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
PRInt32 nsInputStream::read(void* s, PRInt32 n)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
if (!mInputStream)
|
||||||
|
return 0;
|
||||||
|
PRInt32 result = 0;
|
||||||
|
mInputStream->Read((char*)s, n, (PRUint32*)&result);
|
||||||
|
if (result == 0)
|
||||||
|
set_at_eof(PR_TRUE);
|
||||||
|
return result;
|
||||||
|
} // nsInputStream::read
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
static void TidyEndOfLine(char*& cp)
|
||||||
|
// Assumes that cp is pointing at \n or \r. Nulls out the character, checks for
|
||||||
|
// a second terminator (of the opposite persuasion), and returns cp pointing past the
|
||||||
|
// entire eol construct (one or two characters).
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
char ch = *cp;
|
||||||
|
*cp++ = '\0'; // terminate at the newline, then skip past it
|
||||||
|
if ((ch == '\n' && *cp == '\r') || (ch == '\r' && *cp == '\n'))
|
||||||
|
cp++; // possibly a pair.
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsInputStream& nsInputStream::operator >> (char& c)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
c = get();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//========================================================================================
|
||||||
|
// nsOutputStream
|
||||||
|
//========================================================================================
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsOutputStream::~nsOutputStream()
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
void nsOutputStream::put(char c)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
write(&c, sizeof(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
PRInt32 nsOutputStream::write(const void* s, PRInt32 n)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
if (!mOutputStream)
|
||||||
|
return 0;
|
||||||
|
PRInt32 result = 0;
|
||||||
|
mWriteStatus = mOutputStream->Write((char*)s, n, (PRUint32*)&result);
|
||||||
|
return result;
|
||||||
|
} // nsOutputStream::write
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsresult nsOutputStream::flush()
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsresult nsOutputStream::lastWriteStatus()
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
return mWriteStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsOutputStream& nsOutputStream::operator << (char c)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
put(c);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsOutputStream& nsOutputStream::operator << (const char* s)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
if (s)
|
||||||
|
write(s, strlen(s));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsOutputStream& nsOutputStream::operator << (short val)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
char buf[30];
|
||||||
|
sprintf(buf, "%hd", val);
|
||||||
|
return (*this << buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsOutputStream& nsOutputStream::operator << (unsigned short val)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
char buf[30];
|
||||||
|
sprintf(buf, "%hu", val);
|
||||||
|
return (*this << buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsOutputStream& nsOutputStream::operator << (long val)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
char buf[30];
|
||||||
|
sprintf(buf, "%ld", val);
|
||||||
|
return (*this << buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsOutputStream& nsOutputStream::operator << (unsigned long val)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
char buf[30];
|
||||||
|
sprintf(buf, "%lu", val);
|
||||||
|
return (*this << buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsOutputStream& nsOutputStream::operator << (int val)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
char buf[30];
|
||||||
|
sprintf(buf, "%d", val);
|
||||||
|
return (*this << buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsOutputStream& nsOutputStream::operator << (unsigned int val)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
char buf[30];
|
||||||
|
sprintf(buf, "%u", val);
|
||||||
|
return (*this << buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
//========================================================================================
|
||||||
|
// nsRandomAccessInputStream
|
||||||
|
//========================================================================================
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
PRBool nsRandomAccessInputStream::readline(char* s, PRInt32 n)
|
||||||
|
// This will truncate if the buffer is too small. Result will always be null-terminated.
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
PRBool bufferLargeEnough = PR_TRUE; // result
|
||||||
|
if (!s || !n)
|
||||||
|
return PR_TRUE;
|
||||||
|
|
||||||
|
PRIntn position = tell();
|
||||||
|
if (position < 0)
|
||||||
|
return PR_FALSE;
|
||||||
|
PRInt32 bytesRead = read(s, n - 1);
|
||||||
|
if (failed())
|
||||||
|
return PR_FALSE;
|
||||||
|
s[bytesRead] = '\0'; // always terminate at the end of the buffer
|
||||||
|
char* tp = strpbrk(s, "\n\r");
|
||||||
|
if (tp)
|
||||||
|
{
|
||||||
|
TidyEndOfLine(tp);
|
||||||
|
bytesRead = (tp - s);
|
||||||
|
}
|
||||||
|
else if (!eof() && n-1 == bytesRead)
|
||||||
|
bufferLargeEnough = PR_FALSE;
|
||||||
|
position += bytesRead;
|
||||||
|
seek(position);
|
||||||
|
return bufferLargeEnough;
|
||||||
|
} // nsRandomAccessInputStream::readline
|
||||||
|
|
||||||
|
//========================================================================================
|
||||||
|
// nsInputStringStream
|
||||||
|
//========================================================================================
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
nsInputStringStream::nsInputStringStream(const char* stringToRead)
|
||||||
|
//----------------------------------------------------------------------------------------
|
||||||
|
{
|
||||||
|
nsISupports* stream;
|
||||||
|
if (NS_FAILED(NS_NewCharInputStream(&stream, stringToRead)))
|
||||||
|
return;
|
||||||
|
mInputStream = do_QueryInterface(stream);
|
||||||
|
mStore = do_QueryInterface(stream);
|
||||||
|
NS_RELEASE(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
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Загрузка…
Ссылка в новой задаче