first draft of a xpcom obsolete dir. NOT PART OF BUILD

This commit is contained in:
dougt%netscape.com 2003-03-10 20:56:23 +00:00
Родитель 93be16ebcd
Коммит 69ac8a028e
34 изменённых файлов: 16335 добавлений и 0 удалений

Просмотреть файл

@ -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

Разница между файлами не показана из-за своего большого размера Загрузить разницу

784
xpcom/obsolete/nsFileSpec.h Normal file
Просмотреть файл

@ -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

Просмотреть файл

Просмотреть файл

Просмотреть файл

Просмотреть файл

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл