Merging branch BASE_19_FEB_99 to tip. These are extensive changes
to nsFileSpec and and nsFileStream. See dougt@netscape.com or John McMullen for futher information. git-svn-id: svn://10.0.0.236/trunk@21977 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -5,6 +5,7 @@
|
||||
nsAutoLock.h
|
||||
nsISizeOfHandler.h
|
||||
nsFileStream.h
|
||||
nsIFileStream.h
|
||||
nsFileSpec.h
|
||||
nsRepeater.h
|
||||
nsIProperties.h
|
||||
|
||||
@@ -32,6 +32,7 @@ EXPORTS = \
|
||||
nsEscape.h \
|
||||
nsFileSpec.h \
|
||||
nsFileStream.h \
|
||||
nsIFileStream.h \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
|
||||
|
||||
@@ -28,6 +28,7 @@ EXPORTS = \
|
||||
nsEscape.h \
|
||||
nsFileSpec.h \
|
||||
nsFileStream.h \
|
||||
nsIFileStream.h \
|
||||
$(NULL)
|
||||
|
||||
MODULE = raptor
|
||||
|
||||
@@ -24,7 +24,16 @@
|
||||
//
|
||||
// Classes defined:
|
||||
//
|
||||
// nsFilePath, nsFileURL, nsNativeFileSpec.
|
||||
// nsFilePath, nsFileURL, nsFileSpec, nsPersistentFileDescriptor.
|
||||
//
|
||||
// Q. How should I represent files at run time?
|
||||
// A. Use nsFileSpec. Using char* will lose information on some platforms.
|
||||
//
|
||||
// Q. Then what are nsFilePath and nsFileURL for?
|
||||
// A. Only when you need a char* parameter for legacy code.
|
||||
//
|
||||
// Q. How should I represent files in a persistent way (eg, in a disk file)?
|
||||
// A. Use nsPersistentFileDescriptor. Convert to and from nsFileSpec at run time.
|
||||
//
|
||||
// This suite provides the following services:
|
||||
//
|
||||
@@ -63,7 +72,7 @@
|
||||
//
|
||||
// Initialize a native file spec from a URL
|
||||
//
|
||||
// nsNativeFileSpec fileSpec(fileURL);
|
||||
// nsFileSpec fileSpec(fileURL);
|
||||
//
|
||||
// Make the spec unique (this one has no suffix).
|
||||
//
|
||||
@@ -103,6 +112,7 @@
|
||||
#define _FILESPEC_H_
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsError.h"
|
||||
|
||||
//========================================================================================
|
||||
// Compiler-specific macros, as needed
|
||||
@@ -116,11 +126,13 @@
|
||||
#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 ===============================
|
||||
@@ -137,33 +149,50 @@
|
||||
// Here are the allowable ways to describe a file.
|
||||
//========================================================================================
|
||||
|
||||
class nsFilePath; // This can be passed to NSPR file I/O routines.
|
||||
class nsFileSpec; // Preferred. For i/o use nsInputFileStream, nsOutputFileStream
|
||||
class nsFilePath; // This can be passed to NSPR file I/O routines, if you must.
|
||||
class nsFileURL;
|
||||
class nsNativeFileSpec;
|
||||
class nsPersistentFileDescriptor; // Used for storage across program launches.
|
||||
|
||||
#define kFileURLPrefix "file://"
|
||||
#define kFileURLPrefixLength (7)
|
||||
|
||||
class nsBasicOutStream;
|
||||
class nsOutputStream;
|
||||
class nsInputStream;
|
||||
class nsOutputFileStream;
|
||||
class nsInputFileStream;
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsNativeFileSpec
|
||||
// Conversion of native file errors to nsresult values. These are really only for use
|
||||
// in the file module, clients of this interface shouldn't really need them.
|
||||
// Error results returned from this interface have, in the low-order 16 bits,
|
||||
// native errors that are masked to 16 bits. Assumption: a native error of 0 is success
|
||||
// on all platforms. Note the way we define this using an inline function. This
|
||||
// avoids multiple evaluation if people go NS_FILE_RESULT(function_call()).
|
||||
#define NS_FILE_RESULT(x) ns_file_convert_result((PRInt32)x)
|
||||
nsresult ns_file_convert_result(PRInt32 nativeErr);
|
||||
#define NS_FILE_FAILURE NS_FILE_RESULT(-1)
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsFileSpec
|
||||
// This is whatever each platform really prefers to describe files as. Declared first
|
||||
// because the other two types have an embeded nsNativeFileSpec object.
|
||||
// because the other two types have an embeded nsFileSpec object.
|
||||
//========================================================================================
|
||||
{
|
||||
public:
|
||||
nsNativeFileSpec();
|
||||
explicit nsNativeFileSpec(const char* inString, bool inCreateDirs = false);
|
||||
explicit nsNativeFileSpec(const nsFilePath& inPath);
|
||||
explicit nsNativeFileSpec(const nsFileURL& inURL);
|
||||
nsNativeFileSpec(const nsNativeFileSpec& inPath);
|
||||
virtual ~nsNativeFileSpec();
|
||||
nsFileSpec();
|
||||
NS_EXPLICIT nsFileSpec(const char* inString, PRBool inCreateDirs = PR_FALSE);
|
||||
NS_EXPLICIT nsFileSpec(const nsFilePath& inPath);
|
||||
NS_EXPLICIT nsFileSpec(const nsFileURL& inURL);
|
||||
NS_EXPLICIT nsFileSpec(const nsPersistentFileDescriptor& inURL);
|
||||
nsFileSpec(const nsFileSpec& inPath);
|
||||
virtual ~nsFileSpec();
|
||||
|
||||
void operator = (const char* inPath);
|
||||
void operator = (const nsFilePath& inPath);
|
||||
void operator = (const nsFileURL& inURL);
|
||||
void operator = (const nsNativeFileSpec& inOther);
|
||||
void operator = (const nsFileSpec& inOther);
|
||||
void operator = (const nsPersistentFileDescriptor& inOther);
|
||||
|
||||
#ifndef XP_MAC
|
||||
operator const char* () const { return mPath; }
|
||||
@@ -175,23 +204,22 @@ class NS_BASE nsNativeFileSpec
|
||||
#ifdef XP_MAC
|
||||
// For Macintosh people, this is meant to be useful in its own right as a C++ version
|
||||
// of the FSSpec struct.
|
||||
nsNativeFileSpec(
|
||||
nsFileSpec(
|
||||
short vRefNum,
|
||||
long parID,
|
||||
ConstStr255Param name);
|
||||
nsNativeFileSpec(const FSSpec& inSpec)
|
||||
: mSpec(inSpec), mError(noErr) {}
|
||||
nsFileSpec(const FSSpec& inSpec)
|
||||
: mSpec(inSpec), mError(NS_OK) {}
|
||||
|
||||
operator FSSpec* () { return &mSpec; }
|
||||
operator const FSSpec* const () { return &mSpec; }
|
||||
operator FSSpec& () { return mSpec; }
|
||||
operator const FSSpec& () const { return mSpec; }
|
||||
OSErr Error() const { return mError; }
|
||||
void MakeAliasSafe();
|
||||
// Called for the spec of an alias. Copies the alias to
|
||||
// a secret temp directory and modifies the spec to point
|
||||
// to it. Sets mError.
|
||||
void ResolveAlias(bool& wasAliased);
|
||||
void ResolveAlias(PRBool& wasAliased);
|
||||
// Called for the spec of an alias. Modifies the spec to
|
||||
// point to the original. Sets mError.
|
||||
void MakeUnique(ConstStr255Param inSuggestedLeafName);
|
||||
@@ -199,15 +227,15 @@ class NS_BASE nsNativeFileSpec
|
||||
ConstStr255Param GetLeafPName() const { return mSpec.name; }
|
||||
#endif // end of Macintosh utility methods.
|
||||
|
||||
#ifdef XP_MAC
|
||||
bool Valid() const { return mError == noErr; }
|
||||
#else
|
||||
bool Valid() const { return true; } // Fixme.
|
||||
#endif // XP_MAC
|
||||
PRBool Valid() const { return NS_SUCCEEDED(Error()); }
|
||||
nsresult Error() const { return mError; }
|
||||
|
||||
friend NS_BASE nsBasicOutStream& operator << (
|
||||
nsBasicOutStream& s,
|
||||
const nsNativeFileSpec& spec);
|
||||
#if DEBUG
|
||||
friend NS_BASE nsOutputStream& operator << (
|
||||
nsOutputStream& s,
|
||||
const nsFileSpec& spec); // THIS IS FOR DEBUGGING ONLY.
|
||||
// see PersistentFileDescriptor for the real deal.
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------
|
||||
// Queries and path algebra. These do not modify the disk.
|
||||
@@ -218,7 +246,7 @@ class NS_BASE nsNativeFileSpec
|
||||
// inLeafName can be a relative path, so this allows
|
||||
// one kind of concatenation of "paths".
|
||||
|
||||
void GetParent(nsNativeFileSpec& outSpec) const;
|
||||
void GetParent(nsFileSpec& outSpec) const;
|
||||
// Return the filespec of the parent directory. Used
|
||||
// in conjunction with GetLeafName(), this lets you
|
||||
// parse a path into a list of node names. Beware,
|
||||
@@ -226,7 +254,7 @@ class NS_BASE nsNativeFileSpec
|
||||
// but a spec. Volumes on Macintosh can have identical
|
||||
// names. Perhaps could be used for an operator --() ?
|
||||
|
||||
nsNativeFileSpec operator + (const char* inRelativePath) const;
|
||||
nsFileSpec operator + (const char* inRelativePath) const;
|
||||
void operator += (const char* inRelativePath);
|
||||
// Concatenate the relative path to this directory.
|
||||
// Used for constructing the filespec of a descendant.
|
||||
@@ -240,19 +268,24 @@ class NS_BASE nsNativeFileSpec
|
||||
void MakeUnique();
|
||||
void MakeUnique(const char* inSuggestedLeafName);
|
||||
|
||||
bool IsDirectory() const;
|
||||
PRBool IsDirectory() const;
|
||||
// More stringent than Exists()
|
||||
bool IsFile() const;
|
||||
PRBool IsFile() const;
|
||||
// More stringent than Exists()
|
||||
bool Exists() const;
|
||||
PRBool Exists() const;
|
||||
|
||||
//--------------------------------------------------
|
||||
// Creation and deletion of objects. These can modify the disk.
|
||||
//--------------------------------------------------
|
||||
|
||||
void CreateDirectory(int mode = 0700 /* for unix */);
|
||||
void Delete(bool inRecursive);
|
||||
void Delete(PRBool inRecursive);
|
||||
|
||||
nsresult Rename(const char* inNewName); // not const: gets updated
|
||||
nsresult Copy(const nsFileSpec& inNewParentDirectory) const;
|
||||
nsresult Move(const nsFileSpec& inNewParentDirectory) const;
|
||||
nsresult Execute(const char* args) const;
|
||||
|
||||
//--------------------------------------------------
|
||||
// Data
|
||||
//--------------------------------------------------
|
||||
@@ -261,11 +294,15 @@ class NS_BASE nsNativeFileSpec
|
||||
friend class nsFilePath;
|
||||
#ifdef XP_MAC
|
||||
FSSpec mSpec;
|
||||
OSErr mError;
|
||||
#else
|
||||
char* mPath;
|
||||
#endif
|
||||
}; // class nsNativeFileSpec
|
||||
nsresult mError;
|
||||
}; // class nsFileSpec
|
||||
|
||||
// FOR HISTORICAL REASONS:
|
||||
|
||||
typedef nsFileSpec nsNativeFileSpec;
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsFileURL
|
||||
@@ -276,9 +313,9 @@ class NS_BASE nsFileURL
|
||||
{
|
||||
public:
|
||||
nsFileURL(const nsFileURL& inURL);
|
||||
explicit nsFileURL(const char* inString, bool inCreateDirs = false);
|
||||
explicit nsFileURL(const nsFilePath& inPath);
|
||||
explicit nsFileURL(const nsNativeFileSpec& inPath);
|
||||
NS_EXPLICIT nsFileURL(const char* inString, PRBool inCreateDirs = PR_FALSE);
|
||||
NS_EXPLICIT nsFileURL(const nsFilePath& inPath);
|
||||
NS_EXPLICIT nsFileURL(const nsFileSpec& inPath);
|
||||
virtual ~nsFileURL();
|
||||
|
||||
// nsString GetString() const { return mPath; }
|
||||
@@ -288,14 +325,14 @@ class NS_BASE nsFileURL
|
||||
void operator = (const nsFileURL& inURL);
|
||||
void operator = (const char* inString);
|
||||
void operator = (const nsFilePath& inOther);
|
||||
void operator = (const nsNativeFileSpec& inOther);
|
||||
void operator = (const nsFileSpec& inOther);
|
||||
|
||||
friend NS_BASE nsBasicOutStream& operator << (
|
||||
nsBasicOutStream& s, const nsFileURL& spec);
|
||||
friend NS_BASE nsOutputStream& operator << (
|
||||
nsOutputStream& s, const nsFileURL& spec);
|
||||
|
||||
#ifdef XP_MAC
|
||||
// Accessor to allow quick assignment to a mNativeFileSpec
|
||||
const nsNativeFileSpec& GetNativeSpec() const { return mNativeFileSpec; }
|
||||
// Accessor to allow quick assignment to a mFileSpec
|
||||
const nsFileSpec& GetFileSpec() const { return mFileSpec; }
|
||||
#endif
|
||||
private:
|
||||
// Should not be defined (only nsFilePath is to be treated as strings.
|
||||
@@ -306,8 +343,8 @@ class NS_BASE nsFileURL
|
||||
char* mURL;
|
||||
#ifdef XP_MAC
|
||||
// Since the path on the macintosh does not uniquely specify a file (volumes
|
||||
// can have the same name), stash the secret nsNativeFileSpec, too.
|
||||
nsNativeFileSpec mNativeFileSpec;
|
||||
// can have the same name), stash the secret nsFileSpec, too.
|
||||
nsFileSpec mFileSpec;
|
||||
#endif
|
||||
}; // class nsFileURL
|
||||
|
||||
@@ -319,9 +356,9 @@ class NS_BASE nsFilePath
|
||||
{
|
||||
public:
|
||||
nsFilePath(const nsFilePath& inPath);
|
||||
explicit nsFilePath(const char* inString, bool inCreateDirs = false);
|
||||
explicit nsFilePath(const nsFileURL& inURL);
|
||||
explicit nsFilePath(const nsNativeFileSpec& inPath);
|
||||
NS_EXPLICIT nsFilePath(const char* inString, PRBool inCreateDirs = PR_FALSE);
|
||||
NS_EXPLICIT nsFilePath(const nsFileURL& inURL);
|
||||
NS_EXPLICIT nsFilePath(const nsFileSpec& inPath);
|
||||
virtual ~nsFilePath();
|
||||
|
||||
|
||||
@@ -337,12 +374,12 @@ class NS_BASE nsFilePath
|
||||
void operator = (const nsFilePath& inPath);
|
||||
void operator = (const char* inString);
|
||||
void operator = (const nsFileURL& inURL);
|
||||
void operator = (const nsNativeFileSpec& inOther);
|
||||
void operator = (const nsFileSpec& inOther);
|
||||
|
||||
#ifdef XP_MAC
|
||||
public:
|
||||
// Accessor to allow quick assignment to a mNativeFileSpec
|
||||
const nsNativeFileSpec& GetNativeSpec() const { return mNativeFileSpec; }
|
||||
// Accessor to allow quick assignment to a mFileSpec
|
||||
const nsFileSpec& GetFileSpec() const { return mFileSpec; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
@@ -350,26 +387,59 @@ class NS_BASE nsFilePath
|
||||
char* mPath;
|
||||
#ifdef XP_MAC
|
||||
// Since the path on the macintosh does not uniquely specify a file (volumes
|
||||
// can have the same name), stash the secret nsNativeFileSpec, too.
|
||||
nsNativeFileSpec mNativeFileSpec;
|
||||
// can have the same name), stash the secret nsFileSpec, too.
|
||||
nsFileSpec mFileSpec;
|
||||
#endif
|
||||
}; // class nsFilePath
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsPersistentFileDescriptor
|
||||
//========================================================================================
|
||||
{
|
||||
public:
|
||||
nsPersistentFileDescriptor() : mDescriptorString(nsnull) {}
|
||||
// For use prior to reading in from a stream
|
||||
nsPersistentFileDescriptor(const nsPersistentFileDescriptor& inPath);
|
||||
virtual ~nsPersistentFileDescriptor();
|
||||
void operator = (const nsPersistentFileDescriptor& inPath);
|
||||
|
||||
// Conversions
|
||||
nsPersistentFileDescriptor(const nsFileSpec& inPath);
|
||||
void operator = (const nsFileSpec& inPath);
|
||||
|
||||
friend NS_BASE nsInputStream& operator >> (nsInputStream&, nsPersistentFileDescriptor&);
|
||||
// reads the data from a file
|
||||
friend NS_BASE nsOutputStream& operator << (nsOutputStream&, const nsPersistentFileDescriptor&);
|
||||
// writes the data to a file
|
||||
friend class nsFileSpec;
|
||||
|
||||
private:
|
||||
// Here are the ways to get data in and out of a file.
|
||||
void GetData(void*& outData, PRInt32& outSize) const;
|
||||
// DON'T FREE the returned data!
|
||||
void SetData(const void* inData, PRInt32 inSize);
|
||||
|
||||
private:
|
||||
|
||||
char* mDescriptorString;
|
||||
|
||||
}; // class nsPersistentFileDescriptor
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsDirectoryIterator
|
||||
// Example:
|
||||
//
|
||||
// nsNativeFileSpec parentDir(...); // directory over whose children we shall iterate
|
||||
// nsFileSpec parentDir(...); // directory over whose children we shall iterate
|
||||
// for (nsDirectoryIterator i(parentDir); i; i++)
|
||||
// {
|
||||
// // do something with (const nsNativeFileSpec&)i
|
||||
// // do something with (const nsFileSpec&)i
|
||||
// }
|
||||
//
|
||||
// or:
|
||||
//
|
||||
// for (nsDirectoryIterator i(parentDir, false); i; i--)
|
||||
// for (nsDirectoryIterator i(parentDir, PR_FALSE); i; i--)
|
||||
// {
|
||||
// // do something with (const nsNativeFileSpec&)i
|
||||
// // do something with (const nsFileSpec&)i
|
||||
// }
|
||||
//
|
||||
// Currently, the only platform on which backwards iteration actually goes backwards
|
||||
@@ -378,21 +448,21 @@ class NS_BASE nsDirectoryIterator
|
||||
{
|
||||
public:
|
||||
nsDirectoryIterator(
|
||||
const nsNativeFileSpec& parent,
|
||||
const nsFileSpec& parent,
|
||||
int iterateDirection = +1);
|
||||
#ifndef XP_MAC
|
||||
// Macintosh currently doesn't allocate, so needn't clean up.
|
||||
virtual ~nsDirectoryIterator();
|
||||
#endif
|
||||
operator bool() const { return mExists; }
|
||||
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 nsNativeFileSpec&() { return mCurrent; }
|
||||
operator nsFileSpec&() { return mCurrent; }
|
||||
private:
|
||||
nsNativeFileSpec mCurrent;
|
||||
bool mExists;
|
||||
nsFileSpec mCurrent;
|
||||
bool mExists; // MUST be bool.
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
DIR* mDir;
|
||||
|
||||
@@ -19,14 +19,31 @@
|
||||
// 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:
|
||||
//
|
||||
// single-byte char:
|
||||
//
|
||||
// nsInputStream, nsOutputStream
|
||||
// These are the lightweight STATICALLY LINKED wrappers for
|
||||
// the xpcom objects nsIInputStream and nsIOutputstream.
|
||||
// Possible uses:
|
||||
// If you are implementing a function that accepts one of these xpcom
|
||||
// streams, just make one of these little jobbies on the stack, and
|
||||
// the handy << or >> notation can be yours.
|
||||
//
|
||||
// nsInputFileStream, nsOutputFileStream
|
||||
// These are the STATICALLY LINKED versions of the file i/o streams,
|
||||
// which wrap the NSPR file i/o plus console i/o.
|
||||
//
|
||||
// Related files:
|
||||
// prio.h the NSPR file i/o C API), which is wrapped by
|
||||
// THIS FILE statically linked C++ wrappers, which in turn are wrapped by
|
||||
// nsIFileStream.h COM wrappers for this file, which are wrapped by
|
||||
// nsAutoFileStream.h more easily used, nicer syntax wrappers for the
|
||||
// COMified ones. Wrapper of a wrapper of a wrapper.
|
||||
//
|
||||
// This suite provide the following services:
|
||||
//
|
||||
@@ -41,13 +58,13 @@
|
||||
//
|
||||
// Basic example:
|
||||
//
|
||||
// nsFilePath myPath("/Development/iotest.txt");
|
||||
// nsFileSpec myPath("/Development/iotest.txt");
|
||||
//
|
||||
// nsOutputFileStream testStream(myPath);
|
||||
// testStream << "Hello World" << nsEndl;
|
||||
//
|
||||
// 4. Requires streams to be constructed using typesafe nsFilePath specifier
|
||||
// (not the notorious and bug prone const char*), namely nsFilePath. See
|
||||
// 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
|
||||
@@ -73,7 +90,13 @@
|
||||
#else
|
||||
#include "prio.h"
|
||||
#endif
|
||||
#include "nsFileSpec.h"
|
||||
|
||||
#include "nsIFileStream.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class nsFileSpec;
|
||||
class nsInputFileStream;
|
||||
class nsOutputFileStream;
|
||||
|
||||
//========================================================================================
|
||||
// Compiler-specific macros, as needed
|
||||
@@ -133,201 +156,392 @@ using std::ostream;
|
||||
//=========================== End Compiler-specific macros ===============================
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsBasicFileStream
|
||||
class NS_BASE nsInputStream
|
||||
// This is a convenience class, for use on the STACK ("new" junkies: get detoxed first).
|
||||
// Given a COM-style stream, this allows you to use the >> operators. It also acquires and
|
||||
// reference counts its stream.
|
||||
// Please read the comments at the top of this file
|
||||
//========================================================================================
|
||||
{
|
||||
public:
|
||||
nsBasicFileStream();
|
||||
nsBasicFileStream(PRFileDesc* desc, int nsprMode);
|
||||
nsBasicFileStream(
|
||||
const nsFilePath& inFile,
|
||||
int nsprMode,
|
||||
PRIntn accessMode);
|
||||
virtual ~nsBasicFileStream();
|
||||
nsInputStream(nsIInputStream* inStream)
|
||||
: mInputStream(do_QueryInterface(inStream))
|
||||
, mEOF(PR_FALSE)
|
||||
{}
|
||||
virtual ~nsInputStream();
|
||||
|
||||
nsCOMPtr<nsIInputStream> GetIStream() const
|
||||
{
|
||||
return mInputStream;
|
||||
}
|
||||
char eof() const { return mEOF; }
|
||||
char get();
|
||||
PRInt32 read(void* s, PRInt32 n)
|
||||
{
|
||||
if (!mInputStream)
|
||||
return 0;
|
||||
PRInt32 result = 0;
|
||||
mInputStream->Read((char*)s, 0, n, (PRUint32*)&result);
|
||||
if (result < n)
|
||||
mEOF = PR_TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Input streamers. Add more as needed (int&, unsigned int& etc). (but you have to
|
||||
// add delegators to the derived classes, too, because these operators don't inherit).
|
||||
nsInputStream& operator >> (char& ch);
|
||||
|
||||
inline PRBool is_open() const { return mFileDesc != 0; }
|
||||
void open(
|
||||
const nsFilePath& inFile,
|
||||
int nsprMode,
|
||||
PRIntn accessMode);
|
||||
void close();
|
||||
PRIntn tell() const;
|
||||
void seek(PRInt32 offset) { seek(PR_SEEK_SET, offset); }
|
||||
void seek(PRSeekWhence whence, PRInt32 offset);
|
||||
PRBool eof() const { return mEOF; }
|
||||
PRBool failed() const { return mFailed; }
|
||||
// call PR_GetError() for details
|
||||
protected:
|
||||
|
||||
PRFileDesc* GetFileDescriptor() const { return mFileDesc; }
|
||||
|
||||
protected:
|
||||
|
||||
friend class nsBasicInStream;
|
||||
friend class nsBasicOutStream;
|
||||
|
||||
PRFileDesc* mFileDesc;
|
||||
int mNSPRMode;
|
||||
PRBool mFailed;
|
||||
PRBool mEOF;
|
||||
}; // class nsBasicFileStream
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsBasicInStream
|
||||
//========================================================================================
|
||||
{
|
||||
protected:
|
||||
nsBasicInStream(nsBasicFileStream& inStream, istream* stream);
|
||||
|
||||
public:
|
||||
|
||||
nsBasicInStream& operator >> (nsBasicInStream& (*pf)(nsBasicInStream&))
|
||||
// Support manipulators
|
||||
nsInputStream& operator >> (nsInputStream& (*pf)(nsInputStream&))
|
||||
{
|
||||
return pf(*this);
|
||||
}
|
||||
void get(char& c);
|
||||
PRInt32 read(void* s, PRInt32 n);
|
||||
}
|
||||
private:
|
||||
|
||||
nsInputStream& operator >> (char* buf); // TOO DANGEROUS. DON'T DEFINE.
|
||||
|
||||
// DATA
|
||||
protected:
|
||||
nsCOMPtr<nsIInputStream> mInputStream;
|
||||
PRBool mEOF;
|
||||
}; // class nsInputStream
|
||||
|
||||
typedef nsInputStream nsBasicInStream; // historic support for this name
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsOutputStream
|
||||
// This is a convenience class, for use on the STACK ("new" junkies, get detoxed first).
|
||||
// Given a COM-style stream, this allows you to use the << operators. It also acquires and
|
||||
// reference counts its stream.
|
||||
// Please read the comments at the top of this file
|
||||
//========================================================================================
|
||||
{
|
||||
public:
|
||||
nsOutputStream() {}
|
||||
nsOutputStream(nsIOutputStream* inStream)
|
||||
: mOutputStream(do_QueryInterface(inStream))
|
||||
{}
|
||||
|
||||
virtual ~nsOutputStream();
|
||||
|
||||
nsCOMPtr<nsIOutputStream> GetIStream() const
|
||||
{
|
||||
return mOutputStream;
|
||||
}
|
||||
void put(char c);
|
||||
PRInt32 write(const void* s, PRInt32 n)
|
||||
{
|
||||
if (!mOutputStream)
|
||||
return 0;
|
||||
PRInt32 result = 0;
|
||||
mOutputStream->Write((char*)s, 0, n, (PRUint32*)&result);
|
||||
return result;
|
||||
}
|
||||
virtual void flush();
|
||||
|
||||
// Output streamers. Add more as needed (but you have to add delegators to the derived
|
||||
// classes, too, because these operators don't inherit).
|
||||
nsOutputStream& operator << (const char* buf);
|
||||
nsOutputStream& operator << (char ch);
|
||||
nsOutputStream& operator << (short val);
|
||||
nsOutputStream& operator << (unsigned short val);
|
||||
nsOutputStream& operator << (long val);
|
||||
nsOutputStream& operator << (unsigned long val);
|
||||
|
||||
// Support manipulators
|
||||
nsOutputStream& operator << (nsOutputStream& (*pf)(nsOutputStream&))
|
||||
{
|
||||
return pf(*this);
|
||||
}
|
||||
|
||||
// DATA
|
||||
protected:
|
||||
nsCOMPtr<nsIOutputStream> mOutputStream;
|
||||
}; // class nsOutputStream
|
||||
|
||||
typedef nsOutputStream nsBasicOutStream; // Historic support for this name
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsFileClient
|
||||
// Because COM does not allow us to write functions which return a boolean value etc,
|
||||
// this class is here to take care of the tedious "declare variable then call with
|
||||
// the address of the variable" chores.
|
||||
//========================================================================================
|
||||
{
|
||||
public:
|
||||
nsFileClient() // for delayed opening
|
||||
: mResult(NS_OK)
|
||||
{
|
||||
}
|
||||
nsFileClient(const nsCOMPtr<nsIFile>& inFile)
|
||||
: mFile(do_QueryInterface(inFile))
|
||||
, mResult(NS_OK)
|
||||
{
|
||||
}
|
||||
|
||||
PRBool is_file() const
|
||||
{
|
||||
return mFile ? PR_TRUE : PR_FALSE;
|
||||
}
|
||||
void open(
|
||||
const nsFileSpec& inFile,
|
||||
int nsprMode,
|
||||
PRIntn accessMode)
|
||||
{
|
||||
if (mFile)
|
||||
mResult = mFile->Open(inFile, nsprMode, accessMode);
|
||||
}
|
||||
PRBool is_open() const
|
||||
{
|
||||
PRBool result = PR_FALSE;
|
||||
if (mFile)
|
||||
mFile->GetIsOpen(&result);
|
||||
return result;
|
||||
}
|
||||
PRBool failed() const
|
||||
{
|
||||
return NS_FAILED(mResult);
|
||||
}
|
||||
void seek(PRInt32 offset)
|
||||
{
|
||||
seek(PR_SEEK_SET, offset);
|
||||
}
|
||||
|
||||
void seek(PRSeekWhence whence, PRInt32 offset)
|
||||
{
|
||||
if (mFile)
|
||||
mResult = mFile->Seek(whence, offset);
|
||||
}
|
||||
PRIntn tell()
|
||||
{
|
||||
PRIntn result = -1;
|
||||
if (mFile)
|
||||
mResult = mFile->Tell(&result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// DATA
|
||||
protected:
|
||||
nsCOMPtr<nsIFile> mFile;
|
||||
PRBool mResult;
|
||||
}; // class nsFileClient
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsInputFileStream
|
||||
// Please read the comments at the top of this file
|
||||
//========================================================================================
|
||||
: public nsInputStream
|
||||
, public nsFileClient
|
||||
{
|
||||
public:
|
||||
enum { kDefaultMode = PR_RDONLY };
|
||||
nsInputFileStream(nsIInputStream* inStream)
|
||||
: nsInputStream(inStream)
|
||||
, nsFileClient(do_QueryInterface(inStream))
|
||||
, mFileInputStream(do_QueryInterface(inStream))
|
||||
{
|
||||
}
|
||||
nsInputFileStream(
|
||||
const nsFileSpec& inFile,
|
||||
int nsprMode = kDefaultMode,
|
||||
PRIntn accessMode = 00700) // <- OCTAL
|
||||
: nsInputStream(nsnull)
|
||||
{
|
||||
nsISupports* stream;
|
||||
NS_NewIOFileStream(
|
||||
&stream,
|
||||
inFile, nsprMode, accessMode);
|
||||
mFile = nsQueryInterface(stream);
|
||||
mInputStream = nsQueryInterface(stream);
|
||||
mFileInputStream = nsQueryInterface(stream);
|
||||
}
|
||||
|
||||
PRBool readline(char* s, PRInt32 n);
|
||||
// Result always null-terminated.
|
||||
// Check eof() before each call.
|
||||
// CAUTION: false result only indicates line was truncated
|
||||
// to fit buffer, or an error occurred (OTHER THAN eof).
|
||||
|
||||
// Input streamers. Add more as needed
|
||||
nsBasicInStream& operator >> (char& ch);
|
||||
|
||||
istream* GetStandardStream() const { return mStdStream; }
|
||||
|
||||
protected:
|
||||
|
||||
nsBasicFileStream& mBase;
|
||||
istream* mStdStream;
|
||||
}; // class nsBasicInStream
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsBasicOutStream
|
||||
//========================================================================================
|
||||
{
|
||||
protected:
|
||||
|
||||
nsBasicOutStream(nsBasicFileStream& inStream, ostream* stream);
|
||||
|
||||
public:
|
||||
|
||||
nsBasicOutStream& operator << (nsBasicOutStream& (*pf)(nsBasicOutStream&))
|
||||
{
|
||||
return pf(*this);
|
||||
}
|
||||
void put(char c);
|
||||
PRInt32 write(const void* s, PRInt32 n);
|
||||
void flush();
|
||||
|
||||
// Output streamers. Add more as needed
|
||||
nsBasicOutStream& operator << (const char* buf);
|
||||
nsBasicOutStream& operator << (char ch);
|
||||
nsBasicOutStream& operator << (short val);
|
||||
nsBasicOutStream& operator << (unsigned short val);
|
||||
nsBasicOutStream& operator << (long val);
|
||||
nsBasicOutStream& operator << (unsigned long val);
|
||||
|
||||
ostream* GetStandardStream() const { return mStdStream; }
|
||||
|
||||
protected:
|
||||
|
||||
nsBasicFileStream& mBase;
|
||||
ostream* mStdStream;
|
||||
}; // class nsBasicOutStream
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsInputFileStream
|
||||
//========================================================================================
|
||||
: public nsBasicFileStream
|
||||
, public nsBasicInStream
|
||||
{
|
||||
public:
|
||||
enum { kDefaultMode = PR_RDONLY };
|
||||
nsInputFileStream(istream* stream = CONSOLE_IN);
|
||||
nsInputFileStream(
|
||||
const nsFilePath& inFile,
|
||||
int nsprMode = kDefaultMode,
|
||||
PRIntn accessMode = 00700) // <- OCTAL
|
||||
: nsBasicFileStream(inFile, nsprMode, accessMode)
|
||||
, nsBasicInStream(*this, 0)
|
||||
{}
|
||||
|
||||
void open(
|
||||
const nsFilePath& inFile,
|
||||
void Open(
|
||||
const nsFileSpec& inFile,
|
||||
int nsprMode = kDefaultMode,
|
||||
PRIntn accessMode = 00700) // <- OCTAL
|
||||
{
|
||||
nsBasicFileStream::open(inFile, nsprMode, accessMode);
|
||||
if (mFile)
|
||||
mFile->Open(inFile, nsprMode, accessMode);
|
||||
}
|
||||
private:
|
||||
|
||||
nsInputFileStream& operator >> (char* buf); // TOO DANGEROUS. DON'T DEFINE.
|
||||
// Input streamers. Unfortunately, they don't inherit!
|
||||
nsInputStream& operator >> (char& ch)
|
||||
{ return nsInputStream::operator >>(ch); }
|
||||
nsInputStream& operator >> (nsInputStream& (*pf)(nsInputStream&))
|
||||
{ return nsInputStream::operator >>(pf); }
|
||||
|
||||
// DATA
|
||||
protected:
|
||||
nsCOMPtr<nsIFileInputStream> mFileInputStream;
|
||||
}; // class nsInputFileStream
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsOutputFileStream
|
||||
// Please read the comments at the top of this file
|
||||
//========================================================================================
|
||||
: public nsBasicFileStream
|
||||
, public nsBasicOutStream
|
||||
: public nsOutputStream
|
||||
, public nsFileClient
|
||||
{
|
||||
public:
|
||||
enum { kDefaultMode = (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE) };
|
||||
|
||||
nsOutputFileStream(ostream* stream = CONSOLE_OUT);
|
||||
nsOutputFileStream() {}
|
||||
nsOutputFileStream(nsIOutputStream* inStream)
|
||||
: nsOutputStream(inStream)
|
||||
, nsFileClient(do_QueryInterface(inStream))
|
||||
, mFileOutputStream(do_QueryInterface(inStream))
|
||||
{
|
||||
}
|
||||
nsOutputFileStream(
|
||||
const nsFilePath& inFile,
|
||||
const nsFileSpec& inFile,
|
||||
int nsprMode = kDefaultMode,
|
||||
PRIntn accessMode = 00700) // <- OCTAL
|
||||
: nsBasicFileStream(inFile, nsprMode, accessMode)
|
||||
, nsBasicOutStream(*this, 0)
|
||||
{}
|
||||
|
||||
inline void open(
|
||||
const nsFilePath& inFile,
|
||||
int nsprMode = kDefaultMode,
|
||||
PRIntn accessMode = 00700) // <- OCTAL
|
||||
: nsOutputStream(nsnull)
|
||||
{
|
||||
nsBasicFileStream::open(inFile, nsprMode, accessMode);
|
||||
nsISupports* stream;
|
||||
if (NS_FAILED(NS_NewIOFileStream(
|
||||
&stream,
|
||||
inFile, nsprMode, accessMode)))
|
||||
return;
|
||||
mFile = nsQueryInterface(stream);
|
||||
mOutputStream = nsQueryInterface(stream);
|
||||
mFileOutputStream = nsQueryInterface(stream);
|
||||
}
|
||||
|
||||
virtual void flush();
|
||||
|
||||
// Output streamers. Unfortunately, they don't inherit!
|
||||
nsOutputStream& operator << (const char* buf)
|
||||
{ return nsOutputStream::operator << (buf); }
|
||||
nsOutputStream& operator << (char ch)
|
||||
{ return nsOutputStream::operator << (ch); }
|
||||
nsOutputStream& operator << (short val)
|
||||
{ return nsOutputStream::operator << (val); }
|
||||
nsOutputStream& operator << (unsigned short val)
|
||||
{ return nsOutputStream::operator << (val); }
|
||||
nsOutputStream& operator << (long val)
|
||||
{ return nsOutputStream::operator << (val); }
|
||||
nsOutputStream& operator << (unsigned long val)
|
||||
{ return nsOutputStream::operator << (val); }
|
||||
nsOutputStream& operator << (nsOutputStream& (*pf)(nsOutputStream&))
|
||||
{ return nsOutputStream::operator << (pf); }
|
||||
|
||||
// DATA
|
||||
protected:
|
||||
nsCOMPtr<nsIFileOutputStream> mFileOutputStream;
|
||||
}; // class nsOutputFileStream
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsIOFileStream
|
||||
class NS_BASE nsOutputConsoleStream
|
||||
// Please read the comments at the top of this file
|
||||
//========================================================================================
|
||||
: public nsBasicFileStream
|
||||
, public nsBasicOutStream
|
||||
, public nsBasicInStream
|
||||
: public nsOutputFileStream
|
||||
{
|
||||
public:
|
||||
|
||||
nsOutputConsoleStream()
|
||||
{
|
||||
nsISupports* stream;
|
||||
if (NS_FAILED(NS_NewOutputConsoleStream(&stream)))
|
||||
return;
|
||||
mFile = nsQueryInterface(stream);
|
||||
mOutputStream = nsQueryInterface(stream);
|
||||
mFileOutputStream = nsQueryInterface(stream);
|
||||
}
|
||||
|
||||
// Output streamers. Unfortunately, they don't inherit!
|
||||
nsOutputStream& operator << (const char* buf)
|
||||
{ return nsOutputStream::operator << (buf); }
|
||||
nsOutputStream& operator << (char ch)
|
||||
{ return nsOutputStream::operator << (ch); }
|
||||
nsOutputStream& operator << (short val)
|
||||
{ return nsOutputStream::operator << (val); }
|
||||
nsOutputStream& operator << (unsigned short val)
|
||||
{ return nsOutputStream::operator << (val); }
|
||||
nsOutputStream& operator << (long val)
|
||||
{ return nsOutputStream::operator << (val); }
|
||||
nsOutputStream& operator << (unsigned long val)
|
||||
{ return nsOutputStream::operator << (val); }
|
||||
nsOutputStream& operator << (nsOutputStream& (*pf)(nsOutputStream&))
|
||||
{ return nsOutputStream::operator << (pf); }
|
||||
|
||||
}; // class nsOutputConsoleStream
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsIOFileStream
|
||||
// Please read the comments at the top of this file
|
||||
//========================================================================================
|
||||
: public nsInputFileStream
|
||||
, public nsOutputStream
|
||||
{
|
||||
public:
|
||||
enum { kDefaultMode = (PR_RDWR | PR_CREATE_FILE) };
|
||||
|
||||
nsIOFileStream(
|
||||
const nsFilePath& inFile,
|
||||
nsIInputStream* inInputStream
|
||||
, nsIOutputStream* inOutputStream)
|
||||
: nsInputFileStream(inInputStream)
|
||||
, nsOutputStream(inOutputStream)
|
||||
, mFileOutputStream(do_QueryInterface(inOutputStream))
|
||||
{
|
||||
}
|
||||
nsIOFileStream(
|
||||
const nsFileSpec& inFile,
|
||||
int nsprMode = kDefaultMode,
|
||||
PRIntn accessMode = 00700) // <- OCTAL
|
||||
: nsBasicFileStream(inFile, nsprMode, accessMode)
|
||||
, nsBasicInStream(*this, 0)
|
||||
, nsBasicOutStream(*this, 0)
|
||||
{}
|
||||
|
||||
inline void open(
|
||||
const nsFilePath& inFile,
|
||||
int nsprMode = kDefaultMode,
|
||||
PRIntn accessMode = 00700) // <- OCTAL
|
||||
: nsInputFileStream(nsnull)
|
||||
, nsOutputStream(nsnull)
|
||||
{
|
||||
nsBasicFileStream::open(inFile, nsprMode, accessMode);
|
||||
nsISupports* stream;
|
||||
if (NS_FAILED(NS_NewIOFileStream(
|
||||
&stream,
|
||||
inFile, nsprMode, accessMode)))
|
||||
return;
|
||||
mFile = nsQueryInterface(stream);
|
||||
mInputStream = nsQueryInterface(stream);
|
||||
mOutputStream = nsQueryInterface(stream);
|
||||
mFileInputStream = nsQueryInterface(stream);
|
||||
mFileOutputStream = nsQueryInterface(stream);
|
||||
}
|
||||
}; // class nsIOFileStream
|
||||
|
||||
// Output streamers. Unfortunately, they don't inherit!
|
||||
nsOutputStream& operator << (const char* buf)
|
||||
{ return nsOutputStream::operator << (buf); }
|
||||
nsOutputStream& operator << (char ch)
|
||||
{ return nsOutputStream::operator << (ch); }
|
||||
nsOutputStream& operator << (short val)
|
||||
{ return nsOutputStream::operator << (val); }
|
||||
nsOutputStream& operator << (unsigned short val)
|
||||
{ return nsOutputStream::operator << (val); }
|
||||
nsOutputStream& operator << (long val)
|
||||
{ return nsOutputStream::operator << (val); }
|
||||
nsOutputStream& operator << (unsigned long val)
|
||||
{ return nsOutputStream::operator << (val); }
|
||||
nsOutputStream& operator << (nsOutputStream& (*pf)(nsOutputStream&))
|
||||
{ return nsOutputStream::operator << (pf); }
|
||||
|
||||
// Input streamers. Unfortunately, they don't inherit!
|
||||
nsInputStream& operator >> (char& ch)
|
||||
{ return nsInputStream::operator >>(ch); }
|
||||
nsInputStream& operator >> (nsInputStream& (*pf)(nsInputStream&))
|
||||
{ return nsInputStream::operator >>(pf); }
|
||||
// DATA
|
||||
protected:
|
||||
nsCOMPtr<nsIFileOutputStream> mFileOutputStream;
|
||||
}; // class nsIOFileStream
|
||||
|
||||
//========================================================================================
|
||||
// Manipulators
|
||||
//========================================================================================
|
||||
NS_BASE nsBasicOutStream& nsEndl(nsBasicOutStream& os);
|
||||
|
||||
|
||||
NS_BASE nsOutputStream& nsEndl(nsOutputStream& os); // outputs and FLUSHES.
|
||||
|
||||
|
||||
#endif /* _FILESTREAM_H_ */
|
||||
|
||||
127
mozilla/base/public/nsIFileStream.h
Normal file
127
mozilla/base/public/nsIFileStream.h
Normal file
@@ -0,0 +1,127 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
#ifndef nsIFileStream_h___
|
||||
#define nsIFileStream_h___
|
||||
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "prio.h"
|
||||
|
||||
class nsFileSpec;
|
||||
|
||||
/* a6cf90e8-15b3-11d2-932e-00805f8add32 */
|
||||
#define NS_IFILE_IID \
|
||||
{ 0xa6cf90e8, 0x15b3, 0x11d2, \
|
||||
{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
|
||||
|
||||
//========================================================================================
|
||||
class nsIFile
|
||||
// Represents a file, and supports Open, Tell etc.
|
||||
//========================================================================================
|
||||
: public nsISupports
|
||||
{
|
||||
public:
|
||||
static const nsIID& IID() { static nsIID iid = NS_IFILE_IID; return iid; }
|
||||
NS_IMETHOD Open(
|
||||
const nsFileSpec& inFile,
|
||||
int nsprMode,
|
||||
PRIntn accessMode) = 0;
|
||||
// Note: Open() is only needed after
|
||||
// an explicit Close(). All file streams
|
||||
// are automatically opened on construction.
|
||||
NS_IMETHOD Seek(PRSeekWhence whence, PRInt32 offset) = 0;
|
||||
NS_IMETHOD GetIsOpen(PRBool* outOpen) = 0;
|
||||
NS_IMETHOD Tell(PRIntn* outWhere) = 0;
|
||||
}; // class nsIFile
|
||||
|
||||
/* a6cf90e6-15b3-11d2-932e-00805f8add32 */
|
||||
#define NS_IFILEINPUTSTREAM_IID \
|
||||
{ 0xa6cf90e6, 0x15b3, 0x11d2, \
|
||||
{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
|
||||
|
||||
//========================================================================================
|
||||
class nsIFileInputStream
|
||||
// These are additional file-specific methods that files have, above what
|
||||
// nsIInputStream supports. The current implementation supports both
|
||||
// interfaces.
|
||||
//========================================================================================
|
||||
: public nsISupports
|
||||
{
|
||||
public:
|
||||
static const nsIID& IID() { static nsIID iid = NS_IFILEINPUTSTREAM_IID; return iid; }
|
||||
}; // class nsIFileInputStream
|
||||
|
||||
/* a6cf90e7-15b3-11d2-932e-00805f8add32 */
|
||||
#define NS_IFILEOUTPUTSTREAM_IID \
|
||||
{ 0xa6cf90e7, 0x15b3, 0x11d2, \
|
||||
{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
|
||||
|
||||
//========================================================================================
|
||||
class nsIFileOutputStream
|
||||
// These are additional file-specific methods that files have, above what
|
||||
// nsIOutputStream supports. The current implementation supports both
|
||||
// interfaces.
|
||||
//========================================================================================
|
||||
: public nsISupports
|
||||
{
|
||||
public:
|
||||
static const nsIID& IID() { static nsIID iid = NS_IFILEOUTPUTSTREAM_IID; return iid; }
|
||||
NS_IMETHOD Flush() = 0;
|
||||
// Forces a write to disk.
|
||||
}; // class nsIFileOutputStream
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_BASE nsresult NS_NewTypicalInputFileStream(
|
||||
nsISupports** aStreamResult,
|
||||
const nsFileSpec& inFile
|
||||
/*Default nsprMode == PR_RDONLY*/
|
||||
/*Default accessmode = 0700 (octal)*/);
|
||||
// Factory method to get an nsInputStream from a file, using most common options
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
extern "C" NS_BASE nsresult NS_NewOutputConsoleStream(
|
||||
nsISupports** aStreamResult);
|
||||
// Factory method to get an nsOutputStream to the console.
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
extern "C" NS_BASE nsresult NS_NewTypicalOutputFileStream(
|
||||
nsISupports** aStreamResult, // will implement all the above interfaces
|
||||
const nsFileSpec& inFile
|
||||
/*default nsprMode= (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE)*/
|
||||
/*Default accessMode= 0700 (octal)*/);
|
||||
// Factory method to get an nsOutputStream to a file - most common case.
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
extern "C" NS_BASE nsresult NS_NewTypicalIOFileStream(
|
||||
nsISupports** aStreamResult, // will implement all the above interfaces
|
||||
const nsFileSpec& inFile
|
||||
/*default nsprMode = (PR_RDWR | PR_CREATE_FILE)*/
|
||||
/*Default accessMode = 0700 (octal)*/);
|
||||
// Factory method to get an object that implements both nsIInputStream
|
||||
// and nsIOutputStream, associated with a single file.
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
extern "C" NS_BASE nsresult NS_NewIOFileStream(
|
||||
nsISupports** aStreamResult, // will implement all the above interfaces
|
||||
const nsFileSpec& inFile,
|
||||
PRInt32 nsprMode,
|
||||
PRInt32 accessMode);
|
||||
// Factory method to get an object that implements both nsIInputStream
|
||||
// and nsIOutputStream, associated with a single file.
|
||||
|
||||
#endif /* nsIFileStream_h___ */
|
||||
@@ -39,6 +39,7 @@ CPPSRCS = \
|
||||
nsEscape.cpp \
|
||||
nsFileSpec.cpp \
|
||||
nsFileStream.cpp \
|
||||
nsIFileStream.cpp \
|
||||
nsProperties.cpp \
|
||||
nsRBTree.cpp \
|
||||
nsSizeOfHandler.cpp \
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <Folders.h>
|
||||
#include <Errors.h>
|
||||
#include <TextUtils.h>
|
||||
#include <Processes.h>
|
||||
|
||||
const unsigned char* kAliasHavenFolderName = "\pnsAliasHaven";
|
||||
|
||||
@@ -74,7 +75,7 @@ namespace MacFileHelpers
|
||||
// to support attaching of aliases in mail.
|
||||
void EnsureAliasHaven();
|
||||
void SetNoResolve(Boolean inResolve);
|
||||
bool IsAliasSafe(const FSSpec& inSpec);
|
||||
PRBool IsAliasSafe(const FSSpec& inSpec);
|
||||
OSErr MakeAliasSafe(FSSpec& inOutSpec);
|
||||
OSErr ResolveAliasFile(FSSpec& inOutSpec, Boolean& wasAliased);
|
||||
|
||||
@@ -131,8 +132,8 @@ char* MacFileHelpers::EncodeMacPath(
|
||||
// Method: Swap ':' and '/', hex escape the result
|
||||
//-----------------------------------
|
||||
{
|
||||
if (inPath == NULL)
|
||||
return NULL;
|
||||
if (inPath == nsnull)
|
||||
return nsnull;
|
||||
int pathSize = strlen(inPath);
|
||||
|
||||
// XP code sometimes chokes if there's a final slash in the unix path.
|
||||
@@ -145,8 +146,8 @@ char* MacFileHelpers::EncodeMacPath(
|
||||
pathSize--;
|
||||
}
|
||||
|
||||
char * newPath = NULL;
|
||||
char * finalPath = NULL;
|
||||
char * newPath = nsnull;
|
||||
char * finalPath = nsnull;
|
||||
|
||||
if (prependSlash)
|
||||
{
|
||||
@@ -188,10 +189,10 @@ OSErr MacFileHelpers::MakeAliasSafe(FSSpec& inOutSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
EnsureAliasHaven();
|
||||
nsNativeFileSpec dstDirSpec(sAliasHavenVRefNum, sAliasHavenDirID, "\p");
|
||||
nsFileSpec dstDirSpec(sAliasHavenVRefNum, sAliasHavenDirID, "\p");
|
||||
|
||||
// Make sure its name is unique
|
||||
nsNativeFileSpec havenSpec(sAliasHavenVRefNum, sAliasHavenDirID, "\pG'day");
|
||||
nsFileSpec havenSpec(sAliasHavenVRefNum, sAliasHavenDirID, "\pG'day");
|
||||
if (havenSpec.Valid())
|
||||
havenSpec.MakeUnique(inOutSpec.name);
|
||||
// Copy the file into the haven directory
|
||||
@@ -221,9 +222,9 @@ char* MacFileHelpers::MacPathFromUnixPath(const char* unixPath)
|
||||
{
|
||||
char* dst = result;
|
||||
const char* src = unixPath;
|
||||
if (*src == '/') // ¥ full path
|
||||
if (*src == '/') // * full path
|
||||
src++;
|
||||
else if (strchr(src, '/')) // ¥ partial path, and not just a leaf name
|
||||
else if (strchr(src, '/')) // * partial path, and not just a leaf name
|
||||
*dst++ = ':';
|
||||
strcpy(dst, src);
|
||||
nsUnescape(dst); // Hex Decode
|
||||
@@ -346,7 +347,7 @@ void MacFileHelpers::EnsureAliasHaven()
|
||||
} // MacFileHelpers::EnsureAliasHaven
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool MacFileHelpers::IsAliasSafe(const FSSpec& inSpec)
|
||||
PRBool MacFileHelpers::IsAliasSafe(const FSSpec& inSpec)
|
||||
// Returns true if the alias is in the alias haven directory, or if alias resolution
|
||||
// has been turned off.
|
||||
//----------------------------------------------------------------------------------------
|
||||
@@ -379,7 +380,7 @@ OSErr MacFileHelpers::FSSpecFromFullUnixPath(
|
||||
// then it is combined with inOutSpec's vRefNum and parID to form a new spec.
|
||||
//-----------------------------------
|
||||
{
|
||||
if (unixPath == NULL)
|
||||
if (unixPath == nsnull)
|
||||
return badFidErr;
|
||||
char* macPath = MacPathFromUnixPath(unixPath);
|
||||
if (!macPath)
|
||||
@@ -413,7 +414,7 @@ char* MacFileHelpers::PathNameFromFSSpec( const FSSpec& inSpec, Boolean wantLeaf
|
||||
OSErr err = noErr;
|
||||
|
||||
short fullPathLength = 0;
|
||||
Handle fullPath = NULL;
|
||||
Handle fullPath = nsnull;
|
||||
|
||||
FSSpec tempSpec = inSpec;
|
||||
if ( tempSpec.parID == fsRtParID )
|
||||
@@ -471,7 +472,7 @@ char* MacFileHelpers::PathNameFromFSSpec( const FSSpec& inSpec, Boolean wantLeaf
|
||||
tempSpec.name[tempSpec.name[0]] = ':';
|
||||
|
||||
/* Add directory name to beginning of fullPath */
|
||||
(void) Munger(fullPath, 0, NULL, 0, &tempSpec.name[1], tempSpec.name[0]);
|
||||
(void) Munger(fullPath, 0, nsnull, 0, &tempSpec.name[1], tempSpec.name[0]);
|
||||
err = MemError();
|
||||
}
|
||||
} while ( err == noErr && pb.dirInfo.ioDrDirID != fsRtDirID );
|
||||
@@ -500,19 +501,19 @@ Clean:
|
||||
} // MacFileHelpers::PathNameFromFSSpec
|
||||
|
||||
//========================================================================================
|
||||
// Macintosh nsNativeFileSpec implementation
|
||||
// Macintosh nsFileSpec implementation
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec()
|
||||
nsFileSpec::nsFileSpec()
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mError(noErr)
|
||||
: mError(NS_OK)
|
||||
{
|
||||
mSpec.name[0] = '\0';
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec(const nsNativeFileSpec& inSpec)
|
||||
nsFileSpec::nsFileSpec(const nsFileSpec& inSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mSpec(inSpec.mSpec)
|
||||
, mError(inSpec.Error())
|
||||
@@ -520,87 +521,90 @@ nsNativeFileSpec::nsNativeFileSpec(const nsNativeFileSpec& inSpec)
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec(const char* inString, bool inCreateDirs)
|
||||
nsFileSpec::nsFileSpec(const char* inString, PRBool inCreateDirs)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mError = MacFileHelpers::FSSpecFromFullUnixPath(
|
||||
inString, mSpec, true, true, inCreateDirs);
|
||||
mError = NS_FILE_RESULT(MacFileHelpers::FSSpecFromFullUnixPath(
|
||||
inString, mSpec, false, true, inCreateDirs));
|
||||
// allow a partial path, create as necessary
|
||||
if (mError == fnfErr)
|
||||
mError = noErr;
|
||||
} // nsNativeFileSpec::nsNativeFileSpec
|
||||
if (mError == NS_FILE_RESULT(fnfErr))
|
||||
mError = NS_OK;
|
||||
} // nsFileSpec::nsFileSpec
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec(
|
||||
nsFileSpec::nsFileSpec(
|
||||
short vRefNum,
|
||||
long parID,
|
||||
ConstStr255Param name)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mError = ::FSMakeFSSpec(vRefNum, parID, name, &mSpec);
|
||||
if (mError == fnfErr)
|
||||
mError = NS_FILE_RESULT(::FSMakeFSSpec(vRefNum, parID, name, &mSpec));
|
||||
if (mError == NS_FILE_RESULT(fnfErr))
|
||||
mError = noErr;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec(const nsFilePath& inPath)
|
||||
nsFileSpec::nsFileSpec(const nsFilePath& inPath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
*this = inPath.GetNativeSpec();
|
||||
*this = inPath.GetFileSpec();
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicOutStream& operator << (nsBasicOutStream& s, const nsNativeFileSpec& spec)
|
||||
nsOutputStream& operator << (nsOutputStream& s, const nsFileSpec& spec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
s << spec.mSpec.vRefNum << ", " << spec.mSpec.parID << ", \"";
|
||||
s.write((const char*)&spec.mSpec.name[1], spec.mSpec.name[0]);
|
||||
return s << "\"";
|
||||
} // nsOutputFileStream& operator << (nsOutputFileStream&, const nsNativeFileSpec&)
|
||||
} // nsOutputStream& operator << (nsOutputStream&, const nsFileSpec&)
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator = (const char* inString)
|
||||
void nsFileSpec::operator = (const char* inString)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mError = MacFileHelpers::FSSpecFromFullUnixPath(inString, mSpec, true);
|
||||
} // nsNativeFileSpec::operator =
|
||||
mError = NS_FILE_RESULT(MacFileHelpers::FSSpecFromFullUnixPath(inString, mSpec, false));
|
||||
} // nsFileSpec::operator =
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator = (const nsNativeFileSpec& inSpec)
|
||||
void nsFileSpec::operator = (const nsFileSpec& inSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mSpec = inSpec.mSpec;
|
||||
mError = inSpec.Error();
|
||||
} // nsNativeFileSpec::operator =
|
||||
} // nsFileSpec::operator =
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator = (const nsFilePath& inPath)
|
||||
void nsFileSpec::operator = (const nsFilePath& inPath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
*this = inPath.GetNativeSpec();
|
||||
} // nsNativeFileSpec::operator =
|
||||
*this = inPath.GetFileSpec();
|
||||
} // nsFileSpec::operator =
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::Exists() const
|
||||
PRBool nsFileSpec::Exists() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
FSSpec temp;
|
||||
return ::FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, mSpec.name, &temp) == noErr;
|
||||
} // nsNativeFileSpec::operator =
|
||||
} // nsFileSpec::operator =
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::SetLeafName(const char* inLeafName)
|
||||
void nsFileSpec::SetLeafName(const char* inLeafName)
|
||||
// In leaf name can actually be a partial path...
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// what about long relative paths? Hmm?
|
||||
Str255 partialPath;
|
||||
MacFileHelpers::PLstrcpy(partialPath, inLeafName);
|
||||
mError = FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, partialPath, &mSpec);
|
||||
} // nsNativeFileSpec::SetLeafName
|
||||
mError = NS_FILE_RESULT(
|
||||
::FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, partialPath, &mSpec));
|
||||
} // nsFileSpec::SetLeafName
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
char* nsNativeFileSpec::GetLeafName() const
|
||||
char* nsFileSpec::GetLeafName() const
|
||||
// Result needs to be delete[]ed.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
@@ -608,133 +612,206 @@ char* nsNativeFileSpec::GetLeafName() const
|
||||
memcpy(leaf, &mSpec.name[1], mSpec.name[0]);
|
||||
leaf[mSpec.name[0]] = '\0';
|
||||
return nsFileSpecHelpers::StringDup(leaf);
|
||||
} // nsNativeFileSpec::GetLeafName
|
||||
} // nsFileSpec::GetLeafName
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::MakeAliasSafe()
|
||||
void nsFileSpec::MakeAliasSafe()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mError = MacFileHelpers::MakeAliasSafe(mSpec);
|
||||
} // nsNativeFileSpec::MakeAliasSafe
|
||||
mError = NS_FILE_RESULT(MacFileHelpers::MakeAliasSafe(mSpec));
|
||||
} // nsFileSpec::MakeAliasSafe
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::MakeUnique(ConstStr255Param inSuggestedLeafName)
|
||||
void nsFileSpec::MakeUnique(ConstStr255Param inSuggestedLeafName)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (inSuggestedLeafName[0] > 0)
|
||||
MacFileHelpers::PLstrcpy(mSpec.name, inSuggestedLeafName);
|
||||
|
||||
MakeUnique();
|
||||
} // nsNativeFileSpec::MakeUnique
|
||||
} // nsFileSpec::MakeUnique
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::ResolveAlias(bool& wasAliased)
|
||||
void nsFileSpec::ResolveAlias(PRBool& wasAliased)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
Boolean wasAliased2;
|
||||
mError = MacFileHelpers::ResolveAliasFile(mSpec, wasAliased2);
|
||||
mError = NS_FILE_RESULT(MacFileHelpers::ResolveAliasFile(mSpec, wasAliased2));
|
||||
wasAliased = (wasAliased2 != false);
|
||||
} // nsNativeFileSpec::ResolveAlias
|
||||
} // nsFileSpec::ResolveAlias
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::IsFile() const
|
||||
PRBool nsFileSpec::IsFile() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
long dirID;
|
||||
Boolean isDirectory;
|
||||
return (noErr == FSpGetDirectoryID(&mSpec, &dirID, &isDirectory) && !isDirectory);
|
||||
} // nsNativeFileSpec::IsFile
|
||||
} // nsFileSpec::IsFile
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::IsDirectory() const
|
||||
PRBool nsFileSpec::IsDirectory() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
long dirID;
|
||||
Boolean isDirectory;
|
||||
return (noErr == FSpGetDirectoryID(&mSpec, &dirID, &isDirectory) && isDirectory);
|
||||
} // nsNativeFileSpec::IsDirectory
|
||||
} // nsFileSpec::IsDirectory
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::GetParent(nsNativeFileSpec& outSpec) const
|
||||
void nsFileSpec::GetParent(nsFileSpec& outSpec) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (mError == noErr)
|
||||
outSpec.mError = FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, NULL, outSpec);
|
||||
} // nsNativeFileSpec::GetParent
|
||||
if (NS_SUCCEEDED(mError))
|
||||
outSpec.mError
|
||||
= NS_FILE_RESULT(::FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, nsnull, outSpec));
|
||||
} // nsFileSpec::GetParent
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator += (const char* inRelativePath)
|
||||
void nsFileSpec::operator += (const char* inRelativePath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
long dirID;
|
||||
Boolean isDirectory;
|
||||
mError = FSpGetDirectoryID(&mSpec, &dirID, &isDirectory);
|
||||
if (mError == noErr && isDirectory)
|
||||
mError = NS_FILE_RESULT(::FSpGetDirectoryID(&mSpec, &dirID, &isDirectory));
|
||||
if (NS_SUCCEEDED(mError) && isDirectory)
|
||||
{
|
||||
Str255 partialPath;
|
||||
MacFileHelpers::PLstrcpy(partialPath, inRelativePath);
|
||||
mError = FSMakeFSSpec(mSpec.vRefNum, dirID, partialPath, *this);
|
||||
//if (mError == noErr)
|
||||
mError = NS_FILE_RESULT(::FSMakeFSSpec(mSpec.vRefNum, dirID, partialPath, *this));
|
||||
//if (NS_SUCCEEDED(mError))
|
||||
// SetLeafName(inRelativePath);
|
||||
}
|
||||
} // nsNativeFileSpec::operator +=
|
||||
} // nsFileSpec::operator +=
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::CreateDirectory(int /* unix mode */)
|
||||
void nsFileSpec::CreateDirectory(int /* unix mode */)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
long ignoredDirID;
|
||||
FSpDirCreate(&mSpec, smCurrentScript, &ignoredDirID);
|
||||
} // nsNativeFileSpec::CreateDirectory
|
||||
} // nsFileSpec::CreateDirectory
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::Delete(bool inRecursive)
|
||||
void nsFileSpec::Delete(PRBool inRecursive)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (inRecursive)
|
||||
{
|
||||
// MoreFilesExtras
|
||||
mError = DeleteDirectory(
|
||||
mError = NS_FILE_RESULT(::DeleteDirectory(
|
||||
mSpec.vRefNum,
|
||||
mSpec.parID,
|
||||
const_cast<unsigned char*>(mSpec.name));
|
||||
const_cast<unsigned char*>(mSpec.name)));
|
||||
}
|
||||
else
|
||||
mError = FSpDelete(&mSpec);
|
||||
} // nsNativeFileSpec::Delete
|
||||
mError = NS_FILE_RESULT(FSpDelete(&mSpec));
|
||||
} // nsFileSpec::Delete
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult nsFileSpec::Rename(const char* inNewName)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (strchr(inNewName, '/'))
|
||||
return -1; // no relative paths here!
|
||||
Str255 pName;
|
||||
MacFileHelpers::PLstrcpy(pName, inNewName);
|
||||
if (FSpRename(&mSpec, pName) != noErr)
|
||||
return -1;
|
||||
SetLeafName(inNewName);
|
||||
return 0;
|
||||
} // nsFileSpec::Rename
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult nsFileSpec::Copy(const nsFileSpec& newParentDir) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// We can only copy into a directory, and (for now) can not copy entire directories
|
||||
|
||||
if (!newParentDir.IsDirectory() || (IsDirectory() ) )
|
||||
return NS_FILE_FAILURE;
|
||||
|
||||
|
||||
nsresult result = NS_FILE_RESULT(::FSpFileCopy( &mSpec,
|
||||
&newParentDir.mSpec,
|
||||
const_cast<StringPtr>(GetLeafPName()),
|
||||
nsnull,
|
||||
0,
|
||||
true));
|
||||
|
||||
return result;
|
||||
|
||||
} // nsFileSpec::Copy
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult nsFileSpec::Move(const nsFileSpec& newParentDir) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// We can only move into a directory
|
||||
|
||||
if (!newParentDir.IsDirectory())
|
||||
return NS_FILE_FAILURE;
|
||||
|
||||
nsresult result = NS_FILE_RESULT(::FSpMoveRenameCompat(&mSpec,
|
||||
&newParentDir.mSpec,
|
||||
const_cast<StringPtr>(GetLeafPName())));
|
||||
|
||||
return result;
|
||||
} // nsFileSpec::Move
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult nsFileSpec::Execute(const char* /*args - how can this be cross-platform? problem! */ ) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (IsDirectory())
|
||||
return NS_FILE_FAILURE;
|
||||
|
||||
LaunchParamBlockRec launchThis;
|
||||
launchThis.launchAppSpec = const_cast<FSSpec*>(&mSpec);
|
||||
launchThis.launchAppParameters = nsnull; // args;
|
||||
/* launch the thing */
|
||||
launchThis.launchBlockID = extendedBlock;
|
||||
launchThis.launchEPBLength = extendedBlockLen;
|
||||
launchThis.launchFileFlags = nsnull;
|
||||
launchThis.launchControlFlags = launchContinue + launchNoFileFlags + launchUseMinimum;
|
||||
launchThis.launchControlFlags += launchDontSwitch;
|
||||
|
||||
nsresult result = NS_FILE_RESULT(::LaunchApplication(&launchThis));
|
||||
return result;
|
||||
|
||||
} // nsFileSpec::Execute
|
||||
|
||||
//========================================================================================
|
||||
// Macintosh nsFilePath implementation
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFilePath::nsFilePath(const char* inString, bool inCreateDirs)
|
||||
nsFilePath::nsFilePath(const char* inString, PRBool inCreateDirs)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(nsnull)
|
||||
, mNativeFileSpec(inString, inCreateDirs)
|
||||
, mFileSpec(inString, inCreateDirs)
|
||||
{
|
||||
// Make canonical and absolute.
|
||||
char * path = MacFileHelpers::PathNameFromFSSpec( mNativeFileSpec, TRUE );
|
||||
char * path = MacFileHelpers::PathNameFromFSSpec( mFileSpec, TRUE );
|
||||
mPath = MacFileHelpers::EncodeMacPath(path, true, true);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFilePath::nsFilePath(const nsNativeFileSpec& inSpec)
|
||||
nsFilePath::nsFilePath(const nsFileSpec& inSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mNativeFileSpec(inSpec)
|
||||
: mFileSpec(inSpec)
|
||||
{
|
||||
char * path = MacFileHelpers::PathNameFromFSSpec( inSpec.mSpec, TRUE );
|
||||
mPath = MacFileHelpers::EncodeMacPath(path, true, true);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsFilePath::operator = (const nsNativeFileSpec& inSpec)
|
||||
void nsFilePath::operator = (const nsFileSpec& inSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
delete [] mPath;
|
||||
char * path = MacFileHelpers::PathNameFromFSSpec( inSpec.mSpec, TRUE );
|
||||
mPath = MacFileHelpers::EncodeMacPath(path, true, true);
|
||||
mNativeFileSpec = inSpec;
|
||||
mFileSpec = inSpec;
|
||||
} // nsFilePath::operator =
|
||||
|
||||
//========================================================================================
|
||||
@@ -742,14 +819,14 @@ void nsFilePath::operator = (const nsNativeFileSpec& inSpec)
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFileURL::nsFileURL(const char* inString, bool inCreateDirs)
|
||||
nsFileURL::nsFileURL(const char* inString, PRBool inCreateDirs)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mURL(nsnull)
|
||||
, mNativeFileSpec(inString + kFileURLPrefixLength, inCreateDirs)
|
||||
, mFileSpec(inString + kFileURLPrefixLength, inCreateDirs)
|
||||
{
|
||||
NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!");
|
||||
// Make canonical and absolute.
|
||||
char* path = MacFileHelpers::PathNameFromFSSpec( mNativeFileSpec, TRUE );
|
||||
char* path = MacFileHelpers::PathNameFromFSSpec( mFileSpec, TRUE );
|
||||
char* escapedPath = MacFileHelpers::EncodeMacPath(path, true, true);
|
||||
mURL = nsFileSpecHelpers::StringDup(kFileURLPrefix, kFileURLPrefixLength + strlen(escapedPath));
|
||||
strcat(mURL, escapedPath);
|
||||
@@ -762,7 +839,7 @@ nsFileURL::nsFileURL(const char* inString, bool inCreateDirs)
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator::nsDirectoryIterator(
|
||||
const nsNativeFileSpec& inDirectory
|
||||
const nsFileSpec& inDirectory
|
||||
, int inIterateDirection)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mCurrent(inDirectory)
|
||||
@@ -772,7 +849,7 @@ nsDirectoryIterator::nsDirectoryIterator(
|
||||
CInfoPBRec pb;
|
||||
DirInfo* dipb = (DirInfo*)&pb;
|
||||
// Sorry about this, there seems to be a bug in CWPro 4:
|
||||
const FSSpec& inSpec = inDirectory.nsNativeFileSpec::operator const FSSpec&();
|
||||
const FSSpec& inSpec = inDirectory.nsFileSpec::operator const FSSpec&();
|
||||
Str255 outName;
|
||||
MacFileHelpers::PLstrcpy(outName, inSpec.name);
|
||||
pb.hFileInfo.ioNamePtr = outName;
|
||||
@@ -786,7 +863,7 @@ nsDirectoryIterator::nsDirectoryIterator(
|
||||
if ( (err != noErr ) || !( dipb->ioFlAttrib & 0x0010 ) )
|
||||
return;
|
||||
// Sorry about this, there seems to be a bug in CWPro 4:
|
||||
FSSpec& currentSpec = mCurrent.nsNativeFileSpec::operator FSSpec&();
|
||||
FSSpec& currentSpec = mCurrent.nsFileSpec::operator FSSpec&();
|
||||
currentSpec.vRefNum = inSpec.vRefNum;
|
||||
currentSpec.parID = dipb->ioDrDirID;
|
||||
mMaxIndex = pb.dirInfo.ioDrNmFls;
|
||||
@@ -809,10 +886,10 @@ OSErr nsDirectoryIterator::SetToIndex()
|
||||
CInfoPBRec cipb;
|
||||
DirInfo *dipb=(DirInfo *)&cipb;
|
||||
Str255 objectName;
|
||||
dipb->ioCompletion = NULL;
|
||||
dipb->ioCompletion = nsnull;
|
||||
dipb->ioFDirIndex = mIndex;
|
||||
// Sorry about this, there seems to be a bug in CWPro 4:
|
||||
FSSpec& currentSpec = mCurrent.nsNativeFileSpec::operator FSSpec&();
|
||||
FSSpec& currentSpec = mCurrent.nsFileSpec::operator FSSpec&();
|
||||
dipb->ioVRefNum = currentSpec.vRefNum; /* Might need to use vRefNum, not sure*/
|
||||
dipb->ioDrDirID = currentSpec.parID;
|
||||
dipb->ioNamePtr = objectName;
|
||||
|
||||
@@ -41,6 +41,7 @@ CPPSRCS = \
|
||||
nsFileSpec.cpp \
|
||||
nsFileStream.cpp \
|
||||
nsEscape.cpp \
|
||||
nsIFileStream.cpp \
|
||||
$(NULL)
|
||||
|
||||
CPP_OBJS = \
|
||||
@@ -61,6 +62,7 @@ CPP_OBJS = \
|
||||
.\$(OBJDIR)\nsFileSpec.obj \
|
||||
.\$(OBJDIR)\nsFileStream.obj \
|
||||
.\$(OBJDIR)\nsEscape.obj \
|
||||
.\$(OBJDIR)\nsIFileStream.obj \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS=nscore.h nsIArena.h nsIAtom.h nsIByteBuffer.h \
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
#include "nsDebug.h"
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "plstr.h"
|
||||
#include "plbase64.h"
|
||||
#include "prmem.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@@ -40,7 +43,7 @@ NS_NAMESPACE nsFileSpecHelpers
|
||||
char inSeparator,
|
||||
const char* inLeafName);
|
||||
#ifndef XP_MAC
|
||||
NS_NAMESPACE_PROTOTYPE void Canonify(char*& ioPath, bool inMakeDirs);
|
||||
NS_NAMESPACE_PROTOTYPE void Canonify(char*& ioPath, PRBool inMakeDirs);
|
||||
NS_NAMESPACE_PROTOTYPE void MakeAllDirectories(const char* inPath, int mode);
|
||||
#endif
|
||||
NS_NAMESPACE_PROTOTYPE char* GetLeaf(const char* inPath, char inSeparator); // allocated
|
||||
@@ -54,6 +57,14 @@ NS_NAMESPACE nsFileSpecHelpers
|
||||
#endif
|
||||
} NS_NAMESPACE_END
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult ns_file_convert_result(PRInt32 nativeErr)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return nativeErr ?
|
||||
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES,((nativeErr)&0xFFFF))
|
||||
: NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
char* nsFileSpecHelpers::StringDup(
|
||||
@@ -65,7 +76,7 @@ char* nsFileSpecHelpers::StringDup(
|
||||
allocLength = strlen(inString);
|
||||
char* newPath = inString || allocLength ? new char[allocLength + 1] : nsnull;
|
||||
if (!newPath)
|
||||
return NULL;
|
||||
return nsnull;
|
||||
strcpy(newPath, inString);
|
||||
return newPath;
|
||||
} // nsFileSpecHelpers::StringDup
|
||||
@@ -77,7 +88,7 @@ char* nsFileSpecHelpers::AllocCat(
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!inString1)
|
||||
return inString2 ? StringDup(inString2) : (char*)NULL;
|
||||
return inString2 ? StringDup(inString2) : (char*)nsnull;
|
||||
if (!inString2)
|
||||
return StringDup(inString1);
|
||||
char* outString = StringDup(inString1, strlen(inString1) + strlen(inString2));
|
||||
@@ -95,7 +106,7 @@ char* nsFileSpecHelpers::StringAssign(
|
||||
if (!inString2)
|
||||
{
|
||||
delete [] ioString;
|
||||
ioString = (char*)NULL;
|
||||
ioString = (char*)nsnull;
|
||||
return ioString;
|
||||
}
|
||||
if (!ioString || (strlen(inString2) > strlen(ioString)))
|
||||
@@ -125,8 +136,19 @@ void nsFileSpecHelpers::LeafReplace(
|
||||
}
|
||||
char* lastSeparator = strrchr(ioPath, inSeparator);
|
||||
int oldLength = strlen(ioPath);
|
||||
*(++lastSeparator) = '\0'; // strip the current leaf name
|
||||
int newLength = lastSeparator - ioPath + strlen(inLeafName);
|
||||
PRBool trailingSeparator = (lastSeparator + 1 == ioPath + oldLength);
|
||||
if (trailingSeparator)
|
||||
{
|
||||
*lastSeparator = '\0';
|
||||
lastSeparator = strrchr(ioPath, inSeparator);
|
||||
}
|
||||
if (lastSeparator)
|
||||
lastSeparator++; // point at the trailing string
|
||||
else
|
||||
lastSeparator = ioPath; // the full monty
|
||||
*lastSeparator = '\0'; // strip the current leaf name
|
||||
|
||||
int newLength = (lastSeparator - ioPath) + strlen(inLeafName) + int(trailingSeparator);
|
||||
if (newLength > oldLength)
|
||||
{
|
||||
char* newPath = StringDup(ioPath, newLength + 1);
|
||||
@@ -134,7 +156,14 @@ void nsFileSpecHelpers::LeafReplace(
|
||||
ioPath = newPath;
|
||||
}
|
||||
strcat(ioPath, inLeafName);
|
||||
} // nsNativeFileSpec::LeafReplace
|
||||
if (trailingSeparator)
|
||||
{
|
||||
// If the original ended in a slash, then the new one should, too.
|
||||
char sepStr[2] = "/";
|
||||
*sepStr = inSeparator;
|
||||
strcat(ioPath, sepStr);
|
||||
}
|
||||
} // nsFileSpecHelpers::LeafReplace
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
char* nsFileSpecHelpers::GetLeaf(const char* inPath, char inSeparator)
|
||||
@@ -142,12 +171,32 @@ char* nsFileSpecHelpers::GetLeaf(const char* inPath, char inSeparator)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!inPath)
|
||||
return NULL;
|
||||
char* lastSeparator = strrchr(inPath, inSeparator);
|
||||
if (lastSeparator)
|
||||
return StringDup(++lastSeparator);
|
||||
return StringDup(inPath);
|
||||
} // nsNativeFileSpec::GetLeaf
|
||||
return nsnull;
|
||||
const char* lastSeparator = strrchr(inPath, inSeparator);
|
||||
|
||||
// If there was no separator, then return a copy of the caller's path.
|
||||
if (!lastSeparator)
|
||||
return StringDup(inPath);
|
||||
|
||||
// So there's at least one separator. What's just after it?
|
||||
// If the separator was not the last character, return the trailing string.
|
||||
const char* leafPointer = lastSeparator + 1;
|
||||
if (*leafPointer)
|
||||
return StringDup(leafPointer);
|
||||
|
||||
// So now, separator was the last character. Poke in a null instead.
|
||||
*(char*)lastSeparator = '\0'; // Should use const_cast, but Unix has old compiler.
|
||||
leafPointer = strrchr(inPath, inSeparator);
|
||||
char* result = leafPointer ? StringDup(leafPointer++) : StringDup(inPath);
|
||||
// Restore the poked null before returning.
|
||||
*(char*)lastSeparator = inSeparator;
|
||||
#ifdef XP_PC
|
||||
// If it's a drive letter use the colon notation.
|
||||
if (!leafPointer && strlen(result) == 2 && result[1] == '|')
|
||||
result[1] = ':';
|
||||
#endif
|
||||
return result;
|
||||
} // nsFileSpecHelpers::GetLeaf
|
||||
|
||||
#if defined(XP_UNIX) || defined(XP_PC)
|
||||
|
||||
@@ -177,7 +226,7 @@ void nsFileSpecHelpers::MakeAllDirectories(const char* inPath, int mode)
|
||||
if (currentEnd)
|
||||
{
|
||||
*currentEnd = '\0';
|
||||
nsNativeFileSpec spec(nsFilePath(pathCopy, false));
|
||||
nsFileSpec spec(nsFilePath(pathCopy, PR_FALSE));
|
||||
do
|
||||
{
|
||||
// If the node doesn't exist, and it is not the initial node in a full path,
|
||||
@@ -209,7 +258,7 @@ char* nsFileSpecHelpers::ReallocCat(char*& ioString, const char* inString1)
|
||||
delete [] ioString;
|
||||
ioString = newString;
|
||||
return ioString;
|
||||
} // nsNativeFileSpec::ReallocCat
|
||||
} // nsFileSpecHelpers::ReallocCat
|
||||
|
||||
#if defined(XP_PC)
|
||||
#include "windows/nsFileSpecWin.cpp" // Windows-specific implementations
|
||||
@@ -225,7 +274,7 @@ char* nsFileSpecHelpers::ReallocCat(char*& ioString, const char* inString1)
|
||||
|
||||
#ifndef XP_MAC
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFileURL::nsFileURL(const char* inString, bool inCreateDirs)
|
||||
nsFileURL::nsFileURL(const char* inString, PRBool inCreateDirs)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mURL(nsnull)
|
||||
{
|
||||
@@ -243,7 +292,7 @@ nsFileURL::nsFileURL(const nsFileURL& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mURL(nsFileSpecHelpers::StringDup(inOther.mURL))
|
||||
#ifdef XP_MAC
|
||||
, mNativeFileSpec(inOther.GetNativeSpec())
|
||||
, mFileSpec(inOther.GetFileSpec())
|
||||
#endif
|
||||
{
|
||||
} // nsFileURL::nsFileURL
|
||||
@@ -253,16 +302,16 @@ nsFileURL::nsFileURL(const nsFilePath& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mURL(nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)inOther))
|
||||
#ifdef XP_MAC
|
||||
, mNativeFileSpec(inOther.GetNativeSpec())
|
||||
, mFileSpec(inOther.GetFileSpec())
|
||||
#endif
|
||||
{
|
||||
} // nsFileURL::nsFileURL
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFileURL::nsFileURL(const nsNativeFileSpec& inOther)
|
||||
nsFileURL::nsFileURL(const nsFileSpec& inOther)
|
||||
: mURL(nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)nsFilePath(inOther)))
|
||||
#ifdef XP_MAC
|
||||
, mNativeFileSpec(inOther)
|
||||
, mFileSpec(inOther)
|
||||
#endif
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
@@ -282,7 +331,7 @@ void nsFileURL::operator = (const char* inString)
|
||||
nsFileSpecHelpers::StringAssign(mURL, inString);
|
||||
NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!");
|
||||
#ifdef XP_MAC
|
||||
mNativeFileSpec = inString + kFileURLPrefixLength;
|
||||
mFileSpec = inString + kFileURLPrefixLength;
|
||||
#endif
|
||||
} // nsFileURL::operator =
|
||||
|
||||
@@ -292,7 +341,7 @@ void nsFileURL::operator = (const nsFileURL& inOther)
|
||||
{
|
||||
mURL = nsFileSpecHelpers::StringAssign(mURL, inOther.mURL);
|
||||
#ifdef XP_MAC
|
||||
mNativeFileSpec = inOther.GetNativeSpec();
|
||||
mFileSpec = inOther.GetFileSpec();
|
||||
#endif
|
||||
} // nsFileURL::operator =
|
||||
|
||||
@@ -303,27 +352,29 @@ void nsFileURL::operator = (const nsFilePath& inOther)
|
||||
delete [] mURL;
|
||||
mURL = nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)inOther);
|
||||
#ifdef XP_MAC
|
||||
mNativeFileSpec = inOther.GetNativeSpec();
|
||||
mFileSpec = inOther.GetFileSpec();
|
||||
#endif
|
||||
} // nsFileURL::operator =
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsFileURL::operator = (const nsNativeFileSpec& inOther)
|
||||
void nsFileURL::operator = (const nsFileSpec& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
delete [] mURL;
|
||||
mURL = nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)nsFilePath(inOther));
|
||||
#ifdef XP_MAC
|
||||
mNativeFileSpec = inOther;
|
||||
mFileSpec = inOther;
|
||||
#endif
|
||||
} // nsFileURL::operator =
|
||||
|
||||
#if DEBUG
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicOutStream& operator << (nsBasicOutStream& s, const nsFileURL& url)
|
||||
nsOutputStream& operator << (nsOutputStream& s, const nsFileURL& url)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return (s << url.mURL);
|
||||
}
|
||||
#endif
|
||||
|
||||
//========================================================================================
|
||||
// nsFilePath implementation
|
||||
@@ -332,14 +383,14 @@ nsBasicOutStream& operator << (nsBasicOutStream& s, const nsFileURL& url)
|
||||
nsFilePath::nsFilePath(const nsFilePath& inPath)
|
||||
: mPath(nsFileSpecHelpers::StringDup(inPath.mPath))
|
||||
#ifdef XP_MAC
|
||||
, mNativeFileSpec(inPath.mNativeFileSpec)
|
||||
, mFileSpec(inPath.mFileSpec)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
#ifndef XP_MAC
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFilePath::nsFilePath(const char* inString, bool inCreateDirs)
|
||||
nsFilePath::nsFilePath(const char* inString, PRBool inCreateDirs)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(nsFileSpecHelpers::StringDup(inString))
|
||||
{
|
||||
@@ -362,14 +413,14 @@ nsFilePath::nsFilePath(const nsFileURL& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(nsFileSpecHelpers::StringDup(inOther.mURL + kFileURLPrefixLength))
|
||||
#ifdef XP_MAC
|
||||
, mNativeFileSpec(inOther.GetNativeSpec())
|
||||
, mFileSpec(inOther.GetFileSpec())
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef XP_UNIX
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFilePath::nsFilePath(const nsNativeFileSpec& inOther)
|
||||
nsFilePath::nsFilePath(const nsFileSpec& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(nsFileSpecHelpers::StringDup(inOther.mPath))
|
||||
{
|
||||
@@ -385,7 +436,7 @@ nsFilePath::~nsFilePath()
|
||||
|
||||
#ifdef XP_UNIX
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsFilePath::operator = (const nsNativeFileSpec& inOther)
|
||||
void nsFilePath::operator = (const nsFileSpec& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mPath = nsFileSpecHelpers::StringAssign(mPath, inOther.mPath);
|
||||
@@ -398,14 +449,14 @@ void nsFilePath::operator = (const char* inString)
|
||||
{
|
||||
NS_ASSERTION(strstr(inString, kFileURLPrefix) != inString, "URL passed as path");
|
||||
#ifdef XP_MAC
|
||||
mNativeFileSpec = inString;
|
||||
nsFileSpecHelpers::StringAssign(mPath, (const char*)nsFilePath(mNativeFileSpec));
|
||||
mFileSpec = inString;
|
||||
nsFileSpecHelpers::StringAssign(mPath, (const char*)nsFilePath(mFileSpec));
|
||||
#else
|
||||
#ifdef XP_PC
|
||||
nsFileSpecHelpers::UnixToNative(mPath);
|
||||
#endif
|
||||
// Make canonical and absolute.
|
||||
nsFileSpecHelpers::Canonify(mPath, false /* XXX? */);
|
||||
nsFileSpecHelpers::Canonify(mPath, PR_FALSE /* XXX? */);
|
||||
#ifdef XP_PC
|
||||
nsFileSpecHelpers::NativeToUnix(mPath);
|
||||
#endif
|
||||
@@ -418,7 +469,7 @@ void nsFilePath::operator = (const nsFileURL& inOther)
|
||||
{
|
||||
nsFileSpecHelpers::StringAssign(mPath, (const char*)nsFilePath(inOther));
|
||||
#ifdef XP_MAC
|
||||
mNativeFileSpec = inOther.GetNativeSpec();
|
||||
mFileSpec = inOther.GetFileSpec();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -433,40 +484,51 @@ void nsFilePath::operator = (const nsFilePath& inOther)
|
||||
}
|
||||
|
||||
//========================================================================================
|
||||
// nsNativeFileSpec implementation
|
||||
// nsFileSpec implementation
|
||||
//========================================================================================
|
||||
|
||||
#ifndef XP_MAC
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec()
|
||||
nsFileSpec::nsFileSpec()
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(NULL)
|
||||
: mPath(nsnull)
|
||||
, mError(NS_OK)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec(const nsFileURL& inURL)
|
||||
nsFileSpec::nsFileSpec(const nsPersistentFileDescriptor& inDescriptor)
|
||||
//----------------------------------------------------------------------------------------
|
||||
#ifndef XP_MAC
|
||||
: mPath(NULL)
|
||||
: mPath(nsnull)
|
||||
#endif
|
||||
{
|
||||
*this = inDescriptor;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFileSpec::nsFileSpec(const nsFileURL& inURL)
|
||||
//----------------------------------------------------------------------------------------
|
||||
#ifndef XP_MAC
|
||||
: mPath(nsnull)
|
||||
#endif
|
||||
{
|
||||
*this = nsFilePath(inURL); // convert to unix path first
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::MakeUnique(const char* inSuggestedLeafName)
|
||||
void nsFileSpec::MakeUnique(const char* inSuggestedLeafName)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (inSuggestedLeafName && *inSuggestedLeafName)
|
||||
SetLeafName(inSuggestedLeafName);
|
||||
|
||||
MakeUnique();
|
||||
} // nsNativeFileSpec::MakeUnique
|
||||
} // nsFileSpec::MakeUnique
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::MakeUnique()
|
||||
void nsFileSpec::MakeUnique()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!Exists())
|
||||
@@ -497,51 +559,82 @@ void nsNativeFileSpec::MakeUnique()
|
||||
if (*suffix)
|
||||
delete [] suffix;
|
||||
delete [] leafName;
|
||||
} // nsNativeFileSpec::MakeUnique
|
||||
} // nsFileSpec::MakeUnique
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator = (const nsFileURL& inURL)
|
||||
void nsFileSpec::operator = (const nsFileURL& inURL)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
*this = nsFilePath(inURL); // convert to unix path first
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsFileSpec::operator = (const nsPersistentFileDescriptor& inDescriptor)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
|
||||
void* data;
|
||||
PRInt32 dataSize;
|
||||
inDescriptor.GetData(data, dataSize);
|
||||
|
||||
#ifdef XP_MAC
|
||||
char* decodedData = PL_Base64Decode((const char*)data, (int)dataSize, nsnull);
|
||||
// Cast to an alias record and resolve.
|
||||
AliasHandle aliasH = nsnull;
|
||||
mError = NS_FILE_RESULT(PtrToHand(decodedData, &(Handle)aliasH, (dataSize * 3) / 4));
|
||||
PR_Free(decodedData);
|
||||
if (NS_SUCCEEDED(mError))
|
||||
return; // not enough memory?
|
||||
|
||||
Boolean changed;
|
||||
mError = NS_FILE_RESULT(::ResolveAlias(nsnull, aliasH, &mSpec, &changed));
|
||||
DisposeHandle((Handle) aliasH);
|
||||
#else
|
||||
nsFileSpecHelpers::StringAssign(mPath, (char*)data);
|
||||
mError = NS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
//========================================================================================
|
||||
// UNIX & WIN nsNativeFileSpec implementation
|
||||
// UNIX & WIN nsFileSpec implementation
|
||||
//========================================================================================
|
||||
|
||||
#ifdef XP_UNIX
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec(const nsFilePath& inPath)
|
||||
nsFileSpec::nsFileSpec(const nsFilePath& inPath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(nsFileSpecHelpers::StringDup((const char*)inPath))
|
||||
, mError(NS_OK)
|
||||
{
|
||||
}
|
||||
#endif // XP_UNIX
|
||||
|
||||
#ifdef XP_UNIX
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator = (const nsFilePath& inPath)
|
||||
void nsFileSpec::operator = (const nsFilePath& inPath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::StringAssign(mPath, (const char*)inPath);
|
||||
mError = NS_OK;
|
||||
}
|
||||
#endif //XP_UNIX
|
||||
|
||||
#if defined(XP_UNIX) || defined(XP_PC)
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec(const nsNativeFileSpec& inSpec)
|
||||
nsFileSpec::nsFileSpec(const nsFileSpec& inSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(nsFileSpecHelpers::StringDup(inSpec.mPath))
|
||||
, mError(NS_OK)
|
||||
{
|
||||
}
|
||||
#endif //XP_UNIX
|
||||
|
||||
#if defined(XP_UNIX) || defined(XP_PC)
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec(const char* inString, bool inCreateDirs)
|
||||
nsFileSpec::nsFileSpec(const char* inString, PRBool inCreateDirs)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(nsFileSpecHelpers::StringDup(inString))
|
||||
, mError(NS_OK)
|
||||
{
|
||||
// Make canonical and absolute.
|
||||
nsFileSpecHelpers::Canonify(mPath, inCreateDirs);
|
||||
@@ -549,7 +642,7 @@ nsNativeFileSpec::nsNativeFileSpec(const char* inString, bool inCreateDirs)
|
||||
#endif //XP_UNIX,PC
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::~nsNativeFileSpec()
|
||||
nsFileSpec::~nsFileSpec()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
#ifndef XP_MAC
|
||||
@@ -559,39 +652,160 @@ nsNativeFileSpec::~nsNativeFileSpec()
|
||||
|
||||
#if defined(XP_UNIX) || defined(XP_PC)
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator = (const nsNativeFileSpec& inSpec)
|
||||
void nsFileSpec::operator = (const nsFileSpec& inSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mPath = nsFileSpecHelpers::StringAssign(mPath, inSpec.mPath);
|
||||
mError = inSpec.Error();
|
||||
}
|
||||
#endif //XP_UNIX
|
||||
|
||||
|
||||
#if defined(XP_UNIX) || defined(XP_PC)
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator = (const char* inString)
|
||||
void nsFileSpec::operator = (const char* inString)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mPath = nsFileSpecHelpers::StringAssign(mPath, inString);
|
||||
// Make canonical and absolute.
|
||||
nsFileSpecHelpers::Canonify(mPath, true /* XXX? */);
|
||||
nsFileSpecHelpers::Canonify(mPath, PR_TRUE /* XXX? */);
|
||||
mError = NS_OK;
|
||||
}
|
||||
#endif //XP_UNIX
|
||||
|
||||
#if DEBUG
|
||||
#if (defined(XP_UNIX) || defined(XP_PC))
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicOutStream& operator << (nsBasicOutStream& s, const nsNativeFileSpec& spec)
|
||||
nsOutputStream& operator << (nsOutputStream& s, const nsFileSpec& spec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return (s << (const char*)spec.mPath);
|
||||
}
|
||||
#endif // DEBUG && XP_UNIX
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec nsNativeFileSpec::operator + (const char* inRelativePath) const
|
||||
nsFileSpec nsFileSpec::operator + (const char* inRelativePath) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsNativeFileSpec result = *this;
|
||||
nsFileSpec result = *this;
|
||||
result += inRelativePath;
|
||||
return result;
|
||||
} // nsNativeFileSpec::operator +
|
||||
} // nsFileSpec::operator +
|
||||
|
||||
//========================================================================================
|
||||
// class nsPersistentFileDescriptor
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsPersistentFileDescriptor::nsPersistentFileDescriptor(const nsPersistentFileDescriptor& inDesc)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mDescriptorString(nsFileSpecHelpers::StringDup(inDesc.mDescriptorString))
|
||||
{
|
||||
} // nsPersistentFileDescriptor::nsPersistentFileDescriptor
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsPersistentFileDescriptor::operator = (const nsPersistentFileDescriptor& inDesc)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::StringAssign(mDescriptorString, inDesc.mDescriptorString);
|
||||
} // nsPersistentFileDescriptor::operator =
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsPersistentFileDescriptor::nsPersistentFileDescriptor(const nsFileSpec& inSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mDescriptorString(nsnull)
|
||||
{
|
||||
*this = inSpec;
|
||||
} // nsPersistentFileDescriptor::nsPersistentFileDescriptor
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsPersistentFileDescriptor::operator = (const nsFileSpec& inSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
#ifdef XP_MAC
|
||||
if (inSpec.Error())
|
||||
return;
|
||||
AliasHandle aliasH;
|
||||
OSErr err = NewAlias(nil, inSpec.operator const FSSpec* const (), &aliasH);
|
||||
if (err != noErr)
|
||||
return;
|
||||
|
||||
PRUint32 bytes = GetHandleSize((Handle) aliasH);
|
||||
HLock((Handle) aliasH);
|
||||
char* buf = PL_Base64Encode((const char*)*aliasH, bytes, nsnull);
|
||||
DisposeHandle((Handle) aliasH);
|
||||
|
||||
nsFileSpecHelpers::StringAssign(mDescriptorString, buf);
|
||||
PR_Free(buf);
|
||||
#else
|
||||
nsFileSpecHelpers::StringAssign(mDescriptorString, inSpec);
|
||||
#endif // XP_MAC
|
||||
} // nsPersistentFileDescriptor::operator =
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsPersistentFileDescriptor::~nsPersistentFileDescriptor()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
delete [] mDescriptorString;
|
||||
} // nsPersistentFileDescriptor::~nsPersistentFileDescriptor
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsPersistentFileDescriptor::GetData(void*& outData, PRInt32& outSize) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
outSize = PL_strlen(mDescriptorString);
|
||||
outData = mDescriptorString;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsPersistentFileDescriptor::SetData(const void* inData, PRInt32 inSize)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
delete [] mDescriptorString;
|
||||
mDescriptorString = new char[1 + inSize];
|
||||
if (!mDescriptorString)
|
||||
return;
|
||||
memcpy(mDescriptorString, inData, inSize);
|
||||
mDescriptorString[inSize] = '\0';
|
||||
}
|
||||
|
||||
#define MAX_PERSISTENT_DATA_SIZE 1000
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsInputStream& operator >> (nsInputStream& s, nsPersistentFileDescriptor& d)
|
||||
// reads the data from a file
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
char bigBuffer[MAX_PERSISTENT_DATA_SIZE + 1];
|
||||
// The first 8 bytes of the data should be a hex version of the data size to follow.
|
||||
PRInt32 bytesRead = 8;
|
||||
bytesRead = s.read(bigBuffer, bytesRead);
|
||||
if (bytesRead != 8)
|
||||
return (nsInputFileStream&)s;
|
||||
bigBuffer[8] = '\0';
|
||||
sscanf(bigBuffer, "%lx", &bytesRead);
|
||||
if (bytesRead > MAX_PERSISTENT_DATA_SIZE)
|
||||
return (nsInputFileStream&)s; // preposterous.
|
||||
// Now we know how many bytes to read, do it.
|
||||
s.read(bigBuffer, bytesRead);
|
||||
d.SetData(bigBuffer, bytesRead);
|
||||
return (nsInputFileStream&)s;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsOutputStream& operator << (nsOutputStream& s, const nsPersistentFileDescriptor& d)
|
||||
// writes the data to a file
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
char littleBuf[9];
|
||||
PRInt32 dataSize;
|
||||
void* data;
|
||||
d.GetData(data, dataSize);
|
||||
// First write (in hex) the length of the data to follow. Exactly 8 bytes
|
||||
sprintf(littleBuf, "%0.8x", dataSize);
|
||||
s << littleBuf;
|
||||
// Now write the data itself
|
||||
s << d.mDescriptorString;
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -22,332 +22,78 @@
|
||||
|
||||
#include "nsFileStream.h"
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef XP_MAC
|
||||
#include <Errors.h>
|
||||
#endif
|
||||
|
||||
//========================================================================================
|
||||
// nsBasicFileStream
|
||||
// nsInputStream
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicFileStream::nsBasicFileStream()
|
||||
nsInputStream::~nsInputStream()
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mFileDesc(0)
|
||||
, mNSPRMode(0)
|
||||
, mFailed(false)
|
||||
, mEOF(false)
|
||||
{
|
||||
mInputStream->Close();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicFileStream::nsBasicFileStream(
|
||||
const nsFilePath& inFile,
|
||||
int nsprMode,
|
||||
PRIntn accessMode)
|
||||
char nsInputStream::get()
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mFileDesc(0)
|
||||
, mNSPRMode(0)
|
||||
, mFailed(false)
|
||||
, mEOF(false)
|
||||
{
|
||||
open(inFile, nsprMode, accessMode);
|
||||
char c;
|
||||
read(&c, sizeof(c));
|
||||
return c;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicFileStream::nsBasicFileStream(PRFileDesc* desc, int nsprMode)
|
||||
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).
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mFileDesc(desc)
|
||||
, mNSPRMode(nsprMode)
|
||||
, mFailed(false)
|
||||
, mEOF(false)
|
||||
{
|
||||
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.
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicFileStream::~nsBasicFileStream()
|
||||
nsInputStream& nsInputStream::operator >> (char& c)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsBasicFileStream::open(
|
||||
const nsFilePath& inFile,
|
||||
int nsprMode,
|
||||
PRIntn accessMode)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (mFileDesc)
|
||||
return;
|
||||
|
||||
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;
|
||||
|
||||
#ifdef XP_MAC
|
||||
// Use the file spec to open the file, because one path can be common to
|
||||
// several files on the Macintosh (you can have several volumes with the
|
||||
// same name, see).
|
||||
mFileDesc = 0;
|
||||
if (inFile.GetNativeSpec().Error() != noErr)
|
||||
return;
|
||||
OSErr err = noErr;
|
||||
#if DEBUG
|
||||
const OSType kCreator = 'CWIE';
|
||||
#else
|
||||
const OSType kCreator = 'MOSS';
|
||||
#endif
|
||||
nsNativeFileSpec nativeSpec = inFile.GetNativeSpec();
|
||||
FSSpec* spec = (FSSpec*)nativeSpec;
|
||||
if (nsprMode & PR_CREATE_FILE)
|
||||
err = FSpCreate(spec, kCreator, 'TEXT', 0);
|
||||
if (err == dupFNErr)
|
||||
err = noErr;
|
||||
if (err != noErr)
|
||||
return;
|
||||
|
||||
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;
|
||||
|
||||
if ((mFileDesc = PR_ImportFile(refnum)) == 0)
|
||||
return;
|
||||
#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*)nsNativeFileSpec(inFile), nsprMode, accessMode)) == 0)
|
||||
return;
|
||||
#endif
|
||||
mNSPRMode = nsprMode;
|
||||
} // nsFileStreamHelpers::open
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsBasicFileStream::close()
|
||||
// Must precede the destructor because both are inline.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR || mFileDesc == 0)
|
||||
return;
|
||||
if (PR_Close(mFileDesc) == PR_SUCCESS)
|
||||
mFileDesc = 0;
|
||||
} // nsBasicFileStream::close
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsBasicFileStream::seek(PRSeekWhence whence, PRInt32 offset)
|
||||
// Must precede the destructor because both are inline.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR || mFileDesc == 0)
|
||||
return;
|
||||
mFailed = false; // reset on a seek.
|
||||
mEOF = false; // reset on a seek.
|
||||
PRInt32 position = PR_Seek(mFileDesc, 0, PR_SEEK_CUR);
|
||||
PRInt32 available = PR_Available(mFileDesc);
|
||||
PRInt32 fileSize = position + available;
|
||||
PRInt32 newPosition;
|
||||
switch (whence)
|
||||
{
|
||||
case PR_SEEK_CUR: newPosition = position + offset; break;
|
||||
case PR_SEEK_SET: newPosition = offset; break;
|
||||
case PR_SEEK_END: newPosition = fileSize + offset; break;
|
||||
}
|
||||
if (newPosition < 0)
|
||||
{
|
||||
newPosition = 0;
|
||||
mFailed = true;
|
||||
}
|
||||
else if (newPosition >= fileSize)
|
||||
{
|
||||
newPosition = fileSize;
|
||||
mEOF = true;
|
||||
}
|
||||
if (PR_Seek(mFileDesc, newPosition, PR_SEEK_SET) < 0)
|
||||
mFailed = true;
|
||||
} // nsBasicFileStream::seek
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
PRIntn nsBasicFileStream::tell() const
|
||||
// Must precede the destructor because both are inline.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR || mFileDesc == 0)
|
||||
return -1;
|
||||
return PR_Seek(mFileDesc, 0, PR_SEEK_CUR);
|
||||
} // nsBasicFileStream::tell
|
||||
|
||||
//========================================================================================
|
||||
// nsBasicInStream
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicInStream::nsBasicInStream(nsBasicFileStream& inBasicStream, istream* inStream)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mBase(inBasicStream)
|
||||
, mStdStream(inStream)
|
||||
{
|
||||
}
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsBasicInStream::get(char& c)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
read(&c, sizeof(char));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
PRBool nsBasicInStream::readline(char* s, PRInt32 n)
|
||||
// This will truncate if the buffer is too small. Result will always be null-terminated.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
PRBool bufferLargeEnough = true; // result
|
||||
if (!s || !n)
|
||||
return true;
|
||||
PRIntn position = mBase.tell();
|
||||
if (position < 0)
|
||||
return false;
|
||||
PRInt32 bytesRead = read(s, n - 1);
|
||||
if (mBase.failed())
|
||||
return false;
|
||||
s[bytesRead] = '\0'; // always terminate at the end of the buffer
|
||||
char* tp = strpbrk(s, "\n\r");
|
||||
if (tp)
|
||||
{
|
||||
char ch = *tp;
|
||||
*tp++ = '\0'; // terminate at the newline, then skip past it
|
||||
if ((ch == '\n' && *tp == '\r') || (ch == '\r' && *tp == '\n'))
|
||||
tp++; // possibly a pair.
|
||||
bytesRead = (tp - s);
|
||||
}
|
||||
else if (!mBase.eof())
|
||||
bufferLargeEnough = false;
|
||||
position += bytesRead;
|
||||
mBase.seek(position);
|
||||
return bufferLargeEnough;
|
||||
} // nsBasicInStream::getline
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
PRInt32 nsBasicInStream::read(void* s, PRInt32 n)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
#ifndef NS_USE_PR_STDIO
|
||||
// Calling PR_Read on stdin is sure suicide on Macintosh.
|
||||
if (GetStandardStream())
|
||||
{
|
||||
GetStandardStream()->read((char*)s, n);
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
if (!mBase.is_open() || mBase.failed())
|
||||
return -1;
|
||||
PRInt32 bytesRead = PR_Read(mBase.GetFileDescriptor(), s, n);
|
||||
if (bytesRead < 0)
|
||||
mBase.mFailed = true;
|
||||
else if (bytesRead < n)
|
||||
mBase.mEOF = true;
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicInStream& nsBasicInStream::operator >> (char& c)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
get(c);
|
||||
c = get();
|
||||
return *this;
|
||||
}
|
||||
|
||||
//========================================================================================
|
||||
// nsInputFileStream
|
||||
// nsOutputStream
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsInputFileStream::nsInputFileStream(istream* stream)
|
||||
nsOutputStream::~nsOutputStream()
|
||||
//----------------------------------------------------------------------------------------
|
||||
#ifndef NS_USE_PR_STDIO
|
||||
: nsBasicFileStream(0, kDefaultMode)
|
||||
, nsBasicInStream(*this, stream)
|
||||
#else
|
||||
: nsBasicFileStream(PR_STDIN, kDefaultMode)
|
||||
, nsBasicInStream(*this, 0)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
//========================================================================================
|
||||
// nsBasicOutStream
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicOutStream::nsBasicOutStream(nsBasicFileStream& inBase, ostream* stream)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mBase(inBase)
|
||||
, mStdStream(stream)
|
||||
{
|
||||
mOutputStream->Close();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsBasicOutStream::put(char c)
|
||||
void nsOutputStream::put(char c)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
write(&c, sizeof(c));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
PRInt32 nsBasicOutStream::write(const void* s, PRInt32 n)
|
||||
void nsOutputStream::flush()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
#ifndef NS_USE_PR_STDIO
|
||||
// Calling PR_Write on stdout is sure suicide.
|
||||
if (mStdStream)
|
||||
{
|
||||
mStdStream->write((const char*)s, n);
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
if (!mBase.mFileDesc || mBase.failed())
|
||||
return -1;
|
||||
PRInt32 bytesWrit = PR_Write(mBase.mFileDesc, s, n);
|
||||
if (bytesWrit != n)
|
||||
mBase.mFailed = true;
|
||||
return bytesWrit;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicOutStream& nsBasicOutStream::operator << (char c)
|
||||
nsOutputStream& nsOutputStream::operator << (char c)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
put(c);
|
||||
@@ -355,7 +101,7 @@ nsBasicOutStream& nsBasicOutStream::operator << (char c)
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicOutStream& nsBasicOutStream::operator << (const char* s)
|
||||
nsOutputStream& nsOutputStream::operator << (const char* s)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
write(s, strlen(s));
|
||||
@@ -363,78 +109,84 @@ nsBasicOutStream& nsBasicOutStream::operator << (const char* s)
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicOutStream& nsBasicOutStream::operator << (short val)
|
||||
nsOutputStream& nsOutputStream::operator << (short val)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
char buf[30];
|
||||
sprintf(buf, "%d", val);
|
||||
return *this << buf;
|
||||
return (*this << buf);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicOutStream& nsBasicOutStream::operator << (unsigned short val)
|
||||
nsOutputStream& nsOutputStream::operator << (unsigned short val)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
char buf[30];
|
||||
sprintf(buf, "%ud", val);
|
||||
return *this << buf;
|
||||
return (*this << buf);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicOutStream& nsBasicOutStream::operator << (long val)
|
||||
nsOutputStream& nsOutputStream::operator << (long val)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
char buf[30];
|
||||
sprintf(buf, "%ld", val);
|
||||
return *this << buf;
|
||||
return (*this << buf);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicOutStream& nsBasicOutStream::operator << (unsigned long val)
|
||||
nsOutputStream& nsOutputStream::operator << (unsigned long val)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
char buf[30];
|
||||
sprintf(buf, "%uld", val);
|
||||
return *this << buf;
|
||||
return (*this << buf);
|
||||
}
|
||||
|
||||
//========================================================================================
|
||||
// nsInputFileStream
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsBasicOutStream::flush()
|
||||
// Must precede the destructor because both are inline.
|
||||
PRBool nsInputFileStream::readline(char* s, PRInt32 n)
|
||||
// This will truncate if the buffer is too small. Result will always be null-terminated.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
#ifndef NS_USE_PR_STDIO
|
||||
if (mStdStream)
|
||||
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)
|
||||
{
|
||||
mStdStream->flush();
|
||||
return;
|
||||
TidyEndOfLine(tp);
|
||||
bytesRead = (tp - s);
|
||||
}
|
||||
#endif
|
||||
if (mBase.mFileDesc == 0)
|
||||
return;
|
||||
PRBool itFailed = PR_Sync(mBase.mFileDesc) != PR_SUCCESS;
|
||||
#ifdef XP_MAC
|
||||
// On unix, it seems to fail always.
|
||||
if (itFailed)
|
||||
mBase.mFailed = true;
|
||||
#endif
|
||||
} // nsBasicOutStream::flush
|
||||
else if (!eof())
|
||||
bufferLargeEnough = PR_FALSE;
|
||||
position += bytesRead;
|
||||
seek(position);
|
||||
return bufferLargeEnough;
|
||||
} // nsInputStream::readline
|
||||
|
||||
//========================================================================================
|
||||
// nsOutputFileStream
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsOutputFileStream::nsOutputFileStream(ostream* stream)
|
||||
void nsOutputFileStream::flush()
|
||||
//----------------------------------------------------------------------------------------
|
||||
#ifndef NS_USE_PR_STDIO
|
||||
: nsBasicFileStream(0, kDefaultMode)
|
||||
, nsBasicOutStream(*this, stream)
|
||||
#else
|
||||
: nsBasicFileStream(PR_STDOUT, kDefaultMode)
|
||||
, nsBasicOutStream(*this, 0)
|
||||
#endif
|
||||
{
|
||||
if (mFileOutputStream)
|
||||
mFileOutputStream->Flush();
|
||||
}
|
||||
|
||||
//========================================================================================
|
||||
@@ -442,19 +194,10 @@ nsOutputFileStream::nsOutputFileStream(ostream* stream)
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicOutStream& nsEndl(nsBasicOutStream& os)
|
||||
nsOutputStream& nsEndl(nsOutputStream& os)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
#ifndef NS_USE_PR_STDIO
|
||||
// Calling PR_Write on stdout is sure suicide on Macintosh.
|
||||
ostream* stream = os.GetStandardStream();
|
||||
if (stream)
|
||||
{
|
||||
*stream << std::endl;
|
||||
return os;
|
||||
}
|
||||
#endif
|
||||
os.put('\n');
|
||||
os.flush();
|
||||
return os;
|
||||
}
|
||||
os.put('\n');
|
||||
os.flush();
|
||||
return os;
|
||||
} // nsEndl
|
||||
@@ -31,6 +31,8 @@
|
||||
class nsIBaseStream : public nsISupports {
|
||||
public:
|
||||
|
||||
static const nsIID& IID() { static nsIID iid = NS_IBASESTREAM_IID; return iid; }
|
||||
|
||||
/** Close the stream. */
|
||||
NS_IMETHOD
|
||||
Close(void) = 0;
|
||||
|
||||
451
mozilla/base/src/nsIFileStream.cpp
Normal file
451
mozilla/base/src/nsIFileStream.cpp
Normal file
@@ -0,0 +1,451 @@
|
||||
#include "nsIFileStream.h"
|
||||
#include "nsFileSpec.h"
|
||||
|
||||
#include "prerror.h"
|
||||
|
||||
#ifdef XP_MAC
|
||||
#include "pprio.h" // To get PR_ImportFile
|
||||
#else
|
||||
#include "prio.h"
|
||||
#endif
|
||||
|
||||
#ifdef XP_MAC
|
||||
#include <Errors.h>
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
//========================================================================================
|
||||
class FileImpl
|
||||
: public nsIOutputStream
|
||||
, public nsIInputStream
|
||||
, public nsIFileOutputStream
|
||||
, public nsIFileInputStream
|
||||
, public nsIFile
|
||||
//========================================================================================
|
||||
{
|
||||
public:
|
||||
FileImpl(PRFileDesc* inDesc)
|
||||
: mFileDesc(inDesc)
|
||||
, mFailed(PR_FALSE)
|
||||
, mEOF(PR_FALSE)
|
||||
, mLength(-1)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
FileImpl(
|
||||
const nsFileSpec& inFile,
|
||||
int nsprMode,
|
||||
PRIntn accessMode)
|
||||
: mFileDesc(nsnull)
|
||||
, mFailed(PR_FALSE)
|
||||
, mEOF(PR_FALSE)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
Open(inFile, nsprMode, accessMode);
|
||||
}
|
||||
virtual ~FileImpl()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
// nsISupports interface
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIFile interface
|
||||
NS_IMETHOD Open(
|
||||
const nsFileSpec& inFile,
|
||||
int nsprMode,
|
||||
PRIntn accessMode);
|
||||
NS_IMETHOD Close();
|
||||
NS_IMETHOD Seek(PRSeekWhence whence, PRInt32 offset);
|
||||
|
||||
NS_IMETHOD GetIsOpen(PRBool* outOpen)
|
||||
{
|
||||
*outOpen = (mFileDesc != nsnull);
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD Tell(PRIntn* outWhere);
|
||||
|
||||
// nsIInputStream interface
|
||||
NS_IMETHOD GetLength(PRUint32 *aLength)
|
||||
{
|
||||
NS_PRECONDITION(aLength != nsnull, "null ptr");
|
||||
if (!aLength)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
if (mLength < 0)
|
||||
return NS_FILE_RESULT(NS_ERROR_UNEXPECTED);
|
||||
*aLength = mLength;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD Read(char* aBuf,
|
||||
PRUint32 aOffset,
|
||||
PRUint32 aCount,
|
||||
PRUint32 *aReadCount)
|
||||
{
|
||||
NS_PRECONDITION(aBuf != nsnull, "null ptr");
|
||||
if (!aBuf)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
NS_PRECONDITION(aReadCount != nsnull, "null ptr");
|
||||
if (!aReadCount)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
if (!mFileDesc)
|
||||
return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
|
||||
if (mFailed)
|
||||
return NS_ERROR_FAILURE;
|
||||
if (aOffset)
|
||||
PR_Seek(mFileDesc, aOffset, PR_SEEK_CUR);
|
||||
PRInt32 bytesRead = PR_Read(mFileDesc, aBuf, aCount);
|
||||
if (bytesRead < 0)
|
||||
{
|
||||
*aReadCount = 0;
|
||||
mFailed = PR_TRUE;
|
||||
return NS_FILE_RESULT(PR_GetError());
|
||||
}
|
||||
*aReadCount = bytesRead;
|
||||
return NS_OK;
|
||||
}
|
||||
// nsIOutputStream interface
|
||||
NS_IMETHOD Write(const char* aBuf,
|
||||
PRUint32 aOffset,
|
||||
PRUint32 aCount,
|
||||
PRUint32 *aWriteCount)
|
||||
{
|
||||
NS_PRECONDITION(aBuf != nsnull, "null ptr");
|
||||
NS_PRECONDITION(aWriteCount != nsnull, "null ptr");
|
||||
|
||||
|
||||
#ifdef XP_MAC
|
||||
// Calling PR_Write on stdout is sure suicide.
|
||||
if (mFileDesc == PR_STDOUT || mFileDesc == PR_STDERR)
|
||||
{
|
||||
cout.write(aBuf, aCount);
|
||||
*aWriteCount = aCount;
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
if (!mFileDesc)
|
||||
return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
|
||||
if (mFailed)
|
||||
return NS_ERROR_FAILURE;
|
||||
if (aOffset)
|
||||
PR_Seek(mFileDesc, aOffset, PR_SEEK_CUR);
|
||||
PRInt32 bytesWrit = PR_Write(mFileDesc, aBuf, aCount);
|
||||
if (bytesWrit != aCount)
|
||||
{
|
||||
mFailed = PR_TRUE;
|
||||
*aWriteCount = 0;
|
||||
return NS_FILE_RESULT(PR_GetError());
|
||||
}
|
||||
*aWriteCount = bytesWrit;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD Flush();
|
||||
|
||||
protected:
|
||||
|
||||
PRFileDesc* mFileDesc;
|
||||
int mNSPRMode;
|
||||
PRBool mFailed;
|
||||
PRBool mEOF;
|
||||
PRInt32 mLength;
|
||||
}; // class FileImpl
|
||||
|
||||
#define SAY_I_IMPLEMENT(classname) \
|
||||
if (aIID.Equals(classname::IID())) \
|
||||
{ \
|
||||
*aInstancePtr = (void*)((classname*)this); \
|
||||
NS_ADDREF_THIS(); \
|
||||
return NS_OK; \
|
||||
}
|
||||
|
||||
NS_IMPL_RELEASE(FileImpl)
|
||||
NS_IMPL_ADDREF(FileImpl)
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_IMETHODIMP FileImpl::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!aInstancePtr)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aInstancePtr = nsnull;
|
||||
|
||||
SAY_I_IMPLEMENT(nsIFile)
|
||||
SAY_I_IMPLEMENT(nsIOutputStream)
|
||||
SAY_I_IMPLEMENT(nsIInputStream)
|
||||
SAY_I_IMPLEMENT(nsIFileInputStream)
|
||||
SAY_I_IMPLEMENT(nsIFileOutputStream)
|
||||
// Note that we derive from two copies of nsIBaseStream (and hence
|
||||
// of nsISupports), one through
|
||||
// nsIOutputStream, the other through nsIInputStream. Resolve this
|
||||
// by giving them a specific one
|
||||
if (aIID.Equals(((nsIBaseStream*)(nsIOutputStream*)this)->IID()))
|
||||
{
|
||||
*aInstancePtr = (void*)((nsIBaseStream*)(nsIOutputStream*)this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if (aIID.Equals(((nsISupports*)(nsIOutputStream*)this)->IID()))
|
||||
{
|
||||
*aInstancePtr = (void*)((nsISupports*)(nsIOutputStream*)this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
} // FileImpl::QueryInterface
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_IMETHODIMP FileImpl::Open(
|
||||
const nsFileSpec& inFile,
|
||||
int nsprMode,
|
||||
PRIntn accessMode)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (mFileDesc)
|
||||
if ((nsprMode & mNSPRMode) == nsprMode)
|
||||
return NS_OK;
|
||||
else
|
||||
return NS_FILE_RESULT(PR_ILLEGAL_ACCESS_ERROR);
|
||||
|
||||
const int nspr_modes[]={
|
||||
PR_WRONLY | PR_CREATE_FILE,
|
||||
PR_WRONLY | PR_CREATE_FILE | PR_APPEND,
|
||||
PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
|
||||
PR_RDONLY,
|
||||
PR_RDONLY | PR_APPEND,
|
||||
PR_RDWR | PR_CREATE_FILE,
|
||||
PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE,
|
||||
// "wb",
|
||||
// "ab",
|
||||
// "wb",
|
||||
// "rb",
|
||||
// "r+b",
|
||||
// "w+b",
|
||||
0 };
|
||||
const int* currentLegalMode = nspr_modes;
|
||||
while (*currentLegalMode && nsprMode != *currentLegalMode)
|
||||
++currentLegalMode;
|
||||
if (!*currentLegalMode)
|
||||
return NS_FILE_RESULT(PR_ILLEGAL_ACCESS_ERROR);
|
||||
|
||||
#ifdef XP_MAC
|
||||
// Use the file spec to open the file, because one path can be common to
|
||||
// several files on the Macintosh (you can have several volumes with the
|
||||
// same name, see).
|
||||
mFileDesc = 0;
|
||||
if (inFile.Error() != noErr)
|
||||
return NS_FILE_RESULT(inFile.Error());
|
||||
OSErr err = noErr;
|
||||
#if DEBUG
|
||||
const OSType kCreator = 'CWIE';
|
||||
#else
|
||||
const OSType kCreator = 'MOSS';
|
||||
#endif
|
||||
// Resolve the alias to the original file.
|
||||
nsFileSpec original = inFile;
|
||||
PRBool ignoredResult;
|
||||
original.ResolveAlias(ignoredResult);
|
||||
const FSSpec& spec = original.operator const FSSpec&();
|
||||
if (nsprMode & PR_CREATE_FILE)
|
||||
err = FSpCreate(&spec, kCreator, 'TEXT', 0);
|
||||
if (err == dupFNErr)
|
||||
err = noErr;
|
||||
if (err != noErr)
|
||||
return NS_FILE_RESULT(err);
|
||||
|
||||
SInt8 perm;
|
||||
if (nsprMode & PR_RDWR)
|
||||
perm = fsRdWrPerm;
|
||||
else if (nsprMode & PR_WRONLY)
|
||||
perm = fsWrPerm;
|
||||
else
|
||||
perm = fsRdPerm;
|
||||
|
||||
short refnum;
|
||||
err = FSpOpenDF(&spec, perm, &refnum);
|
||||
|
||||
if (err == noErr && (nsprMode & PR_TRUNCATE))
|
||||
err = SetEOF(refnum, 0);
|
||||
if (err == noErr && (nsprMode & PR_APPEND))
|
||||
err = SetFPos(refnum, fsFromLEOF, 0);
|
||||
if (err != noErr)
|
||||
return NS_FILE_RESULT(err);
|
||||
|
||||
if ((mFileDesc = PR_ImportFile(refnum)) == 0)
|
||||
return NS_FILE_RESULT(PR_GetError());
|
||||
#else
|
||||
// Platforms other than Macintosh...
|
||||
// Another bug in NSPR: Mac PR_Open assumes a unix style path, but Win PR_Open assumes
|
||||
// a windows path.
|
||||
if ((mFileDesc = PR_Open((const char*)nsFileSpec(inFile), nsprMode, accessMode)) == 0)
|
||||
return NS_FILE_RESULT(PR_GetError());
|
||||
#endif
|
||||
mNSPRMode = nsprMode;
|
||||
mLength = PR_Available(mFileDesc);
|
||||
return NS_OK;
|
||||
} // FileImpl::Open
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_IMETHODIMP FileImpl::Seek(PRSeekWhence whence, PRInt32 offset)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR || !mFileDesc)
|
||||
return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
|
||||
mFailed = PR_FALSE; // reset on a seek.
|
||||
mEOF = PR_FALSE; // reset on a seek.
|
||||
PRInt32 position = PR_Seek(mFileDesc, 0, PR_SEEK_CUR);
|
||||
PRInt32 available = PR_Available(mFileDesc);
|
||||
PRInt32 fileSize = position + available;
|
||||
PRInt32 newPosition;
|
||||
switch (whence)
|
||||
{
|
||||
case PR_SEEK_CUR: newPosition = position + offset; break;
|
||||
case PR_SEEK_SET: newPosition = offset; break;
|
||||
case PR_SEEK_END: newPosition = fileSize + offset; break;
|
||||
}
|
||||
if (newPosition < 0)
|
||||
{
|
||||
newPosition = 0;
|
||||
mFailed = PR_TRUE;
|
||||
}
|
||||
else if (newPosition >= fileSize)
|
||||
{
|
||||
newPosition = fileSize;
|
||||
mEOF = PR_TRUE;
|
||||
}
|
||||
if (PR_Seek(mFileDesc, newPosition, PR_SEEK_SET) < 0)
|
||||
mFailed = PR_TRUE;
|
||||
return NS_OK;
|
||||
} // FileImpl::Seek
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_IMETHODIMP FileImpl::Tell(PRIntn* outWhere)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR || !mFileDesc)
|
||||
return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
|
||||
*outWhere = PR_Seek(mFileDesc, 0, PR_SEEK_CUR);
|
||||
return NS_OK;
|
||||
} // FileImpl::Tell
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_IMETHODIMP FileImpl::Close()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR || !mFileDesc)
|
||||
return NS_OK;
|
||||
if (PR_Close(mFileDesc) == PR_SUCCESS)
|
||||
mFileDesc = 0;
|
||||
else
|
||||
return NS_FILE_RESULT(PR_GetError());
|
||||
return NS_OK;
|
||||
} // FileImpl::close
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_IMETHODIMP FileImpl::Flush()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
#ifdef XP_MAC
|
||||
if (mFileDesc == PR_STDOUT || mFileDesc == PR_STDERR)
|
||||
{
|
||||
cout.flush();
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
if (!mFileDesc)
|
||||
return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
|
||||
PRBool itFailed = PR_Sync(mFileDesc) != PR_SUCCESS;
|
||||
#ifdef XP_MAC
|
||||
// On unix, it seems to fail always.
|
||||
if (itFailed)
|
||||
mFailed = PR_TRUE;
|
||||
#endif
|
||||
return NS_OK;
|
||||
} // FileImpl::flush
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_BASE nsresult NS_NewTypicalInputFileStream(
|
||||
nsISupports** aResult,
|
||||
const nsFileSpec& inFile
|
||||
/*Default nsprMode == PR_RDONLY*/
|
||||
/*Default accessmode = 0700 (octal)*/)
|
||||
// Factory method to get an nsInputStream from a file, using most common options
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return NS_NewIOFileStream(aResult, inFile, PR_RDONLY, 0700);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_BASE nsresult NS_NewOutputConsoleStream(
|
||||
nsISupports** aResult)
|
||||
// Factory method to get an nsOutputStream to the console.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
NS_PRECONDITION(aResult != nsnull, "null ptr");
|
||||
if (! aResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
FileImpl* stream = new FileImpl(PR_STDOUT);
|
||||
if (! stream)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(stream);
|
||||
*aResult = (nsISupports*)(void*)stream;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_BASE nsresult NS_NewTypicalOutputFileStream(
|
||||
nsISupports** aResult,
|
||||
const nsFileSpec& inFile
|
||||
/*default nsprMode= (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE)*/
|
||||
/*Default accessMode= 0700 (octal)*/)
|
||||
// Factory method to get an nsOutputStream to a file - most common case.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return NS_NewIOFileStream(
|
||||
aResult,
|
||||
inFile,
|
||||
(PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE),
|
||||
0700);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_BASE nsresult NS_NewIOFileStream(
|
||||
nsISupports** aResult,
|
||||
const nsFileSpec& inFile,
|
||||
PRInt32 nsprMode /*default = (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE)*/,
|
||||
PRInt32 accessMode /*Default = 0700 (octal)*/)
|
||||
// Factory method to get an object that implements both nsIInputStream
|
||||
// and nsIOutputStream, associated with a file.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
NS_PRECONDITION(aResult != nsnull, "null ptr");
|
||||
if (!aResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
FileImpl* stream = new FileImpl(inFile, nsprMode, accessMode);
|
||||
if (! stream)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(stream);
|
||||
*aResult = (nsISupports*)(void*)stream;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_BASE nsresult NS_NewTypicalIOFileStream(
|
||||
nsISupports** aResult,
|
||||
const nsFileSpec& inFile
|
||||
/*default nsprMode= (PR_RDWR | PR_CREATE_FILE)*/
|
||||
/*Default accessMode= 0700 (octal)*/)
|
||||
// Factory method to get an object that implements both nsIInputStream
|
||||
// and nsIOutputStream, associated with a single file.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return NS_NewIOFileStream(
|
||||
aResult,
|
||||
inFile,
|
||||
(PR_RDWR | PR_CREATE_FILE),
|
||||
0700);
|
||||
}
|
||||
@@ -28,6 +28,8 @@
|
||||
class nsIInputStream : public nsIBaseStream {
|
||||
public:
|
||||
|
||||
static const nsIID& IID() { static nsIID iid = NS_IINPUTSTREAM_IID; return iid; }
|
||||
|
||||
/** Return the number of bytes in the stream
|
||||
* @param aLength out parameter to hold the length
|
||||
* of the stream. if an error occurs, the length
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
class nsIOutputStream : public nsIBaseStream {
|
||||
public:
|
||||
|
||||
static const nsIID& IID() { static nsIID iid = NS_IOUTPUTSTREAM_IID; return iid; }
|
||||
|
||||
/** Write data into the stream.
|
||||
* @param aBuf the buffer into which the data is read
|
||||
* @param aOffset the start offset of the data
|
||||
|
||||
@@ -25,9 +25,10 @@
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include "nsError.h"
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsFileSpecHelpers::Canonify(char*& ioPath, bool inMakeDirs)
|
||||
void nsFileSpecHelpers::Canonify(char*& ioPath, PRBool inMakeDirs)
|
||||
// Canonify, make absolute, and check whether directories exist
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
@@ -76,75 +77,78 @@ void nsFileSpecHelpers::Canonify(char*& ioPath, bool inMakeDirs)
|
||||
} // nsFileSpecHelpers::Canonify
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::SetLeafName(const char* inLeafName)
|
||||
void nsFileSpec::SetLeafName(const char* inLeafName)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::LeafReplace(mPath, '/', inLeafName);
|
||||
} // nsNativeFileSpec::SetLeafName
|
||||
} // nsFileSpec::SetLeafName
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
char* nsNativeFileSpec::GetLeafName() const
|
||||
char* nsFileSpec::GetLeafName() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return nsFileSpecHelpers::GetLeaf(mPath, '/');
|
||||
} // nsNativeFileSpec::GetLeafName
|
||||
} // nsFileSpec::GetLeafName
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::Exists() const
|
||||
PRBool nsFileSpec::Exists() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
struct stat st;
|
||||
return 0 == stat(mPath, &st);
|
||||
} // nsNativeFileSpec::Exists
|
||||
} // nsFileSpec::Exists
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::IsFile() const
|
||||
PRBool nsFileSpec::IsFile() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
struct stat st;
|
||||
return 0 == stat(mPath, &st) && S_ISREG(st.st_mode);
|
||||
} // nsNativeFileSpec::IsFile
|
||||
} // nsFileSpec::IsFile
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::IsDirectory() const
|
||||
PRBool nsFileSpec::IsDirectory() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
struct stat st;
|
||||
return 0 == stat(mPath, &st) && S_ISDIR(st.st_mode);
|
||||
} // nsNativeFileSpec::IsDirectory
|
||||
} // nsFileSpec::IsDirectory
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::GetParent(nsNativeFileSpec& outSpec) const
|
||||
void nsFileSpec::GetParent(nsFileSpec& outSpec) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::StringAssign(outSpec.mPath, mPath);
|
||||
char* cp = strrchr(outSpec.mPath, '/');
|
||||
if (cp)
|
||||
*cp = '\0';
|
||||
} // nsNativeFileSpec::GetParent
|
||||
} // nsFileSpec::GetParent
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator += (const char* inRelativePath)
|
||||
void nsFileSpec::operator += (const char* inRelativePath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!inRelativePath || !mPath)
|
||||
return;
|
||||
|
||||
if (mPath[strlen(mPath) - 1] != '/')
|
||||
char* newPath = nsFileSpecHelpers::ReallocCat(mPath, "/");
|
||||
char endChar = mPath[strlen(mPath) - 1];
|
||||
if (endChar == '/')
|
||||
nsFileSpecHelpers::ReallocCat(mPath, "x");
|
||||
else
|
||||
nsFileSpecHelpers::ReallocCat(mPath, "/x");
|
||||
SetLeafName(inRelativePath);
|
||||
} // nsNativeFileSpec::operator +=
|
||||
} // nsFileSpec::operator +=
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::CreateDirectory(int mode)
|
||||
void nsFileSpec::CreateDirectory(int mode)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// Note that mPath is canonical!
|
||||
mkdir(mPath, mode);
|
||||
} // nsNativeFileSpec::CreateDirectory
|
||||
} // nsFileSpec::CreateDirectory
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::Delete(bool inRecursive)
|
||||
void nsFileSpec::Delete(PRBool inRecursive)
|
||||
// To check if this worked, call Exists() afterwards, see?
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
@@ -152,9 +156,9 @@ void nsNativeFileSpec::Delete(bool inRecursive)
|
||||
{
|
||||
if (inRecursive)
|
||||
{
|
||||
for (nsDirectoryIterator i(*this); i; i++)
|
||||
for (nsDirectoryIterator i(*this); i.Exists(); i++)
|
||||
{
|
||||
nsNativeFileSpec& child = (nsNativeFileSpec&)i;
|
||||
nsFileSpec& child = (nsFileSpec&)i;
|
||||
child.Delete(inRecursive);
|
||||
}
|
||||
}
|
||||
@@ -162,7 +166,148 @@ void nsNativeFileSpec::Delete(bool inRecursive)
|
||||
}
|
||||
else
|
||||
remove(mPath);
|
||||
} // nsNativeFileSpec::Delete
|
||||
} // nsFileSpec::Delete
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult nsFileSpec::Rename(const char* inNewName)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// This function should not be used to move a file on disk.
|
||||
if (strchr(inNewName, '/'))
|
||||
return NS_FILE_FAILURE;
|
||||
|
||||
if (PR_Rename(mPath, inNewName) != 0)
|
||||
{
|
||||
return NS_FILE_FAILURE;
|
||||
}
|
||||
SetLeafName(inNewName);
|
||||
return NS_OK;
|
||||
} // nsFileSpec::Rename
|
||||
|
||||
static int CrudeFileCopy(const char* in, const char* out)
|
||||
{
|
||||
struct stat in_stat;
|
||||
int stat_result = -1;
|
||||
|
||||
char buf [1024];
|
||||
FILE *ifp, *ofp;
|
||||
int rbytes, wbytes;
|
||||
|
||||
if (!in || !out)
|
||||
return -1;
|
||||
|
||||
stat_result = stat (in, &in_stat);
|
||||
|
||||
ifp = fopen (in, "r");
|
||||
if (!ifp)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ofp = fopen (out, "w");
|
||||
if (!ofp)
|
||||
{
|
||||
fclose (ifp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((rbytes = fread (buf, 1, sizeof(buf), ifp)) > 0)
|
||||
{
|
||||
while (rbytes > 0)
|
||||
{
|
||||
if ( (wbytes = fwrite (buf, 1, rbytes, ofp)) < 0 )
|
||||
{
|
||||
fclose (ofp);
|
||||
fclose (ifp);
|
||||
unlink(out);
|
||||
return -1;
|
||||
}
|
||||
rbytes -= wbytes;
|
||||
}
|
||||
}
|
||||
fclose (ofp);
|
||||
fclose (ifp);
|
||||
|
||||
if (stat_result == 0)
|
||||
{
|
||||
chmod (out, in_stat.st_mode & 0777);
|
||||
}
|
||||
|
||||
return 0;
|
||||
} // nsFileSpec::Rename
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult nsFileSpec::Copy(const nsFileSpec& inParentDirectory) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// We can only copy into a directory, and (for now) can not copy entire directories
|
||||
nsresult result = NS_FILE_FAILURE;
|
||||
|
||||
if (inParentDirectory.IsDirectory() && (! IsDirectory() ) )
|
||||
{
|
||||
char *leafname = GetLeafName();
|
||||
char* destPath = nsFileSpecHelpers::StringDup(inParentDirectory, ( strlen(inParentDirectory) + 1 + strlen(leafname) ) );
|
||||
strcat(destPath, "/");
|
||||
strcat(destPath, leafname);
|
||||
delete [] leafname;
|
||||
|
||||
result = NS_FILE_RESULT(CrudeFileCopy(*this, destPath));
|
||||
|
||||
delete [] destPath;
|
||||
}
|
||||
return result;
|
||||
} // nsFileSpec::Copy
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult nsFileSpec::Move(const nsFileSpec& inNewParentDirectory) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// We can only copy into a directory, and (for now) can not copy entire directories
|
||||
nsresult result = NS_FILE_FAILURE;
|
||||
|
||||
if (inNewParentDirectory.IsDirectory() && (! IsDirectory() ) )
|
||||
{
|
||||
char *leafname = GetLeafName();
|
||||
char* destPath
|
||||
= nsFileSpecHelpers::StringDup(
|
||||
inNewParentDirectory,
|
||||
strlen(inNewParentDirectory) + 1 + strlen(leafname));
|
||||
strcat(destPath, "/");
|
||||
strcat(destPath, leafname);
|
||||
delete [] leafname;
|
||||
|
||||
result = NS_FILE_RESULT(CrudeFileCopy(*this, destPath));
|
||||
if (result == NS_OK)
|
||||
{
|
||||
Delete(PR_FALSE);
|
||||
}
|
||||
delete [] destPath;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult nsFileSpec::Execute(const char* inArgs ) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsresult result = NS_FILE_FAILURE;
|
||||
|
||||
if (! IsDirectory())
|
||||
{
|
||||
char* fileNameWithArgs
|
||||
= nsFileSpecHelpers::StringDup(mPath, strlen(mPath) + 1 + strlen(inArgs));
|
||||
strcat(fileNameWithArgs, " ");
|
||||
strcat(fileNameWithArgs, inArgs);
|
||||
|
||||
result = NS_FILE_RESULT(system(fileNameWithArgs));
|
||||
delete [] fileNameWithArgs;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
} // nsFileSpec::Execute
|
||||
|
||||
//========================================================================================
|
||||
// nsDirectoryIterator
|
||||
@@ -170,7 +315,7 @@ void nsNativeFileSpec::Delete(bool inRecursive)
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator::nsDirectoryIterator(
|
||||
const nsNativeFileSpec& inDirectory
|
||||
const nsFileSpec& inDirectory
|
||||
, int inIterateDirection)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mCurrent(inDirectory)
|
||||
|
||||
@@ -23,9 +23,18 @@
|
||||
#include <direct.h>
|
||||
#include <stdlib.h>
|
||||
#include "prio.h"
|
||||
#include "nsError.h"
|
||||
|
||||
#include "windows.h"
|
||||
|
||||
#ifdef UNICODE
|
||||
#define CreateDirectoryW CreateDirectory
|
||||
#else
|
||||
#define CreateDirectoryA CreateDirectory
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsFileSpecHelpers::Canonify(char*& ioPath, bool inMakeDirs)
|
||||
void nsFileSpecHelpers::Canonify(char*& ioPath, PRBool inMakeDirs)
|
||||
// Canonify, make absolute, and check whether directories exist. This
|
||||
// takes a (possibly relative) native path and converts it into a
|
||||
// fully qualified native path.
|
||||
@@ -125,7 +134,7 @@ void nsFileSpecHelpers::NativeToUnix(char*& ioPath)
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec(const nsFilePath& inPath)
|
||||
nsFileSpec::nsFileSpec(const nsFilePath& inPath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(NULL)
|
||||
{
|
||||
@@ -133,15 +142,16 @@ nsNativeFileSpec::nsNativeFileSpec(const nsFilePath& inPath)
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator = (const nsFilePath& inPath)
|
||||
void nsFileSpec::operator = (const nsFilePath& inPath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::StringAssign(mPath, (const char*)inPath);
|
||||
nsFileSpecHelpers::UnixToNative(mPath);
|
||||
} // nsNativeFileSpec::operator =
|
||||
mError = NS_OK;
|
||||
} // nsFileSpec::operator =
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFilePath::nsFilePath(const nsNativeFileSpec& inSpec)
|
||||
nsFilePath::nsFilePath(const nsFileSpec& inSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(NULL)
|
||||
{
|
||||
@@ -149,7 +159,7 @@ nsFilePath::nsFilePath(const nsNativeFileSpec& inSpec)
|
||||
} // nsFilePath::nsFilePath
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsFilePath::operator = (const nsNativeFileSpec& inSpec)
|
||||
void nsFilePath::operator = (const nsFileSpec& inSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::StringAssign(mPath, inSpec.mPath);
|
||||
@@ -157,84 +167,86 @@ void nsFilePath::operator = (const nsNativeFileSpec& inSpec)
|
||||
} // nsFilePath::operator =
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::SetLeafName(const char* inLeafName)
|
||||
void nsFileSpec::SetLeafName(const char* inLeafName)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::LeafReplace(mPath, '\\', inLeafName);
|
||||
} // nsNativeFileSpec::SetLeafName
|
||||
} // nsFileSpec::SetLeafName
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
char* nsNativeFileSpec::GetLeafName() const
|
||||
char* nsFileSpec::GetLeafName() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return nsFileSpecHelpers::GetLeaf(mPath, '\\');
|
||||
} // nsNativeFileSpec::GetLeafName
|
||||
} // nsFileSpec::GetLeafName
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::Exists() const
|
||||
PRBool nsFileSpec::Exists() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
struct stat st;
|
||||
return 0 == stat(mPath, &st);
|
||||
} // nsNativeFileSpec::Exists
|
||||
} // nsFileSpec::Exists
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::IsFile() const
|
||||
PRBool nsFileSpec::IsFile() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
struct stat st;
|
||||
return 0 == stat(mPath, &st) && (_S_IFREG & st.st_mode);
|
||||
} // nsNativeFileSpec::IsFile
|
||||
} // nsFileSpec::IsFile
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::IsDirectory() const
|
||||
PRBool nsFileSpec::IsDirectory() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
struct stat st;
|
||||
return 0 == stat(mPath, &st) && (_S_IFDIR & st.st_mode);
|
||||
} // nsNativeFileSpec::IsDirectory
|
||||
} // nsFileSpec::IsDirectory
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::GetParent(nsNativeFileSpec& outSpec) const
|
||||
void nsFileSpec::GetParent(nsFileSpec& outSpec) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::StringAssign(outSpec.mPath, mPath);
|
||||
char* cp = strrchr(outSpec.mPath, '\\');
|
||||
if (cp)
|
||||
*cp = '\0';
|
||||
} // nsNativeFileSpec::GetParent
|
||||
} // nsFileSpec::GetParent
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator += (const char* inRelativePath)
|
||||
void nsFileSpec::operator += (const char* inRelativePath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!inRelativePath || !mPath)
|
||||
return;
|
||||
|
||||
if (mPath[strlen(mPath) - 1] != '\\')
|
||||
char* newPath = nsFileSpecHelpers::ReallocCat(mPath, "\\");
|
||||
if (mPath[strlen(mPath) - 1] == '\\')
|
||||
nsFileSpecHelpers::ReallocCat(mPath, "x");
|
||||
else
|
||||
nsFileSpecHelpers::ReallocCat(mPath, "\\x");
|
||||
SetLeafName(inRelativePath);
|
||||
} // nsNativeFileSpec::operator +=
|
||||
} // nsFileSpec::operator +=
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::CreateDirectory(int /*mode*/)
|
||||
void nsFileSpec::CreateDirectory(int /*mode*/)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// Note that mPath is canonical!
|
||||
mkdir(mPath);
|
||||
} // nsNativeFileSpec::CreateDirectory
|
||||
} // nsFileSpec::CreateDirectory
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::Delete(bool inRecursive)
|
||||
void nsFileSpec::Delete(PRBool inRecursive)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (IsDirectory())
|
||||
{
|
||||
if (inRecursive)
|
||||
{
|
||||
for (nsDirectoryIterator i(*this); i; i++)
|
||||
for (nsDirectoryIterator i(*this); i.Exists(); i++)
|
||||
{
|
||||
nsNativeFileSpec& child = (nsNativeFileSpec&)i;
|
||||
nsFileSpec& child = (nsFileSpec&)i;
|
||||
child.Delete(inRecursive);
|
||||
}
|
||||
}
|
||||
@@ -244,7 +256,106 @@ void nsNativeFileSpec::Delete(bool inRecursive)
|
||||
{
|
||||
remove(mPath);
|
||||
}
|
||||
} // nsNativeFileSpec::Delete
|
||||
} // nsFileSpec::Delete
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult nsFileSpec::Rename(const char* inNewName)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// This function should not be used to move a file on disk.
|
||||
if (strchr(inNewName, '/'))
|
||||
return NS_FILE_FAILURE;
|
||||
|
||||
if (PR_Rename(*this, inNewName) != NS_OK)
|
||||
{
|
||||
return NS_FILE_FAILURE;
|
||||
}
|
||||
SetLeafName(inNewName);
|
||||
return NS_OK;
|
||||
} // nsFileSpec::Rename
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult nsFileSpec::Copy(const nsFileSpec& inParentDirectory) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// We can only copy into a directory, and (for now) can not copy entire directories
|
||||
|
||||
if (inParentDirectory.IsDirectory() && (! IsDirectory() ) )
|
||||
{
|
||||
char *leafname = GetLeafName();
|
||||
char* destPath = nsFileSpecHelpers::StringDup(inParentDirectory, ( strlen(inParentDirectory) + 1 + strlen(leafname) ) );
|
||||
strcat(destPath, "\\");
|
||||
strcat(destPath, leafname);
|
||||
delete [] leafname;
|
||||
|
||||
// CopyFile returns non-zero if succeeds
|
||||
int copyOK = CopyFile(*this, destPath, true);
|
||||
|
||||
delete[] destPath;
|
||||
|
||||
if (copyOK)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_FILE_FAILURE;
|
||||
} // nsFileSpec::Copy
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult nsFileSpec::Move(const nsFileSpec& nsNewParentDirectory) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// We can only copy into a directory, and (for now) can not copy entire directories
|
||||
|
||||
if (nsNewParentDirectory.IsDirectory() && (! IsDirectory() ) )
|
||||
{
|
||||
char *leafname = GetLeafName();
|
||||
char *destPath = nsFileSpecHelpers::StringDup(nsNewParentDirectory, ( strlen(nsNewParentDirectory) + 1 + strlen(leafname) ));
|
||||
strcat(destPath, "\\");
|
||||
strcat(destPath, leafname);
|
||||
delete [] leafname;
|
||||
|
||||
// MoveFile returns non-zero if succeeds
|
||||
int copyOK = MoveFile(*this, destPath);
|
||||
|
||||
delete [] destPath;
|
||||
|
||||
if (copyOK)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_FILE_FAILURE;
|
||||
} // nsFileSpec::Move
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult nsFileSpec::Execute(const char* inArgs ) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
|
||||
if (! IsDirectory())
|
||||
{
|
||||
char* fileNameWithArgs = NULL;
|
||||
|
||||
fileNameWithArgs = nsFileSpecHelpers::StringDup(mPath, ( strlen(mPath) + 1 + strlen(inArgs) ) );
|
||||
strcat(fileNameWithArgs, " ");
|
||||
strcat(fileNameWithArgs, inArgs);
|
||||
|
||||
int execResult = WinExec( fileNameWithArgs, SW_NORMAL );
|
||||
|
||||
delete [] fileNameWithArgs;
|
||||
|
||||
if (execResult > 31)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_FILE_FAILURE;
|
||||
} // nsFileSpec::Execute
|
||||
|
||||
//========================================================================================
|
||||
// nsDirectoryIterator
|
||||
@@ -252,7 +363,7 @@ void nsNativeFileSpec::Delete(bool inRecursive)
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator::nsDirectoryIterator(
|
||||
const nsNativeFileSpec& inDirectory
|
||||
const nsFileSpec& inDirectory
|
||||
, int inIterateDirection)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mCurrent(inDirectory)
|
||||
|
||||
@@ -16,10 +16,11 @@
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "string.h"
|
||||
#include "nsFileSpec.h"
|
||||
#include "nsFileStream.h"
|
||||
|
||||
//#include "string.h"
|
||||
|
||||
struct FilesTest
|
||||
{
|
||||
FilesTest() : mConsole() {}
|
||||
@@ -30,18 +31,25 @@ struct FilesTest
|
||||
int InputStream(const char* relativePath);
|
||||
int OutputStream(const char* relativePath);
|
||||
int IOStream(const char* relativePath);
|
||||
int Parent(const char* relativePath, nsNativeFileSpec& outParent);
|
||||
int Delete(nsNativeFileSpec& victim);
|
||||
int CreateDirectory(nsNativeFileSpec& victim);
|
||||
int IterateDirectoryChildren(nsNativeFileSpec& startChild);
|
||||
int Parent(const char* relativePath, nsFileSpec& outParent);
|
||||
int Delete(nsFileSpec& victim);
|
||||
int CreateDirectory(nsFileSpec& victim);
|
||||
int IterateDirectoryChildren(nsFileSpec& startChild);
|
||||
int CanonicalPath(const char* relativePath);
|
||||
int Persistence(const char* relativePath);
|
||||
|
||||
int Copy(const char* sourceFile, const char* targDir);
|
||||
int Move(const char* sourceFile, const char* targDir);
|
||||
int Rename(const char* sourceFile, const char* newName);
|
||||
|
||||
int Execute(const char* appName, const char* args);
|
||||
|
||||
void Banner(const char* bannerString);
|
||||
void Passed();
|
||||
void Failed();
|
||||
void Inspect();
|
||||
|
||||
nsOutputFileStream mConsole;
|
||||
nsOutputConsoleStream mConsole;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
@@ -59,7 +67,8 @@ void FilesTest::Banner(const char* bannerString)
|
||||
void FilesTest::Passed()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mConsole << "Test passed." << nsEndl;
|
||||
((nsOutputStream&)mConsole) << "Test passed.";
|
||||
mConsole << nsEndl;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
@@ -89,7 +98,7 @@ void FilesTest::WriteStuff(nsOutputFileStream& s)
|
||||
s << "As a unix path: \"" << (const char*)filePath << "\""<< nsEndl;
|
||||
|
||||
// Initialize a native file spec from a URL
|
||||
nsNativeFileSpec fileSpec(fileURL);
|
||||
nsFileSpec fileSpec(fileURL);
|
||||
s << "As a file spec: " << fileSpec << nsEndl;
|
||||
|
||||
// Make the spec unique (this one has no suffix).
|
||||
@@ -119,10 +128,10 @@ int FilesTest::OutputStream(const char* relativePath)
|
||||
{
|
||||
nsFilePath myTextFilePath(relativePath, true); // relative path.
|
||||
const char* pathAsString = (const char*)myTextFilePath;
|
||||
nsNativeFileSpec mySpec(myTextFilePath);
|
||||
nsFileSpec mySpec(myTextFilePath);
|
||||
{
|
||||
mConsole << "WRITING IDENTICAL OUTPUT TO " << pathAsString << nsEndl << nsEndl;
|
||||
nsOutputFileStream testStream(myTextFilePath);
|
||||
nsOutputFileStream testStream(mySpec);
|
||||
if (!testStream.is_open())
|
||||
{
|
||||
mConsole
|
||||
@@ -154,9 +163,10 @@ int FilesTest::IOStream(const char* relativePath)
|
||||
{
|
||||
nsFilePath myTextFilePath(relativePath, true); // relative path.
|
||||
const char* pathAsString = (const char*)myTextFilePath;
|
||||
nsFileSpec mySpec(myTextFilePath);
|
||||
mConsole
|
||||
<< "Replacing \"path\" by \"ZUUL\" in " << pathAsString << nsEndl << nsEndl;
|
||||
nsIOFileStream testStream(myTextFilePath);
|
||||
nsIOFileStream testStream(mySpec);
|
||||
if (!testStream.is_open())
|
||||
{
|
||||
mConsole
|
||||
@@ -183,6 +193,57 @@ int FilesTest::IOStream(const char* relativePath)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
int FilesTest::Persistence(
|
||||
const char* relativePathToWrite)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFilePath myTextFilePath(relativePathToWrite, true);
|
||||
const char* pathAsString = (const char*)myTextFilePath;
|
||||
nsFileSpec mySpec(myTextFilePath);
|
||||
|
||||
nsIOFileStream testStream(mySpec, (PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE));
|
||||
if (!testStream.is_open())
|
||||
{
|
||||
mConsole
|
||||
<< "ERROR: File "
|
||||
<< pathAsString
|
||||
<< " could not be opened for input+output"
|
||||
<< nsEndl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
nsPersistentFileDescriptor myPersistent(mySpec);
|
||||
mConsole
|
||||
<< "Writing persistent file data " << pathAsString << nsEndl << nsEndl;
|
||||
|
||||
testStream.seek(0); // check that the seek compiles
|
||||
testStream << myPersistent;
|
||||
|
||||
testStream.seek(0);
|
||||
|
||||
nsPersistentFileDescriptor mySecondPersistent;
|
||||
testStream >> mySecondPersistent;
|
||||
|
||||
mySpec = mySecondPersistent;
|
||||
#ifdef XP_MAC
|
||||
if (mySpec.Error())
|
||||
{
|
||||
Failed();
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!mySpec.Exists())
|
||||
{
|
||||
Failed();
|
||||
return -1;
|
||||
}
|
||||
|
||||
Passed();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
int FilesTest::InputStream(const char* relativePath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
@@ -190,7 +251,8 @@ int FilesTest::InputStream(const char* relativePath)
|
||||
nsFilePath myTextFilePath(relativePath, true);
|
||||
const char* pathAsString = (const char*)myTextFilePath;
|
||||
mConsole << "READING BACK DATA FROM " << pathAsString << nsEndl << nsEndl;
|
||||
nsInputFileStream testStream2(myTextFilePath);
|
||||
nsFileSpec mySpec(myTextFilePath);
|
||||
nsInputFileStream testStream2(mySpec);
|
||||
if (!testStream2.is_open())
|
||||
{
|
||||
mConsole
|
||||
@@ -215,12 +277,12 @@ int FilesTest::InputStream(const char* relativePath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
int FilesTest::Parent(
|
||||
const char* relativePath,
|
||||
nsNativeFileSpec& outParent)
|
||||
nsFileSpec& outParent)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFilePath myTextFilePath(relativePath, true);
|
||||
const char* pathAsString = (const char*)myTextFilePath;
|
||||
nsNativeFileSpec mySpec(myTextFilePath);
|
||||
nsFileSpec mySpec(myTextFilePath);
|
||||
|
||||
mySpec.GetParent(outParent);
|
||||
nsFilePath parentPath(outParent);
|
||||
@@ -235,7 +297,7 @@ int FilesTest::Parent(
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
int FilesTest::Delete(nsNativeFileSpec& victim)
|
||||
int FilesTest::Delete(nsFileSpec& victim)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// - Test of non-recursive delete
|
||||
@@ -284,7 +346,7 @@ int FilesTest::Delete(nsNativeFileSpec& victim)
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
int FilesTest::CreateDirectory(nsNativeFileSpec& dirSpec)
|
||||
int FilesTest::CreateDirectory(nsFileSpec& dirSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFilePath dirPath(dirSpec);
|
||||
@@ -306,27 +368,27 @@ int FilesTest::CreateDirectory(nsNativeFileSpec& dirSpec)
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
int FilesTest::IterateDirectoryChildren(nsNativeFileSpec& startChild)
|
||||
int FilesTest::IterateDirectoryChildren(nsFileSpec& startChild)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// - Test of directory iterator
|
||||
|
||||
nsNativeFileSpec grandparent;
|
||||
nsFileSpec grandparent;
|
||||
startChild.GetParent(grandparent); // should be the original default directory.
|
||||
nsFilePath grandparentPath(grandparent);
|
||||
|
||||
mConsole << "Forwards listing of " << (const char*)grandparentPath << ":" << nsEndl;
|
||||
for (nsDirectoryIterator i(grandparent, +1); i; i++)
|
||||
for (nsDirectoryIterator i(grandparent, +1); i.Exists(); i++)
|
||||
{
|
||||
char* itemName = ((nsNativeFileSpec&)i).GetLeafName();
|
||||
char* itemName = ((nsFileSpec&)i).GetLeafName();
|
||||
mConsole << '\t' << itemName << nsEndl;
|
||||
delete [] itemName;
|
||||
}
|
||||
|
||||
mConsole << "Backwards listing of " << (const char*)grandparentPath << ":" << nsEndl;
|
||||
for (nsDirectoryIterator j(grandparent, -1); j; j--)
|
||||
for (nsDirectoryIterator j(grandparent, -1); j.Exists(); j--)
|
||||
{
|
||||
char* itemName = ((nsNativeFileSpec&)j).GetLeafName();
|
||||
char* itemName = ((nsFileSpec&)j).GetLeafName();
|
||||
mConsole << '\t' << itemName << nsEndl;
|
||||
delete [] itemName;
|
||||
}
|
||||
@@ -355,6 +417,110 @@ int FilesTest::CanonicalPath(
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
int FilesTest::Copy(const char* file, const char* dir)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpec dirPath(dir, true);
|
||||
|
||||
dirPath.CreateDirectory();
|
||||
if (! dirPath.Exists())
|
||||
{
|
||||
Failed();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
nsFileSpec mySpec(file, true); // relative path.
|
||||
{
|
||||
nsIOFileStream testStream(mySpec); // creates the file
|
||||
// Scope ends here, file gets closed
|
||||
}
|
||||
|
||||
nsFileSpec filePath(file);
|
||||
if (! filePath.Exists())
|
||||
{
|
||||
Failed();
|
||||
return -1;
|
||||
}
|
||||
|
||||
nsresult error = filePath.Copy(dirPath);
|
||||
|
||||
dirPath += filePath.GetLeafName();
|
||||
if (! dirPath.Exists() || ! filePath.Exists() || NS_FAILED(error))
|
||||
{
|
||||
Failed();
|
||||
return -1;
|
||||
}
|
||||
|
||||
Passed();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
int FilesTest::Move(const char* file, const char* dir)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpec dirPath(dir, true);
|
||||
|
||||
dirPath.CreateDirectory();
|
||||
if (! dirPath.Exists())
|
||||
{
|
||||
Failed();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
nsFileSpec srcSpec(file, true); // relative path.
|
||||
{
|
||||
nsIOFileStream testStream(srcSpec); // creates the file
|
||||
// file gets closed here because scope ends here.
|
||||
};
|
||||
|
||||
if (! srcSpec.Exists())
|
||||
{
|
||||
Failed();
|
||||
return -1;
|
||||
}
|
||||
|
||||
nsresult error = srcSpec.Move(dirPath);
|
||||
|
||||
|
||||
dirPath += srcSpec.GetLeafName();
|
||||
if (! dirPath.Exists() || srcSpec.Exists() || NS_FAILED(error))
|
||||
{
|
||||
Failed();
|
||||
return -1;
|
||||
}
|
||||
|
||||
Passed();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
int FilesTest::Execute(const char* appName, const char* args)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpec appPath(appName, false);
|
||||
if (!appPath.Exists())
|
||||
{
|
||||
Failed();
|
||||
return -1;
|
||||
}
|
||||
|
||||
nsresult error = appPath.Execute(args);
|
||||
if (NS_FAILED(error))
|
||||
{
|
||||
Failed();
|
||||
return -1;
|
||||
}
|
||||
|
||||
Passed();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
int FilesTest::RunAllTests()
|
||||
// For use with DEBUG defined.
|
||||
@@ -389,7 +555,7 @@ int FilesTest::RunAllTests()
|
||||
return -1;
|
||||
|
||||
Banner("Parent");
|
||||
nsNativeFileSpec parent;
|
||||
nsFileSpec parent;
|
||||
if (Parent("mumble/iotest.txt", parent) != 0)
|
||||
return -1;
|
||||
|
||||
@@ -405,6 +571,36 @@ int FilesTest::RunAllTests()
|
||||
if (IterateDirectoryChildren(parent) != 0)
|
||||
return -1;
|
||||
|
||||
Banner("Copy");
|
||||
if (Copy("mumble/copyfile.txt", "mumble/copy") != 0)
|
||||
return -1;
|
||||
|
||||
Banner("Move");
|
||||
if (Move("mumble/moveFile.txt", "mumble/move") != 0)
|
||||
return -1;
|
||||
|
||||
Banner("Execute");
|
||||
#ifdef XP_MAC
|
||||
// This path is hard-coded to test on jrm's machine. Finding an app
|
||||
// on an arbitrary Macintosh would cost more trouble than it's worth.
|
||||
// Change path to suit.
|
||||
if NS_FAILED(Execute("/Projects/Nav45_BRANCH/ns/cmd/macfe/"\
|
||||
"projects/client45/Client45PPC", ""))
|
||||
#elif XP_PC
|
||||
if NS_FAILED(Execute("c:\\windows\\notepad.exe", ""))
|
||||
#else
|
||||
if NS_FAILED(Execute("/bin/ls", "/"))
|
||||
#endif
|
||||
return -1;
|
||||
|
||||
Banner("Persistence");
|
||||
if (Persistence("mumble/filedesc.dat") != 0)
|
||||
return -1;
|
||||
|
||||
Banner("Delete again (to clean up our mess)");
|
||||
if (Delete(parent) != 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -413,7 +609,6 @@ int main()
|
||||
// For use with DEBUG defined.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
|
||||
FilesTest tester;
|
||||
return tester.RunAllTests();
|
||||
} // main
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
#include "nsDebug.h"
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "plstr.h"
|
||||
#include "plbase64.h"
|
||||
#include "prmem.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@@ -40,7 +43,7 @@ NS_NAMESPACE nsFileSpecHelpers
|
||||
char inSeparator,
|
||||
const char* inLeafName);
|
||||
#ifndef XP_MAC
|
||||
NS_NAMESPACE_PROTOTYPE void Canonify(char*& ioPath, bool inMakeDirs);
|
||||
NS_NAMESPACE_PROTOTYPE void Canonify(char*& ioPath, PRBool inMakeDirs);
|
||||
NS_NAMESPACE_PROTOTYPE void MakeAllDirectories(const char* inPath, int mode);
|
||||
#endif
|
||||
NS_NAMESPACE_PROTOTYPE char* GetLeaf(const char* inPath, char inSeparator); // allocated
|
||||
@@ -54,6 +57,14 @@ NS_NAMESPACE nsFileSpecHelpers
|
||||
#endif
|
||||
} NS_NAMESPACE_END
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult ns_file_convert_result(PRInt32 nativeErr)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return nativeErr ?
|
||||
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_FILES,((nativeErr)&0xFFFF))
|
||||
: NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
char* nsFileSpecHelpers::StringDup(
|
||||
@@ -65,7 +76,7 @@ char* nsFileSpecHelpers::StringDup(
|
||||
allocLength = strlen(inString);
|
||||
char* newPath = inString || allocLength ? new char[allocLength + 1] : nsnull;
|
||||
if (!newPath)
|
||||
return NULL;
|
||||
return nsnull;
|
||||
strcpy(newPath, inString);
|
||||
return newPath;
|
||||
} // nsFileSpecHelpers::StringDup
|
||||
@@ -77,7 +88,7 @@ char* nsFileSpecHelpers::AllocCat(
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!inString1)
|
||||
return inString2 ? StringDup(inString2) : (char*)NULL;
|
||||
return inString2 ? StringDup(inString2) : (char*)nsnull;
|
||||
if (!inString2)
|
||||
return StringDup(inString1);
|
||||
char* outString = StringDup(inString1, strlen(inString1) + strlen(inString2));
|
||||
@@ -95,7 +106,7 @@ char* nsFileSpecHelpers::StringAssign(
|
||||
if (!inString2)
|
||||
{
|
||||
delete [] ioString;
|
||||
ioString = (char*)NULL;
|
||||
ioString = (char*)nsnull;
|
||||
return ioString;
|
||||
}
|
||||
if (!ioString || (strlen(inString2) > strlen(ioString)))
|
||||
@@ -125,8 +136,19 @@ void nsFileSpecHelpers::LeafReplace(
|
||||
}
|
||||
char* lastSeparator = strrchr(ioPath, inSeparator);
|
||||
int oldLength = strlen(ioPath);
|
||||
*(++lastSeparator) = '\0'; // strip the current leaf name
|
||||
int newLength = lastSeparator - ioPath + strlen(inLeafName);
|
||||
PRBool trailingSeparator = (lastSeparator + 1 == ioPath + oldLength);
|
||||
if (trailingSeparator)
|
||||
{
|
||||
*lastSeparator = '\0';
|
||||
lastSeparator = strrchr(ioPath, inSeparator);
|
||||
}
|
||||
if (lastSeparator)
|
||||
lastSeparator++; // point at the trailing string
|
||||
else
|
||||
lastSeparator = ioPath; // the full monty
|
||||
*lastSeparator = '\0'; // strip the current leaf name
|
||||
|
||||
int newLength = (lastSeparator - ioPath) + strlen(inLeafName) + int(trailingSeparator);
|
||||
if (newLength > oldLength)
|
||||
{
|
||||
char* newPath = StringDup(ioPath, newLength + 1);
|
||||
@@ -134,7 +156,14 @@ void nsFileSpecHelpers::LeafReplace(
|
||||
ioPath = newPath;
|
||||
}
|
||||
strcat(ioPath, inLeafName);
|
||||
} // nsNativeFileSpec::LeafReplace
|
||||
if (trailingSeparator)
|
||||
{
|
||||
// If the original ended in a slash, then the new one should, too.
|
||||
char sepStr[2] = "/";
|
||||
*sepStr = inSeparator;
|
||||
strcat(ioPath, sepStr);
|
||||
}
|
||||
} // nsFileSpecHelpers::LeafReplace
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
char* nsFileSpecHelpers::GetLeaf(const char* inPath, char inSeparator)
|
||||
@@ -142,12 +171,32 @@ char* nsFileSpecHelpers::GetLeaf(const char* inPath, char inSeparator)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!inPath)
|
||||
return NULL;
|
||||
char* lastSeparator = strrchr(inPath, inSeparator);
|
||||
if (lastSeparator)
|
||||
return StringDup(++lastSeparator);
|
||||
return StringDup(inPath);
|
||||
} // nsNativeFileSpec::GetLeaf
|
||||
return nsnull;
|
||||
const char* lastSeparator = strrchr(inPath, inSeparator);
|
||||
|
||||
// If there was no separator, then return a copy of the caller's path.
|
||||
if (!lastSeparator)
|
||||
return StringDup(inPath);
|
||||
|
||||
// So there's at least one separator. What's just after it?
|
||||
// If the separator was not the last character, return the trailing string.
|
||||
const char* leafPointer = lastSeparator + 1;
|
||||
if (*leafPointer)
|
||||
return StringDup(leafPointer);
|
||||
|
||||
// So now, separator was the last character. Poke in a null instead.
|
||||
*(char*)lastSeparator = '\0'; // Should use const_cast, but Unix has old compiler.
|
||||
leafPointer = strrchr(inPath, inSeparator);
|
||||
char* result = leafPointer ? StringDup(leafPointer++) : StringDup(inPath);
|
||||
// Restore the poked null before returning.
|
||||
*(char*)lastSeparator = inSeparator;
|
||||
#ifdef XP_PC
|
||||
// If it's a drive letter use the colon notation.
|
||||
if (!leafPointer && strlen(result) == 2 && result[1] == '|')
|
||||
result[1] = ':';
|
||||
#endif
|
||||
return result;
|
||||
} // nsFileSpecHelpers::GetLeaf
|
||||
|
||||
#if defined(XP_UNIX) || defined(XP_PC)
|
||||
|
||||
@@ -177,7 +226,7 @@ void nsFileSpecHelpers::MakeAllDirectories(const char* inPath, int mode)
|
||||
if (currentEnd)
|
||||
{
|
||||
*currentEnd = '\0';
|
||||
nsNativeFileSpec spec(nsFilePath(pathCopy, false));
|
||||
nsFileSpec spec(nsFilePath(pathCopy, PR_FALSE));
|
||||
do
|
||||
{
|
||||
// If the node doesn't exist, and it is not the initial node in a full path,
|
||||
@@ -209,7 +258,7 @@ char* nsFileSpecHelpers::ReallocCat(char*& ioString, const char* inString1)
|
||||
delete [] ioString;
|
||||
ioString = newString;
|
||||
return ioString;
|
||||
} // nsNativeFileSpec::ReallocCat
|
||||
} // nsFileSpecHelpers::ReallocCat
|
||||
|
||||
#if defined(XP_PC)
|
||||
#include "windows/nsFileSpecWin.cpp" // Windows-specific implementations
|
||||
@@ -225,7 +274,7 @@ char* nsFileSpecHelpers::ReallocCat(char*& ioString, const char* inString1)
|
||||
|
||||
#ifndef XP_MAC
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFileURL::nsFileURL(const char* inString, bool inCreateDirs)
|
||||
nsFileURL::nsFileURL(const char* inString, PRBool inCreateDirs)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mURL(nsnull)
|
||||
{
|
||||
@@ -243,7 +292,7 @@ nsFileURL::nsFileURL(const nsFileURL& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mURL(nsFileSpecHelpers::StringDup(inOther.mURL))
|
||||
#ifdef XP_MAC
|
||||
, mNativeFileSpec(inOther.GetNativeSpec())
|
||||
, mFileSpec(inOther.GetFileSpec())
|
||||
#endif
|
||||
{
|
||||
} // nsFileURL::nsFileURL
|
||||
@@ -253,16 +302,16 @@ nsFileURL::nsFileURL(const nsFilePath& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mURL(nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)inOther))
|
||||
#ifdef XP_MAC
|
||||
, mNativeFileSpec(inOther.GetNativeSpec())
|
||||
, mFileSpec(inOther.GetFileSpec())
|
||||
#endif
|
||||
{
|
||||
} // nsFileURL::nsFileURL
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFileURL::nsFileURL(const nsNativeFileSpec& inOther)
|
||||
nsFileURL::nsFileURL(const nsFileSpec& inOther)
|
||||
: mURL(nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)nsFilePath(inOther)))
|
||||
#ifdef XP_MAC
|
||||
, mNativeFileSpec(inOther)
|
||||
, mFileSpec(inOther)
|
||||
#endif
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
@@ -282,7 +331,7 @@ void nsFileURL::operator = (const char* inString)
|
||||
nsFileSpecHelpers::StringAssign(mURL, inString);
|
||||
NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!");
|
||||
#ifdef XP_MAC
|
||||
mNativeFileSpec = inString + kFileURLPrefixLength;
|
||||
mFileSpec = inString + kFileURLPrefixLength;
|
||||
#endif
|
||||
} // nsFileURL::operator =
|
||||
|
||||
@@ -292,7 +341,7 @@ void nsFileURL::operator = (const nsFileURL& inOther)
|
||||
{
|
||||
mURL = nsFileSpecHelpers::StringAssign(mURL, inOther.mURL);
|
||||
#ifdef XP_MAC
|
||||
mNativeFileSpec = inOther.GetNativeSpec();
|
||||
mFileSpec = inOther.GetFileSpec();
|
||||
#endif
|
||||
} // nsFileURL::operator =
|
||||
|
||||
@@ -303,27 +352,29 @@ void nsFileURL::operator = (const nsFilePath& inOther)
|
||||
delete [] mURL;
|
||||
mURL = nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)inOther);
|
||||
#ifdef XP_MAC
|
||||
mNativeFileSpec = inOther.GetNativeSpec();
|
||||
mFileSpec = inOther.GetFileSpec();
|
||||
#endif
|
||||
} // nsFileURL::operator =
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsFileURL::operator = (const nsNativeFileSpec& inOther)
|
||||
void nsFileURL::operator = (const nsFileSpec& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
delete [] mURL;
|
||||
mURL = nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)nsFilePath(inOther));
|
||||
#ifdef XP_MAC
|
||||
mNativeFileSpec = inOther;
|
||||
mFileSpec = inOther;
|
||||
#endif
|
||||
} // nsFileURL::operator =
|
||||
|
||||
#if DEBUG
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicOutStream& operator << (nsBasicOutStream& s, const nsFileURL& url)
|
||||
nsOutputStream& operator << (nsOutputStream& s, const nsFileURL& url)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return (s << url.mURL);
|
||||
}
|
||||
#endif
|
||||
|
||||
//========================================================================================
|
||||
// nsFilePath implementation
|
||||
@@ -332,14 +383,14 @@ nsBasicOutStream& operator << (nsBasicOutStream& s, const nsFileURL& url)
|
||||
nsFilePath::nsFilePath(const nsFilePath& inPath)
|
||||
: mPath(nsFileSpecHelpers::StringDup(inPath.mPath))
|
||||
#ifdef XP_MAC
|
||||
, mNativeFileSpec(inPath.mNativeFileSpec)
|
||||
, mFileSpec(inPath.mFileSpec)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
#ifndef XP_MAC
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFilePath::nsFilePath(const char* inString, bool inCreateDirs)
|
||||
nsFilePath::nsFilePath(const char* inString, PRBool inCreateDirs)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(nsFileSpecHelpers::StringDup(inString))
|
||||
{
|
||||
@@ -362,14 +413,14 @@ nsFilePath::nsFilePath(const nsFileURL& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(nsFileSpecHelpers::StringDup(inOther.mURL + kFileURLPrefixLength))
|
||||
#ifdef XP_MAC
|
||||
, mNativeFileSpec(inOther.GetNativeSpec())
|
||||
, mFileSpec(inOther.GetFileSpec())
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef XP_UNIX
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFilePath::nsFilePath(const nsNativeFileSpec& inOther)
|
||||
nsFilePath::nsFilePath(const nsFileSpec& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(nsFileSpecHelpers::StringDup(inOther.mPath))
|
||||
{
|
||||
@@ -385,7 +436,7 @@ nsFilePath::~nsFilePath()
|
||||
|
||||
#ifdef XP_UNIX
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsFilePath::operator = (const nsNativeFileSpec& inOther)
|
||||
void nsFilePath::operator = (const nsFileSpec& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mPath = nsFileSpecHelpers::StringAssign(mPath, inOther.mPath);
|
||||
@@ -398,14 +449,14 @@ void nsFilePath::operator = (const char* inString)
|
||||
{
|
||||
NS_ASSERTION(strstr(inString, kFileURLPrefix) != inString, "URL passed as path");
|
||||
#ifdef XP_MAC
|
||||
mNativeFileSpec = inString;
|
||||
nsFileSpecHelpers::StringAssign(mPath, (const char*)nsFilePath(mNativeFileSpec));
|
||||
mFileSpec = inString;
|
||||
nsFileSpecHelpers::StringAssign(mPath, (const char*)nsFilePath(mFileSpec));
|
||||
#else
|
||||
#ifdef XP_PC
|
||||
nsFileSpecHelpers::UnixToNative(mPath);
|
||||
#endif
|
||||
// Make canonical and absolute.
|
||||
nsFileSpecHelpers::Canonify(mPath, false /* XXX? */);
|
||||
nsFileSpecHelpers::Canonify(mPath, PR_FALSE /* XXX? */);
|
||||
#ifdef XP_PC
|
||||
nsFileSpecHelpers::NativeToUnix(mPath);
|
||||
#endif
|
||||
@@ -418,7 +469,7 @@ void nsFilePath::operator = (const nsFileURL& inOther)
|
||||
{
|
||||
nsFileSpecHelpers::StringAssign(mPath, (const char*)nsFilePath(inOther));
|
||||
#ifdef XP_MAC
|
||||
mNativeFileSpec = inOther.GetNativeSpec();
|
||||
mFileSpec = inOther.GetFileSpec();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -433,40 +484,51 @@ void nsFilePath::operator = (const nsFilePath& inOther)
|
||||
}
|
||||
|
||||
//========================================================================================
|
||||
// nsNativeFileSpec implementation
|
||||
// nsFileSpec implementation
|
||||
//========================================================================================
|
||||
|
||||
#ifndef XP_MAC
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec()
|
||||
nsFileSpec::nsFileSpec()
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(NULL)
|
||||
: mPath(nsnull)
|
||||
, mError(NS_OK)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec(const nsFileURL& inURL)
|
||||
nsFileSpec::nsFileSpec(const nsPersistentFileDescriptor& inDescriptor)
|
||||
//----------------------------------------------------------------------------------------
|
||||
#ifndef XP_MAC
|
||||
: mPath(NULL)
|
||||
: mPath(nsnull)
|
||||
#endif
|
||||
{
|
||||
*this = inDescriptor;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFileSpec::nsFileSpec(const nsFileURL& inURL)
|
||||
//----------------------------------------------------------------------------------------
|
||||
#ifndef XP_MAC
|
||||
: mPath(nsnull)
|
||||
#endif
|
||||
{
|
||||
*this = nsFilePath(inURL); // convert to unix path first
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::MakeUnique(const char* inSuggestedLeafName)
|
||||
void nsFileSpec::MakeUnique(const char* inSuggestedLeafName)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (inSuggestedLeafName && *inSuggestedLeafName)
|
||||
SetLeafName(inSuggestedLeafName);
|
||||
|
||||
MakeUnique();
|
||||
} // nsNativeFileSpec::MakeUnique
|
||||
} // nsFileSpec::MakeUnique
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::MakeUnique()
|
||||
void nsFileSpec::MakeUnique()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!Exists())
|
||||
@@ -497,51 +559,82 @@ void nsNativeFileSpec::MakeUnique()
|
||||
if (*suffix)
|
||||
delete [] suffix;
|
||||
delete [] leafName;
|
||||
} // nsNativeFileSpec::MakeUnique
|
||||
} // nsFileSpec::MakeUnique
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator = (const nsFileURL& inURL)
|
||||
void nsFileSpec::operator = (const nsFileURL& inURL)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
*this = nsFilePath(inURL); // convert to unix path first
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsFileSpec::operator = (const nsPersistentFileDescriptor& inDescriptor)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
|
||||
void* data;
|
||||
PRInt32 dataSize;
|
||||
inDescriptor.GetData(data, dataSize);
|
||||
|
||||
#ifdef XP_MAC
|
||||
char* decodedData = PL_Base64Decode((const char*)data, (int)dataSize, nsnull);
|
||||
// Cast to an alias record and resolve.
|
||||
AliasHandle aliasH = nsnull;
|
||||
mError = NS_FILE_RESULT(PtrToHand(decodedData, &(Handle)aliasH, (dataSize * 3) / 4));
|
||||
PR_Free(decodedData);
|
||||
if (NS_SUCCEEDED(mError))
|
||||
return; // not enough memory?
|
||||
|
||||
Boolean changed;
|
||||
mError = NS_FILE_RESULT(::ResolveAlias(nsnull, aliasH, &mSpec, &changed));
|
||||
DisposeHandle((Handle) aliasH);
|
||||
#else
|
||||
nsFileSpecHelpers::StringAssign(mPath, (char*)data);
|
||||
mError = NS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
//========================================================================================
|
||||
// UNIX & WIN nsNativeFileSpec implementation
|
||||
// UNIX & WIN nsFileSpec implementation
|
||||
//========================================================================================
|
||||
|
||||
#ifdef XP_UNIX
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec(const nsFilePath& inPath)
|
||||
nsFileSpec::nsFileSpec(const nsFilePath& inPath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(nsFileSpecHelpers::StringDup((const char*)inPath))
|
||||
, mError(NS_OK)
|
||||
{
|
||||
}
|
||||
#endif // XP_UNIX
|
||||
|
||||
#ifdef XP_UNIX
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator = (const nsFilePath& inPath)
|
||||
void nsFileSpec::operator = (const nsFilePath& inPath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::StringAssign(mPath, (const char*)inPath);
|
||||
mError = NS_OK;
|
||||
}
|
||||
#endif //XP_UNIX
|
||||
|
||||
#if defined(XP_UNIX) || defined(XP_PC)
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec(const nsNativeFileSpec& inSpec)
|
||||
nsFileSpec::nsFileSpec(const nsFileSpec& inSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(nsFileSpecHelpers::StringDup(inSpec.mPath))
|
||||
, mError(NS_OK)
|
||||
{
|
||||
}
|
||||
#endif //XP_UNIX
|
||||
|
||||
#if defined(XP_UNIX) || defined(XP_PC)
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec(const char* inString, bool inCreateDirs)
|
||||
nsFileSpec::nsFileSpec(const char* inString, PRBool inCreateDirs)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(nsFileSpecHelpers::StringDup(inString))
|
||||
, mError(NS_OK)
|
||||
{
|
||||
// Make canonical and absolute.
|
||||
nsFileSpecHelpers::Canonify(mPath, inCreateDirs);
|
||||
@@ -549,7 +642,7 @@ nsNativeFileSpec::nsNativeFileSpec(const char* inString, bool inCreateDirs)
|
||||
#endif //XP_UNIX,PC
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::~nsNativeFileSpec()
|
||||
nsFileSpec::~nsFileSpec()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
#ifndef XP_MAC
|
||||
@@ -559,39 +652,160 @@ nsNativeFileSpec::~nsNativeFileSpec()
|
||||
|
||||
#if defined(XP_UNIX) || defined(XP_PC)
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator = (const nsNativeFileSpec& inSpec)
|
||||
void nsFileSpec::operator = (const nsFileSpec& inSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mPath = nsFileSpecHelpers::StringAssign(mPath, inSpec.mPath);
|
||||
mError = inSpec.Error();
|
||||
}
|
||||
#endif //XP_UNIX
|
||||
|
||||
|
||||
#if defined(XP_UNIX) || defined(XP_PC)
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator = (const char* inString)
|
||||
void nsFileSpec::operator = (const char* inString)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mPath = nsFileSpecHelpers::StringAssign(mPath, inString);
|
||||
// Make canonical and absolute.
|
||||
nsFileSpecHelpers::Canonify(mPath, true /* XXX? */);
|
||||
nsFileSpecHelpers::Canonify(mPath, PR_TRUE /* XXX? */);
|
||||
mError = NS_OK;
|
||||
}
|
||||
#endif //XP_UNIX
|
||||
|
||||
#if DEBUG
|
||||
#if (defined(XP_UNIX) || defined(XP_PC))
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicOutStream& operator << (nsBasicOutStream& s, const nsNativeFileSpec& spec)
|
||||
nsOutputStream& operator << (nsOutputStream& s, const nsFileSpec& spec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return (s << (const char*)spec.mPath);
|
||||
}
|
||||
#endif // DEBUG && XP_UNIX
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec nsNativeFileSpec::operator + (const char* inRelativePath) const
|
||||
nsFileSpec nsFileSpec::operator + (const char* inRelativePath) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsNativeFileSpec result = *this;
|
||||
nsFileSpec result = *this;
|
||||
result += inRelativePath;
|
||||
return result;
|
||||
} // nsNativeFileSpec::operator +
|
||||
} // nsFileSpec::operator +
|
||||
|
||||
//========================================================================================
|
||||
// class nsPersistentFileDescriptor
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsPersistentFileDescriptor::nsPersistentFileDescriptor(const nsPersistentFileDescriptor& inDesc)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mDescriptorString(nsFileSpecHelpers::StringDup(inDesc.mDescriptorString))
|
||||
{
|
||||
} // nsPersistentFileDescriptor::nsPersistentFileDescriptor
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsPersistentFileDescriptor::operator = (const nsPersistentFileDescriptor& inDesc)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::StringAssign(mDescriptorString, inDesc.mDescriptorString);
|
||||
} // nsPersistentFileDescriptor::operator =
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsPersistentFileDescriptor::nsPersistentFileDescriptor(const nsFileSpec& inSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mDescriptorString(nsnull)
|
||||
{
|
||||
*this = inSpec;
|
||||
} // nsPersistentFileDescriptor::nsPersistentFileDescriptor
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsPersistentFileDescriptor::operator = (const nsFileSpec& inSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
#ifdef XP_MAC
|
||||
if (inSpec.Error())
|
||||
return;
|
||||
AliasHandle aliasH;
|
||||
OSErr err = NewAlias(nil, inSpec.operator const FSSpec* const (), &aliasH);
|
||||
if (err != noErr)
|
||||
return;
|
||||
|
||||
PRUint32 bytes = GetHandleSize((Handle) aliasH);
|
||||
HLock((Handle) aliasH);
|
||||
char* buf = PL_Base64Encode((const char*)*aliasH, bytes, nsnull);
|
||||
DisposeHandle((Handle) aliasH);
|
||||
|
||||
nsFileSpecHelpers::StringAssign(mDescriptorString, buf);
|
||||
PR_Free(buf);
|
||||
#else
|
||||
nsFileSpecHelpers::StringAssign(mDescriptorString, inSpec);
|
||||
#endif // XP_MAC
|
||||
} // nsPersistentFileDescriptor::operator =
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsPersistentFileDescriptor::~nsPersistentFileDescriptor()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
delete [] mDescriptorString;
|
||||
} // nsPersistentFileDescriptor::~nsPersistentFileDescriptor
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsPersistentFileDescriptor::GetData(void*& outData, PRInt32& outSize) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
outSize = PL_strlen(mDescriptorString);
|
||||
outData = mDescriptorString;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsPersistentFileDescriptor::SetData(const void* inData, PRInt32 inSize)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
delete [] mDescriptorString;
|
||||
mDescriptorString = new char[1 + inSize];
|
||||
if (!mDescriptorString)
|
||||
return;
|
||||
memcpy(mDescriptorString, inData, inSize);
|
||||
mDescriptorString[inSize] = '\0';
|
||||
}
|
||||
|
||||
#define MAX_PERSISTENT_DATA_SIZE 1000
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsInputStream& operator >> (nsInputStream& s, nsPersistentFileDescriptor& d)
|
||||
// reads the data from a file
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
char bigBuffer[MAX_PERSISTENT_DATA_SIZE + 1];
|
||||
// The first 8 bytes of the data should be a hex version of the data size to follow.
|
||||
PRInt32 bytesRead = 8;
|
||||
bytesRead = s.read(bigBuffer, bytesRead);
|
||||
if (bytesRead != 8)
|
||||
return (nsInputFileStream&)s;
|
||||
bigBuffer[8] = '\0';
|
||||
sscanf(bigBuffer, "%lx", &bytesRead);
|
||||
if (bytesRead > MAX_PERSISTENT_DATA_SIZE)
|
||||
return (nsInputFileStream&)s; // preposterous.
|
||||
// Now we know how many bytes to read, do it.
|
||||
s.read(bigBuffer, bytesRead);
|
||||
d.SetData(bigBuffer, bytesRead);
|
||||
return (nsInputFileStream&)s;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsOutputStream& operator << (nsOutputStream& s, const nsPersistentFileDescriptor& d)
|
||||
// writes the data to a file
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
char littleBuf[9];
|
||||
PRInt32 dataSize;
|
||||
void* data;
|
||||
d.GetData(data, dataSize);
|
||||
// First write (in hex) the length of the data to follow. Exactly 8 bytes
|
||||
sprintf(littleBuf, "%0.8x", dataSize);
|
||||
s << littleBuf;
|
||||
// Now write the data itself
|
||||
s << d.mDescriptorString;
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,16 @@
|
||||
//
|
||||
// Classes defined:
|
||||
//
|
||||
// nsFilePath, nsFileURL, nsNativeFileSpec.
|
||||
// nsFilePath, nsFileURL, nsFileSpec, nsPersistentFileDescriptor.
|
||||
//
|
||||
// Q. How should I represent files at run time?
|
||||
// A. Use nsFileSpec. Using char* will lose information on some platforms.
|
||||
//
|
||||
// Q. Then what are nsFilePath and nsFileURL for?
|
||||
// A. Only when you need a char* parameter for legacy code.
|
||||
//
|
||||
// Q. How should I represent files in a persistent way (eg, in a disk file)?
|
||||
// A. Use nsPersistentFileDescriptor. Convert to and from nsFileSpec at run time.
|
||||
//
|
||||
// This suite provides the following services:
|
||||
//
|
||||
@@ -63,7 +72,7 @@
|
||||
//
|
||||
// Initialize a native file spec from a URL
|
||||
//
|
||||
// nsNativeFileSpec fileSpec(fileURL);
|
||||
// nsFileSpec fileSpec(fileURL);
|
||||
//
|
||||
// Make the spec unique (this one has no suffix).
|
||||
//
|
||||
@@ -103,6 +112,7 @@
|
||||
#define _FILESPEC_H_
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsError.h"
|
||||
|
||||
//========================================================================================
|
||||
// Compiler-specific macros, as needed
|
||||
@@ -116,11 +126,13 @@
|
||||
#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 ===============================
|
||||
@@ -137,33 +149,50 @@
|
||||
// Here are the allowable ways to describe a file.
|
||||
//========================================================================================
|
||||
|
||||
class nsFilePath; // This can be passed to NSPR file I/O routines.
|
||||
class nsFileSpec; // Preferred. For i/o use nsInputFileStream, nsOutputFileStream
|
||||
class nsFilePath; // This can be passed to NSPR file I/O routines, if you must.
|
||||
class nsFileURL;
|
||||
class nsNativeFileSpec;
|
||||
class nsPersistentFileDescriptor; // Used for storage across program launches.
|
||||
|
||||
#define kFileURLPrefix "file://"
|
||||
#define kFileURLPrefixLength (7)
|
||||
|
||||
class nsBasicOutStream;
|
||||
class nsOutputStream;
|
||||
class nsInputStream;
|
||||
class nsOutputFileStream;
|
||||
class nsInputFileStream;
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsNativeFileSpec
|
||||
// Conversion of native file errors to nsresult values. These are really only for use
|
||||
// in the file module, clients of this interface shouldn't really need them.
|
||||
// Error results returned from this interface have, in the low-order 16 bits,
|
||||
// native errors that are masked to 16 bits. Assumption: a native error of 0 is success
|
||||
// on all platforms. Note the way we define this using an inline function. This
|
||||
// avoids multiple evaluation if people go NS_FILE_RESULT(function_call()).
|
||||
#define NS_FILE_RESULT(x) ns_file_convert_result((PRInt32)x)
|
||||
nsresult ns_file_convert_result(PRInt32 nativeErr);
|
||||
#define NS_FILE_FAILURE NS_FILE_RESULT(-1)
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsFileSpec
|
||||
// This is whatever each platform really prefers to describe files as. Declared first
|
||||
// because the other two types have an embeded nsNativeFileSpec object.
|
||||
// because the other two types have an embeded nsFileSpec object.
|
||||
//========================================================================================
|
||||
{
|
||||
public:
|
||||
nsNativeFileSpec();
|
||||
explicit nsNativeFileSpec(const char* inString, bool inCreateDirs = false);
|
||||
explicit nsNativeFileSpec(const nsFilePath& inPath);
|
||||
explicit nsNativeFileSpec(const nsFileURL& inURL);
|
||||
nsNativeFileSpec(const nsNativeFileSpec& inPath);
|
||||
virtual ~nsNativeFileSpec();
|
||||
nsFileSpec();
|
||||
NS_EXPLICIT nsFileSpec(const char* inString, PRBool inCreateDirs = PR_FALSE);
|
||||
NS_EXPLICIT nsFileSpec(const nsFilePath& inPath);
|
||||
NS_EXPLICIT nsFileSpec(const nsFileURL& inURL);
|
||||
NS_EXPLICIT nsFileSpec(const nsPersistentFileDescriptor& inURL);
|
||||
nsFileSpec(const nsFileSpec& inPath);
|
||||
virtual ~nsFileSpec();
|
||||
|
||||
void operator = (const char* inPath);
|
||||
void operator = (const nsFilePath& inPath);
|
||||
void operator = (const nsFileURL& inURL);
|
||||
void operator = (const nsNativeFileSpec& inOther);
|
||||
void operator = (const nsFileSpec& inOther);
|
||||
void operator = (const nsPersistentFileDescriptor& inOther);
|
||||
|
||||
#ifndef XP_MAC
|
||||
operator const char* () const { return mPath; }
|
||||
@@ -175,23 +204,22 @@ class NS_BASE nsNativeFileSpec
|
||||
#ifdef XP_MAC
|
||||
// For Macintosh people, this is meant to be useful in its own right as a C++ version
|
||||
// of the FSSpec struct.
|
||||
nsNativeFileSpec(
|
||||
nsFileSpec(
|
||||
short vRefNum,
|
||||
long parID,
|
||||
ConstStr255Param name);
|
||||
nsNativeFileSpec(const FSSpec& inSpec)
|
||||
: mSpec(inSpec), mError(noErr) {}
|
||||
nsFileSpec(const FSSpec& inSpec)
|
||||
: mSpec(inSpec), mError(NS_OK) {}
|
||||
|
||||
operator FSSpec* () { return &mSpec; }
|
||||
operator const FSSpec* const () { return &mSpec; }
|
||||
operator FSSpec& () { return mSpec; }
|
||||
operator const FSSpec& () const { return mSpec; }
|
||||
OSErr Error() const { return mError; }
|
||||
void MakeAliasSafe();
|
||||
// Called for the spec of an alias. Copies the alias to
|
||||
// a secret temp directory and modifies the spec to point
|
||||
// to it. Sets mError.
|
||||
void ResolveAlias(bool& wasAliased);
|
||||
void ResolveAlias(PRBool& wasAliased);
|
||||
// Called for the spec of an alias. Modifies the spec to
|
||||
// point to the original. Sets mError.
|
||||
void MakeUnique(ConstStr255Param inSuggestedLeafName);
|
||||
@@ -199,15 +227,15 @@ class NS_BASE nsNativeFileSpec
|
||||
ConstStr255Param GetLeafPName() const { return mSpec.name; }
|
||||
#endif // end of Macintosh utility methods.
|
||||
|
||||
#ifdef XP_MAC
|
||||
bool Valid() const { return mError == noErr; }
|
||||
#else
|
||||
bool Valid() const { return true; } // Fixme.
|
||||
#endif // XP_MAC
|
||||
PRBool Valid() const { return NS_SUCCEEDED(Error()); }
|
||||
nsresult Error() const { return mError; }
|
||||
|
||||
friend NS_BASE nsBasicOutStream& operator << (
|
||||
nsBasicOutStream& s,
|
||||
const nsNativeFileSpec& spec);
|
||||
#if DEBUG
|
||||
friend NS_BASE nsOutputStream& operator << (
|
||||
nsOutputStream& s,
|
||||
const nsFileSpec& spec); // THIS IS FOR DEBUGGING ONLY.
|
||||
// see PersistentFileDescriptor for the real deal.
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------
|
||||
// Queries and path algebra. These do not modify the disk.
|
||||
@@ -218,7 +246,7 @@ class NS_BASE nsNativeFileSpec
|
||||
// inLeafName can be a relative path, so this allows
|
||||
// one kind of concatenation of "paths".
|
||||
|
||||
void GetParent(nsNativeFileSpec& outSpec) const;
|
||||
void GetParent(nsFileSpec& outSpec) const;
|
||||
// Return the filespec of the parent directory. Used
|
||||
// in conjunction with GetLeafName(), this lets you
|
||||
// parse a path into a list of node names. Beware,
|
||||
@@ -226,7 +254,7 @@ class NS_BASE nsNativeFileSpec
|
||||
// but a spec. Volumes on Macintosh can have identical
|
||||
// names. Perhaps could be used for an operator --() ?
|
||||
|
||||
nsNativeFileSpec operator + (const char* inRelativePath) const;
|
||||
nsFileSpec operator + (const char* inRelativePath) const;
|
||||
void operator += (const char* inRelativePath);
|
||||
// Concatenate the relative path to this directory.
|
||||
// Used for constructing the filespec of a descendant.
|
||||
@@ -240,19 +268,24 @@ class NS_BASE nsNativeFileSpec
|
||||
void MakeUnique();
|
||||
void MakeUnique(const char* inSuggestedLeafName);
|
||||
|
||||
bool IsDirectory() const;
|
||||
PRBool IsDirectory() const;
|
||||
// More stringent than Exists()
|
||||
bool IsFile() const;
|
||||
PRBool IsFile() const;
|
||||
// More stringent than Exists()
|
||||
bool Exists() const;
|
||||
PRBool Exists() const;
|
||||
|
||||
//--------------------------------------------------
|
||||
// Creation and deletion of objects. These can modify the disk.
|
||||
//--------------------------------------------------
|
||||
|
||||
void CreateDirectory(int mode = 0700 /* for unix */);
|
||||
void Delete(bool inRecursive);
|
||||
void Delete(PRBool inRecursive);
|
||||
|
||||
nsresult Rename(const char* inNewName); // not const: gets updated
|
||||
nsresult Copy(const nsFileSpec& inNewParentDirectory) const;
|
||||
nsresult Move(const nsFileSpec& inNewParentDirectory) const;
|
||||
nsresult Execute(const char* args) const;
|
||||
|
||||
//--------------------------------------------------
|
||||
// Data
|
||||
//--------------------------------------------------
|
||||
@@ -261,11 +294,15 @@ class NS_BASE nsNativeFileSpec
|
||||
friend class nsFilePath;
|
||||
#ifdef XP_MAC
|
||||
FSSpec mSpec;
|
||||
OSErr mError;
|
||||
#else
|
||||
char* mPath;
|
||||
#endif
|
||||
}; // class nsNativeFileSpec
|
||||
nsresult mError;
|
||||
}; // class nsFileSpec
|
||||
|
||||
// FOR HISTORICAL REASONS:
|
||||
|
||||
typedef nsFileSpec nsNativeFileSpec;
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsFileURL
|
||||
@@ -276,9 +313,9 @@ class NS_BASE nsFileURL
|
||||
{
|
||||
public:
|
||||
nsFileURL(const nsFileURL& inURL);
|
||||
explicit nsFileURL(const char* inString, bool inCreateDirs = false);
|
||||
explicit nsFileURL(const nsFilePath& inPath);
|
||||
explicit nsFileURL(const nsNativeFileSpec& inPath);
|
||||
NS_EXPLICIT nsFileURL(const char* inString, PRBool inCreateDirs = PR_FALSE);
|
||||
NS_EXPLICIT nsFileURL(const nsFilePath& inPath);
|
||||
NS_EXPLICIT nsFileURL(const nsFileSpec& inPath);
|
||||
virtual ~nsFileURL();
|
||||
|
||||
// nsString GetString() const { return mPath; }
|
||||
@@ -288,14 +325,14 @@ class NS_BASE nsFileURL
|
||||
void operator = (const nsFileURL& inURL);
|
||||
void operator = (const char* inString);
|
||||
void operator = (const nsFilePath& inOther);
|
||||
void operator = (const nsNativeFileSpec& inOther);
|
||||
void operator = (const nsFileSpec& inOther);
|
||||
|
||||
friend NS_BASE nsBasicOutStream& operator << (
|
||||
nsBasicOutStream& s, const nsFileURL& spec);
|
||||
friend NS_BASE nsOutputStream& operator << (
|
||||
nsOutputStream& s, const nsFileURL& spec);
|
||||
|
||||
#ifdef XP_MAC
|
||||
// Accessor to allow quick assignment to a mNativeFileSpec
|
||||
const nsNativeFileSpec& GetNativeSpec() const { return mNativeFileSpec; }
|
||||
// Accessor to allow quick assignment to a mFileSpec
|
||||
const nsFileSpec& GetFileSpec() const { return mFileSpec; }
|
||||
#endif
|
||||
private:
|
||||
// Should not be defined (only nsFilePath is to be treated as strings.
|
||||
@@ -306,8 +343,8 @@ class NS_BASE nsFileURL
|
||||
char* mURL;
|
||||
#ifdef XP_MAC
|
||||
// Since the path on the macintosh does not uniquely specify a file (volumes
|
||||
// can have the same name), stash the secret nsNativeFileSpec, too.
|
||||
nsNativeFileSpec mNativeFileSpec;
|
||||
// can have the same name), stash the secret nsFileSpec, too.
|
||||
nsFileSpec mFileSpec;
|
||||
#endif
|
||||
}; // class nsFileURL
|
||||
|
||||
@@ -319,9 +356,9 @@ class NS_BASE nsFilePath
|
||||
{
|
||||
public:
|
||||
nsFilePath(const nsFilePath& inPath);
|
||||
explicit nsFilePath(const char* inString, bool inCreateDirs = false);
|
||||
explicit nsFilePath(const nsFileURL& inURL);
|
||||
explicit nsFilePath(const nsNativeFileSpec& inPath);
|
||||
NS_EXPLICIT nsFilePath(const char* inString, PRBool inCreateDirs = PR_FALSE);
|
||||
NS_EXPLICIT nsFilePath(const nsFileURL& inURL);
|
||||
NS_EXPLICIT nsFilePath(const nsFileSpec& inPath);
|
||||
virtual ~nsFilePath();
|
||||
|
||||
|
||||
@@ -337,12 +374,12 @@ class NS_BASE nsFilePath
|
||||
void operator = (const nsFilePath& inPath);
|
||||
void operator = (const char* inString);
|
||||
void operator = (const nsFileURL& inURL);
|
||||
void operator = (const nsNativeFileSpec& inOther);
|
||||
void operator = (const nsFileSpec& inOther);
|
||||
|
||||
#ifdef XP_MAC
|
||||
public:
|
||||
// Accessor to allow quick assignment to a mNativeFileSpec
|
||||
const nsNativeFileSpec& GetNativeSpec() const { return mNativeFileSpec; }
|
||||
// Accessor to allow quick assignment to a mFileSpec
|
||||
const nsFileSpec& GetFileSpec() const { return mFileSpec; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
@@ -350,26 +387,59 @@ class NS_BASE nsFilePath
|
||||
char* mPath;
|
||||
#ifdef XP_MAC
|
||||
// Since the path on the macintosh does not uniquely specify a file (volumes
|
||||
// can have the same name), stash the secret nsNativeFileSpec, too.
|
||||
nsNativeFileSpec mNativeFileSpec;
|
||||
// can have the same name), stash the secret nsFileSpec, too.
|
||||
nsFileSpec mFileSpec;
|
||||
#endif
|
||||
}; // class nsFilePath
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsPersistentFileDescriptor
|
||||
//========================================================================================
|
||||
{
|
||||
public:
|
||||
nsPersistentFileDescriptor() : mDescriptorString(nsnull) {}
|
||||
// For use prior to reading in from a stream
|
||||
nsPersistentFileDescriptor(const nsPersistentFileDescriptor& inPath);
|
||||
virtual ~nsPersistentFileDescriptor();
|
||||
void operator = (const nsPersistentFileDescriptor& inPath);
|
||||
|
||||
// Conversions
|
||||
nsPersistentFileDescriptor(const nsFileSpec& inPath);
|
||||
void operator = (const nsFileSpec& inPath);
|
||||
|
||||
friend NS_BASE nsInputStream& operator >> (nsInputStream&, nsPersistentFileDescriptor&);
|
||||
// reads the data from a file
|
||||
friend NS_BASE nsOutputStream& operator << (nsOutputStream&, const nsPersistentFileDescriptor&);
|
||||
// writes the data to a file
|
||||
friend class nsFileSpec;
|
||||
|
||||
private:
|
||||
// Here are the ways to get data in and out of a file.
|
||||
void GetData(void*& outData, PRInt32& outSize) const;
|
||||
// DON'T FREE the returned data!
|
||||
void SetData(const void* inData, PRInt32 inSize);
|
||||
|
||||
private:
|
||||
|
||||
char* mDescriptorString;
|
||||
|
||||
}; // class nsPersistentFileDescriptor
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsDirectoryIterator
|
||||
// Example:
|
||||
//
|
||||
// nsNativeFileSpec parentDir(...); // directory over whose children we shall iterate
|
||||
// nsFileSpec parentDir(...); // directory over whose children we shall iterate
|
||||
// for (nsDirectoryIterator i(parentDir); i; i++)
|
||||
// {
|
||||
// // do something with (const nsNativeFileSpec&)i
|
||||
// // do something with (const nsFileSpec&)i
|
||||
// }
|
||||
//
|
||||
// or:
|
||||
//
|
||||
// for (nsDirectoryIterator i(parentDir, false); i; i--)
|
||||
// for (nsDirectoryIterator i(parentDir, PR_FALSE); i; i--)
|
||||
// {
|
||||
// // do something with (const nsNativeFileSpec&)i
|
||||
// // do something with (const nsFileSpec&)i
|
||||
// }
|
||||
//
|
||||
// Currently, the only platform on which backwards iteration actually goes backwards
|
||||
@@ -378,21 +448,21 @@ class NS_BASE nsDirectoryIterator
|
||||
{
|
||||
public:
|
||||
nsDirectoryIterator(
|
||||
const nsNativeFileSpec& parent,
|
||||
const nsFileSpec& parent,
|
||||
int iterateDirection = +1);
|
||||
#ifndef XP_MAC
|
||||
// Macintosh currently doesn't allocate, so needn't clean up.
|
||||
virtual ~nsDirectoryIterator();
|
||||
#endif
|
||||
operator bool() const { return mExists; }
|
||||
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 nsNativeFileSpec&() { return mCurrent; }
|
||||
operator nsFileSpec&() { return mCurrent; }
|
||||
private:
|
||||
nsNativeFileSpec mCurrent;
|
||||
bool mExists;
|
||||
nsFileSpec mCurrent;
|
||||
bool mExists; // MUST be bool.
|
||||
|
||||
#if defined(XP_UNIX)
|
||||
DIR* mDir;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <Folders.h>
|
||||
#include <Errors.h>
|
||||
#include <TextUtils.h>
|
||||
#include <Processes.h>
|
||||
|
||||
const unsigned char* kAliasHavenFolderName = "\pnsAliasHaven";
|
||||
|
||||
@@ -74,7 +75,7 @@ namespace MacFileHelpers
|
||||
// to support attaching of aliases in mail.
|
||||
void EnsureAliasHaven();
|
||||
void SetNoResolve(Boolean inResolve);
|
||||
bool IsAliasSafe(const FSSpec& inSpec);
|
||||
PRBool IsAliasSafe(const FSSpec& inSpec);
|
||||
OSErr MakeAliasSafe(FSSpec& inOutSpec);
|
||||
OSErr ResolveAliasFile(FSSpec& inOutSpec, Boolean& wasAliased);
|
||||
|
||||
@@ -131,8 +132,8 @@ char* MacFileHelpers::EncodeMacPath(
|
||||
// Method: Swap ':' and '/', hex escape the result
|
||||
//-----------------------------------
|
||||
{
|
||||
if (inPath == NULL)
|
||||
return NULL;
|
||||
if (inPath == nsnull)
|
||||
return nsnull;
|
||||
int pathSize = strlen(inPath);
|
||||
|
||||
// XP code sometimes chokes if there's a final slash in the unix path.
|
||||
@@ -145,8 +146,8 @@ char* MacFileHelpers::EncodeMacPath(
|
||||
pathSize--;
|
||||
}
|
||||
|
||||
char * newPath = NULL;
|
||||
char * finalPath = NULL;
|
||||
char * newPath = nsnull;
|
||||
char * finalPath = nsnull;
|
||||
|
||||
if (prependSlash)
|
||||
{
|
||||
@@ -188,10 +189,10 @@ OSErr MacFileHelpers::MakeAliasSafe(FSSpec& inOutSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
EnsureAliasHaven();
|
||||
nsNativeFileSpec dstDirSpec(sAliasHavenVRefNum, sAliasHavenDirID, "\p");
|
||||
nsFileSpec dstDirSpec(sAliasHavenVRefNum, sAliasHavenDirID, "\p");
|
||||
|
||||
// Make sure its name is unique
|
||||
nsNativeFileSpec havenSpec(sAliasHavenVRefNum, sAliasHavenDirID, "\pG'day");
|
||||
nsFileSpec havenSpec(sAliasHavenVRefNum, sAliasHavenDirID, "\pG'day");
|
||||
if (havenSpec.Valid())
|
||||
havenSpec.MakeUnique(inOutSpec.name);
|
||||
// Copy the file into the haven directory
|
||||
@@ -221,9 +222,9 @@ char* MacFileHelpers::MacPathFromUnixPath(const char* unixPath)
|
||||
{
|
||||
char* dst = result;
|
||||
const char* src = unixPath;
|
||||
if (*src == '/') // ¥ full path
|
||||
if (*src == '/') // * full path
|
||||
src++;
|
||||
else if (strchr(src, '/')) // ¥ partial path, and not just a leaf name
|
||||
else if (strchr(src, '/')) // * partial path, and not just a leaf name
|
||||
*dst++ = ':';
|
||||
strcpy(dst, src);
|
||||
nsUnescape(dst); // Hex Decode
|
||||
@@ -346,7 +347,7 @@ void MacFileHelpers::EnsureAliasHaven()
|
||||
} // MacFileHelpers::EnsureAliasHaven
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool MacFileHelpers::IsAliasSafe(const FSSpec& inSpec)
|
||||
PRBool MacFileHelpers::IsAliasSafe(const FSSpec& inSpec)
|
||||
// Returns true if the alias is in the alias haven directory, or if alias resolution
|
||||
// has been turned off.
|
||||
//----------------------------------------------------------------------------------------
|
||||
@@ -379,7 +380,7 @@ OSErr MacFileHelpers::FSSpecFromFullUnixPath(
|
||||
// then it is combined with inOutSpec's vRefNum and parID to form a new spec.
|
||||
//-----------------------------------
|
||||
{
|
||||
if (unixPath == NULL)
|
||||
if (unixPath == nsnull)
|
||||
return badFidErr;
|
||||
char* macPath = MacPathFromUnixPath(unixPath);
|
||||
if (!macPath)
|
||||
@@ -413,7 +414,7 @@ char* MacFileHelpers::PathNameFromFSSpec( const FSSpec& inSpec, Boolean wantLeaf
|
||||
OSErr err = noErr;
|
||||
|
||||
short fullPathLength = 0;
|
||||
Handle fullPath = NULL;
|
||||
Handle fullPath = nsnull;
|
||||
|
||||
FSSpec tempSpec = inSpec;
|
||||
if ( tempSpec.parID == fsRtParID )
|
||||
@@ -471,7 +472,7 @@ char* MacFileHelpers::PathNameFromFSSpec( const FSSpec& inSpec, Boolean wantLeaf
|
||||
tempSpec.name[tempSpec.name[0]] = ':';
|
||||
|
||||
/* Add directory name to beginning of fullPath */
|
||||
(void) Munger(fullPath, 0, NULL, 0, &tempSpec.name[1], tempSpec.name[0]);
|
||||
(void) Munger(fullPath, 0, nsnull, 0, &tempSpec.name[1], tempSpec.name[0]);
|
||||
err = MemError();
|
||||
}
|
||||
} while ( err == noErr && pb.dirInfo.ioDrDirID != fsRtDirID );
|
||||
@@ -500,19 +501,19 @@ Clean:
|
||||
} // MacFileHelpers::PathNameFromFSSpec
|
||||
|
||||
//========================================================================================
|
||||
// Macintosh nsNativeFileSpec implementation
|
||||
// Macintosh nsFileSpec implementation
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec()
|
||||
nsFileSpec::nsFileSpec()
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mError(noErr)
|
||||
: mError(NS_OK)
|
||||
{
|
||||
mSpec.name[0] = '\0';
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec(const nsNativeFileSpec& inSpec)
|
||||
nsFileSpec::nsFileSpec(const nsFileSpec& inSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mSpec(inSpec.mSpec)
|
||||
, mError(inSpec.Error())
|
||||
@@ -520,87 +521,90 @@ nsNativeFileSpec::nsNativeFileSpec(const nsNativeFileSpec& inSpec)
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec(const char* inString, bool inCreateDirs)
|
||||
nsFileSpec::nsFileSpec(const char* inString, PRBool inCreateDirs)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mError = MacFileHelpers::FSSpecFromFullUnixPath(
|
||||
inString, mSpec, true, true, inCreateDirs);
|
||||
mError = NS_FILE_RESULT(MacFileHelpers::FSSpecFromFullUnixPath(
|
||||
inString, mSpec, false, true, inCreateDirs));
|
||||
// allow a partial path, create as necessary
|
||||
if (mError == fnfErr)
|
||||
mError = noErr;
|
||||
} // nsNativeFileSpec::nsNativeFileSpec
|
||||
if (mError == NS_FILE_RESULT(fnfErr))
|
||||
mError = NS_OK;
|
||||
} // nsFileSpec::nsFileSpec
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec(
|
||||
nsFileSpec::nsFileSpec(
|
||||
short vRefNum,
|
||||
long parID,
|
||||
ConstStr255Param name)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mError = ::FSMakeFSSpec(vRefNum, parID, name, &mSpec);
|
||||
if (mError == fnfErr)
|
||||
mError = NS_FILE_RESULT(::FSMakeFSSpec(vRefNum, parID, name, &mSpec));
|
||||
if (mError == NS_FILE_RESULT(fnfErr))
|
||||
mError = noErr;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec(const nsFilePath& inPath)
|
||||
nsFileSpec::nsFileSpec(const nsFilePath& inPath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
*this = inPath.GetNativeSpec();
|
||||
*this = inPath.GetFileSpec();
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicOutStream& operator << (nsBasicOutStream& s, const nsNativeFileSpec& spec)
|
||||
nsOutputStream& operator << (nsOutputStream& s, const nsFileSpec& spec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
s << spec.mSpec.vRefNum << ", " << spec.mSpec.parID << ", \"";
|
||||
s.write((const char*)&spec.mSpec.name[1], spec.mSpec.name[0]);
|
||||
return s << "\"";
|
||||
} // nsOutputFileStream& operator << (nsOutputFileStream&, const nsNativeFileSpec&)
|
||||
} // nsOutputStream& operator << (nsOutputStream&, const nsFileSpec&)
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator = (const char* inString)
|
||||
void nsFileSpec::operator = (const char* inString)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mError = MacFileHelpers::FSSpecFromFullUnixPath(inString, mSpec, true);
|
||||
} // nsNativeFileSpec::operator =
|
||||
mError = NS_FILE_RESULT(MacFileHelpers::FSSpecFromFullUnixPath(inString, mSpec, false));
|
||||
} // nsFileSpec::operator =
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator = (const nsNativeFileSpec& inSpec)
|
||||
void nsFileSpec::operator = (const nsFileSpec& inSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mSpec = inSpec.mSpec;
|
||||
mError = inSpec.Error();
|
||||
} // nsNativeFileSpec::operator =
|
||||
} // nsFileSpec::operator =
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator = (const nsFilePath& inPath)
|
||||
void nsFileSpec::operator = (const nsFilePath& inPath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
*this = inPath.GetNativeSpec();
|
||||
} // nsNativeFileSpec::operator =
|
||||
*this = inPath.GetFileSpec();
|
||||
} // nsFileSpec::operator =
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::Exists() const
|
||||
PRBool nsFileSpec::Exists() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
FSSpec temp;
|
||||
return ::FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, mSpec.name, &temp) == noErr;
|
||||
} // nsNativeFileSpec::operator =
|
||||
} // nsFileSpec::operator =
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::SetLeafName(const char* inLeafName)
|
||||
void nsFileSpec::SetLeafName(const char* inLeafName)
|
||||
// In leaf name can actually be a partial path...
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// what about long relative paths? Hmm?
|
||||
Str255 partialPath;
|
||||
MacFileHelpers::PLstrcpy(partialPath, inLeafName);
|
||||
mError = FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, partialPath, &mSpec);
|
||||
} // nsNativeFileSpec::SetLeafName
|
||||
mError = NS_FILE_RESULT(
|
||||
::FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, partialPath, &mSpec));
|
||||
} // nsFileSpec::SetLeafName
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
char* nsNativeFileSpec::GetLeafName() const
|
||||
char* nsFileSpec::GetLeafName() const
|
||||
// Result needs to be delete[]ed.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
@@ -608,133 +612,206 @@ char* nsNativeFileSpec::GetLeafName() const
|
||||
memcpy(leaf, &mSpec.name[1], mSpec.name[0]);
|
||||
leaf[mSpec.name[0]] = '\0';
|
||||
return nsFileSpecHelpers::StringDup(leaf);
|
||||
} // nsNativeFileSpec::GetLeafName
|
||||
} // nsFileSpec::GetLeafName
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::MakeAliasSafe()
|
||||
void nsFileSpec::MakeAliasSafe()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mError = MacFileHelpers::MakeAliasSafe(mSpec);
|
||||
} // nsNativeFileSpec::MakeAliasSafe
|
||||
mError = NS_FILE_RESULT(MacFileHelpers::MakeAliasSafe(mSpec));
|
||||
} // nsFileSpec::MakeAliasSafe
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::MakeUnique(ConstStr255Param inSuggestedLeafName)
|
||||
void nsFileSpec::MakeUnique(ConstStr255Param inSuggestedLeafName)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (inSuggestedLeafName[0] > 0)
|
||||
MacFileHelpers::PLstrcpy(mSpec.name, inSuggestedLeafName);
|
||||
|
||||
MakeUnique();
|
||||
} // nsNativeFileSpec::MakeUnique
|
||||
} // nsFileSpec::MakeUnique
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::ResolveAlias(bool& wasAliased)
|
||||
void nsFileSpec::ResolveAlias(PRBool& wasAliased)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
Boolean wasAliased2;
|
||||
mError = MacFileHelpers::ResolveAliasFile(mSpec, wasAliased2);
|
||||
mError = NS_FILE_RESULT(MacFileHelpers::ResolveAliasFile(mSpec, wasAliased2));
|
||||
wasAliased = (wasAliased2 != false);
|
||||
} // nsNativeFileSpec::ResolveAlias
|
||||
} // nsFileSpec::ResolveAlias
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::IsFile() const
|
||||
PRBool nsFileSpec::IsFile() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
long dirID;
|
||||
Boolean isDirectory;
|
||||
return (noErr == FSpGetDirectoryID(&mSpec, &dirID, &isDirectory) && !isDirectory);
|
||||
} // nsNativeFileSpec::IsFile
|
||||
} // nsFileSpec::IsFile
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::IsDirectory() const
|
||||
PRBool nsFileSpec::IsDirectory() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
long dirID;
|
||||
Boolean isDirectory;
|
||||
return (noErr == FSpGetDirectoryID(&mSpec, &dirID, &isDirectory) && isDirectory);
|
||||
} // nsNativeFileSpec::IsDirectory
|
||||
} // nsFileSpec::IsDirectory
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::GetParent(nsNativeFileSpec& outSpec) const
|
||||
void nsFileSpec::GetParent(nsFileSpec& outSpec) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (mError == noErr)
|
||||
outSpec.mError = FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, NULL, outSpec);
|
||||
} // nsNativeFileSpec::GetParent
|
||||
if (NS_SUCCEEDED(mError))
|
||||
outSpec.mError
|
||||
= NS_FILE_RESULT(::FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, nsnull, outSpec));
|
||||
} // nsFileSpec::GetParent
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator += (const char* inRelativePath)
|
||||
void nsFileSpec::operator += (const char* inRelativePath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
long dirID;
|
||||
Boolean isDirectory;
|
||||
mError = FSpGetDirectoryID(&mSpec, &dirID, &isDirectory);
|
||||
if (mError == noErr && isDirectory)
|
||||
mError = NS_FILE_RESULT(::FSpGetDirectoryID(&mSpec, &dirID, &isDirectory));
|
||||
if (NS_SUCCEEDED(mError) && isDirectory)
|
||||
{
|
||||
Str255 partialPath;
|
||||
MacFileHelpers::PLstrcpy(partialPath, inRelativePath);
|
||||
mError = FSMakeFSSpec(mSpec.vRefNum, dirID, partialPath, *this);
|
||||
//if (mError == noErr)
|
||||
mError = NS_FILE_RESULT(::FSMakeFSSpec(mSpec.vRefNum, dirID, partialPath, *this));
|
||||
//if (NS_SUCCEEDED(mError))
|
||||
// SetLeafName(inRelativePath);
|
||||
}
|
||||
} // nsNativeFileSpec::operator +=
|
||||
} // nsFileSpec::operator +=
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::CreateDirectory(int /* unix mode */)
|
||||
void nsFileSpec::CreateDirectory(int /* unix mode */)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
long ignoredDirID;
|
||||
FSpDirCreate(&mSpec, smCurrentScript, &ignoredDirID);
|
||||
} // nsNativeFileSpec::CreateDirectory
|
||||
} // nsFileSpec::CreateDirectory
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::Delete(bool inRecursive)
|
||||
void nsFileSpec::Delete(PRBool inRecursive)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (inRecursive)
|
||||
{
|
||||
// MoreFilesExtras
|
||||
mError = DeleteDirectory(
|
||||
mError = NS_FILE_RESULT(::DeleteDirectory(
|
||||
mSpec.vRefNum,
|
||||
mSpec.parID,
|
||||
const_cast<unsigned char*>(mSpec.name));
|
||||
const_cast<unsigned char*>(mSpec.name)));
|
||||
}
|
||||
else
|
||||
mError = FSpDelete(&mSpec);
|
||||
} // nsNativeFileSpec::Delete
|
||||
mError = NS_FILE_RESULT(FSpDelete(&mSpec));
|
||||
} // nsFileSpec::Delete
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult nsFileSpec::Rename(const char* inNewName)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (strchr(inNewName, '/'))
|
||||
return -1; // no relative paths here!
|
||||
Str255 pName;
|
||||
MacFileHelpers::PLstrcpy(pName, inNewName);
|
||||
if (FSpRename(&mSpec, pName) != noErr)
|
||||
return -1;
|
||||
SetLeafName(inNewName);
|
||||
return 0;
|
||||
} // nsFileSpec::Rename
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult nsFileSpec::Copy(const nsFileSpec& newParentDir) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// We can only copy into a directory, and (for now) can not copy entire directories
|
||||
|
||||
if (!newParentDir.IsDirectory() || (IsDirectory() ) )
|
||||
return NS_FILE_FAILURE;
|
||||
|
||||
|
||||
nsresult result = NS_FILE_RESULT(::FSpFileCopy( &mSpec,
|
||||
&newParentDir.mSpec,
|
||||
const_cast<StringPtr>(GetLeafPName()),
|
||||
nsnull,
|
||||
0,
|
||||
true));
|
||||
|
||||
return result;
|
||||
|
||||
} // nsFileSpec::Copy
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult nsFileSpec::Move(const nsFileSpec& newParentDir) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// We can only move into a directory
|
||||
|
||||
if (!newParentDir.IsDirectory())
|
||||
return NS_FILE_FAILURE;
|
||||
|
||||
nsresult result = NS_FILE_RESULT(::FSpMoveRenameCompat(&mSpec,
|
||||
&newParentDir.mSpec,
|
||||
const_cast<StringPtr>(GetLeafPName())));
|
||||
|
||||
return result;
|
||||
} // nsFileSpec::Move
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult nsFileSpec::Execute(const char* /*args - how can this be cross-platform? problem! */ ) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (IsDirectory())
|
||||
return NS_FILE_FAILURE;
|
||||
|
||||
LaunchParamBlockRec launchThis;
|
||||
launchThis.launchAppSpec = const_cast<FSSpec*>(&mSpec);
|
||||
launchThis.launchAppParameters = nsnull; // args;
|
||||
/* launch the thing */
|
||||
launchThis.launchBlockID = extendedBlock;
|
||||
launchThis.launchEPBLength = extendedBlockLen;
|
||||
launchThis.launchFileFlags = nsnull;
|
||||
launchThis.launchControlFlags = launchContinue + launchNoFileFlags + launchUseMinimum;
|
||||
launchThis.launchControlFlags += launchDontSwitch;
|
||||
|
||||
nsresult result = NS_FILE_RESULT(::LaunchApplication(&launchThis));
|
||||
return result;
|
||||
|
||||
} // nsFileSpec::Execute
|
||||
|
||||
//========================================================================================
|
||||
// Macintosh nsFilePath implementation
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFilePath::nsFilePath(const char* inString, bool inCreateDirs)
|
||||
nsFilePath::nsFilePath(const char* inString, PRBool inCreateDirs)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(nsnull)
|
||||
, mNativeFileSpec(inString, inCreateDirs)
|
||||
, mFileSpec(inString, inCreateDirs)
|
||||
{
|
||||
// Make canonical and absolute.
|
||||
char * path = MacFileHelpers::PathNameFromFSSpec( mNativeFileSpec, TRUE );
|
||||
char * path = MacFileHelpers::PathNameFromFSSpec( mFileSpec, TRUE );
|
||||
mPath = MacFileHelpers::EncodeMacPath(path, true, true);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFilePath::nsFilePath(const nsNativeFileSpec& inSpec)
|
||||
nsFilePath::nsFilePath(const nsFileSpec& inSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mNativeFileSpec(inSpec)
|
||||
: mFileSpec(inSpec)
|
||||
{
|
||||
char * path = MacFileHelpers::PathNameFromFSSpec( inSpec.mSpec, TRUE );
|
||||
mPath = MacFileHelpers::EncodeMacPath(path, true, true);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsFilePath::operator = (const nsNativeFileSpec& inSpec)
|
||||
void nsFilePath::operator = (const nsFileSpec& inSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
delete [] mPath;
|
||||
char * path = MacFileHelpers::PathNameFromFSSpec( inSpec.mSpec, TRUE );
|
||||
mPath = MacFileHelpers::EncodeMacPath(path, true, true);
|
||||
mNativeFileSpec = inSpec;
|
||||
mFileSpec = inSpec;
|
||||
} // nsFilePath::operator =
|
||||
|
||||
//========================================================================================
|
||||
@@ -742,14 +819,14 @@ void nsFilePath::operator = (const nsNativeFileSpec& inSpec)
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFileURL::nsFileURL(const char* inString, bool inCreateDirs)
|
||||
nsFileURL::nsFileURL(const char* inString, PRBool inCreateDirs)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mURL(nsnull)
|
||||
, mNativeFileSpec(inString + kFileURLPrefixLength, inCreateDirs)
|
||||
, mFileSpec(inString + kFileURLPrefixLength, inCreateDirs)
|
||||
{
|
||||
NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!");
|
||||
// Make canonical and absolute.
|
||||
char* path = MacFileHelpers::PathNameFromFSSpec( mNativeFileSpec, TRUE );
|
||||
char* path = MacFileHelpers::PathNameFromFSSpec( mFileSpec, TRUE );
|
||||
char* escapedPath = MacFileHelpers::EncodeMacPath(path, true, true);
|
||||
mURL = nsFileSpecHelpers::StringDup(kFileURLPrefix, kFileURLPrefixLength + strlen(escapedPath));
|
||||
strcat(mURL, escapedPath);
|
||||
@@ -762,7 +839,7 @@ nsFileURL::nsFileURL(const char* inString, bool inCreateDirs)
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator::nsDirectoryIterator(
|
||||
const nsNativeFileSpec& inDirectory
|
||||
const nsFileSpec& inDirectory
|
||||
, int inIterateDirection)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mCurrent(inDirectory)
|
||||
@@ -772,7 +849,7 @@ nsDirectoryIterator::nsDirectoryIterator(
|
||||
CInfoPBRec pb;
|
||||
DirInfo* dipb = (DirInfo*)&pb;
|
||||
// Sorry about this, there seems to be a bug in CWPro 4:
|
||||
const FSSpec& inSpec = inDirectory.nsNativeFileSpec::operator const FSSpec&();
|
||||
const FSSpec& inSpec = inDirectory.nsFileSpec::operator const FSSpec&();
|
||||
Str255 outName;
|
||||
MacFileHelpers::PLstrcpy(outName, inSpec.name);
|
||||
pb.hFileInfo.ioNamePtr = outName;
|
||||
@@ -786,7 +863,7 @@ nsDirectoryIterator::nsDirectoryIterator(
|
||||
if ( (err != noErr ) || !( dipb->ioFlAttrib & 0x0010 ) )
|
||||
return;
|
||||
// Sorry about this, there seems to be a bug in CWPro 4:
|
||||
FSSpec& currentSpec = mCurrent.nsNativeFileSpec::operator FSSpec&();
|
||||
FSSpec& currentSpec = mCurrent.nsFileSpec::operator FSSpec&();
|
||||
currentSpec.vRefNum = inSpec.vRefNum;
|
||||
currentSpec.parID = dipb->ioDrDirID;
|
||||
mMaxIndex = pb.dirInfo.ioDrNmFls;
|
||||
@@ -809,10 +886,10 @@ OSErr nsDirectoryIterator::SetToIndex()
|
||||
CInfoPBRec cipb;
|
||||
DirInfo *dipb=(DirInfo *)&cipb;
|
||||
Str255 objectName;
|
||||
dipb->ioCompletion = NULL;
|
||||
dipb->ioCompletion = nsnull;
|
||||
dipb->ioFDirIndex = mIndex;
|
||||
// Sorry about this, there seems to be a bug in CWPro 4:
|
||||
FSSpec& currentSpec = mCurrent.nsNativeFileSpec::operator FSSpec&();
|
||||
FSSpec& currentSpec = mCurrent.nsFileSpec::operator FSSpec&();
|
||||
dipb->ioVRefNum = currentSpec.vRefNum; /* Might need to use vRefNum, not sure*/
|
||||
dipb->ioDrDirID = currentSpec.parID;
|
||||
dipb->ioNamePtr = objectName;
|
||||
|
||||
@@ -25,9 +25,10 @@
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include "nsError.h"
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsFileSpecHelpers::Canonify(char*& ioPath, bool inMakeDirs)
|
||||
void nsFileSpecHelpers::Canonify(char*& ioPath, PRBool inMakeDirs)
|
||||
// Canonify, make absolute, and check whether directories exist
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
@@ -76,75 +77,78 @@ void nsFileSpecHelpers::Canonify(char*& ioPath, bool inMakeDirs)
|
||||
} // nsFileSpecHelpers::Canonify
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::SetLeafName(const char* inLeafName)
|
||||
void nsFileSpec::SetLeafName(const char* inLeafName)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::LeafReplace(mPath, '/', inLeafName);
|
||||
} // nsNativeFileSpec::SetLeafName
|
||||
} // nsFileSpec::SetLeafName
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
char* nsNativeFileSpec::GetLeafName() const
|
||||
char* nsFileSpec::GetLeafName() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return nsFileSpecHelpers::GetLeaf(mPath, '/');
|
||||
} // nsNativeFileSpec::GetLeafName
|
||||
} // nsFileSpec::GetLeafName
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::Exists() const
|
||||
PRBool nsFileSpec::Exists() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
struct stat st;
|
||||
return 0 == stat(mPath, &st);
|
||||
} // nsNativeFileSpec::Exists
|
||||
} // nsFileSpec::Exists
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::IsFile() const
|
||||
PRBool nsFileSpec::IsFile() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
struct stat st;
|
||||
return 0 == stat(mPath, &st) && S_ISREG(st.st_mode);
|
||||
} // nsNativeFileSpec::IsFile
|
||||
} // nsFileSpec::IsFile
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::IsDirectory() const
|
||||
PRBool nsFileSpec::IsDirectory() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
struct stat st;
|
||||
return 0 == stat(mPath, &st) && S_ISDIR(st.st_mode);
|
||||
} // nsNativeFileSpec::IsDirectory
|
||||
} // nsFileSpec::IsDirectory
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::GetParent(nsNativeFileSpec& outSpec) const
|
||||
void nsFileSpec::GetParent(nsFileSpec& outSpec) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::StringAssign(outSpec.mPath, mPath);
|
||||
char* cp = strrchr(outSpec.mPath, '/');
|
||||
if (cp)
|
||||
*cp = '\0';
|
||||
} // nsNativeFileSpec::GetParent
|
||||
} // nsFileSpec::GetParent
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator += (const char* inRelativePath)
|
||||
void nsFileSpec::operator += (const char* inRelativePath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!inRelativePath || !mPath)
|
||||
return;
|
||||
|
||||
if (mPath[strlen(mPath) - 1] != '/')
|
||||
char* newPath = nsFileSpecHelpers::ReallocCat(mPath, "/");
|
||||
char endChar = mPath[strlen(mPath) - 1];
|
||||
if (endChar == '/')
|
||||
nsFileSpecHelpers::ReallocCat(mPath, "x");
|
||||
else
|
||||
nsFileSpecHelpers::ReallocCat(mPath, "/x");
|
||||
SetLeafName(inRelativePath);
|
||||
} // nsNativeFileSpec::operator +=
|
||||
} // nsFileSpec::operator +=
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::CreateDirectory(int mode)
|
||||
void nsFileSpec::CreateDirectory(int mode)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// Note that mPath is canonical!
|
||||
mkdir(mPath, mode);
|
||||
} // nsNativeFileSpec::CreateDirectory
|
||||
} // nsFileSpec::CreateDirectory
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::Delete(bool inRecursive)
|
||||
void nsFileSpec::Delete(PRBool inRecursive)
|
||||
// To check if this worked, call Exists() afterwards, see?
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
@@ -152,9 +156,9 @@ void nsNativeFileSpec::Delete(bool inRecursive)
|
||||
{
|
||||
if (inRecursive)
|
||||
{
|
||||
for (nsDirectoryIterator i(*this); i; i++)
|
||||
for (nsDirectoryIterator i(*this); i.Exists(); i++)
|
||||
{
|
||||
nsNativeFileSpec& child = (nsNativeFileSpec&)i;
|
||||
nsFileSpec& child = (nsFileSpec&)i;
|
||||
child.Delete(inRecursive);
|
||||
}
|
||||
}
|
||||
@@ -162,7 +166,148 @@ void nsNativeFileSpec::Delete(bool inRecursive)
|
||||
}
|
||||
else
|
||||
remove(mPath);
|
||||
} // nsNativeFileSpec::Delete
|
||||
} // nsFileSpec::Delete
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult nsFileSpec::Rename(const char* inNewName)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// This function should not be used to move a file on disk.
|
||||
if (strchr(inNewName, '/'))
|
||||
return NS_FILE_FAILURE;
|
||||
|
||||
if (PR_Rename(mPath, inNewName) != 0)
|
||||
{
|
||||
return NS_FILE_FAILURE;
|
||||
}
|
||||
SetLeafName(inNewName);
|
||||
return NS_OK;
|
||||
} // nsFileSpec::Rename
|
||||
|
||||
static int CrudeFileCopy(const char* in, const char* out)
|
||||
{
|
||||
struct stat in_stat;
|
||||
int stat_result = -1;
|
||||
|
||||
char buf [1024];
|
||||
FILE *ifp, *ofp;
|
||||
int rbytes, wbytes;
|
||||
|
||||
if (!in || !out)
|
||||
return -1;
|
||||
|
||||
stat_result = stat (in, &in_stat);
|
||||
|
||||
ifp = fopen (in, "r");
|
||||
if (!ifp)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
ofp = fopen (out, "w");
|
||||
if (!ofp)
|
||||
{
|
||||
fclose (ifp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((rbytes = fread (buf, 1, sizeof(buf), ifp)) > 0)
|
||||
{
|
||||
while (rbytes > 0)
|
||||
{
|
||||
if ( (wbytes = fwrite (buf, 1, rbytes, ofp)) < 0 )
|
||||
{
|
||||
fclose (ofp);
|
||||
fclose (ifp);
|
||||
unlink(out);
|
||||
return -1;
|
||||
}
|
||||
rbytes -= wbytes;
|
||||
}
|
||||
}
|
||||
fclose (ofp);
|
||||
fclose (ifp);
|
||||
|
||||
if (stat_result == 0)
|
||||
{
|
||||
chmod (out, in_stat.st_mode & 0777);
|
||||
}
|
||||
|
||||
return 0;
|
||||
} // nsFileSpec::Rename
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult nsFileSpec::Copy(const nsFileSpec& inParentDirectory) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// We can only copy into a directory, and (for now) can not copy entire directories
|
||||
nsresult result = NS_FILE_FAILURE;
|
||||
|
||||
if (inParentDirectory.IsDirectory() && (! IsDirectory() ) )
|
||||
{
|
||||
char *leafname = GetLeafName();
|
||||
char* destPath = nsFileSpecHelpers::StringDup(inParentDirectory, ( strlen(inParentDirectory) + 1 + strlen(leafname) ) );
|
||||
strcat(destPath, "/");
|
||||
strcat(destPath, leafname);
|
||||
delete [] leafname;
|
||||
|
||||
result = NS_FILE_RESULT(CrudeFileCopy(*this, destPath));
|
||||
|
||||
delete [] destPath;
|
||||
}
|
||||
return result;
|
||||
} // nsFileSpec::Copy
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult nsFileSpec::Move(const nsFileSpec& inNewParentDirectory) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// We can only copy into a directory, and (for now) can not copy entire directories
|
||||
nsresult result = NS_FILE_FAILURE;
|
||||
|
||||
if (inNewParentDirectory.IsDirectory() && (! IsDirectory() ) )
|
||||
{
|
||||
char *leafname = GetLeafName();
|
||||
char* destPath
|
||||
= nsFileSpecHelpers::StringDup(
|
||||
inNewParentDirectory,
|
||||
strlen(inNewParentDirectory) + 1 + strlen(leafname));
|
||||
strcat(destPath, "/");
|
||||
strcat(destPath, leafname);
|
||||
delete [] leafname;
|
||||
|
||||
result = NS_FILE_RESULT(CrudeFileCopy(*this, destPath));
|
||||
if (result == NS_OK)
|
||||
{
|
||||
Delete(PR_FALSE);
|
||||
}
|
||||
delete [] destPath;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult nsFileSpec::Execute(const char* inArgs ) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsresult result = NS_FILE_FAILURE;
|
||||
|
||||
if (! IsDirectory())
|
||||
{
|
||||
char* fileNameWithArgs
|
||||
= nsFileSpecHelpers::StringDup(mPath, strlen(mPath) + 1 + strlen(inArgs));
|
||||
strcat(fileNameWithArgs, " ");
|
||||
strcat(fileNameWithArgs, inArgs);
|
||||
|
||||
result = NS_FILE_RESULT(system(fileNameWithArgs));
|
||||
delete [] fileNameWithArgs;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
} // nsFileSpec::Execute
|
||||
|
||||
//========================================================================================
|
||||
// nsDirectoryIterator
|
||||
@@ -170,7 +315,7 @@ void nsNativeFileSpec::Delete(bool inRecursive)
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator::nsDirectoryIterator(
|
||||
const nsNativeFileSpec& inDirectory
|
||||
const nsFileSpec& inDirectory
|
||||
, int inIterateDirection)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mCurrent(inDirectory)
|
||||
|
||||
@@ -23,9 +23,18 @@
|
||||
#include <direct.h>
|
||||
#include <stdlib.h>
|
||||
#include "prio.h"
|
||||
#include "nsError.h"
|
||||
|
||||
#include "windows.h"
|
||||
|
||||
#ifdef UNICODE
|
||||
#define CreateDirectoryW CreateDirectory
|
||||
#else
|
||||
#define CreateDirectoryA CreateDirectory
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsFileSpecHelpers::Canonify(char*& ioPath, bool inMakeDirs)
|
||||
void nsFileSpecHelpers::Canonify(char*& ioPath, PRBool inMakeDirs)
|
||||
// Canonify, make absolute, and check whether directories exist. This
|
||||
// takes a (possibly relative) native path and converts it into a
|
||||
// fully qualified native path.
|
||||
@@ -125,7 +134,7 @@ void nsFileSpecHelpers::NativeToUnix(char*& ioPath)
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec(const nsFilePath& inPath)
|
||||
nsFileSpec::nsFileSpec(const nsFilePath& inPath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(NULL)
|
||||
{
|
||||
@@ -133,15 +142,16 @@ nsNativeFileSpec::nsNativeFileSpec(const nsFilePath& inPath)
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator = (const nsFilePath& inPath)
|
||||
void nsFileSpec::operator = (const nsFilePath& inPath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::StringAssign(mPath, (const char*)inPath);
|
||||
nsFileSpecHelpers::UnixToNative(mPath);
|
||||
} // nsNativeFileSpec::operator =
|
||||
mError = NS_OK;
|
||||
} // nsFileSpec::operator =
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFilePath::nsFilePath(const nsNativeFileSpec& inSpec)
|
||||
nsFilePath::nsFilePath(const nsFileSpec& inSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(NULL)
|
||||
{
|
||||
@@ -149,7 +159,7 @@ nsFilePath::nsFilePath(const nsNativeFileSpec& inSpec)
|
||||
} // nsFilePath::nsFilePath
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsFilePath::operator = (const nsNativeFileSpec& inSpec)
|
||||
void nsFilePath::operator = (const nsFileSpec& inSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::StringAssign(mPath, inSpec.mPath);
|
||||
@@ -157,84 +167,86 @@ void nsFilePath::operator = (const nsNativeFileSpec& inSpec)
|
||||
} // nsFilePath::operator =
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::SetLeafName(const char* inLeafName)
|
||||
void nsFileSpec::SetLeafName(const char* inLeafName)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::LeafReplace(mPath, '\\', inLeafName);
|
||||
} // nsNativeFileSpec::SetLeafName
|
||||
} // nsFileSpec::SetLeafName
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
char* nsNativeFileSpec::GetLeafName() const
|
||||
char* nsFileSpec::GetLeafName() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return nsFileSpecHelpers::GetLeaf(mPath, '\\');
|
||||
} // nsNativeFileSpec::GetLeafName
|
||||
} // nsFileSpec::GetLeafName
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::Exists() const
|
||||
PRBool nsFileSpec::Exists() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
struct stat st;
|
||||
return 0 == stat(mPath, &st);
|
||||
} // nsNativeFileSpec::Exists
|
||||
} // nsFileSpec::Exists
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::IsFile() const
|
||||
PRBool nsFileSpec::IsFile() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
struct stat st;
|
||||
return 0 == stat(mPath, &st) && (_S_IFREG & st.st_mode);
|
||||
} // nsNativeFileSpec::IsFile
|
||||
} // nsFileSpec::IsFile
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::IsDirectory() const
|
||||
PRBool nsFileSpec::IsDirectory() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
struct stat st;
|
||||
return 0 == stat(mPath, &st) && (_S_IFDIR & st.st_mode);
|
||||
} // nsNativeFileSpec::IsDirectory
|
||||
} // nsFileSpec::IsDirectory
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::GetParent(nsNativeFileSpec& outSpec) const
|
||||
void nsFileSpec::GetParent(nsFileSpec& outSpec) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::StringAssign(outSpec.mPath, mPath);
|
||||
char* cp = strrchr(outSpec.mPath, '\\');
|
||||
if (cp)
|
||||
*cp = '\0';
|
||||
} // nsNativeFileSpec::GetParent
|
||||
} // nsFileSpec::GetParent
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator += (const char* inRelativePath)
|
||||
void nsFileSpec::operator += (const char* inRelativePath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!inRelativePath || !mPath)
|
||||
return;
|
||||
|
||||
if (mPath[strlen(mPath) - 1] != '\\')
|
||||
char* newPath = nsFileSpecHelpers::ReallocCat(mPath, "\\");
|
||||
if (mPath[strlen(mPath) - 1] == '\\')
|
||||
nsFileSpecHelpers::ReallocCat(mPath, "x");
|
||||
else
|
||||
nsFileSpecHelpers::ReallocCat(mPath, "\\x");
|
||||
SetLeafName(inRelativePath);
|
||||
} // nsNativeFileSpec::operator +=
|
||||
} // nsFileSpec::operator +=
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::CreateDirectory(int /*mode*/)
|
||||
void nsFileSpec::CreateDirectory(int /*mode*/)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// Note that mPath is canonical!
|
||||
mkdir(mPath);
|
||||
} // nsNativeFileSpec::CreateDirectory
|
||||
} // nsFileSpec::CreateDirectory
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::Delete(bool inRecursive)
|
||||
void nsFileSpec::Delete(PRBool inRecursive)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (IsDirectory())
|
||||
{
|
||||
if (inRecursive)
|
||||
{
|
||||
for (nsDirectoryIterator i(*this); i; i++)
|
||||
for (nsDirectoryIterator i(*this); i.Exists(); i++)
|
||||
{
|
||||
nsNativeFileSpec& child = (nsNativeFileSpec&)i;
|
||||
nsFileSpec& child = (nsFileSpec&)i;
|
||||
child.Delete(inRecursive);
|
||||
}
|
||||
}
|
||||
@@ -244,7 +256,106 @@ void nsNativeFileSpec::Delete(bool inRecursive)
|
||||
{
|
||||
remove(mPath);
|
||||
}
|
||||
} // nsNativeFileSpec::Delete
|
||||
} // nsFileSpec::Delete
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult nsFileSpec::Rename(const char* inNewName)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// This function should not be used to move a file on disk.
|
||||
if (strchr(inNewName, '/'))
|
||||
return NS_FILE_FAILURE;
|
||||
|
||||
if (PR_Rename(*this, inNewName) != NS_OK)
|
||||
{
|
||||
return NS_FILE_FAILURE;
|
||||
}
|
||||
SetLeafName(inNewName);
|
||||
return NS_OK;
|
||||
} // nsFileSpec::Rename
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult nsFileSpec::Copy(const nsFileSpec& inParentDirectory) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// We can only copy into a directory, and (for now) can not copy entire directories
|
||||
|
||||
if (inParentDirectory.IsDirectory() && (! IsDirectory() ) )
|
||||
{
|
||||
char *leafname = GetLeafName();
|
||||
char* destPath = nsFileSpecHelpers::StringDup(inParentDirectory, ( strlen(inParentDirectory) + 1 + strlen(leafname) ) );
|
||||
strcat(destPath, "\\");
|
||||
strcat(destPath, leafname);
|
||||
delete [] leafname;
|
||||
|
||||
// CopyFile returns non-zero if succeeds
|
||||
int copyOK = CopyFile(*this, destPath, true);
|
||||
|
||||
delete[] destPath;
|
||||
|
||||
if (copyOK)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_FILE_FAILURE;
|
||||
} // nsFileSpec::Copy
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult nsFileSpec::Move(const nsFileSpec& nsNewParentDirectory) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// We can only copy into a directory, and (for now) can not copy entire directories
|
||||
|
||||
if (nsNewParentDirectory.IsDirectory() && (! IsDirectory() ) )
|
||||
{
|
||||
char *leafname = GetLeafName();
|
||||
char *destPath = nsFileSpecHelpers::StringDup(nsNewParentDirectory, ( strlen(nsNewParentDirectory) + 1 + strlen(leafname) ));
|
||||
strcat(destPath, "\\");
|
||||
strcat(destPath, leafname);
|
||||
delete [] leafname;
|
||||
|
||||
// MoveFile returns non-zero if succeeds
|
||||
int copyOK = MoveFile(*this, destPath);
|
||||
|
||||
delete [] destPath;
|
||||
|
||||
if (copyOK)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_FILE_FAILURE;
|
||||
} // nsFileSpec::Move
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsresult nsFileSpec::Execute(const char* inArgs ) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
|
||||
if (! IsDirectory())
|
||||
{
|
||||
char* fileNameWithArgs = NULL;
|
||||
|
||||
fileNameWithArgs = nsFileSpecHelpers::StringDup(mPath, ( strlen(mPath) + 1 + strlen(inArgs) ) );
|
||||
strcat(fileNameWithArgs, " ");
|
||||
strcat(fileNameWithArgs, inArgs);
|
||||
|
||||
int execResult = WinExec( fileNameWithArgs, SW_NORMAL );
|
||||
|
||||
delete [] fileNameWithArgs;
|
||||
|
||||
if (execResult > 31)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_FILE_FAILURE;
|
||||
} // nsFileSpec::Execute
|
||||
|
||||
//========================================================================================
|
||||
// nsDirectoryIterator
|
||||
@@ -252,7 +363,7 @@ void nsNativeFileSpec::Delete(bool inRecursive)
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator::nsDirectoryIterator(
|
||||
const nsNativeFileSpec& inDirectory
|
||||
const nsFileSpec& inDirectory
|
||||
, int inIterateDirection)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mCurrent(inDirectory)
|
||||
|
||||
@@ -22,332 +22,78 @@
|
||||
|
||||
#include "nsFileStream.h"
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef XP_MAC
|
||||
#include <Errors.h>
|
||||
#endif
|
||||
|
||||
//========================================================================================
|
||||
// nsBasicFileStream
|
||||
// nsInputStream
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicFileStream::nsBasicFileStream()
|
||||
nsInputStream::~nsInputStream()
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mFileDesc(0)
|
||||
, mNSPRMode(0)
|
||||
, mFailed(false)
|
||||
, mEOF(false)
|
||||
{
|
||||
mInputStream->Close();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicFileStream::nsBasicFileStream(
|
||||
const nsFilePath& inFile,
|
||||
int nsprMode,
|
||||
PRIntn accessMode)
|
||||
char nsInputStream::get()
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mFileDesc(0)
|
||||
, mNSPRMode(0)
|
||||
, mFailed(false)
|
||||
, mEOF(false)
|
||||
{
|
||||
open(inFile, nsprMode, accessMode);
|
||||
char c;
|
||||
read(&c, sizeof(c));
|
||||
return c;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicFileStream::nsBasicFileStream(PRFileDesc* desc, int nsprMode)
|
||||
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).
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mFileDesc(desc)
|
||||
, mNSPRMode(nsprMode)
|
||||
, mFailed(false)
|
||||
, mEOF(false)
|
||||
{
|
||||
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.
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicFileStream::~nsBasicFileStream()
|
||||
nsInputStream& nsInputStream::operator >> (char& c)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsBasicFileStream::open(
|
||||
const nsFilePath& inFile,
|
||||
int nsprMode,
|
||||
PRIntn accessMode)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (mFileDesc)
|
||||
return;
|
||||
|
||||
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;
|
||||
|
||||
#ifdef XP_MAC
|
||||
// Use the file spec to open the file, because one path can be common to
|
||||
// several files on the Macintosh (you can have several volumes with the
|
||||
// same name, see).
|
||||
mFileDesc = 0;
|
||||
if (inFile.GetNativeSpec().Error() != noErr)
|
||||
return;
|
||||
OSErr err = noErr;
|
||||
#if DEBUG
|
||||
const OSType kCreator = 'CWIE';
|
||||
#else
|
||||
const OSType kCreator = 'MOSS';
|
||||
#endif
|
||||
nsNativeFileSpec nativeSpec = inFile.GetNativeSpec();
|
||||
FSSpec* spec = (FSSpec*)nativeSpec;
|
||||
if (nsprMode & PR_CREATE_FILE)
|
||||
err = FSpCreate(spec, kCreator, 'TEXT', 0);
|
||||
if (err == dupFNErr)
|
||||
err = noErr;
|
||||
if (err != noErr)
|
||||
return;
|
||||
|
||||
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;
|
||||
|
||||
if ((mFileDesc = PR_ImportFile(refnum)) == 0)
|
||||
return;
|
||||
#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*)nsNativeFileSpec(inFile), nsprMode, accessMode)) == 0)
|
||||
return;
|
||||
#endif
|
||||
mNSPRMode = nsprMode;
|
||||
} // nsFileStreamHelpers::open
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsBasicFileStream::close()
|
||||
// Must precede the destructor because both are inline.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR || mFileDesc == 0)
|
||||
return;
|
||||
if (PR_Close(mFileDesc) == PR_SUCCESS)
|
||||
mFileDesc = 0;
|
||||
} // nsBasicFileStream::close
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsBasicFileStream::seek(PRSeekWhence whence, PRInt32 offset)
|
||||
// Must precede the destructor because both are inline.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR || mFileDesc == 0)
|
||||
return;
|
||||
mFailed = false; // reset on a seek.
|
||||
mEOF = false; // reset on a seek.
|
||||
PRInt32 position = PR_Seek(mFileDesc, 0, PR_SEEK_CUR);
|
||||
PRInt32 available = PR_Available(mFileDesc);
|
||||
PRInt32 fileSize = position + available;
|
||||
PRInt32 newPosition;
|
||||
switch (whence)
|
||||
{
|
||||
case PR_SEEK_CUR: newPosition = position + offset; break;
|
||||
case PR_SEEK_SET: newPosition = offset; break;
|
||||
case PR_SEEK_END: newPosition = fileSize + offset; break;
|
||||
}
|
||||
if (newPosition < 0)
|
||||
{
|
||||
newPosition = 0;
|
||||
mFailed = true;
|
||||
}
|
||||
else if (newPosition >= fileSize)
|
||||
{
|
||||
newPosition = fileSize;
|
||||
mEOF = true;
|
||||
}
|
||||
if (PR_Seek(mFileDesc, newPosition, PR_SEEK_SET) < 0)
|
||||
mFailed = true;
|
||||
} // nsBasicFileStream::seek
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
PRIntn nsBasicFileStream::tell() const
|
||||
// Must precede the destructor because both are inline.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR || mFileDesc == 0)
|
||||
return -1;
|
||||
return PR_Seek(mFileDesc, 0, PR_SEEK_CUR);
|
||||
} // nsBasicFileStream::tell
|
||||
|
||||
//========================================================================================
|
||||
// nsBasicInStream
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicInStream::nsBasicInStream(nsBasicFileStream& inBasicStream, istream* inStream)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mBase(inBasicStream)
|
||||
, mStdStream(inStream)
|
||||
{
|
||||
}
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsBasicInStream::get(char& c)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
read(&c, sizeof(char));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
PRBool nsBasicInStream::readline(char* s, PRInt32 n)
|
||||
// This will truncate if the buffer is too small. Result will always be null-terminated.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
PRBool bufferLargeEnough = true; // result
|
||||
if (!s || !n)
|
||||
return true;
|
||||
PRIntn position = mBase.tell();
|
||||
if (position < 0)
|
||||
return false;
|
||||
PRInt32 bytesRead = read(s, n - 1);
|
||||
if (mBase.failed())
|
||||
return false;
|
||||
s[bytesRead] = '\0'; // always terminate at the end of the buffer
|
||||
char* tp = strpbrk(s, "\n\r");
|
||||
if (tp)
|
||||
{
|
||||
char ch = *tp;
|
||||
*tp++ = '\0'; // terminate at the newline, then skip past it
|
||||
if ((ch == '\n' && *tp == '\r') || (ch == '\r' && *tp == '\n'))
|
||||
tp++; // possibly a pair.
|
||||
bytesRead = (tp - s);
|
||||
}
|
||||
else if (!mBase.eof())
|
||||
bufferLargeEnough = false;
|
||||
position += bytesRead;
|
||||
mBase.seek(position);
|
||||
return bufferLargeEnough;
|
||||
} // nsBasicInStream::getline
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
PRInt32 nsBasicInStream::read(void* s, PRInt32 n)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
#ifndef NS_USE_PR_STDIO
|
||||
// Calling PR_Read on stdin is sure suicide on Macintosh.
|
||||
if (GetStandardStream())
|
||||
{
|
||||
GetStandardStream()->read((char*)s, n);
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
if (!mBase.is_open() || mBase.failed())
|
||||
return -1;
|
||||
PRInt32 bytesRead = PR_Read(mBase.GetFileDescriptor(), s, n);
|
||||
if (bytesRead < 0)
|
||||
mBase.mFailed = true;
|
||||
else if (bytesRead < n)
|
||||
mBase.mEOF = true;
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicInStream& nsBasicInStream::operator >> (char& c)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
get(c);
|
||||
c = get();
|
||||
return *this;
|
||||
}
|
||||
|
||||
//========================================================================================
|
||||
// nsInputFileStream
|
||||
// nsOutputStream
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsInputFileStream::nsInputFileStream(istream* stream)
|
||||
nsOutputStream::~nsOutputStream()
|
||||
//----------------------------------------------------------------------------------------
|
||||
#ifndef NS_USE_PR_STDIO
|
||||
: nsBasicFileStream(0, kDefaultMode)
|
||||
, nsBasicInStream(*this, stream)
|
||||
#else
|
||||
: nsBasicFileStream(PR_STDIN, kDefaultMode)
|
||||
, nsBasicInStream(*this, 0)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
//========================================================================================
|
||||
// nsBasicOutStream
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicOutStream::nsBasicOutStream(nsBasicFileStream& inBase, ostream* stream)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mBase(inBase)
|
||||
, mStdStream(stream)
|
||||
{
|
||||
mOutputStream->Close();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsBasicOutStream::put(char c)
|
||||
void nsOutputStream::put(char c)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
write(&c, sizeof(c));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
PRInt32 nsBasicOutStream::write(const void* s, PRInt32 n)
|
||||
void nsOutputStream::flush()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
#ifndef NS_USE_PR_STDIO
|
||||
// Calling PR_Write on stdout is sure suicide.
|
||||
if (mStdStream)
|
||||
{
|
||||
mStdStream->write((const char*)s, n);
|
||||
return n;
|
||||
}
|
||||
#endif
|
||||
if (!mBase.mFileDesc || mBase.failed())
|
||||
return -1;
|
||||
PRInt32 bytesWrit = PR_Write(mBase.mFileDesc, s, n);
|
||||
if (bytesWrit != n)
|
||||
mBase.mFailed = true;
|
||||
return bytesWrit;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicOutStream& nsBasicOutStream::operator << (char c)
|
||||
nsOutputStream& nsOutputStream::operator << (char c)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
put(c);
|
||||
@@ -355,7 +101,7 @@ nsBasicOutStream& nsBasicOutStream::operator << (char c)
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicOutStream& nsBasicOutStream::operator << (const char* s)
|
||||
nsOutputStream& nsOutputStream::operator << (const char* s)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
write(s, strlen(s));
|
||||
@@ -363,78 +109,84 @@ nsBasicOutStream& nsBasicOutStream::operator << (const char* s)
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicOutStream& nsBasicOutStream::operator << (short val)
|
||||
nsOutputStream& nsOutputStream::operator << (short val)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
char buf[30];
|
||||
sprintf(buf, "%d", val);
|
||||
return *this << buf;
|
||||
return (*this << buf);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicOutStream& nsBasicOutStream::operator << (unsigned short val)
|
||||
nsOutputStream& nsOutputStream::operator << (unsigned short val)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
char buf[30];
|
||||
sprintf(buf, "%ud", val);
|
||||
return *this << buf;
|
||||
return (*this << buf);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicOutStream& nsBasicOutStream::operator << (long val)
|
||||
nsOutputStream& nsOutputStream::operator << (long val)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
char buf[30];
|
||||
sprintf(buf, "%ld", val);
|
||||
return *this << buf;
|
||||
return (*this << buf);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicOutStream& nsBasicOutStream::operator << (unsigned long val)
|
||||
nsOutputStream& nsOutputStream::operator << (unsigned long val)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
char buf[30];
|
||||
sprintf(buf, "%uld", val);
|
||||
return *this << buf;
|
||||
return (*this << buf);
|
||||
}
|
||||
|
||||
//========================================================================================
|
||||
// nsInputFileStream
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsBasicOutStream::flush()
|
||||
// Must precede the destructor because both are inline.
|
||||
PRBool nsInputFileStream::readline(char* s, PRInt32 n)
|
||||
// This will truncate if the buffer is too small. Result will always be null-terminated.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
#ifndef NS_USE_PR_STDIO
|
||||
if (mStdStream)
|
||||
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)
|
||||
{
|
||||
mStdStream->flush();
|
||||
return;
|
||||
TidyEndOfLine(tp);
|
||||
bytesRead = (tp - s);
|
||||
}
|
||||
#endif
|
||||
if (mBase.mFileDesc == 0)
|
||||
return;
|
||||
PRBool itFailed = PR_Sync(mBase.mFileDesc) != PR_SUCCESS;
|
||||
#ifdef XP_MAC
|
||||
// On unix, it seems to fail always.
|
||||
if (itFailed)
|
||||
mBase.mFailed = true;
|
||||
#endif
|
||||
} // nsBasicOutStream::flush
|
||||
else if (!eof())
|
||||
bufferLargeEnough = PR_FALSE;
|
||||
position += bytesRead;
|
||||
seek(position);
|
||||
return bufferLargeEnough;
|
||||
} // nsInputStream::readline
|
||||
|
||||
//========================================================================================
|
||||
// nsOutputFileStream
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsOutputFileStream::nsOutputFileStream(ostream* stream)
|
||||
void nsOutputFileStream::flush()
|
||||
//----------------------------------------------------------------------------------------
|
||||
#ifndef NS_USE_PR_STDIO
|
||||
: nsBasicFileStream(0, kDefaultMode)
|
||||
, nsBasicOutStream(*this, stream)
|
||||
#else
|
||||
: nsBasicFileStream(PR_STDOUT, kDefaultMode)
|
||||
, nsBasicOutStream(*this, 0)
|
||||
#endif
|
||||
{
|
||||
if (mFileOutputStream)
|
||||
mFileOutputStream->Flush();
|
||||
}
|
||||
|
||||
//========================================================================================
|
||||
@@ -442,19 +194,10 @@ nsOutputFileStream::nsOutputFileStream(ostream* stream)
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsBasicOutStream& nsEndl(nsBasicOutStream& os)
|
||||
nsOutputStream& nsEndl(nsOutputStream& os)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
#ifndef NS_USE_PR_STDIO
|
||||
// Calling PR_Write on stdout is sure suicide on Macintosh.
|
||||
ostream* stream = os.GetStandardStream();
|
||||
if (stream)
|
||||
{
|
||||
*stream << std::endl;
|
||||
return os;
|
||||
}
|
||||
#endif
|
||||
os.put('\n');
|
||||
os.flush();
|
||||
return os;
|
||||
}
|
||||
os.put('\n');
|
||||
os.flush();
|
||||
return os;
|
||||
} // nsEndl
|
||||
@@ -19,14 +19,31 @@
|
||||
// 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:
|
||||
//
|
||||
// single-byte char:
|
||||
//
|
||||
// nsInputStream, nsOutputStream
|
||||
// These are the lightweight STATICALLY LINKED wrappers for
|
||||
// the xpcom objects nsIInputStream and nsIOutputstream.
|
||||
// Possible uses:
|
||||
// If you are implementing a function that accepts one of these xpcom
|
||||
// streams, just make one of these little jobbies on the stack, and
|
||||
// the handy << or >> notation can be yours.
|
||||
//
|
||||
// nsInputFileStream, nsOutputFileStream
|
||||
// These are the STATICALLY LINKED versions of the file i/o streams,
|
||||
// which wrap the NSPR file i/o plus console i/o.
|
||||
//
|
||||
// Related files:
|
||||
// prio.h the NSPR file i/o C API), which is wrapped by
|
||||
// THIS FILE statically linked C++ wrappers, which in turn are wrapped by
|
||||
// nsIFileStream.h COM wrappers for this file, which are wrapped by
|
||||
// nsAutoFileStream.h more easily used, nicer syntax wrappers for the
|
||||
// COMified ones. Wrapper of a wrapper of a wrapper.
|
||||
//
|
||||
// This suite provide the following services:
|
||||
//
|
||||
@@ -41,13 +58,13 @@
|
||||
//
|
||||
// Basic example:
|
||||
//
|
||||
// nsFilePath myPath("/Development/iotest.txt");
|
||||
// nsFileSpec myPath("/Development/iotest.txt");
|
||||
//
|
||||
// nsOutputFileStream testStream(myPath);
|
||||
// testStream << "Hello World" << nsEndl;
|
||||
//
|
||||
// 4. Requires streams to be constructed using typesafe nsFilePath specifier
|
||||
// (not the notorious and bug prone const char*), namely nsFilePath. See
|
||||
// 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
|
||||
@@ -73,7 +90,13 @@
|
||||
#else
|
||||
#include "prio.h"
|
||||
#endif
|
||||
#include "nsFileSpec.h"
|
||||
|
||||
#include "nsIFileStream.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
class nsFileSpec;
|
||||
class nsInputFileStream;
|
||||
class nsOutputFileStream;
|
||||
|
||||
//========================================================================================
|
||||
// Compiler-specific macros, as needed
|
||||
@@ -133,201 +156,392 @@ using std::ostream;
|
||||
//=========================== End Compiler-specific macros ===============================
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsBasicFileStream
|
||||
class NS_BASE nsInputStream
|
||||
// This is a convenience class, for use on the STACK ("new" junkies: get detoxed first).
|
||||
// Given a COM-style stream, this allows you to use the >> operators. It also acquires and
|
||||
// reference counts its stream.
|
||||
// Please read the comments at the top of this file
|
||||
//========================================================================================
|
||||
{
|
||||
public:
|
||||
nsBasicFileStream();
|
||||
nsBasicFileStream(PRFileDesc* desc, int nsprMode);
|
||||
nsBasicFileStream(
|
||||
const nsFilePath& inFile,
|
||||
int nsprMode,
|
||||
PRIntn accessMode);
|
||||
virtual ~nsBasicFileStream();
|
||||
nsInputStream(nsIInputStream* inStream)
|
||||
: mInputStream(do_QueryInterface(inStream))
|
||||
, mEOF(PR_FALSE)
|
||||
{}
|
||||
virtual ~nsInputStream();
|
||||
|
||||
nsCOMPtr<nsIInputStream> GetIStream() const
|
||||
{
|
||||
return mInputStream;
|
||||
}
|
||||
char eof() const { return mEOF; }
|
||||
char get();
|
||||
PRInt32 read(void* s, PRInt32 n)
|
||||
{
|
||||
if (!mInputStream)
|
||||
return 0;
|
||||
PRInt32 result = 0;
|
||||
mInputStream->Read((char*)s, 0, n, (PRUint32*)&result);
|
||||
if (result < n)
|
||||
mEOF = PR_TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Input streamers. Add more as needed (int&, unsigned int& etc). (but you have to
|
||||
// add delegators to the derived classes, too, because these operators don't inherit).
|
||||
nsInputStream& operator >> (char& ch);
|
||||
|
||||
inline PRBool is_open() const { return mFileDesc != 0; }
|
||||
void open(
|
||||
const nsFilePath& inFile,
|
||||
int nsprMode,
|
||||
PRIntn accessMode);
|
||||
void close();
|
||||
PRIntn tell() const;
|
||||
void seek(PRInt32 offset) { seek(PR_SEEK_SET, offset); }
|
||||
void seek(PRSeekWhence whence, PRInt32 offset);
|
||||
PRBool eof() const { return mEOF; }
|
||||
PRBool failed() const { return mFailed; }
|
||||
// call PR_GetError() for details
|
||||
protected:
|
||||
|
||||
PRFileDesc* GetFileDescriptor() const { return mFileDesc; }
|
||||
|
||||
protected:
|
||||
|
||||
friend class nsBasicInStream;
|
||||
friend class nsBasicOutStream;
|
||||
|
||||
PRFileDesc* mFileDesc;
|
||||
int mNSPRMode;
|
||||
PRBool mFailed;
|
||||
PRBool mEOF;
|
||||
}; // class nsBasicFileStream
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsBasicInStream
|
||||
//========================================================================================
|
||||
{
|
||||
protected:
|
||||
nsBasicInStream(nsBasicFileStream& inStream, istream* stream);
|
||||
|
||||
public:
|
||||
|
||||
nsBasicInStream& operator >> (nsBasicInStream& (*pf)(nsBasicInStream&))
|
||||
// Support manipulators
|
||||
nsInputStream& operator >> (nsInputStream& (*pf)(nsInputStream&))
|
||||
{
|
||||
return pf(*this);
|
||||
}
|
||||
void get(char& c);
|
||||
PRInt32 read(void* s, PRInt32 n);
|
||||
}
|
||||
private:
|
||||
|
||||
nsInputStream& operator >> (char* buf); // TOO DANGEROUS. DON'T DEFINE.
|
||||
|
||||
// DATA
|
||||
protected:
|
||||
nsCOMPtr<nsIInputStream> mInputStream;
|
||||
PRBool mEOF;
|
||||
}; // class nsInputStream
|
||||
|
||||
typedef nsInputStream nsBasicInStream; // historic support for this name
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsOutputStream
|
||||
// This is a convenience class, for use on the STACK ("new" junkies, get detoxed first).
|
||||
// Given a COM-style stream, this allows you to use the << operators. It also acquires and
|
||||
// reference counts its stream.
|
||||
// Please read the comments at the top of this file
|
||||
//========================================================================================
|
||||
{
|
||||
public:
|
||||
nsOutputStream() {}
|
||||
nsOutputStream(nsIOutputStream* inStream)
|
||||
: mOutputStream(do_QueryInterface(inStream))
|
||||
{}
|
||||
|
||||
virtual ~nsOutputStream();
|
||||
|
||||
nsCOMPtr<nsIOutputStream> GetIStream() const
|
||||
{
|
||||
return mOutputStream;
|
||||
}
|
||||
void put(char c);
|
||||
PRInt32 write(const void* s, PRInt32 n)
|
||||
{
|
||||
if (!mOutputStream)
|
||||
return 0;
|
||||
PRInt32 result = 0;
|
||||
mOutputStream->Write((char*)s, 0, n, (PRUint32*)&result);
|
||||
return result;
|
||||
}
|
||||
virtual void flush();
|
||||
|
||||
// Output streamers. Add more as needed (but you have to add delegators to the derived
|
||||
// classes, too, because these operators don't inherit).
|
||||
nsOutputStream& operator << (const char* buf);
|
||||
nsOutputStream& operator << (char ch);
|
||||
nsOutputStream& operator << (short val);
|
||||
nsOutputStream& operator << (unsigned short val);
|
||||
nsOutputStream& operator << (long val);
|
||||
nsOutputStream& operator << (unsigned long val);
|
||||
|
||||
// Support manipulators
|
||||
nsOutputStream& operator << (nsOutputStream& (*pf)(nsOutputStream&))
|
||||
{
|
||||
return pf(*this);
|
||||
}
|
||||
|
||||
// DATA
|
||||
protected:
|
||||
nsCOMPtr<nsIOutputStream> mOutputStream;
|
||||
}; // class nsOutputStream
|
||||
|
||||
typedef nsOutputStream nsBasicOutStream; // Historic support for this name
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsFileClient
|
||||
// Because COM does not allow us to write functions which return a boolean value etc,
|
||||
// this class is here to take care of the tedious "declare variable then call with
|
||||
// the address of the variable" chores.
|
||||
//========================================================================================
|
||||
{
|
||||
public:
|
||||
nsFileClient() // for delayed opening
|
||||
: mResult(NS_OK)
|
||||
{
|
||||
}
|
||||
nsFileClient(const nsCOMPtr<nsIFile>& inFile)
|
||||
: mFile(do_QueryInterface(inFile))
|
||||
, mResult(NS_OK)
|
||||
{
|
||||
}
|
||||
|
||||
PRBool is_file() const
|
||||
{
|
||||
return mFile ? PR_TRUE : PR_FALSE;
|
||||
}
|
||||
void open(
|
||||
const nsFileSpec& inFile,
|
||||
int nsprMode,
|
||||
PRIntn accessMode)
|
||||
{
|
||||
if (mFile)
|
||||
mResult = mFile->Open(inFile, nsprMode, accessMode);
|
||||
}
|
||||
PRBool is_open() const
|
||||
{
|
||||
PRBool result = PR_FALSE;
|
||||
if (mFile)
|
||||
mFile->GetIsOpen(&result);
|
||||
return result;
|
||||
}
|
||||
PRBool failed() const
|
||||
{
|
||||
return NS_FAILED(mResult);
|
||||
}
|
||||
void seek(PRInt32 offset)
|
||||
{
|
||||
seek(PR_SEEK_SET, offset);
|
||||
}
|
||||
|
||||
void seek(PRSeekWhence whence, PRInt32 offset)
|
||||
{
|
||||
if (mFile)
|
||||
mResult = mFile->Seek(whence, offset);
|
||||
}
|
||||
PRIntn tell()
|
||||
{
|
||||
PRIntn result = -1;
|
||||
if (mFile)
|
||||
mResult = mFile->Tell(&result);
|
||||
return result;
|
||||
}
|
||||
|
||||
// DATA
|
||||
protected:
|
||||
nsCOMPtr<nsIFile> mFile;
|
||||
PRBool mResult;
|
||||
}; // class nsFileClient
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsInputFileStream
|
||||
// Please read the comments at the top of this file
|
||||
//========================================================================================
|
||||
: public nsInputStream
|
||||
, public nsFileClient
|
||||
{
|
||||
public:
|
||||
enum { kDefaultMode = PR_RDONLY };
|
||||
nsInputFileStream(nsIInputStream* inStream)
|
||||
: nsInputStream(inStream)
|
||||
, nsFileClient(do_QueryInterface(inStream))
|
||||
, mFileInputStream(do_QueryInterface(inStream))
|
||||
{
|
||||
}
|
||||
nsInputFileStream(
|
||||
const nsFileSpec& inFile,
|
||||
int nsprMode = kDefaultMode,
|
||||
PRIntn accessMode = 00700) // <- OCTAL
|
||||
: nsInputStream(nsnull)
|
||||
{
|
||||
nsISupports* stream;
|
||||
NS_NewIOFileStream(
|
||||
&stream,
|
||||
inFile, nsprMode, accessMode);
|
||||
mFile = nsQueryInterface(stream);
|
||||
mInputStream = nsQueryInterface(stream);
|
||||
mFileInputStream = nsQueryInterface(stream);
|
||||
}
|
||||
|
||||
PRBool readline(char* s, PRInt32 n);
|
||||
// Result always null-terminated.
|
||||
// Check eof() before each call.
|
||||
// CAUTION: false result only indicates line was truncated
|
||||
// to fit buffer, or an error occurred (OTHER THAN eof).
|
||||
|
||||
// Input streamers. Add more as needed
|
||||
nsBasicInStream& operator >> (char& ch);
|
||||
|
||||
istream* GetStandardStream() const { return mStdStream; }
|
||||
|
||||
protected:
|
||||
|
||||
nsBasicFileStream& mBase;
|
||||
istream* mStdStream;
|
||||
}; // class nsBasicInStream
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsBasicOutStream
|
||||
//========================================================================================
|
||||
{
|
||||
protected:
|
||||
|
||||
nsBasicOutStream(nsBasicFileStream& inStream, ostream* stream);
|
||||
|
||||
public:
|
||||
|
||||
nsBasicOutStream& operator << (nsBasicOutStream& (*pf)(nsBasicOutStream&))
|
||||
{
|
||||
return pf(*this);
|
||||
}
|
||||
void put(char c);
|
||||
PRInt32 write(const void* s, PRInt32 n);
|
||||
void flush();
|
||||
|
||||
// Output streamers. Add more as needed
|
||||
nsBasicOutStream& operator << (const char* buf);
|
||||
nsBasicOutStream& operator << (char ch);
|
||||
nsBasicOutStream& operator << (short val);
|
||||
nsBasicOutStream& operator << (unsigned short val);
|
||||
nsBasicOutStream& operator << (long val);
|
||||
nsBasicOutStream& operator << (unsigned long val);
|
||||
|
||||
ostream* GetStandardStream() const { return mStdStream; }
|
||||
|
||||
protected:
|
||||
|
||||
nsBasicFileStream& mBase;
|
||||
ostream* mStdStream;
|
||||
}; // class nsBasicOutStream
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsInputFileStream
|
||||
//========================================================================================
|
||||
: public nsBasicFileStream
|
||||
, public nsBasicInStream
|
||||
{
|
||||
public:
|
||||
enum { kDefaultMode = PR_RDONLY };
|
||||
nsInputFileStream(istream* stream = CONSOLE_IN);
|
||||
nsInputFileStream(
|
||||
const nsFilePath& inFile,
|
||||
int nsprMode = kDefaultMode,
|
||||
PRIntn accessMode = 00700) // <- OCTAL
|
||||
: nsBasicFileStream(inFile, nsprMode, accessMode)
|
||||
, nsBasicInStream(*this, 0)
|
||||
{}
|
||||
|
||||
void open(
|
||||
const nsFilePath& inFile,
|
||||
void Open(
|
||||
const nsFileSpec& inFile,
|
||||
int nsprMode = kDefaultMode,
|
||||
PRIntn accessMode = 00700) // <- OCTAL
|
||||
{
|
||||
nsBasicFileStream::open(inFile, nsprMode, accessMode);
|
||||
if (mFile)
|
||||
mFile->Open(inFile, nsprMode, accessMode);
|
||||
}
|
||||
private:
|
||||
|
||||
nsInputFileStream& operator >> (char* buf); // TOO DANGEROUS. DON'T DEFINE.
|
||||
// Input streamers. Unfortunately, they don't inherit!
|
||||
nsInputStream& operator >> (char& ch)
|
||||
{ return nsInputStream::operator >>(ch); }
|
||||
nsInputStream& operator >> (nsInputStream& (*pf)(nsInputStream&))
|
||||
{ return nsInputStream::operator >>(pf); }
|
||||
|
||||
// DATA
|
||||
protected:
|
||||
nsCOMPtr<nsIFileInputStream> mFileInputStream;
|
||||
}; // class nsInputFileStream
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsOutputFileStream
|
||||
// Please read the comments at the top of this file
|
||||
//========================================================================================
|
||||
: public nsBasicFileStream
|
||||
, public nsBasicOutStream
|
||||
: public nsOutputStream
|
||||
, public nsFileClient
|
||||
{
|
||||
public:
|
||||
enum { kDefaultMode = (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE) };
|
||||
|
||||
nsOutputFileStream(ostream* stream = CONSOLE_OUT);
|
||||
nsOutputFileStream() {}
|
||||
nsOutputFileStream(nsIOutputStream* inStream)
|
||||
: nsOutputStream(inStream)
|
||||
, nsFileClient(do_QueryInterface(inStream))
|
||||
, mFileOutputStream(do_QueryInterface(inStream))
|
||||
{
|
||||
}
|
||||
nsOutputFileStream(
|
||||
const nsFilePath& inFile,
|
||||
const nsFileSpec& inFile,
|
||||
int nsprMode = kDefaultMode,
|
||||
PRIntn accessMode = 00700) // <- OCTAL
|
||||
: nsBasicFileStream(inFile, nsprMode, accessMode)
|
||||
, nsBasicOutStream(*this, 0)
|
||||
{}
|
||||
|
||||
inline void open(
|
||||
const nsFilePath& inFile,
|
||||
int nsprMode = kDefaultMode,
|
||||
PRIntn accessMode = 00700) // <- OCTAL
|
||||
: nsOutputStream(nsnull)
|
||||
{
|
||||
nsBasicFileStream::open(inFile, nsprMode, accessMode);
|
||||
nsISupports* stream;
|
||||
if (NS_FAILED(NS_NewIOFileStream(
|
||||
&stream,
|
||||
inFile, nsprMode, accessMode)))
|
||||
return;
|
||||
mFile = nsQueryInterface(stream);
|
||||
mOutputStream = nsQueryInterface(stream);
|
||||
mFileOutputStream = nsQueryInterface(stream);
|
||||
}
|
||||
|
||||
virtual void flush();
|
||||
|
||||
// Output streamers. Unfortunately, they don't inherit!
|
||||
nsOutputStream& operator << (const char* buf)
|
||||
{ return nsOutputStream::operator << (buf); }
|
||||
nsOutputStream& operator << (char ch)
|
||||
{ return nsOutputStream::operator << (ch); }
|
||||
nsOutputStream& operator << (short val)
|
||||
{ return nsOutputStream::operator << (val); }
|
||||
nsOutputStream& operator << (unsigned short val)
|
||||
{ return nsOutputStream::operator << (val); }
|
||||
nsOutputStream& operator << (long val)
|
||||
{ return nsOutputStream::operator << (val); }
|
||||
nsOutputStream& operator << (unsigned long val)
|
||||
{ return nsOutputStream::operator << (val); }
|
||||
nsOutputStream& operator << (nsOutputStream& (*pf)(nsOutputStream&))
|
||||
{ return nsOutputStream::operator << (pf); }
|
||||
|
||||
// DATA
|
||||
protected:
|
||||
nsCOMPtr<nsIFileOutputStream> mFileOutputStream;
|
||||
}; // class nsOutputFileStream
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsIOFileStream
|
||||
class NS_BASE nsOutputConsoleStream
|
||||
// Please read the comments at the top of this file
|
||||
//========================================================================================
|
||||
: public nsBasicFileStream
|
||||
, public nsBasicOutStream
|
||||
, public nsBasicInStream
|
||||
: public nsOutputFileStream
|
||||
{
|
||||
public:
|
||||
|
||||
nsOutputConsoleStream()
|
||||
{
|
||||
nsISupports* stream;
|
||||
if (NS_FAILED(NS_NewOutputConsoleStream(&stream)))
|
||||
return;
|
||||
mFile = nsQueryInterface(stream);
|
||||
mOutputStream = nsQueryInterface(stream);
|
||||
mFileOutputStream = nsQueryInterface(stream);
|
||||
}
|
||||
|
||||
// Output streamers. Unfortunately, they don't inherit!
|
||||
nsOutputStream& operator << (const char* buf)
|
||||
{ return nsOutputStream::operator << (buf); }
|
||||
nsOutputStream& operator << (char ch)
|
||||
{ return nsOutputStream::operator << (ch); }
|
||||
nsOutputStream& operator << (short val)
|
||||
{ return nsOutputStream::operator << (val); }
|
||||
nsOutputStream& operator << (unsigned short val)
|
||||
{ return nsOutputStream::operator << (val); }
|
||||
nsOutputStream& operator << (long val)
|
||||
{ return nsOutputStream::operator << (val); }
|
||||
nsOutputStream& operator << (unsigned long val)
|
||||
{ return nsOutputStream::operator << (val); }
|
||||
nsOutputStream& operator << (nsOutputStream& (*pf)(nsOutputStream&))
|
||||
{ return nsOutputStream::operator << (pf); }
|
||||
|
||||
}; // class nsOutputConsoleStream
|
||||
|
||||
//========================================================================================
|
||||
class NS_BASE nsIOFileStream
|
||||
// Please read the comments at the top of this file
|
||||
//========================================================================================
|
||||
: public nsInputFileStream
|
||||
, public nsOutputStream
|
||||
{
|
||||
public:
|
||||
enum { kDefaultMode = (PR_RDWR | PR_CREATE_FILE) };
|
||||
|
||||
nsIOFileStream(
|
||||
const nsFilePath& inFile,
|
||||
nsIInputStream* inInputStream
|
||||
, nsIOutputStream* inOutputStream)
|
||||
: nsInputFileStream(inInputStream)
|
||||
, nsOutputStream(inOutputStream)
|
||||
, mFileOutputStream(do_QueryInterface(inOutputStream))
|
||||
{
|
||||
}
|
||||
nsIOFileStream(
|
||||
const nsFileSpec& inFile,
|
||||
int nsprMode = kDefaultMode,
|
||||
PRIntn accessMode = 00700) // <- OCTAL
|
||||
: nsBasicFileStream(inFile, nsprMode, accessMode)
|
||||
, nsBasicInStream(*this, 0)
|
||||
, nsBasicOutStream(*this, 0)
|
||||
{}
|
||||
|
||||
inline void open(
|
||||
const nsFilePath& inFile,
|
||||
int nsprMode = kDefaultMode,
|
||||
PRIntn accessMode = 00700) // <- OCTAL
|
||||
: nsInputFileStream(nsnull)
|
||||
, nsOutputStream(nsnull)
|
||||
{
|
||||
nsBasicFileStream::open(inFile, nsprMode, accessMode);
|
||||
nsISupports* stream;
|
||||
if (NS_FAILED(NS_NewIOFileStream(
|
||||
&stream,
|
||||
inFile, nsprMode, accessMode)))
|
||||
return;
|
||||
mFile = nsQueryInterface(stream);
|
||||
mInputStream = nsQueryInterface(stream);
|
||||
mOutputStream = nsQueryInterface(stream);
|
||||
mFileInputStream = nsQueryInterface(stream);
|
||||
mFileOutputStream = nsQueryInterface(stream);
|
||||
}
|
||||
}; // class nsIOFileStream
|
||||
|
||||
// Output streamers. Unfortunately, they don't inherit!
|
||||
nsOutputStream& operator << (const char* buf)
|
||||
{ return nsOutputStream::operator << (buf); }
|
||||
nsOutputStream& operator << (char ch)
|
||||
{ return nsOutputStream::operator << (ch); }
|
||||
nsOutputStream& operator << (short val)
|
||||
{ return nsOutputStream::operator << (val); }
|
||||
nsOutputStream& operator << (unsigned short val)
|
||||
{ return nsOutputStream::operator << (val); }
|
||||
nsOutputStream& operator << (long val)
|
||||
{ return nsOutputStream::operator << (val); }
|
||||
nsOutputStream& operator << (unsigned long val)
|
||||
{ return nsOutputStream::operator << (val); }
|
||||
nsOutputStream& operator << (nsOutputStream& (*pf)(nsOutputStream&))
|
||||
{ return nsOutputStream::operator << (pf); }
|
||||
|
||||
// Input streamers. Unfortunately, they don't inherit!
|
||||
nsInputStream& operator >> (char& ch)
|
||||
{ return nsInputStream::operator >>(ch); }
|
||||
nsInputStream& operator >> (nsInputStream& (*pf)(nsInputStream&))
|
||||
{ return nsInputStream::operator >>(pf); }
|
||||
// DATA
|
||||
protected:
|
||||
nsCOMPtr<nsIFileOutputStream> mFileOutputStream;
|
||||
}; // class nsIOFileStream
|
||||
|
||||
//========================================================================================
|
||||
// Manipulators
|
||||
//========================================================================================
|
||||
NS_BASE nsBasicOutStream& nsEndl(nsBasicOutStream& os);
|
||||
|
||||
|
||||
NS_BASE nsOutputStream& nsEndl(nsOutputStream& os); // outputs and FLUSHES.
|
||||
|
||||
|
||||
#endif /* _FILESTREAM_H_ */
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
class nsIBaseStream : public nsISupports {
|
||||
public:
|
||||
|
||||
static const nsIID& IID() { static nsIID iid = NS_IBASESTREAM_IID; return iid; }
|
||||
|
||||
/** Close the stream. */
|
||||
NS_IMETHOD
|
||||
Close(void) = 0;
|
||||
|
||||
451
mozilla/xpcom/io/nsIFileStream.cpp
Normal file
451
mozilla/xpcom/io/nsIFileStream.cpp
Normal file
@@ -0,0 +1,451 @@
|
||||
#include "nsIFileStream.h"
|
||||
#include "nsFileSpec.h"
|
||||
|
||||
#include "prerror.h"
|
||||
|
||||
#ifdef XP_MAC
|
||||
#include "pprio.h" // To get PR_ImportFile
|
||||
#else
|
||||
#include "prio.h"
|
||||
#endif
|
||||
|
||||
#ifdef XP_MAC
|
||||
#include <Errors.h>
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
//========================================================================================
|
||||
class FileImpl
|
||||
: public nsIOutputStream
|
||||
, public nsIInputStream
|
||||
, public nsIFileOutputStream
|
||||
, public nsIFileInputStream
|
||||
, public nsIFile
|
||||
//========================================================================================
|
||||
{
|
||||
public:
|
||||
FileImpl(PRFileDesc* inDesc)
|
||||
: mFileDesc(inDesc)
|
||||
, mFailed(PR_FALSE)
|
||||
, mEOF(PR_FALSE)
|
||||
, mLength(-1)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
FileImpl(
|
||||
const nsFileSpec& inFile,
|
||||
int nsprMode,
|
||||
PRIntn accessMode)
|
||||
: mFileDesc(nsnull)
|
||||
, mFailed(PR_FALSE)
|
||||
, mEOF(PR_FALSE)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
Open(inFile, nsprMode, accessMode);
|
||||
}
|
||||
virtual ~FileImpl()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
// nsISupports interface
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIFile interface
|
||||
NS_IMETHOD Open(
|
||||
const nsFileSpec& inFile,
|
||||
int nsprMode,
|
||||
PRIntn accessMode);
|
||||
NS_IMETHOD Close();
|
||||
NS_IMETHOD Seek(PRSeekWhence whence, PRInt32 offset);
|
||||
|
||||
NS_IMETHOD GetIsOpen(PRBool* outOpen)
|
||||
{
|
||||
*outOpen = (mFileDesc != nsnull);
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD Tell(PRIntn* outWhere);
|
||||
|
||||
// nsIInputStream interface
|
||||
NS_IMETHOD GetLength(PRUint32 *aLength)
|
||||
{
|
||||
NS_PRECONDITION(aLength != nsnull, "null ptr");
|
||||
if (!aLength)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
if (mLength < 0)
|
||||
return NS_FILE_RESULT(NS_ERROR_UNEXPECTED);
|
||||
*aLength = mLength;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD Read(char* aBuf,
|
||||
PRUint32 aOffset,
|
||||
PRUint32 aCount,
|
||||
PRUint32 *aReadCount)
|
||||
{
|
||||
NS_PRECONDITION(aBuf != nsnull, "null ptr");
|
||||
if (!aBuf)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
NS_PRECONDITION(aReadCount != nsnull, "null ptr");
|
||||
if (!aReadCount)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
if (!mFileDesc)
|
||||
return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
|
||||
if (mFailed)
|
||||
return NS_ERROR_FAILURE;
|
||||
if (aOffset)
|
||||
PR_Seek(mFileDesc, aOffset, PR_SEEK_CUR);
|
||||
PRInt32 bytesRead = PR_Read(mFileDesc, aBuf, aCount);
|
||||
if (bytesRead < 0)
|
||||
{
|
||||
*aReadCount = 0;
|
||||
mFailed = PR_TRUE;
|
||||
return NS_FILE_RESULT(PR_GetError());
|
||||
}
|
||||
*aReadCount = bytesRead;
|
||||
return NS_OK;
|
||||
}
|
||||
// nsIOutputStream interface
|
||||
NS_IMETHOD Write(const char* aBuf,
|
||||
PRUint32 aOffset,
|
||||
PRUint32 aCount,
|
||||
PRUint32 *aWriteCount)
|
||||
{
|
||||
NS_PRECONDITION(aBuf != nsnull, "null ptr");
|
||||
NS_PRECONDITION(aWriteCount != nsnull, "null ptr");
|
||||
|
||||
|
||||
#ifdef XP_MAC
|
||||
// Calling PR_Write on stdout is sure suicide.
|
||||
if (mFileDesc == PR_STDOUT || mFileDesc == PR_STDERR)
|
||||
{
|
||||
cout.write(aBuf, aCount);
|
||||
*aWriteCount = aCount;
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
if (!mFileDesc)
|
||||
return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
|
||||
if (mFailed)
|
||||
return NS_ERROR_FAILURE;
|
||||
if (aOffset)
|
||||
PR_Seek(mFileDesc, aOffset, PR_SEEK_CUR);
|
||||
PRInt32 bytesWrit = PR_Write(mFileDesc, aBuf, aCount);
|
||||
if (bytesWrit != aCount)
|
||||
{
|
||||
mFailed = PR_TRUE;
|
||||
*aWriteCount = 0;
|
||||
return NS_FILE_RESULT(PR_GetError());
|
||||
}
|
||||
*aWriteCount = bytesWrit;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHOD Flush();
|
||||
|
||||
protected:
|
||||
|
||||
PRFileDesc* mFileDesc;
|
||||
int mNSPRMode;
|
||||
PRBool mFailed;
|
||||
PRBool mEOF;
|
||||
PRInt32 mLength;
|
||||
}; // class FileImpl
|
||||
|
||||
#define SAY_I_IMPLEMENT(classname) \
|
||||
if (aIID.Equals(classname::IID())) \
|
||||
{ \
|
||||
*aInstancePtr = (void*)((classname*)this); \
|
||||
NS_ADDREF_THIS(); \
|
||||
return NS_OK; \
|
||||
}
|
||||
|
||||
NS_IMPL_RELEASE(FileImpl)
|
||||
NS_IMPL_ADDREF(FileImpl)
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_IMETHODIMP FileImpl::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!aInstancePtr)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
*aInstancePtr = nsnull;
|
||||
|
||||
SAY_I_IMPLEMENT(nsIFile)
|
||||
SAY_I_IMPLEMENT(nsIOutputStream)
|
||||
SAY_I_IMPLEMENT(nsIInputStream)
|
||||
SAY_I_IMPLEMENT(nsIFileInputStream)
|
||||
SAY_I_IMPLEMENT(nsIFileOutputStream)
|
||||
// Note that we derive from two copies of nsIBaseStream (and hence
|
||||
// of nsISupports), one through
|
||||
// nsIOutputStream, the other through nsIInputStream. Resolve this
|
||||
// by giving them a specific one
|
||||
if (aIID.Equals(((nsIBaseStream*)(nsIOutputStream*)this)->IID()))
|
||||
{
|
||||
*aInstancePtr = (void*)((nsIBaseStream*)(nsIOutputStream*)this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
if (aIID.Equals(((nsISupports*)(nsIOutputStream*)this)->IID()))
|
||||
{
|
||||
*aInstancePtr = (void*)((nsISupports*)(nsIOutputStream*)this);
|
||||
NS_ADDREF_THIS();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
} // FileImpl::QueryInterface
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_IMETHODIMP FileImpl::Open(
|
||||
const nsFileSpec& inFile,
|
||||
int nsprMode,
|
||||
PRIntn accessMode)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (mFileDesc)
|
||||
if ((nsprMode & mNSPRMode) == nsprMode)
|
||||
return NS_OK;
|
||||
else
|
||||
return NS_FILE_RESULT(PR_ILLEGAL_ACCESS_ERROR);
|
||||
|
||||
const int nspr_modes[]={
|
||||
PR_WRONLY | PR_CREATE_FILE,
|
||||
PR_WRONLY | PR_CREATE_FILE | PR_APPEND,
|
||||
PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
|
||||
PR_RDONLY,
|
||||
PR_RDONLY | PR_APPEND,
|
||||
PR_RDWR | PR_CREATE_FILE,
|
||||
PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE,
|
||||
// "wb",
|
||||
// "ab",
|
||||
// "wb",
|
||||
// "rb",
|
||||
// "r+b",
|
||||
// "w+b",
|
||||
0 };
|
||||
const int* currentLegalMode = nspr_modes;
|
||||
while (*currentLegalMode && nsprMode != *currentLegalMode)
|
||||
++currentLegalMode;
|
||||
if (!*currentLegalMode)
|
||||
return NS_FILE_RESULT(PR_ILLEGAL_ACCESS_ERROR);
|
||||
|
||||
#ifdef XP_MAC
|
||||
// Use the file spec to open the file, because one path can be common to
|
||||
// several files on the Macintosh (you can have several volumes with the
|
||||
// same name, see).
|
||||
mFileDesc = 0;
|
||||
if (inFile.Error() != noErr)
|
||||
return NS_FILE_RESULT(inFile.Error());
|
||||
OSErr err = noErr;
|
||||
#if DEBUG
|
||||
const OSType kCreator = 'CWIE';
|
||||
#else
|
||||
const OSType kCreator = 'MOSS';
|
||||
#endif
|
||||
// Resolve the alias to the original file.
|
||||
nsFileSpec original = inFile;
|
||||
PRBool ignoredResult;
|
||||
original.ResolveAlias(ignoredResult);
|
||||
const FSSpec& spec = original.operator const FSSpec&();
|
||||
if (nsprMode & PR_CREATE_FILE)
|
||||
err = FSpCreate(&spec, kCreator, 'TEXT', 0);
|
||||
if (err == dupFNErr)
|
||||
err = noErr;
|
||||
if (err != noErr)
|
||||
return NS_FILE_RESULT(err);
|
||||
|
||||
SInt8 perm;
|
||||
if (nsprMode & PR_RDWR)
|
||||
perm = fsRdWrPerm;
|
||||
else if (nsprMode & PR_WRONLY)
|
||||
perm = fsWrPerm;
|
||||
else
|
||||
perm = fsRdPerm;
|
||||
|
||||
short refnum;
|
||||
err = FSpOpenDF(&spec, perm, &refnum);
|
||||
|
||||
if (err == noErr && (nsprMode & PR_TRUNCATE))
|
||||
err = SetEOF(refnum, 0);
|
||||
if (err == noErr && (nsprMode & PR_APPEND))
|
||||
err = SetFPos(refnum, fsFromLEOF, 0);
|
||||
if (err != noErr)
|
||||
return NS_FILE_RESULT(err);
|
||||
|
||||
if ((mFileDesc = PR_ImportFile(refnum)) == 0)
|
||||
return NS_FILE_RESULT(PR_GetError());
|
||||
#else
|
||||
// Platforms other than Macintosh...
|
||||
// Another bug in NSPR: Mac PR_Open assumes a unix style path, but Win PR_Open assumes
|
||||
// a windows path.
|
||||
if ((mFileDesc = PR_Open((const char*)nsFileSpec(inFile), nsprMode, accessMode)) == 0)
|
||||
return NS_FILE_RESULT(PR_GetError());
|
||||
#endif
|
||||
mNSPRMode = nsprMode;
|
||||
mLength = PR_Available(mFileDesc);
|
||||
return NS_OK;
|
||||
} // FileImpl::Open
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_IMETHODIMP FileImpl::Seek(PRSeekWhence whence, PRInt32 offset)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR || !mFileDesc)
|
||||
return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
|
||||
mFailed = PR_FALSE; // reset on a seek.
|
||||
mEOF = PR_FALSE; // reset on a seek.
|
||||
PRInt32 position = PR_Seek(mFileDesc, 0, PR_SEEK_CUR);
|
||||
PRInt32 available = PR_Available(mFileDesc);
|
||||
PRInt32 fileSize = position + available;
|
||||
PRInt32 newPosition;
|
||||
switch (whence)
|
||||
{
|
||||
case PR_SEEK_CUR: newPosition = position + offset; break;
|
||||
case PR_SEEK_SET: newPosition = offset; break;
|
||||
case PR_SEEK_END: newPosition = fileSize + offset; break;
|
||||
}
|
||||
if (newPosition < 0)
|
||||
{
|
||||
newPosition = 0;
|
||||
mFailed = PR_TRUE;
|
||||
}
|
||||
else if (newPosition >= fileSize)
|
||||
{
|
||||
newPosition = fileSize;
|
||||
mEOF = PR_TRUE;
|
||||
}
|
||||
if (PR_Seek(mFileDesc, newPosition, PR_SEEK_SET) < 0)
|
||||
mFailed = PR_TRUE;
|
||||
return NS_OK;
|
||||
} // FileImpl::Seek
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_IMETHODIMP FileImpl::Tell(PRIntn* outWhere)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR || !mFileDesc)
|
||||
return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
|
||||
*outWhere = PR_Seek(mFileDesc, 0, PR_SEEK_CUR);
|
||||
return NS_OK;
|
||||
} // FileImpl::Tell
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_IMETHODIMP FileImpl::Close()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (mFileDesc==PR_STDIN || mFileDesc==PR_STDOUT || mFileDesc==PR_STDERR || !mFileDesc)
|
||||
return NS_OK;
|
||||
if (PR_Close(mFileDesc) == PR_SUCCESS)
|
||||
mFileDesc = 0;
|
||||
else
|
||||
return NS_FILE_RESULT(PR_GetError());
|
||||
return NS_OK;
|
||||
} // FileImpl::close
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_IMETHODIMP FileImpl::Flush()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
#ifdef XP_MAC
|
||||
if (mFileDesc == PR_STDOUT || mFileDesc == PR_STDERR)
|
||||
{
|
||||
cout.flush();
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
if (!mFileDesc)
|
||||
return NS_FILE_RESULT(PR_BAD_DESCRIPTOR_ERROR);
|
||||
PRBool itFailed = PR_Sync(mFileDesc) != PR_SUCCESS;
|
||||
#ifdef XP_MAC
|
||||
// On unix, it seems to fail always.
|
||||
if (itFailed)
|
||||
mFailed = PR_TRUE;
|
||||
#endif
|
||||
return NS_OK;
|
||||
} // FileImpl::flush
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_BASE nsresult NS_NewTypicalInputFileStream(
|
||||
nsISupports** aResult,
|
||||
const nsFileSpec& inFile
|
||||
/*Default nsprMode == PR_RDONLY*/
|
||||
/*Default accessmode = 0700 (octal)*/)
|
||||
// Factory method to get an nsInputStream from a file, using most common options
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return NS_NewIOFileStream(aResult, inFile, PR_RDONLY, 0700);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_BASE nsresult NS_NewOutputConsoleStream(
|
||||
nsISupports** aResult)
|
||||
// Factory method to get an nsOutputStream to the console.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
NS_PRECONDITION(aResult != nsnull, "null ptr");
|
||||
if (! aResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
FileImpl* stream = new FileImpl(PR_STDOUT);
|
||||
if (! stream)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(stream);
|
||||
*aResult = (nsISupports*)(void*)stream;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_BASE nsresult NS_NewTypicalOutputFileStream(
|
||||
nsISupports** aResult,
|
||||
const nsFileSpec& inFile
|
||||
/*default nsprMode= (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE)*/
|
||||
/*Default accessMode= 0700 (octal)*/)
|
||||
// Factory method to get an nsOutputStream to a file - most common case.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return NS_NewIOFileStream(
|
||||
aResult,
|
||||
inFile,
|
||||
(PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE),
|
||||
0700);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_BASE nsresult NS_NewIOFileStream(
|
||||
nsISupports** aResult,
|
||||
const nsFileSpec& inFile,
|
||||
PRInt32 nsprMode /*default = (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE)*/,
|
||||
PRInt32 accessMode /*Default = 0700 (octal)*/)
|
||||
// Factory method to get an object that implements both nsIInputStream
|
||||
// and nsIOutputStream, associated with a file.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
NS_PRECONDITION(aResult != nsnull, "null ptr");
|
||||
if (!aResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
FileImpl* stream = new FileImpl(inFile, nsprMode, accessMode);
|
||||
if (! stream)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(stream);
|
||||
*aResult = (nsISupports*)(void*)stream;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_BASE nsresult NS_NewTypicalIOFileStream(
|
||||
nsISupports** aResult,
|
||||
const nsFileSpec& inFile
|
||||
/*default nsprMode= (PR_RDWR | PR_CREATE_FILE)*/
|
||||
/*Default accessMode= 0700 (octal)*/)
|
||||
// Factory method to get an object that implements both nsIInputStream
|
||||
// and nsIOutputStream, associated with a single file.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return NS_NewIOFileStream(
|
||||
aResult,
|
||||
inFile,
|
||||
(PR_RDWR | PR_CREATE_FILE),
|
||||
0700);
|
||||
}
|
||||
127
mozilla/xpcom/io/nsIFileStream.h
Normal file
127
mozilla/xpcom/io/nsIFileStream.h
Normal file
@@ -0,0 +1,127 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
#ifndef nsIFileStream_h___
|
||||
#define nsIFileStream_h___
|
||||
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "prio.h"
|
||||
|
||||
class nsFileSpec;
|
||||
|
||||
/* a6cf90e8-15b3-11d2-932e-00805f8add32 */
|
||||
#define NS_IFILE_IID \
|
||||
{ 0xa6cf90e8, 0x15b3, 0x11d2, \
|
||||
{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
|
||||
|
||||
//========================================================================================
|
||||
class nsIFile
|
||||
// Represents a file, and supports Open, Tell etc.
|
||||
//========================================================================================
|
||||
: public nsISupports
|
||||
{
|
||||
public:
|
||||
static const nsIID& IID() { static nsIID iid = NS_IFILE_IID; return iid; }
|
||||
NS_IMETHOD Open(
|
||||
const nsFileSpec& inFile,
|
||||
int nsprMode,
|
||||
PRIntn accessMode) = 0;
|
||||
// Note: Open() is only needed after
|
||||
// an explicit Close(). All file streams
|
||||
// are automatically opened on construction.
|
||||
NS_IMETHOD Seek(PRSeekWhence whence, PRInt32 offset) = 0;
|
||||
NS_IMETHOD GetIsOpen(PRBool* outOpen) = 0;
|
||||
NS_IMETHOD Tell(PRIntn* outWhere) = 0;
|
||||
}; // class nsIFile
|
||||
|
||||
/* a6cf90e6-15b3-11d2-932e-00805f8add32 */
|
||||
#define NS_IFILEINPUTSTREAM_IID \
|
||||
{ 0xa6cf90e6, 0x15b3, 0x11d2, \
|
||||
{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
|
||||
|
||||
//========================================================================================
|
||||
class nsIFileInputStream
|
||||
// These are additional file-specific methods that files have, above what
|
||||
// nsIInputStream supports. The current implementation supports both
|
||||
// interfaces.
|
||||
//========================================================================================
|
||||
: public nsISupports
|
||||
{
|
||||
public:
|
||||
static const nsIID& IID() { static nsIID iid = NS_IFILEINPUTSTREAM_IID; return iid; }
|
||||
}; // class nsIFileInputStream
|
||||
|
||||
/* a6cf90e7-15b3-11d2-932e-00805f8add32 */
|
||||
#define NS_IFILEOUTPUTSTREAM_IID \
|
||||
{ 0xa6cf90e7, 0x15b3, 0x11d2, \
|
||||
{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
|
||||
|
||||
//========================================================================================
|
||||
class nsIFileOutputStream
|
||||
// These are additional file-specific methods that files have, above what
|
||||
// nsIOutputStream supports. The current implementation supports both
|
||||
// interfaces.
|
||||
//========================================================================================
|
||||
: public nsISupports
|
||||
{
|
||||
public:
|
||||
static const nsIID& IID() { static nsIID iid = NS_IFILEOUTPUTSTREAM_IID; return iid; }
|
||||
NS_IMETHOD Flush() = 0;
|
||||
// Forces a write to disk.
|
||||
}; // class nsIFileOutputStream
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
NS_BASE nsresult NS_NewTypicalInputFileStream(
|
||||
nsISupports** aStreamResult,
|
||||
const nsFileSpec& inFile
|
||||
/*Default nsprMode == PR_RDONLY*/
|
||||
/*Default accessmode = 0700 (octal)*/);
|
||||
// Factory method to get an nsInputStream from a file, using most common options
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
extern "C" NS_BASE nsresult NS_NewOutputConsoleStream(
|
||||
nsISupports** aStreamResult);
|
||||
// Factory method to get an nsOutputStream to the console.
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
extern "C" NS_BASE nsresult NS_NewTypicalOutputFileStream(
|
||||
nsISupports** aStreamResult, // will implement all the above interfaces
|
||||
const nsFileSpec& inFile
|
||||
/*default nsprMode= (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE)*/
|
||||
/*Default accessMode= 0700 (octal)*/);
|
||||
// Factory method to get an nsOutputStream to a file - most common case.
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
extern "C" NS_BASE nsresult NS_NewTypicalIOFileStream(
|
||||
nsISupports** aStreamResult, // will implement all the above interfaces
|
||||
const nsFileSpec& inFile
|
||||
/*default nsprMode = (PR_RDWR | PR_CREATE_FILE)*/
|
||||
/*Default accessMode = 0700 (octal)*/);
|
||||
// Factory method to get an object that implements both nsIInputStream
|
||||
// and nsIOutputStream, associated with a single file.
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
extern "C" NS_BASE nsresult NS_NewIOFileStream(
|
||||
nsISupports** aStreamResult, // will implement all the above interfaces
|
||||
const nsFileSpec& inFile,
|
||||
PRInt32 nsprMode,
|
||||
PRInt32 accessMode);
|
||||
// Factory method to get an object that implements both nsIInputStream
|
||||
// and nsIOutputStream, associated with a single file.
|
||||
|
||||
#endif /* nsIFileStream_h___ */
|
||||
@@ -28,6 +28,8 @@
|
||||
class nsIInputStream : public nsIBaseStream {
|
||||
public:
|
||||
|
||||
static const nsIID& IID() { static nsIID iid = NS_IINPUTSTREAM_IID; return iid; }
|
||||
|
||||
/** Return the number of bytes in the stream
|
||||
* @param aLength out parameter to hold the length
|
||||
* of the stream. if an error occurs, the length
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
class nsIOutputStream : public nsIBaseStream {
|
||||
public:
|
||||
|
||||
static const nsIID& IID() { static nsIID iid = NS_IOUTPUTSTREAM_IID; return iid; }
|
||||
|
||||
/** Write data into the stream.
|
||||
* @param aBuf the buffer into which the data is read
|
||||
* @param aOffset the start offset of the data
|
||||
|
||||
@@ -16,10 +16,11 @@
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "string.h"
|
||||
#include "nsFileSpec.h"
|
||||
#include "nsFileStream.h"
|
||||
|
||||
//#include "string.h"
|
||||
|
||||
struct FilesTest
|
||||
{
|
||||
FilesTest() : mConsole() {}
|
||||
@@ -30,18 +31,25 @@ struct FilesTest
|
||||
int InputStream(const char* relativePath);
|
||||
int OutputStream(const char* relativePath);
|
||||
int IOStream(const char* relativePath);
|
||||
int Parent(const char* relativePath, nsNativeFileSpec& outParent);
|
||||
int Delete(nsNativeFileSpec& victim);
|
||||
int CreateDirectory(nsNativeFileSpec& victim);
|
||||
int IterateDirectoryChildren(nsNativeFileSpec& startChild);
|
||||
int Parent(const char* relativePath, nsFileSpec& outParent);
|
||||
int Delete(nsFileSpec& victim);
|
||||
int CreateDirectory(nsFileSpec& victim);
|
||||
int IterateDirectoryChildren(nsFileSpec& startChild);
|
||||
int CanonicalPath(const char* relativePath);
|
||||
int Persistence(const char* relativePath);
|
||||
|
||||
int Copy(const char* sourceFile, const char* targDir);
|
||||
int Move(const char* sourceFile, const char* targDir);
|
||||
int Rename(const char* sourceFile, const char* newName);
|
||||
|
||||
int Execute(const char* appName, const char* args);
|
||||
|
||||
void Banner(const char* bannerString);
|
||||
void Passed();
|
||||
void Failed();
|
||||
void Inspect();
|
||||
|
||||
nsOutputFileStream mConsole;
|
||||
nsOutputConsoleStream mConsole;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
@@ -59,7 +67,8 @@ void FilesTest::Banner(const char* bannerString)
|
||||
void FilesTest::Passed()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mConsole << "Test passed." << nsEndl;
|
||||
((nsOutputStream&)mConsole) << "Test passed.";
|
||||
mConsole << nsEndl;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
@@ -89,7 +98,7 @@ void FilesTest::WriteStuff(nsOutputFileStream& s)
|
||||
s << "As a unix path: \"" << (const char*)filePath << "\""<< nsEndl;
|
||||
|
||||
// Initialize a native file spec from a URL
|
||||
nsNativeFileSpec fileSpec(fileURL);
|
||||
nsFileSpec fileSpec(fileURL);
|
||||
s << "As a file spec: " << fileSpec << nsEndl;
|
||||
|
||||
// Make the spec unique (this one has no suffix).
|
||||
@@ -119,10 +128,10 @@ int FilesTest::OutputStream(const char* relativePath)
|
||||
{
|
||||
nsFilePath myTextFilePath(relativePath, true); // relative path.
|
||||
const char* pathAsString = (const char*)myTextFilePath;
|
||||
nsNativeFileSpec mySpec(myTextFilePath);
|
||||
nsFileSpec mySpec(myTextFilePath);
|
||||
{
|
||||
mConsole << "WRITING IDENTICAL OUTPUT TO " << pathAsString << nsEndl << nsEndl;
|
||||
nsOutputFileStream testStream(myTextFilePath);
|
||||
nsOutputFileStream testStream(mySpec);
|
||||
if (!testStream.is_open())
|
||||
{
|
||||
mConsole
|
||||
@@ -154,9 +163,10 @@ int FilesTest::IOStream(const char* relativePath)
|
||||
{
|
||||
nsFilePath myTextFilePath(relativePath, true); // relative path.
|
||||
const char* pathAsString = (const char*)myTextFilePath;
|
||||
nsFileSpec mySpec(myTextFilePath);
|
||||
mConsole
|
||||
<< "Replacing \"path\" by \"ZUUL\" in " << pathAsString << nsEndl << nsEndl;
|
||||
nsIOFileStream testStream(myTextFilePath);
|
||||
nsIOFileStream testStream(mySpec);
|
||||
if (!testStream.is_open())
|
||||
{
|
||||
mConsole
|
||||
@@ -183,6 +193,57 @@ int FilesTest::IOStream(const char* relativePath)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
int FilesTest::Persistence(
|
||||
const char* relativePathToWrite)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFilePath myTextFilePath(relativePathToWrite, true);
|
||||
const char* pathAsString = (const char*)myTextFilePath;
|
||||
nsFileSpec mySpec(myTextFilePath);
|
||||
|
||||
nsIOFileStream testStream(mySpec, (PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE));
|
||||
if (!testStream.is_open())
|
||||
{
|
||||
mConsole
|
||||
<< "ERROR: File "
|
||||
<< pathAsString
|
||||
<< " could not be opened for input+output"
|
||||
<< nsEndl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
nsPersistentFileDescriptor myPersistent(mySpec);
|
||||
mConsole
|
||||
<< "Writing persistent file data " << pathAsString << nsEndl << nsEndl;
|
||||
|
||||
testStream.seek(0); // check that the seek compiles
|
||||
testStream << myPersistent;
|
||||
|
||||
testStream.seek(0);
|
||||
|
||||
nsPersistentFileDescriptor mySecondPersistent;
|
||||
testStream >> mySecondPersistent;
|
||||
|
||||
mySpec = mySecondPersistent;
|
||||
#ifdef XP_MAC
|
||||
if (mySpec.Error())
|
||||
{
|
||||
Failed();
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!mySpec.Exists())
|
||||
{
|
||||
Failed();
|
||||
return -1;
|
||||
}
|
||||
|
||||
Passed();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
int FilesTest::InputStream(const char* relativePath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
@@ -190,7 +251,8 @@ int FilesTest::InputStream(const char* relativePath)
|
||||
nsFilePath myTextFilePath(relativePath, true);
|
||||
const char* pathAsString = (const char*)myTextFilePath;
|
||||
mConsole << "READING BACK DATA FROM " << pathAsString << nsEndl << nsEndl;
|
||||
nsInputFileStream testStream2(myTextFilePath);
|
||||
nsFileSpec mySpec(myTextFilePath);
|
||||
nsInputFileStream testStream2(mySpec);
|
||||
if (!testStream2.is_open())
|
||||
{
|
||||
mConsole
|
||||
@@ -215,12 +277,12 @@ int FilesTest::InputStream(const char* relativePath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
int FilesTest::Parent(
|
||||
const char* relativePath,
|
||||
nsNativeFileSpec& outParent)
|
||||
nsFileSpec& outParent)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFilePath myTextFilePath(relativePath, true);
|
||||
const char* pathAsString = (const char*)myTextFilePath;
|
||||
nsNativeFileSpec mySpec(myTextFilePath);
|
||||
nsFileSpec mySpec(myTextFilePath);
|
||||
|
||||
mySpec.GetParent(outParent);
|
||||
nsFilePath parentPath(outParent);
|
||||
@@ -235,7 +297,7 @@ int FilesTest::Parent(
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
int FilesTest::Delete(nsNativeFileSpec& victim)
|
||||
int FilesTest::Delete(nsFileSpec& victim)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// - Test of non-recursive delete
|
||||
@@ -284,7 +346,7 @@ int FilesTest::Delete(nsNativeFileSpec& victim)
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
int FilesTest::CreateDirectory(nsNativeFileSpec& dirSpec)
|
||||
int FilesTest::CreateDirectory(nsFileSpec& dirSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFilePath dirPath(dirSpec);
|
||||
@@ -306,27 +368,27 @@ int FilesTest::CreateDirectory(nsNativeFileSpec& dirSpec)
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
int FilesTest::IterateDirectoryChildren(nsNativeFileSpec& startChild)
|
||||
int FilesTest::IterateDirectoryChildren(nsFileSpec& startChild)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// - Test of directory iterator
|
||||
|
||||
nsNativeFileSpec grandparent;
|
||||
nsFileSpec grandparent;
|
||||
startChild.GetParent(grandparent); // should be the original default directory.
|
||||
nsFilePath grandparentPath(grandparent);
|
||||
|
||||
mConsole << "Forwards listing of " << (const char*)grandparentPath << ":" << nsEndl;
|
||||
for (nsDirectoryIterator i(grandparent, +1); i; i++)
|
||||
for (nsDirectoryIterator i(grandparent, +1); i.Exists(); i++)
|
||||
{
|
||||
char* itemName = ((nsNativeFileSpec&)i).GetLeafName();
|
||||
char* itemName = ((nsFileSpec&)i).GetLeafName();
|
||||
mConsole << '\t' << itemName << nsEndl;
|
||||
delete [] itemName;
|
||||
}
|
||||
|
||||
mConsole << "Backwards listing of " << (const char*)grandparentPath << ":" << nsEndl;
|
||||
for (nsDirectoryIterator j(grandparent, -1); j; j--)
|
||||
for (nsDirectoryIterator j(grandparent, -1); j.Exists(); j--)
|
||||
{
|
||||
char* itemName = ((nsNativeFileSpec&)j).GetLeafName();
|
||||
char* itemName = ((nsFileSpec&)j).GetLeafName();
|
||||
mConsole << '\t' << itemName << nsEndl;
|
||||
delete [] itemName;
|
||||
}
|
||||
@@ -355,6 +417,110 @@ int FilesTest::CanonicalPath(
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
int FilesTest::Copy(const char* file, const char* dir)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpec dirPath(dir, true);
|
||||
|
||||
dirPath.CreateDirectory();
|
||||
if (! dirPath.Exists())
|
||||
{
|
||||
Failed();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
nsFileSpec mySpec(file, true); // relative path.
|
||||
{
|
||||
nsIOFileStream testStream(mySpec); // creates the file
|
||||
// Scope ends here, file gets closed
|
||||
}
|
||||
|
||||
nsFileSpec filePath(file);
|
||||
if (! filePath.Exists())
|
||||
{
|
||||
Failed();
|
||||
return -1;
|
||||
}
|
||||
|
||||
nsresult error = filePath.Copy(dirPath);
|
||||
|
||||
dirPath += filePath.GetLeafName();
|
||||
if (! dirPath.Exists() || ! filePath.Exists() || NS_FAILED(error))
|
||||
{
|
||||
Failed();
|
||||
return -1;
|
||||
}
|
||||
|
||||
Passed();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
int FilesTest::Move(const char* file, const char* dir)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpec dirPath(dir, true);
|
||||
|
||||
dirPath.CreateDirectory();
|
||||
if (! dirPath.Exists())
|
||||
{
|
||||
Failed();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
nsFileSpec srcSpec(file, true); // relative path.
|
||||
{
|
||||
nsIOFileStream testStream(srcSpec); // creates the file
|
||||
// file gets closed here because scope ends here.
|
||||
};
|
||||
|
||||
if (! srcSpec.Exists())
|
||||
{
|
||||
Failed();
|
||||
return -1;
|
||||
}
|
||||
|
||||
nsresult error = srcSpec.Move(dirPath);
|
||||
|
||||
|
||||
dirPath += srcSpec.GetLeafName();
|
||||
if (! dirPath.Exists() || srcSpec.Exists() || NS_FAILED(error))
|
||||
{
|
||||
Failed();
|
||||
return -1;
|
||||
}
|
||||
|
||||
Passed();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
int FilesTest::Execute(const char* appName, const char* args)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpec appPath(appName, false);
|
||||
if (!appPath.Exists())
|
||||
{
|
||||
Failed();
|
||||
return -1;
|
||||
}
|
||||
|
||||
nsresult error = appPath.Execute(args);
|
||||
if (NS_FAILED(error))
|
||||
{
|
||||
Failed();
|
||||
return -1;
|
||||
}
|
||||
|
||||
Passed();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
int FilesTest::RunAllTests()
|
||||
// For use with DEBUG defined.
|
||||
@@ -389,7 +555,7 @@ int FilesTest::RunAllTests()
|
||||
return -1;
|
||||
|
||||
Banner("Parent");
|
||||
nsNativeFileSpec parent;
|
||||
nsFileSpec parent;
|
||||
if (Parent("mumble/iotest.txt", parent) != 0)
|
||||
return -1;
|
||||
|
||||
@@ -405,6 +571,36 @@ int FilesTest::RunAllTests()
|
||||
if (IterateDirectoryChildren(parent) != 0)
|
||||
return -1;
|
||||
|
||||
Banner("Copy");
|
||||
if (Copy("mumble/copyfile.txt", "mumble/copy") != 0)
|
||||
return -1;
|
||||
|
||||
Banner("Move");
|
||||
if (Move("mumble/moveFile.txt", "mumble/move") != 0)
|
||||
return -1;
|
||||
|
||||
Banner("Execute");
|
||||
#ifdef XP_MAC
|
||||
// This path is hard-coded to test on jrm's machine. Finding an app
|
||||
// on an arbitrary Macintosh would cost more trouble than it's worth.
|
||||
// Change path to suit.
|
||||
if NS_FAILED(Execute("/Projects/Nav45_BRANCH/ns/cmd/macfe/"\
|
||||
"projects/client45/Client45PPC", ""))
|
||||
#elif XP_PC
|
||||
if NS_FAILED(Execute("c:\\windows\\notepad.exe", ""))
|
||||
#else
|
||||
if NS_FAILED(Execute("/bin/ls", "/"))
|
||||
#endif
|
||||
return -1;
|
||||
|
||||
Banner("Persistence");
|
||||
if (Persistence("mumble/filedesc.dat") != 0)
|
||||
return -1;
|
||||
|
||||
Banner("Delete again (to clean up our mess)");
|
||||
if (Delete(parent) != 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -413,7 +609,6 @@ int main()
|
||||
// For use with DEBUG defined.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
|
||||
FilesTest tester;
|
||||
return tester.RunAllTests();
|
||||
} // main
|
||||
|
||||
Reference in New Issue
Block a user