Added a directory iterator class. Added canonification and recursive directory creation, and some other handy methods. Eventual goal: replace xp_file.h entirely.
git-svn-id: svn://10.0.0.236/trunk@17274 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -127,6 +127,10 @@
|
||||
|
||||
#ifdef XP_MAC
|
||||
#include <Files.h>
|
||||
#elif defined(XP_UNIX) || defined (XP_OS2)
|
||||
#include <dirent.h>
|
||||
#elif 0 // defined(XP_PC)
|
||||
#include "winfile.h"
|
||||
#endif
|
||||
|
||||
//========================================================================================
|
||||
@@ -150,7 +154,7 @@ class NS_BASE nsNativeFileSpec
|
||||
{
|
||||
public:
|
||||
nsNativeFileSpec();
|
||||
explicit nsNativeFileSpec(const char* inString);
|
||||
explicit nsNativeFileSpec(const char* inString, bool inCreateDirs = false);
|
||||
explicit nsNativeFileSpec(const nsFilePath& inPath);
|
||||
explicit nsNativeFileSpec(const nsFileURL& inURL);
|
||||
nsNativeFileSpec(const nsNativeFileSpec& inPath);
|
||||
@@ -177,12 +181,12 @@ class NS_BASE nsNativeFileSpec
|
||||
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.
|
||||
// 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);
|
||||
// Called for the spec of an alias. Modifies the spec to
|
||||
// point to the original. Sets mError.
|
||||
// Called for the spec of an alias. Modifies the spec to
|
||||
// point to the original. Sets mError.
|
||||
void MakeUnique(ConstStr255Param inSuggestedLeafName);
|
||||
StringPtr GetLeafPName() { return mSpec.name; }
|
||||
ConstStr255Param GetLeafPName() const { return mSpec.name; }
|
||||
@@ -194,14 +198,58 @@ class NS_BASE nsNativeFileSpec
|
||||
bool Valid() const { return true; } // Fixme.
|
||||
#endif // XP_MAC
|
||||
|
||||
friend NS_BASE nsOutputFileStream& operator << (nsOutputFileStream& s, const nsNativeFileSpec& spec);
|
||||
friend NS_BASE nsOutputFileStream& operator << (
|
||||
nsOutputFileStream& s,
|
||||
const nsNativeFileSpec& spec);
|
||||
|
||||
//--------------------------------------------------
|
||||
// Queries and path algebra. These do not modify the disk.
|
||||
//--------------------------------------------------
|
||||
|
||||
char* GetLeafName() const; // Allocated. Use delete [].
|
||||
void SetLeafName(const char* inLeafName);
|
||||
bool Exists() const;
|
||||
// inLeafName can be a relative path, so this allows
|
||||
// one kind of concatenation of "paths".
|
||||
|
||||
void GetParent(nsNativeFileSpec& 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,
|
||||
// however, that the top node is still not a name,
|
||||
// but a spec. Volumes on Macintosh can have identical
|
||||
// names. Perhaps could be used for an operator --() ?
|
||||
|
||||
nsNativeFileSpec 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.
|
||||
// This must be a directory for this to work. This differs
|
||||
// from SetLeafName(), since the latter will work
|
||||
// starting with a sibling of the directory and throws
|
||||
// away its leaf information, whereas this one assumes
|
||||
// this is a directory, and the relative path starts
|
||||
// "below" this.
|
||||
|
||||
void MakeUnique();
|
||||
void MakeUnique(const char* inSuggestedLeafName);
|
||||
|
||||
bool IsDirectory() const;
|
||||
// More stringent than Exists()
|
||||
bool IsFile() const;
|
||||
// More stringent than Exists()
|
||||
bool Exists() const;
|
||||
|
||||
//--------------------------------------------------
|
||||
// Creation and deletion of objects. These can modify the disk.
|
||||
//--------------------------------------------------
|
||||
|
||||
void CreateDirectory(int mode = 0700 /* for unix */);
|
||||
void Delete(bool inRecursive);
|
||||
|
||||
//--------------------------------------------------
|
||||
// Data
|
||||
//--------------------------------------------------
|
||||
|
||||
private:
|
||||
friend class nsFilePath;
|
||||
#ifdef XP_MAC
|
||||
@@ -221,7 +269,7 @@ class NS_BASE nsFileURL
|
||||
{
|
||||
public:
|
||||
nsFileURL(const nsFileURL& inURL);
|
||||
explicit nsFileURL(const char* inString);
|
||||
explicit nsFileURL(const char* inString, bool inCreateDirs = false);
|
||||
explicit nsFileURL(const nsFilePath& inPath);
|
||||
explicit nsFileURL(const nsNativeFileSpec& inPath);
|
||||
virtual ~nsFileURL();
|
||||
@@ -247,7 +295,7 @@ class NS_BASE nsFileURL
|
||||
operator char* ();
|
||||
operator const char* const ();
|
||||
private:
|
||||
friend class nsFilePath; // to allow construction of nsFilePath
|
||||
friend class nsFilePath; // to allow construction of nsFilePath
|
||||
char* mURL;
|
||||
#ifdef XP_MAC
|
||||
// Since the path on the macintosh does not uniquely specify a file (volumes
|
||||
@@ -264,7 +312,7 @@ class NS_BASE nsFilePath
|
||||
{
|
||||
public:
|
||||
nsFilePath(const nsFilePath& inPath);
|
||||
explicit nsFilePath(const char* inString);
|
||||
explicit nsFilePath(const char* inString, bool inCreateDirs = false);
|
||||
explicit nsFilePath(const nsFileURL& inURL);
|
||||
explicit nsFilePath(const nsNativeFileSpec& inPath);
|
||||
virtual ~nsFilePath();
|
||||
@@ -292,7 +340,7 @@ class NS_BASE nsFilePath
|
||||
|
||||
private:
|
||||
|
||||
char* mPath;
|
||||
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.
|
||||
@@ -300,4 +348,52 @@ class NS_BASE nsFilePath
|
||||
#endif
|
||||
}; // class nsFilePath
|
||||
|
||||
//========================================================================================
|
||||
class nsDirectoryIterator
|
||||
// Example:
|
||||
//
|
||||
// nsNativeFileSpec parentDir(...); // directory over whose children we shall iterate
|
||||
// for (nsDirectoryIterator i(parentDir); i; i++)
|
||||
// {
|
||||
// // do something with (const nsNativeFileSpec&)i
|
||||
// }
|
||||
//
|
||||
// or:
|
||||
//
|
||||
// for (nsDirectoryIterator i(parentDir, false); i; i--)
|
||||
// {
|
||||
// // do something with (const nsNativeFileSpec&)i
|
||||
// }
|
||||
//
|
||||
// Currently, the only platform on which backwards iteration actually goes backwards
|
||||
// is Macintosh. On other platforms, both styles will work, but will go forwards.
|
||||
//========================================================================================
|
||||
{
|
||||
public:
|
||||
nsDirectoryIterator(
|
||||
const nsNativeFileSpec& 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; }
|
||||
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; }
|
||||
private:
|
||||
nsNativeFileSpec mCurrent;
|
||||
bool mExists;
|
||||
|
||||
#if defined(XP_UNIX) // || defined(XP_PC) add when ready
|
||||
DIR* mDir;
|
||||
#elif defined(XP_MAC)
|
||||
OSErr SetToIndex();
|
||||
short mIndex;
|
||||
short mMaxIndex;
|
||||
#endif
|
||||
}; // class nsDirectoryIterator
|
||||
|
||||
#endif // _FILESPEC_H_
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "FullPath.h"
|
||||
#include "FileCopy.h"
|
||||
#include "MoreFilesExtras.h"
|
||||
#include "nsEscape.h"
|
||||
|
||||
#include <Aliases.h>
|
||||
@@ -39,14 +40,16 @@ namespace MacFileHelpers
|
||||
memcpy(dst, src, 1 + src[0]);
|
||||
}
|
||||
|
||||
void PLstrcpy(Str255 dst, const char* src, int inMaxLen);
|
||||
void PLstrcpy(Str255 dst, const char* src, int inMaxLen=255);
|
||||
void PLstrncpy(Str255 dst, const char* src, int inMaxLen);
|
||||
|
||||
void SwapSlashColon(char * s);
|
||||
OSErr FSSpecFromFullUnixPath(
|
||||
const char * unixPath,
|
||||
FSSpec& outSpec,
|
||||
Boolean resolveAlias,
|
||||
Boolean allowPartial = false);
|
||||
Boolean allowPartial = false,
|
||||
Boolean createDirs = false);
|
||||
char* MacPathFromUnixPath(const char* unixPath);
|
||||
char* EncodeMacPath(
|
||||
char* inPath, // NOT const - gets clobbered
|
||||
@@ -54,7 +57,8 @@ namespace MacFileHelpers
|
||||
Boolean doEscape );
|
||||
OSErr FSSpecFromPathname(
|
||||
const char* inPathNamePtr,
|
||||
FSSpec& outSpec);
|
||||
FSSpec& outSpec,
|
||||
Boolean inCreateDirs);
|
||||
char* PathNameFromFSSpec(
|
||||
const FSSpec& inSpec,
|
||||
Boolean wantLeafName );
|
||||
@@ -81,7 +85,7 @@ namespace MacFileHelpers
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void MacFileHelpers::PLstrcpy(Str255 dst, const char* src, int inMax)
|
||||
//========================================================================================
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
int srcLength = strlen(src);
|
||||
NS_ASSERTION(srcLength <= inMax, "Oops, string is too long!");
|
||||
@@ -91,6 +95,17 @@ void MacFileHelpers::PLstrcpy(Str255 dst, const char* src, int inMax)
|
||||
memcpy(&dst[1], src, srcLength);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void MacFileHelpers::PLstrncpy(Str255 dst, const char* src, int inMax)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
int srcLength = strlen(src);
|
||||
if (srcLength > inMax)
|
||||
srcLength = inMax;
|
||||
dst[0] = srcLength;
|
||||
memcpy(&dst[1], src, srcLength);
|
||||
}
|
||||
|
||||
//-----------------------------------
|
||||
void MacFileHelpers::SwapSlashColon(char * s)
|
||||
//-----------------------------------
|
||||
@@ -218,7 +233,10 @@ char* MacFileHelpers::MacPathFromUnixPath(const char* unixPath)
|
||||
} // MacFileHelpers::MacPathFromUnixPath
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
OSErr MacFileHelpers::FSSpecFromPathname(const char* inPathNamePtr, FSSpec& outSpec)
|
||||
OSErr MacFileHelpers::FSSpecFromPathname(
|
||||
const char* inPathNamePtr,
|
||||
FSSpec& outSpec,
|
||||
Boolean inCreateDirs)
|
||||
// FSSpecFromPathname reverses PathNameFromFSSpec.
|
||||
// It returns a FSSpec given a c string which is a mac pathname.
|
||||
//----------------------------------------------------------------------------------------
|
||||
@@ -226,22 +244,55 @@ OSErr MacFileHelpers::FSSpecFromPathname(const char* inPathNamePtr, FSSpec& outS
|
||||
OSErr err;
|
||||
// Simplify this routine to use FSMakeFSSpec if length < 255. Otherwise use the MoreFiles
|
||||
// routine FSpLocationFromFullPath, which allocates memory, to handle longer pathnames.
|
||||
if (strlen(inPathNamePtr) < 255)
|
||||
|
||||
size_t inLength = strlen(inPathNamePtr);
|
||||
if (inLength < 255)
|
||||
{
|
||||
Str255 path;
|
||||
|
||||
int pos = 0;
|
||||
while ( (path[++pos] = *inPathNamePtr++) != 0 )
|
||||
;
|
||||
path[0] = pos-1; // save the length of the string (pos is the next open spot)
|
||||
|
||||
err = ::FSMakeFSSpec(0, 0, path, &outSpec);
|
||||
Str255 ppath;
|
||||
MacFileHelpers::PLstrcpy(ppath, inPathNamePtr);
|
||||
err = ::FSMakeFSSpec(0, 0, ppath, &outSpec);
|
||||
}
|
||||
else
|
||||
err = FSpLocationFromFullPath(strlen(inPathNamePtr), inPathNamePtr, &outSpec);
|
||||
err = FSpLocationFromFullPath(inLength, inPathNamePtr, &outSpec);
|
||||
|
||||
if (err == dirNFErr && inCreateDirs)
|
||||
{
|
||||
const char* path = inPathNamePtr;
|
||||
outSpec.vRefNum = 0;
|
||||
outSpec.parID = 0;
|
||||
do {
|
||||
// Locate the colon that terminates the node.
|
||||
// But if we've a partial path (starting with a colon), find the second one.
|
||||
const char* nextColon = strchr(path + (*path == ':'), ':');
|
||||
// Well, if there are no more colons, point to the end of the string.
|
||||
if (!nextColon)
|
||||
nextColon = path + strlen(path);
|
||||
|
||||
// Make a pascal string out of this node. Include initial
|
||||
// and final colon, if any!
|
||||
Str255 ppath;
|
||||
MacFileHelpers::PLstrncpy(ppath, path, nextColon - path + 1);
|
||||
|
||||
// Use this string as a relative path using the directory created
|
||||
// on the previous round (or directory 0,0 on the first round).
|
||||
err = ::FSMakeFSSpec(outSpec.vRefNum, outSpec.parID, ppath, &outSpec);
|
||||
|
||||
// If this was the leaf node, then we are done.
|
||||
if (!*nextColon)
|
||||
break;
|
||||
|
||||
// If we got "file not found", then
|
||||
// we need to create a directory.
|
||||
if (err == fnfErr && *nextColon)
|
||||
err = FSpDirCreate(&outSpec, smCurrentScript, &outSpec.parID);
|
||||
// For some reason, this usually returns fnfErr, even though it works.
|
||||
if (err != noErr && err != fnfErr)
|
||||
return err;
|
||||
path = nextColon; // next round
|
||||
} while (1);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
} // MacFileHelpers::FSSpecFromPathname
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
OSErr MacFileHelpers::CreateFolderInFolder(
|
||||
@@ -320,7 +371,8 @@ OSErr MacFileHelpers::FSSpecFromFullUnixPath(
|
||||
const char * unixPath,
|
||||
FSSpec& outSpec,
|
||||
Boolean resolveAlias,
|
||||
Boolean allowPartial)
|
||||
Boolean allowPartial,
|
||||
Boolean createDirs)
|
||||
// File spec from URL. Reverses GetURLFromFileSpec
|
||||
// Its input is only the <path> part of the URL
|
||||
// JRM 97/01/08 changed this so that if it's a partial path (doesn't start with '/'),
|
||||
@@ -338,7 +390,7 @@ OSErr MacFileHelpers::FSSpecFromFullUnixPath(
|
||||
{
|
||||
NS_ASSERTION(*unixPath == '/' /*full path*/, "Not a full Unix path!");
|
||||
}
|
||||
err = FSSpecFromPathname(macPath, outSpec);
|
||||
err = FSSpecFromPathname(macPath, outSpec, createDirs);
|
||||
if (err == fnfErr)
|
||||
err = noErr;
|
||||
Boolean dummy;
|
||||
@@ -468,11 +520,12 @@ nsNativeFileSpec::nsNativeFileSpec(const nsNativeFileSpec& inSpec)
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec(const char* inString)
|
||||
nsNativeFileSpec::nsNativeFileSpec(const char* inString, bool inCreateDirs)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mError = MacFileHelpers::FSSpecFromFullUnixPath(inString, mSpec, true, true);
|
||||
// allow a partial path
|
||||
mError = MacFileHelpers::FSSpecFromFullUnixPath(
|
||||
inString, mSpec, true, true, inCreateDirs);
|
||||
// allow a partial path, create as necessary
|
||||
if (mError == fnfErr)
|
||||
mError = noErr;
|
||||
} // nsNativeFileSpec::nsNativeFileSpec
|
||||
@@ -537,9 +590,13 @@ bool nsNativeFileSpec::Exists() const
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::SetLeafName(const char* inLeafName)
|
||||
// In leaf name can actually be a partial path...
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
MacFileHelpers::PLstrcpy(mSpec.name, inLeafName, nsFileSpecHelpers::kMaxFilenameLength);
|
||||
// what about long relative paths? Hmm?
|
||||
Str255 partialPath;
|
||||
MacFileHelpers::PLstrcpy(partialPath, inLeafName);
|
||||
mError = FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, partialPath, &mSpec);
|
||||
} // nsNativeFileSpec::SetLeafName
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
@@ -579,10 +636,86 @@ void nsNativeFileSpec::ResolveAlias(bool& wasAliased)
|
||||
wasAliased = (wasAliased2 != false);
|
||||
} // nsNativeFileSpec::ResolveAlias
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::IsFile() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
long dirID;
|
||||
Boolean isDirectory;
|
||||
return (noErr == FSpGetDirectoryID(&mSpec, &dirID, &isDirectory) && !isDirectory);
|
||||
} // nsNativeFileSpec::IsFile
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::IsDirectory() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
long dirID;
|
||||
Boolean isDirectory;
|
||||
return (noErr == FSpGetDirectoryID(&mSpec, &dirID, &isDirectory) && isDirectory);
|
||||
} // nsNativeFileSpec::IsDirectory
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::GetParent(nsNativeFileSpec& outSpec) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (mError == noErr)
|
||||
outSpec.mError = FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, NULL, outSpec);
|
||||
} // nsNativeFileSpec::GetParent
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator += (const char* inRelativePath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
long dirID;
|
||||
Boolean isDirectory;
|
||||
mError = FSpGetDirectoryID(&mSpec, &dirID, &isDirectory);
|
||||
if (mError == noErr && isDirectory)
|
||||
{
|
||||
mError = FSMakeFSSpec(mSpec.vRefNum, dirID, "\pG'day", *this);
|
||||
if (mError == noErr)
|
||||
SetLeafName(inRelativePath);
|
||||
}
|
||||
} // nsNativeFileSpec::operator +=
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::CreateDirectory(int /* unix mode */)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
long ignoredDirID;
|
||||
FSpDirCreate(&mSpec, smCurrentScript, &ignoredDirID);
|
||||
} // nsNativeFileSpec::CreateDirectory
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::Delete(bool inRecursive)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (inRecursive)
|
||||
{
|
||||
// MoreFilesExtras
|
||||
mError = DeleteDirectory(
|
||||
mSpec.vRefNum,
|
||||
mSpec.parID,
|
||||
const_cast<unsigned char*>(mSpec.name));
|
||||
}
|
||||
else
|
||||
mError = FSpDelete(&mSpec);
|
||||
} // nsNativeFileSpec::Delete
|
||||
|
||||
|
||||
//========================================================================================
|
||||
// Macintosh nsFilePath implementation
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFilePath::nsFilePath(const char* inString, bool inCreateDirs)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(nsnull)
|
||||
, mNativeFileSpec(inString, inCreateDirs)
|
||||
{
|
||||
// Make canonical and absolute.
|
||||
char * path = MacFileHelpers::PathNameFromFSSpec( mNativeFileSpec, TRUE );
|
||||
mPath = MacFileHelpers::EncodeMacPath(path, true, true);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFilePath::nsFilePath(const nsNativeFileSpec& inSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
@@ -601,3 +734,118 @@ void nsFilePath::operator = (const nsNativeFileSpec& inSpec)
|
||||
mPath = MacFileHelpers::EncodeMacPath(path, true, true);
|
||||
mNativeFileSpec = inSpec;
|
||||
} // nsFilePath::operator =
|
||||
|
||||
//========================================================================================
|
||||
// nsFileURL implementation
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFileURL::nsFileURL(const char* inString, bool inCreateDirs)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mURL(nsnull)
|
||||
, mNativeFileSpec(inString + kFileURLPrefixLength, inCreateDirs)
|
||||
{
|
||||
NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!");
|
||||
// Make canonical and absolute.
|
||||
char* path = MacFileHelpers::PathNameFromFSSpec( mNativeFileSpec, TRUE );
|
||||
char* escapedPath = MacFileHelpers::EncodeMacPath(path, true, true);
|
||||
mURL = nsFileSpecHelpers::StringDup(kFileURLPrefix, kFileURLPrefixLength + strlen(escapedPath));
|
||||
strcat(mURL, escapedPath);
|
||||
delete [] escapedPath;
|
||||
} // nsFileURL::nsFileURL
|
||||
|
||||
//========================================================================================
|
||||
// nsDirectoryIterator
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator::nsDirectoryIterator(
|
||||
const nsNativeFileSpec& inDirectory
|
||||
, int inIterateDirection)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mCurrent(inDirectory)
|
||||
, mExists(false)
|
||||
, mIndex(-1)
|
||||
{
|
||||
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&();
|
||||
Str255 outName;
|
||||
MacFileHelpers::PLstrcpy(outName, inSpec.name);
|
||||
pb.hFileInfo.ioNamePtr = outName;
|
||||
pb.hFileInfo.ioVRefNum = inSpec.vRefNum;
|
||||
pb.hFileInfo.ioDirID = inSpec.parID;
|
||||
pb.hFileInfo.ioFDirIndex = 0; // use ioNamePtr and ioDirID
|
||||
|
||||
OSErr err = PBGetCatInfoSync( &pb );
|
||||
|
||||
// test that we have got a directory back, not a file
|
||||
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&();
|
||||
currentSpec.vRefNum = inSpec.vRefNum;
|
||||
currentSpec.parID = dipb->ioDrDirID;
|
||||
mMaxIndex = pb.dirInfo.ioDrNmFls;
|
||||
if (inIterateDirection > 0)
|
||||
{
|
||||
mIndex = 0; // ready to increment
|
||||
++(*this); // the pre-increment operator
|
||||
}
|
||||
else
|
||||
{
|
||||
mIndex = mMaxIndex + 1; // ready to decrement
|
||||
--(*this); // the pre-decrement operator
|
||||
}
|
||||
} // nsDirectoryIterator::nsDirectoryIterator
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
OSErr nsDirectoryIterator::SetToIndex()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
CInfoPBRec cipb;
|
||||
DirInfo *dipb=(DirInfo *)&cipb;
|
||||
Str255 objectName;
|
||||
dipb->ioCompletion = NULL;
|
||||
dipb->ioFDirIndex = mIndex;
|
||||
// Sorry about this, there seems to be a bug in CWPro 4:
|
||||
FSSpec& currentSpec = mCurrent.nsNativeFileSpec::operator FSSpec&();
|
||||
dipb->ioVRefNum = currentSpec.vRefNum; /* Might need to use vRefNum, not sure*/
|
||||
dipb->ioDrDirID = currentSpec.parID;
|
||||
dipb->ioNamePtr = objectName;
|
||||
OSErr err = PBGetCatInfoSync(&cipb);
|
||||
if (err == noErr)
|
||||
err = FSMakeFSSpec(currentSpec.vRefNum, currentSpec.parID, objectName, ¤tSpec);
|
||||
mExists = err == noErr;
|
||||
return err;
|
||||
} // nsDirectoryIterator::SetToIndex()
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator& nsDirectoryIterator::operator -- ()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mExists = false;
|
||||
while (--mIndex > 0)
|
||||
{
|
||||
OSErr err = SetToIndex();
|
||||
if (err == noErr)
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
} // nsDirectoryIterator::operator --
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator& nsDirectoryIterator::operator ++ ()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mExists = false;
|
||||
if (mIndex >= 0) // probably trying to use a file as a directory!
|
||||
while (++mIndex <= mMaxIndex)
|
||||
{
|
||||
OSErr err = SetToIndex();
|
||||
if (err == noErr)
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
} // nsDirectoryIterator::operator ++
|
||||
|
||||
@@ -30,115 +30,180 @@
|
||||
NS_NAMESPACE nsFileSpecHelpers
|
||||
//========================================================================================
|
||||
{
|
||||
enum
|
||||
{ kMaxFilenameLength = 31 // should work on Macintosh, Unix, and Win32.
|
||||
, kMaxAltDigitLength = 5
|
||||
, kMaxCoreLeafNameLength = (kMaxFilenameLength - (kMaxAltDigitLength + 1))
|
||||
};
|
||||
NS_NAMESPACE_PROTOTYPE void LeafReplace(
|
||||
char*& ioPath,
|
||||
char inSeparator,
|
||||
const char* inLeafName);
|
||||
NS_NAMESPACE_PROTOTYPE char* GetLeaf(const char* inPath, char inSeparator); // allocated
|
||||
NS_NAMESPACE_PROTOTYPE char* StringDup(const char* inString, int allocLength = 0);
|
||||
NS_NAMESPACE_PROTOTYPE char* AllocCat(const char* inString1, const char* inString2);
|
||||
NS_NAMESPACE_PROTOTYPE char* StringAssign(char*& ioString, const char* inOther);
|
||||
enum
|
||||
{ kMaxFilenameLength = 31 // should work on Macintosh, Unix, and Win32.
|
||||
, kMaxAltDigitLength = 5
|
||||
, kMaxCoreLeafNameLength = (kMaxFilenameLength - (kMaxAltDigitLength + 1))
|
||||
};
|
||||
NS_NAMESPACE_PROTOTYPE void LeafReplace(
|
||||
char*& ioPath,
|
||||
char inSeparator,
|
||||
const char* inLeafName);
|
||||
#ifndef XP_MAC
|
||||
NS_NAMESPACE_PROTOTYPE void Canonify(char*& ioPath, bool inMakeDirs);
|
||||
NS_NAMESPACE_PROTOTYPE void MakeAllDirectories(const char* inPath, int mode);
|
||||
#endif
|
||||
NS_NAMESPACE_PROTOTYPE char* GetLeaf(const char* inPath, char inSeparator); // allocated
|
||||
NS_NAMESPACE_PROTOTYPE char* StringDup(const char* inString, int allocLength = 0);
|
||||
NS_NAMESPACE_PROTOTYPE char* AllocCat(const char* inString1, const char* inString2);
|
||||
NS_NAMESPACE_PROTOTYPE char* StringAssign(char*& ioString, const char* inOther);
|
||||
NS_NAMESPACE_PROTOTYPE char* ReallocCat(char*& ioString, const char* inString1);
|
||||
} NS_NAMESPACE_END
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
char* nsFileSpecHelpers::StringDup(
|
||||
const char* inString,
|
||||
int allocLength)
|
||||
const char* inString,
|
||||
int allocLength)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!allocLength && inString)
|
||||
allocLength = strlen(inString);
|
||||
char* newPath = inString || allocLength ? new char[allocLength + 1] : 0;
|
||||
if (!newPath)
|
||||
return NULL;
|
||||
strcpy(newPath, inString);
|
||||
return newPath;
|
||||
if (!allocLength && inString)
|
||||
allocLength = strlen(inString);
|
||||
char* newPath = inString || allocLength ? new char[allocLength + 1] : nsnull;
|
||||
if (!newPath)
|
||||
return NULL;
|
||||
strcpy(newPath, inString);
|
||||
return newPath;
|
||||
} // nsFileSpecHelpers::StringDup
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
char* nsFileSpecHelpers::AllocCat(
|
||||
const char* inString1,
|
||||
const char* inString2)
|
||||
const char* inString1,
|
||||
const char* inString2)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!inString1)
|
||||
return inString2 ? StringDup(inString2) : (char*)NULL;
|
||||
if (!inString2)
|
||||
return StringDup(inString1);
|
||||
char* outString = StringDup(inString1, strlen(inString1) + strlen(inString2));
|
||||
if (outString)
|
||||
strcat(outString, inString2);
|
||||
return outString;
|
||||
if (!inString1)
|
||||
return inString2 ? StringDup(inString2) : (char*)NULL;
|
||||
if (!inString2)
|
||||
return StringDup(inString1);
|
||||
char* outString = StringDup(inString1, strlen(inString1) + strlen(inString2));
|
||||
if (outString)
|
||||
strcat(outString, inString2);
|
||||
return outString;
|
||||
} // nsFileSpecHelpers::StringDup
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
char* nsFileSpecHelpers::StringAssign(
|
||||
char*& ioString,
|
||||
const char* inString2)
|
||||
char*& ioString,
|
||||
const char* inString2)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!inString2)
|
||||
{
|
||||
delete [] ioString;
|
||||
ioString = (char*)NULL;
|
||||
return ioString;
|
||||
}
|
||||
if (!ioString || (strlen(inString2) > strlen(ioString)))
|
||||
{
|
||||
delete [] ioString;
|
||||
ioString = StringDup(inString2);
|
||||
return ioString;
|
||||
}
|
||||
strcpy(ioString, inString2);
|
||||
return ioString;
|
||||
if (!inString2)
|
||||
{
|
||||
delete [] ioString;
|
||||
ioString = (char*)NULL;
|
||||
return ioString;
|
||||
}
|
||||
if (!ioString || (strlen(inString2) > strlen(ioString)))
|
||||
{
|
||||
delete [] ioString;
|
||||
ioString = StringDup(inString2);
|
||||
return ioString;
|
||||
}
|
||||
strcpy(ioString, inString2);
|
||||
return ioString;
|
||||
} // nsFileSpecHelpers::StringAssign
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsFileSpecHelpers::LeafReplace(
|
||||
char*& ioPath,
|
||||
char inSeparator,
|
||||
const char* inLeafName)
|
||||
char*& ioPath,
|
||||
char inSeparator,
|
||||
const char* inLeafName)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// Find the existing leaf name
|
||||
if (!ioPath)
|
||||
return;
|
||||
if (!inLeafName)
|
||||
{
|
||||
*ioPath = '\0';
|
||||
return;
|
||||
}
|
||||
char* lastSeparator = strrchr(ioPath, inSeparator);
|
||||
int oldLength = strlen(ioPath);
|
||||
*(++lastSeparator) = '\0'; // strip the current leaf name
|
||||
int newLength = lastSeparator - ioPath + strlen(inLeafName);
|
||||
if (newLength > oldLength)
|
||||
{
|
||||
char* newPath = StringDup(ioPath, newLength + 1);
|
||||
delete [] ioPath;
|
||||
ioPath = newPath;
|
||||
}
|
||||
strcat(ioPath, inLeafName);
|
||||
} // nsNativeFileSpec::SetLeafName
|
||||
// Find the existing leaf name
|
||||
if (!ioPath)
|
||||
return;
|
||||
if (!inLeafName)
|
||||
{
|
||||
*ioPath = '\0';
|
||||
return;
|
||||
}
|
||||
char* lastSeparator = strrchr(ioPath, inSeparator);
|
||||
int oldLength = strlen(ioPath);
|
||||
*(++lastSeparator) = '\0'; // strip the current leaf name
|
||||
int newLength = lastSeparator - ioPath + strlen(inLeafName);
|
||||
if (newLength > oldLength)
|
||||
{
|
||||
char* newPath = StringDup(ioPath, newLength + 1);
|
||||
delete [] ioPath;
|
||||
ioPath = newPath;
|
||||
}
|
||||
strcat(ioPath, inLeafName);
|
||||
} // nsNativeFileSpec::LeafReplace
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
char* nsFileSpecHelpers::GetLeaf(const char* inPath, char inSeparator)
|
||||
// Returns a pointer to an allocated string representing the leaf.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!inPath)
|
||||
return NULL;
|
||||
char* lastSeparator = strrchr(inPath, inSeparator);
|
||||
if (lastSeparator)
|
||||
return StringDup(lastSeparator);
|
||||
return StringDup(inPath);
|
||||
if (!inPath)
|
||||
return NULL;
|
||||
char* lastSeparator = strrchr(inPath, inSeparator);
|
||||
if (lastSeparator)
|
||||
return StringDup(++lastSeparator);
|
||||
return StringDup(inPath);
|
||||
} // nsNativeFileSpec::GetLeaf
|
||||
|
||||
#if defined(XP_UNIX) || defined(XP_PC)
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsFileSpecHelpers::MakeAllDirectories(const char* inPath, int mode)
|
||||
// Make the path a valid one by creating all the intermediate directories. Does NOT
|
||||
// make the leaf into a directory. This should be a unix path.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!inPath)
|
||||
return;
|
||||
|
||||
char* pathCopy = nsFileSpecHelpers::StringDup( inPath );
|
||||
if (!pathCopy)
|
||||
return;
|
||||
|
||||
const char kSeparator = '/'; // I repeat: this should be a unix-style path.
|
||||
const int kSkipFirst = 1;
|
||||
|
||||
#ifdef XP_WIN
|
||||
NS_ASSERTION( pathCopy[2] == '|', "No drive letter!" );
|
||||
#endif
|
||||
char* currentStart = pathCopy;
|
||||
char* currentEnd = strchr(currentStart + kSkipFirst, kSeparator);
|
||||
if (currentEnd)
|
||||
{
|
||||
*currentEnd = '\0';
|
||||
nsNativeFileSpec spec(nsFilePath(pathCopy, false));
|
||||
do
|
||||
{
|
||||
// If the node doesn't exist, and it is not the initial node in a full path,
|
||||
// then make a directory (We cannot make the initial (volume) node).
|
||||
if (!spec.Exists() && *currentStart != kSeparator)
|
||||
spec.CreateDirectory(mode);
|
||||
if (!spec.Exists())
|
||||
{
|
||||
NS_ASSERTION(spec.Exists(), "Could not create the directory?");
|
||||
break;
|
||||
}
|
||||
currentStart = ++currentEnd;
|
||||
currentEnd = strchr(currentStart, kSeparator);
|
||||
if (!currentEnd)
|
||||
break;
|
||||
spec += currentStart; // "lengthen" the path, adding the next node.
|
||||
} while (currentEnd);
|
||||
}
|
||||
delete [] pathCopy;
|
||||
} // nsFileSpecHelpers::MakeAllDirectories
|
||||
|
||||
#endif // XP_PC || XP_UNIX
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
char* nsFileSpecHelpers::ReallocCat(char*& ioString, const char* inString1)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
char* newString = AllocCat(ioString, inString1);
|
||||
delete [] ioString;
|
||||
ioString = newString;
|
||||
return ioString;
|
||||
} // nsNativeFileSpec::ReallocCat
|
||||
|
||||
#if defined(XP_PC)
|
||||
#include "windows/nsFileSpecWin.cpp" // Windows-specific implementations
|
||||
@@ -149,26 +214,30 @@ char* nsFileSpecHelpers::GetLeaf(const char* inPath, char inSeparator)
|
||||
#endif
|
||||
|
||||
//========================================================================================
|
||||
// nsFileURL implementation
|
||||
// nsFileURL implementation
|
||||
//========================================================================================
|
||||
|
||||
#ifndef XP_MAC
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFileURL::nsFileURL(const char* inString)
|
||||
nsFileURL::nsFileURL(const char* inString, bool inCreateDirs)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mURL(nsFileSpecHelpers::StringDup(inString))
|
||||
#ifdef XP_MAC
|
||||
, mNativeFileSpec(inString + kFileURLPrefixLength)
|
||||
#endif
|
||||
: mURL(nsnull)
|
||||
{
|
||||
NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!");
|
||||
if (!inString)
|
||||
return;
|
||||
NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!");
|
||||
// Make canonical and absolute.
|
||||
nsFilePath path(inString + kFileURLPrefixLength, inCreateDirs);
|
||||
*this = path;
|
||||
} // nsFileURL::nsFileURL
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFileURL::nsFileURL(const nsFileURL& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mURL(nsFileSpecHelpers::StringDup(inOther.mURL))
|
||||
: mURL(nsFileSpecHelpers::StringDup(inOther.mURL))
|
||||
#ifdef XP_MAC
|
||||
, mNativeFileSpec(inOther.GetNativeSpec())
|
||||
, mNativeFileSpec(inOther.GetNativeSpec())
|
||||
#endif
|
||||
{
|
||||
} // nsFileURL::nsFileURL
|
||||
@@ -176,18 +245,18 @@ nsFileURL::nsFileURL(const nsFileURL& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFileURL::nsFileURL(const nsFilePath& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mURL(nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)inOther))
|
||||
: mURL(nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)inOther))
|
||||
#ifdef XP_MAC
|
||||
, mNativeFileSpec(inOther.GetNativeSpec())
|
||||
, mNativeFileSpec(inOther.GetNativeSpec())
|
||||
#endif
|
||||
{
|
||||
} // nsFileURL::nsFileURL
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFileURL::nsFileURL(const nsNativeFileSpec& inOther)
|
||||
: mURL(nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)nsFilePath(inOther)))
|
||||
: mURL(nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)nsFilePath(inOther)))
|
||||
#ifdef XP_MAC
|
||||
, mNativeFileSpec(inOther)
|
||||
, mNativeFileSpec(inOther)
|
||||
#endif
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
@@ -197,17 +266,17 @@ nsFileURL::nsFileURL(const nsNativeFileSpec& inOther)
|
||||
nsFileURL::~nsFileURL()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
delete [] mURL;
|
||||
delete [] mURL;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsFileURL::operator = (const char* inString)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::StringAssign(mURL, inString);
|
||||
NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!");
|
||||
nsFileSpecHelpers::StringAssign(mURL, inString);
|
||||
NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!");
|
||||
#ifdef XP_MAC
|
||||
mNativeFileSpec = inString + kFileURLPrefixLength;
|
||||
mNativeFileSpec = inString + kFileURLPrefixLength;
|
||||
#endif
|
||||
} // nsFileURL::operator =
|
||||
|
||||
@@ -215,9 +284,9 @@ void nsFileURL::operator = (const char* inString)
|
||||
void nsFileURL::operator = (const nsFileURL& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mURL = nsFileSpecHelpers::StringAssign(mURL, inOther.mURL);
|
||||
mURL = nsFileSpecHelpers::StringAssign(mURL, inOther.mURL);
|
||||
#ifdef XP_MAC
|
||||
mNativeFileSpec = inOther.GetNativeSpec();
|
||||
mNativeFileSpec = inOther.GetNativeSpec();
|
||||
#endif
|
||||
} // nsFileURL::operator =
|
||||
|
||||
@@ -225,10 +294,10 @@ void nsFileURL::operator = (const nsFileURL& inOther)
|
||||
void nsFileURL::operator = (const nsFilePath& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
delete [] mURL;
|
||||
mURL = nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)inOther);
|
||||
delete [] mURL;
|
||||
mURL = nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)inOther);
|
||||
#ifdef XP_MAC
|
||||
mNativeFileSpec = inOther.GetNativeSpec();
|
||||
mNativeFileSpec = inOther.GetNativeSpec();
|
||||
#endif
|
||||
} // nsFileURL::operator =
|
||||
|
||||
@@ -236,10 +305,10 @@ void nsFileURL::operator = (const nsFilePath& inOther)
|
||||
void nsFileURL::operator = (const nsNativeFileSpec& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
delete [] mURL;
|
||||
mURL = nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)nsFilePath(inOther));
|
||||
delete [] mURL;
|
||||
mURL = nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)nsFilePath(inOther));
|
||||
#ifdef XP_MAC
|
||||
mNativeFileSpec = inOther;
|
||||
mNativeFileSpec = inOther;
|
||||
#endif
|
||||
} // nsFileURL::operator =
|
||||
|
||||
@@ -251,26 +320,27 @@ nsOutputFileStream& operator << (nsOutputFileStream& s, const nsFileURL& url)
|
||||
}
|
||||
|
||||
//========================================================================================
|
||||
// nsFilePath implementation
|
||||
// nsFilePath implementation
|
||||
//========================================================================================
|
||||
|
||||
#ifndef XP_MAC
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFilePath::nsFilePath(const char* inString)
|
||||
nsFilePath::nsFilePath(const char* inString, bool inCreateDirs)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(nsFileSpecHelpers::StringDup(inString))
|
||||
#ifdef XP_MAC
|
||||
, mNativeFileSpec(inString)
|
||||
#endif
|
||||
: mPath(nsFileSpecHelpers::StringDup(inString))
|
||||
{
|
||||
NS_ASSERTION(strstr(inString, kFileURLPrefix) != inString, "URL passed as path");
|
||||
NS_ASSERTION(strstr(inString, kFileURLPrefix) != inString, "URL passed as path");
|
||||
// Make canonical and absolute.
|
||||
nsFileSpecHelpers::Canonify(mPath, inCreateDirs);
|
||||
}
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFilePath::nsFilePath(const nsFileURL& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(nsFileSpecHelpers::StringDup(inOther.mURL + kFileURLPrefixLength))
|
||||
: mPath(nsFileSpecHelpers::StringDup(inOther.mURL + kFileURLPrefixLength))
|
||||
#ifdef XP_MAC
|
||||
, mNativeFileSpec(inOther.GetNativeSpec())
|
||||
, mNativeFileSpec(inOther.GetNativeSpec())
|
||||
#endif
|
||||
{
|
||||
}
|
||||
@@ -288,7 +358,7 @@ nsFilePath::nsFilePath(const nsNativeFileSpec& inOther)
|
||||
nsFilePath::~nsFilePath()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
delete [] mPath;
|
||||
delete [] mPath;
|
||||
}
|
||||
|
||||
#ifdef XP_UNIX
|
||||
@@ -304,10 +374,13 @@ void nsFilePath::operator = (const nsNativeFileSpec& inOther)
|
||||
void nsFilePath::operator = (const char* inString)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
NS_ASSERTION(strstr(inString, kFileURLPrefix) != inString, "URL passed as path");
|
||||
nsFileSpecHelpers::StringAssign(mPath, inString);
|
||||
NS_ASSERTION(strstr(inString, kFileURLPrefix) != inString, "URL passed as path");
|
||||
#ifdef XP_MAC
|
||||
mNativeFileSpec = inString;
|
||||
mNativeFileSpec = inString;
|
||||
nsFileSpecHelpers::StringAssign(mPath, (const char*)nsFilePath(mNativeFileSpec));
|
||||
#else
|
||||
nsFileSpecHelpers::StringAssign(mPath, inString);
|
||||
nsFileSpecHelpers::Canonify(mPath, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -315,21 +388,21 @@ void nsFilePath::operator = (const char* inString)
|
||||
void nsFilePath::operator = (const nsFileURL& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::StringAssign(mPath, (const char*)nsFilePath(inOther));
|
||||
nsFileSpecHelpers::StringAssign(mPath, (const char*)nsFilePath(inOther));
|
||||
#ifdef XP_MAC
|
||||
mNativeFileSpec = inOther.GetNativeSpec();
|
||||
mNativeFileSpec = inOther.GetNativeSpec();
|
||||
#endif
|
||||
}
|
||||
|
||||
//========================================================================================
|
||||
// nsNativeFileSpec implementation
|
||||
// nsNativeFileSpec implementation
|
||||
//========================================================================================
|
||||
|
||||
#ifndef XP_MAC
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec()
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(NULL)
|
||||
: mPath(NULL)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
@@ -338,7 +411,7 @@ nsNativeFileSpec::nsNativeFileSpec()
|
||||
nsNativeFileSpec::nsNativeFileSpec(const nsFileURL& inURL)
|
||||
//----------------------------------------------------------------------------------------
|
||||
#ifndef XP_MAC
|
||||
: mPath(NULL)
|
||||
: mPath(NULL)
|
||||
#endif
|
||||
{
|
||||
*this = nsFilePath(inURL); // convert to unix path first
|
||||
@@ -348,44 +421,44 @@ nsNativeFileSpec::nsNativeFileSpec(const nsFileURL& inURL)
|
||||
void nsNativeFileSpec::MakeUnique(const char* inSuggestedLeafName)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (inSuggestedLeafName && *inSuggestedLeafName)
|
||||
SetLeafName(inSuggestedLeafName);
|
||||
if (inSuggestedLeafName && *inSuggestedLeafName)
|
||||
SetLeafName(inSuggestedLeafName);
|
||||
|
||||
MakeUnique();
|
||||
MakeUnique();
|
||||
} // nsNativeFileSpec::MakeUnique
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::MakeUnique()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!Exists())
|
||||
return;
|
||||
if (!Exists())
|
||||
return;
|
||||
|
||||
char* leafName = GetLeafName();
|
||||
if (!leafName)
|
||||
return;
|
||||
char* leafName = GetLeafName();
|
||||
if (!leafName)
|
||||
return;
|
||||
|
||||
char* lastDot = strrchr(leafName, '.');
|
||||
char* suffix = "";
|
||||
if (lastDot)
|
||||
{
|
||||
suffix = nsFileSpecHelpers::StringDup(lastDot); // include '.'
|
||||
*lastDot = '\0'; // strip suffix and dot.
|
||||
}
|
||||
const int kMaxRootLength
|
||||
= nsFileSpecHelpers::kMaxCoreLeafNameLength - strlen(suffix) - 1;
|
||||
if (strlen(leafName) > kMaxRootLength)
|
||||
leafName[kMaxRootLength] = '\0';
|
||||
for (short index = 1; index < 1000 && Exists(); index++)
|
||||
{
|
||||
// start with "Picture-1.jpg" after "Picture.jpg" exists
|
||||
char newName[nsFileSpecHelpers::kMaxFilenameLength + 1];
|
||||
sprintf(newName, "%s-%d%s", leafName, index, suffix);
|
||||
SetLeafName(newName);
|
||||
}
|
||||
if (*suffix)
|
||||
delete [] suffix;
|
||||
delete [] leafName;
|
||||
char* lastDot = strrchr(leafName, '.');
|
||||
char* suffix = "";
|
||||
if (lastDot)
|
||||
{
|
||||
suffix = nsFileSpecHelpers::StringDup(lastDot); // include '.'
|
||||
*lastDot = '\0'; // strip suffix and dot.
|
||||
}
|
||||
const int kMaxRootLength
|
||||
= nsFileSpecHelpers::kMaxCoreLeafNameLength - strlen(suffix) - 1;
|
||||
if (strlen(leafName) > kMaxRootLength)
|
||||
leafName[kMaxRootLength] = '\0';
|
||||
for (short index = 1; index < 1000 && Exists(); index++)
|
||||
{
|
||||
// start with "Picture-1.jpg" after "Picture.jpg" exists
|
||||
char newName[nsFileSpecHelpers::kMaxFilenameLength + 1];
|
||||
sprintf(newName, "%s-%d%s", leafName, index, suffix);
|
||||
SetLeafName(newName);
|
||||
}
|
||||
if (*suffix)
|
||||
delete [] suffix;
|
||||
delete [] leafName;
|
||||
} // nsNativeFileSpec::MakeUnique
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
@@ -428,10 +501,12 @@ nsNativeFileSpec::nsNativeFileSpec(const nsNativeFileSpec& inSpec)
|
||||
|
||||
#if defined(XP_UNIX) || defined(XP_PC)
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec(const char* inString)
|
||||
nsNativeFileSpec::nsNativeFileSpec(const char* inString, bool inCreateDirs)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(nsFileSpecHelpers::StringDup(inString))
|
||||
{
|
||||
// Make canonical and absolute.
|
||||
nsFileSpecHelpers::Canonify(mPath, inCreateDirs);
|
||||
}
|
||||
#endif //XP_UNIX,PC
|
||||
|
||||
@@ -440,7 +515,7 @@ nsNativeFileSpec::~nsNativeFileSpec()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
#ifndef XP_MAC
|
||||
delete [] mPath;
|
||||
delete [] mPath;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -472,3 +547,12 @@ nsOutputFileStream& operator << (nsOutputFileStream& s, const nsNativeFileSpec&
|
||||
}
|
||||
#endif // DEBUG && XP_UNIX
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec nsNativeFileSpec::operator + (const char* inRelativePath) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsNativeFileSpec result = *this;
|
||||
result += inRelativePath;
|
||||
return result;
|
||||
} // nsNativeFileSpec::operator +
|
||||
|
||||
|
||||
@@ -16,27 +16,205 @@
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
// This file is included by nsFileSpec.cpp, and includes the Unix-specific
|
||||
// implementations.
|
||||
// This file is included by nsFileSpec.cpp, and includes the Unix-specific
|
||||
// implementations.
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/dir.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsFileSpecHelpers::Canonify(char*& ioPath, bool inMakeDirs)
|
||||
// Canonify, make absolute, and check whether directories exist
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!ioPath)
|
||||
return;
|
||||
if (inMakeDirs)
|
||||
{
|
||||
const mode_t mode = 0700;
|
||||
nsFileSpecHelpers::MakeAllDirectories(ioPath, mode);
|
||||
}
|
||||
char buffer[MAXPATHLEN];
|
||||
errno = 0;
|
||||
*buffer = '\0';
|
||||
char* canonicalPath = realpath(ioPath, buffer);
|
||||
if (!canonicalPath)
|
||||
{
|
||||
// Linux's realpath() is pathetically buggy. If the reason for the nil
|
||||
// result is just that the leaf does not exist, strip the leaf off,
|
||||
// process that, and then add the leaf back.
|
||||
char* allButLeaf = nsFileSpecHelpers::StringDup(ioPath);
|
||||
if (!allButLeaf)
|
||||
return;
|
||||
char* lastSeparator = strrchr(allButLeaf, '/');
|
||||
if (lastSeparator)
|
||||
{
|
||||
*lastSeparator = '\0';
|
||||
canonicalPath = realpath(allButLeaf, buffer);
|
||||
strcat(buffer, "/");
|
||||
// Add back the leaf
|
||||
strcat(buffer, ++lastSeparator);
|
||||
}
|
||||
delete [] allButLeaf;
|
||||
}
|
||||
if (!canonicalPath && *ioPath != '/' && !inMakeDirs)
|
||||
{
|
||||
// Well, if it's a relative path, hack it ourselves.
|
||||
canonicalPath = realpath(".", buffer);
|
||||
if (canonicalPath)
|
||||
{
|
||||
strcat(canonicalPath, "/");
|
||||
strcat(canonicalPath, ioPath);
|
||||
}
|
||||
}
|
||||
if (canonicalPath)
|
||||
nsFileSpecHelpers::StringAssign(ioPath, canonicalPath);
|
||||
} // nsFileSpecHelpers::Canonify
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::SetLeafName(const char* inLeafName)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::LeafReplace(mPath, '/', inLeafName);
|
||||
nsFileSpecHelpers::LeafReplace(mPath, '/', inLeafName);
|
||||
} // nsNativeFileSpec::SetLeafName
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
char* nsNativeFileSpec::GetLeafName() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return nsFileSpecHelpers::GetLeaf(mPath, '/');
|
||||
return nsFileSpecHelpers::GetLeaf(mPath, '/');
|
||||
} // nsNativeFileSpec::GetLeafName
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::Exists() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return false; // fixme
|
||||
struct stat st;
|
||||
return 0 == stat(mPath, &st);
|
||||
} // nsNativeFileSpec::Exists
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::IsFile() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
struct stat st;
|
||||
return 0 == stat(mPath, &st) && S_ISREG(st.st_mode);
|
||||
} // nsNativeFileSpec::IsFile
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::IsDirectory() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
struct stat st;
|
||||
return 0 == stat(mPath, &st) && S_ISDIR(st.st_mode);
|
||||
} // nsNativeFileSpec::IsDirectory
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::GetParent(nsNativeFileSpec& outSpec) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::StringAssign(outSpec.mPath, mPath);
|
||||
char* cp = strrchr(outSpec.mPath, '/');
|
||||
if (cp)
|
||||
*cp = '\0';
|
||||
} // nsNativeFileSpec::GetParent
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator += (const char* inRelativePath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!inRelativePath || !mPath)
|
||||
return;
|
||||
|
||||
if (mPath[strlen(mPath) - 1] != '/')
|
||||
char* newPath = nsFileSpecHelpers::ReallocCat(mPath, "/");
|
||||
SetLeafName(inRelativePath);
|
||||
} // nsNativeFileSpec::operator +=
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::CreateDirectory(int mode)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// Note that mPath is canonical!
|
||||
mkdir(mPath, mode);
|
||||
} // nsNativeFileSpec::CreateDirectory
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::Delete(bool inRecursive)
|
||||
// To check if this worked, call Exists() afterwards, see?
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (IsDirectory())
|
||||
{
|
||||
if (inRecursive)
|
||||
{
|
||||
for (nsDirectoryIterator i(*this); i; i++)
|
||||
{
|
||||
nsNativeFileSpec& child = (nsNativeFileSpec&)i;
|
||||
child.Delete(inRecursive);
|
||||
}
|
||||
}
|
||||
rmdir(mPath);
|
||||
}
|
||||
else
|
||||
remove(mPath);
|
||||
} // nsNativeFileSpec::Delete
|
||||
|
||||
//========================================================================================
|
||||
// nsDirectoryIterator
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator::nsDirectoryIterator(
|
||||
const nsNativeFileSpec& inDirectory
|
||||
, int inIterateDirection)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mCurrent(inDirectory)
|
||||
, mDir(nsnull)
|
||||
, mExists(false)
|
||||
{
|
||||
mCurrent += "sysygy"; // prepare the path for SetLeafName
|
||||
mDir = opendir((const char*)nsFilePath(inDirectory));
|
||||
++(*this);
|
||||
} // nsDirectoryIterator::nsDirectoryIterator
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator::~nsDirectoryIterator()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (mDir)
|
||||
closedir(mDir);
|
||||
} // nsDirectoryIterator::nsDirectoryIterator
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator& nsDirectoryIterator::operator ++ ()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mExists = false;
|
||||
if (!mDir)
|
||||
return *this;
|
||||
char* dot = ".";
|
||||
char* dotdot = "..";
|
||||
struct dirent* entry = readdir(mDir);
|
||||
if (entry && strcmp(entry->d_name, dot) == 0)
|
||||
entry = readdir(mDir);
|
||||
if (entry && strcmp(entry->d_name, dotdot) == 0)
|
||||
entry = readdir(mDir);
|
||||
if (entry)
|
||||
{
|
||||
mExists = true;
|
||||
mCurrent.SetLeafName(entry->d_name);
|
||||
}
|
||||
return *this;
|
||||
} // nsDirectoryIterator::operator ++
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator& nsDirectoryIterator::operator -- ()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return ++(*this); // can't do it backwards.
|
||||
} // nsDirectoryIterator::operator --
|
||||
|
||||
@@ -19,6 +19,17 @@
|
||||
// This file is included by nsFileSpec.cp, and includes the Windows-specific
|
||||
// implementations.
|
||||
|
||||
#include <stat.h>
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsFileSpecHelpers::Canonify(char*& ioPath, bool inMakeDirs)
|
||||
// Canonify, make absolute, and check whether directories exist
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("Please, some Winhead please write this!");
|
||||
return ioPath;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec(const nsFilePath& inPath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
@@ -31,9 +42,17 @@ nsNativeFileSpec::nsNativeFileSpec(const nsFilePath& inPath)
|
||||
void nsNativeFileSpec::operator = (const nsFilePath& inPath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// Convert '/' to '\'
|
||||
nsFileSpecHelpers::StringAssign(mPath, (const char*)inPath);
|
||||
for (char* cp = mPath; *cp; cp++)
|
||||
// Strip the leading slash, which should
|
||||
// leave us pointing to a drive letter.
|
||||
nsFileSpecHelpers::StringAssign(mPath, (const char*)inPath + 1);
|
||||
|
||||
// Convert the vertical slash to a colon
|
||||
char* cp = mPath + 1;
|
||||
if (strstr(cp, "|/") == cp)
|
||||
*cp = ':';
|
||||
|
||||
// Convert '/' to '\'.
|
||||
while (*++cp)
|
||||
{
|
||||
if (*cp == '/')
|
||||
*cp = '\\';
|
||||
@@ -79,6 +98,138 @@ char* nsNativeFileSpec::GetLeafName() const
|
||||
bool nsNativeFileSpec::Exists() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return false; // fixme
|
||||
struct stat st;
|
||||
return 0 == stat(mPath, &st);
|
||||
} // nsNativeFileSpec::Exists
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::IsFile() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
struct stat st;
|
||||
return 0 == stat(mPath, &st) && S_ISREG(st.st_mode);
|
||||
} // nsNativeFileSpec::IsFile
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::IsDirectory() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
struct stat st;
|
||||
return 0 == stat(mPath, &st) && S_ISDIR(st.st_mode);
|
||||
} // nsNativeFileSpec::IsDirectory
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::GetParent(nsNativeFileSpec& outSpec) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::StringAssign(outSpec.mPath, mPath);
|
||||
char* cp = strrchr(outSpec.mPath, '\\');
|
||||
if (cp)
|
||||
*cp = '\0';
|
||||
} // nsNativeFileSpec::GetParent
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator += (const char* inRelativePath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!inRelativePath || !mPath)
|
||||
return;
|
||||
|
||||
if (mPath[strlen(mPath) - 1] != '\\')
|
||||
char* newPath = nsFileSpecHelpers::ReallocCat(mPath, "\\");
|
||||
SetLeafName(inRelativePath);
|
||||
} // nsNativeFileSpec::operator +=
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::CreateDirectory()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// Note that mPath is canonical!
|
||||
NS_NOTYETIMPLEMENTED("Please, some Winhead please fix this!");
|
||||
mkdir(mPath, mode);
|
||||
} // nsNativeFileSpec::CreateDirectory
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::Delete(bool inRecursive)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (IsDirectory())
|
||||
{
|
||||
if (inRecursive)
|
||||
{
|
||||
for (nsDirectoryIterator i(*this); i; i++)
|
||||
{
|
||||
const nsNativeFileSpec& child = (nsNativeFileSpec&)i;
|
||||
child.Delete(inRecursive);
|
||||
}
|
||||
}
|
||||
NS_NOTYETIMPLEMENTED("Please, some Winhead please fix this!");
|
||||
rmdir(mPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("Please, some Winhead please write this!");
|
||||
remove(mPath);
|
||||
}
|
||||
} // nsNativeFileSpec::Delete
|
||||
|
||||
//========================================================================================
|
||||
// nsDirectoryIterator
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator::nsDirectoryIterator(
|
||||
const nsNativeFileSpec& inDirectory
|
||||
, int inIterateDirection)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mCurrent(inDirectory)
|
||||
#if 0 // Some kind winhead please build, test, and remove when ready.
|
||||
, mDir(nsnull)
|
||||
#endif // XP_PC -- ifdef to be removed.
|
||||
, mExists(false)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("Please, some kind Winhead please check this!");
|
||||
mCurrent += "foo";
|
||||
#if 0 // Some kind winhead please build, test, and remove when ready.
|
||||
mDir = opendir(mPath);
|
||||
#endif // XP_PC -- ifdef to be removed.
|
||||
++(*this);
|
||||
} // nsDirectoryIterator::nsDirectoryIterator
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator::~nsDirectoryIterator()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("Please, some kind Winhead please check this!");
|
||||
#if 0 // Some kind winhead please build, test, and remove when ready.
|
||||
if (mDir)
|
||||
closedir(mDir);
|
||||
#endif // XP_PC -- ifdef to be removed.
|
||||
} // nsDirectoryIterator::nsDirectoryIterator
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator& nsDirectoryIterator::operator ++ ()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mExists = false;
|
||||
NS_NOTYETIMPLEMENTED("Please, some kind Winhead please check this!");
|
||||
#if 0 // Some kind winhead please build, test, and remove when ready.
|
||||
if (!mDir)
|
||||
return *this;
|
||||
struct dirent* entry = readdir(mDir);
|
||||
if (entry)
|
||||
{
|
||||
mExists = true;
|
||||
mCurrent.SetLeafName(entry->d_name);
|
||||
}
|
||||
#endif // XP_PC -- ifdef to be removed.
|
||||
return *this;
|
||||
} // nsDirectoryIterator::operator ++
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator& nsDirectoryIterator::operator -- ()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return ++(*this); // can't do it backwards.
|
||||
} // nsDirectoryIterator::operator --
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ void FilesTest::WriteStuff(nsOutputFileStream& s)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// Initialize a URL from a string without suffix. Change the path to suit your machine.
|
||||
nsFileURL fileURL("file:///Development/MPW/MPW%20Shell");
|
||||
nsFileURL fileURL("file:///Development/MPW/MPW%20Shell", false);
|
||||
s << "File URL initialized to: \"" << fileURL << "\""<< nsEndl;
|
||||
|
||||
// Initialize a Unix path from a URL
|
||||
@@ -44,7 +44,7 @@ void FilesTest::WriteStuff(nsOutputFileStream& s)
|
||||
} // WriteStuff
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void main()
|
||||
int main()
|
||||
// For use with DEBUG defined.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
@@ -59,38 +59,59 @@ void main()
|
||||
FilesTest::WriteStuff(nsOut);
|
||||
nsOut << nsEndl << nsEndl;
|
||||
|
||||
// Test of nsOutputFileStream
|
||||
|
||||
nsFilePath myTextFilePath("iotest.txt");
|
||||
// - Test of nsOutputFileStream
|
||||
|
||||
nsFilePath myTextFilePath("mumble/iotest.txt", true); // relative path.
|
||||
const char* pathAsString = (const char*)myTextFilePath;
|
||||
if (*pathAsString != '/')
|
||||
{
|
||||
nsOut << "WRITING IDENTICAL OUTPUT TO " << (const char*)myTextFilePath << nsEndl << nsEndl;
|
||||
nsOut
|
||||
<< "ERROR: after initializing the path object with a relative path,"
|
||||
<< "\n the path consisted of the string "
|
||||
<< "\n\t" << pathAsString
|
||||
<< "\n which is not a canonical full path!"
|
||||
<< nsEndl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
nsNativeFileSpec mySpec(myTextFilePath);
|
||||
{
|
||||
nsOut << "WRITING IDENTICAL OUTPUT TO " << pathAsString << nsEndl << nsEndl;
|
||||
nsOutputFileStream testStream(myTextFilePath);
|
||||
if (!testStream.is_open())
|
||||
{
|
||||
nsOut
|
||||
<< "ERROR: File "
|
||||
<< (const char*)myTextFilePath
|
||||
<< pathAsString
|
||||
<< " could not be opened for output"
|
||||
<< nsEndl;
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
FilesTest::WriteStuff(testStream);
|
||||
} // <-- Scope closes the stream (and the file).
|
||||
|
||||
// Test of nsInputFileStream
|
||||
if (!mySpec.Exists() || mySpec.IsDirectory() || !mySpec.IsFile())
|
||||
{
|
||||
nsOut
|
||||
<< "ERROR: File "
|
||||
<< pathAsString
|
||||
<< " is not a file (cela n'est pas un pipe)"
|
||||
<< nsEndl;
|
||||
return -1;
|
||||
}
|
||||
// - Test of nsInputFileStream
|
||||
|
||||
{
|
||||
nsOut << "READING BACK DATA FROM " << (const char*)myTextFilePath << nsEndl << nsEndl;
|
||||
nsOut << "READING BACK DATA FROM " << pathAsString << nsEndl << nsEndl;
|
||||
nsInputFileStream testStream2(myTextFilePath);
|
||||
if (!testStream2.is_open())
|
||||
{
|
||||
nsOut
|
||||
<< "ERROR: File "
|
||||
<< (const char*)myTextFilePath
|
||||
<< pathAsString
|
||||
<< " could not be opened for input"
|
||||
<< nsEndl;
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
char line[1000];
|
||||
|
||||
@@ -101,4 +122,101 @@ void main()
|
||||
nsOut << line << nsEndl;
|
||||
}
|
||||
} // <-- Scope closes the stream (and the file).
|
||||
|
||||
// - Test of GetParent()
|
||||
|
||||
nsNativeFileSpec parent;
|
||||
mySpec.GetParent(parent);
|
||||
nsFilePath parentPath(parent);
|
||||
nsOut
|
||||
<< "GetParent() on "
|
||||
<< "\n\t" << pathAsString
|
||||
<< "\n yields "
|
||||
<< "\n\t" << (const char*)parentPath
|
||||
<< nsEndl;
|
||||
|
||||
// - Test of non-recursive delete
|
||||
|
||||
nsOut
|
||||
<< "Attempting to delete "
|
||||
<< "\n\t" << (const char*)parentPath
|
||||
<< "\n without recursive option (should fail)"
|
||||
<< nsEndl;
|
||||
parent.Delete(false);
|
||||
if (parent.Exists())
|
||||
nsOut << "Test passed." << nsEndl;
|
||||
else
|
||||
{
|
||||
nsOut
|
||||
<< "ERROR: File "
|
||||
<< "\n\t" << (const char*)parentPath
|
||||
<< "\n has been deleted without the recursion option,"
|
||||
<< "\n and is a nonempty directory!"
|
||||
<< nsEndl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// - Test of recursive delete
|
||||
|
||||
nsOut
|
||||
<< "Deleting "
|
||||
<< "\n\t" << (const char*)parentPath
|
||||
<< "\n with recursive option"
|
||||
<< nsEndl;
|
||||
parent.Delete(true);
|
||||
if (parent.Exists())
|
||||
{
|
||||
nsOut
|
||||
<< "ERROR: Directory "
|
||||
<< "\n\t" << (const char*)parentPath
|
||||
<< "\n has NOT been deleted despite the recursion option!"
|
||||
<< nsEndl;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
nsOut << "Test passed." << nsEndl;
|
||||
|
||||
// - Test of CreateDirectory
|
||||
|
||||
nsOut
|
||||
<< "Testing CreateDirectory() using"
|
||||
<< "\n\t" << (const char*)parentPath
|
||||
<< nsEndl;
|
||||
|
||||
parent.CreateDirectory();
|
||||
if (parent.Exists())
|
||||
nsOut << "Test passed." << nsEndl;
|
||||
else
|
||||
{
|
||||
nsOut << "ERROR: Test failed." << nsEndl;
|
||||
return -1;
|
||||
}
|
||||
parent.Delete(true);
|
||||
|
||||
#ifndef XP_PC // uncomment when tested and ready.
|
||||
|
||||
// - Test of directory iterator
|
||||
|
||||
nsNativeFileSpec grandparent;
|
||||
parent.GetParent(grandparent); // should be the original default directory.
|
||||
nsFilePath grandparentPath(grandparent);
|
||||
|
||||
nsOut << "Forwards listing of " << (const char*)grandparentPath << ":" << nsEndl;
|
||||
for (nsDirectoryIterator i(grandparent, +1); i; i++)
|
||||
{
|
||||
char* itemName = ((nsNativeFileSpec&)i).GetLeafName();
|
||||
nsOut << '\t' << itemName << nsEndl;
|
||||
delete [] itemName;
|
||||
}
|
||||
|
||||
nsOut << "Backwards listing of " << (const char*)grandparentPath << ":" << nsEndl;
|
||||
for (nsDirectoryIterator i(grandparent, -1); i; i--)
|
||||
{
|
||||
char* itemName = ((nsNativeFileSpec&)i).GetLeafName();
|
||||
nsOut << '\t' << itemName << nsEndl;
|
||||
delete [] itemName;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
} // main
|
||||
|
||||
@@ -30,115 +30,180 @@
|
||||
NS_NAMESPACE nsFileSpecHelpers
|
||||
//========================================================================================
|
||||
{
|
||||
enum
|
||||
{ kMaxFilenameLength = 31 // should work on Macintosh, Unix, and Win32.
|
||||
, kMaxAltDigitLength = 5
|
||||
, kMaxCoreLeafNameLength = (kMaxFilenameLength - (kMaxAltDigitLength + 1))
|
||||
};
|
||||
NS_NAMESPACE_PROTOTYPE void LeafReplace(
|
||||
char*& ioPath,
|
||||
char inSeparator,
|
||||
const char* inLeafName);
|
||||
NS_NAMESPACE_PROTOTYPE char* GetLeaf(const char* inPath, char inSeparator); // allocated
|
||||
NS_NAMESPACE_PROTOTYPE char* StringDup(const char* inString, int allocLength = 0);
|
||||
NS_NAMESPACE_PROTOTYPE char* AllocCat(const char* inString1, const char* inString2);
|
||||
NS_NAMESPACE_PROTOTYPE char* StringAssign(char*& ioString, const char* inOther);
|
||||
enum
|
||||
{ kMaxFilenameLength = 31 // should work on Macintosh, Unix, and Win32.
|
||||
, kMaxAltDigitLength = 5
|
||||
, kMaxCoreLeafNameLength = (kMaxFilenameLength - (kMaxAltDigitLength + 1))
|
||||
};
|
||||
NS_NAMESPACE_PROTOTYPE void LeafReplace(
|
||||
char*& ioPath,
|
||||
char inSeparator,
|
||||
const char* inLeafName);
|
||||
#ifndef XP_MAC
|
||||
NS_NAMESPACE_PROTOTYPE void Canonify(char*& ioPath, bool inMakeDirs);
|
||||
NS_NAMESPACE_PROTOTYPE void MakeAllDirectories(const char* inPath, int mode);
|
||||
#endif
|
||||
NS_NAMESPACE_PROTOTYPE char* GetLeaf(const char* inPath, char inSeparator); // allocated
|
||||
NS_NAMESPACE_PROTOTYPE char* StringDup(const char* inString, int allocLength = 0);
|
||||
NS_NAMESPACE_PROTOTYPE char* AllocCat(const char* inString1, const char* inString2);
|
||||
NS_NAMESPACE_PROTOTYPE char* StringAssign(char*& ioString, const char* inOther);
|
||||
NS_NAMESPACE_PROTOTYPE char* ReallocCat(char*& ioString, const char* inString1);
|
||||
} NS_NAMESPACE_END
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
char* nsFileSpecHelpers::StringDup(
|
||||
const char* inString,
|
||||
int allocLength)
|
||||
const char* inString,
|
||||
int allocLength)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!allocLength && inString)
|
||||
allocLength = strlen(inString);
|
||||
char* newPath = inString || allocLength ? new char[allocLength + 1] : 0;
|
||||
if (!newPath)
|
||||
return NULL;
|
||||
strcpy(newPath, inString);
|
||||
return newPath;
|
||||
if (!allocLength && inString)
|
||||
allocLength = strlen(inString);
|
||||
char* newPath = inString || allocLength ? new char[allocLength + 1] : nsnull;
|
||||
if (!newPath)
|
||||
return NULL;
|
||||
strcpy(newPath, inString);
|
||||
return newPath;
|
||||
} // nsFileSpecHelpers::StringDup
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
char* nsFileSpecHelpers::AllocCat(
|
||||
const char* inString1,
|
||||
const char* inString2)
|
||||
const char* inString1,
|
||||
const char* inString2)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!inString1)
|
||||
return inString2 ? StringDup(inString2) : (char*)NULL;
|
||||
if (!inString2)
|
||||
return StringDup(inString1);
|
||||
char* outString = StringDup(inString1, strlen(inString1) + strlen(inString2));
|
||||
if (outString)
|
||||
strcat(outString, inString2);
|
||||
return outString;
|
||||
if (!inString1)
|
||||
return inString2 ? StringDup(inString2) : (char*)NULL;
|
||||
if (!inString2)
|
||||
return StringDup(inString1);
|
||||
char* outString = StringDup(inString1, strlen(inString1) + strlen(inString2));
|
||||
if (outString)
|
||||
strcat(outString, inString2);
|
||||
return outString;
|
||||
} // nsFileSpecHelpers::StringDup
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
char* nsFileSpecHelpers::StringAssign(
|
||||
char*& ioString,
|
||||
const char* inString2)
|
||||
char*& ioString,
|
||||
const char* inString2)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!inString2)
|
||||
{
|
||||
delete [] ioString;
|
||||
ioString = (char*)NULL;
|
||||
return ioString;
|
||||
}
|
||||
if (!ioString || (strlen(inString2) > strlen(ioString)))
|
||||
{
|
||||
delete [] ioString;
|
||||
ioString = StringDup(inString2);
|
||||
return ioString;
|
||||
}
|
||||
strcpy(ioString, inString2);
|
||||
return ioString;
|
||||
if (!inString2)
|
||||
{
|
||||
delete [] ioString;
|
||||
ioString = (char*)NULL;
|
||||
return ioString;
|
||||
}
|
||||
if (!ioString || (strlen(inString2) > strlen(ioString)))
|
||||
{
|
||||
delete [] ioString;
|
||||
ioString = StringDup(inString2);
|
||||
return ioString;
|
||||
}
|
||||
strcpy(ioString, inString2);
|
||||
return ioString;
|
||||
} // nsFileSpecHelpers::StringAssign
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsFileSpecHelpers::LeafReplace(
|
||||
char*& ioPath,
|
||||
char inSeparator,
|
||||
const char* inLeafName)
|
||||
char*& ioPath,
|
||||
char inSeparator,
|
||||
const char* inLeafName)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// Find the existing leaf name
|
||||
if (!ioPath)
|
||||
return;
|
||||
if (!inLeafName)
|
||||
{
|
||||
*ioPath = '\0';
|
||||
return;
|
||||
}
|
||||
char* lastSeparator = strrchr(ioPath, inSeparator);
|
||||
int oldLength = strlen(ioPath);
|
||||
*(++lastSeparator) = '\0'; // strip the current leaf name
|
||||
int newLength = lastSeparator - ioPath + strlen(inLeafName);
|
||||
if (newLength > oldLength)
|
||||
{
|
||||
char* newPath = StringDup(ioPath, newLength + 1);
|
||||
delete [] ioPath;
|
||||
ioPath = newPath;
|
||||
}
|
||||
strcat(ioPath, inLeafName);
|
||||
} // nsNativeFileSpec::SetLeafName
|
||||
// Find the existing leaf name
|
||||
if (!ioPath)
|
||||
return;
|
||||
if (!inLeafName)
|
||||
{
|
||||
*ioPath = '\0';
|
||||
return;
|
||||
}
|
||||
char* lastSeparator = strrchr(ioPath, inSeparator);
|
||||
int oldLength = strlen(ioPath);
|
||||
*(++lastSeparator) = '\0'; // strip the current leaf name
|
||||
int newLength = lastSeparator - ioPath + strlen(inLeafName);
|
||||
if (newLength > oldLength)
|
||||
{
|
||||
char* newPath = StringDup(ioPath, newLength + 1);
|
||||
delete [] ioPath;
|
||||
ioPath = newPath;
|
||||
}
|
||||
strcat(ioPath, inLeafName);
|
||||
} // nsNativeFileSpec::LeafReplace
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
char* nsFileSpecHelpers::GetLeaf(const char* inPath, char inSeparator)
|
||||
// Returns a pointer to an allocated string representing the leaf.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!inPath)
|
||||
return NULL;
|
||||
char* lastSeparator = strrchr(inPath, inSeparator);
|
||||
if (lastSeparator)
|
||||
return StringDup(lastSeparator);
|
||||
return StringDup(inPath);
|
||||
if (!inPath)
|
||||
return NULL;
|
||||
char* lastSeparator = strrchr(inPath, inSeparator);
|
||||
if (lastSeparator)
|
||||
return StringDup(++lastSeparator);
|
||||
return StringDup(inPath);
|
||||
} // nsNativeFileSpec::GetLeaf
|
||||
|
||||
#if defined(XP_UNIX) || defined(XP_PC)
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsFileSpecHelpers::MakeAllDirectories(const char* inPath, int mode)
|
||||
// Make the path a valid one by creating all the intermediate directories. Does NOT
|
||||
// make the leaf into a directory. This should be a unix path.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!inPath)
|
||||
return;
|
||||
|
||||
char* pathCopy = nsFileSpecHelpers::StringDup( inPath );
|
||||
if (!pathCopy)
|
||||
return;
|
||||
|
||||
const char kSeparator = '/'; // I repeat: this should be a unix-style path.
|
||||
const int kSkipFirst = 1;
|
||||
|
||||
#ifdef XP_WIN
|
||||
NS_ASSERTION( pathCopy[2] == '|', "No drive letter!" );
|
||||
#endif
|
||||
char* currentStart = pathCopy;
|
||||
char* currentEnd = strchr(currentStart + kSkipFirst, kSeparator);
|
||||
if (currentEnd)
|
||||
{
|
||||
*currentEnd = '\0';
|
||||
nsNativeFileSpec spec(nsFilePath(pathCopy, false));
|
||||
do
|
||||
{
|
||||
// If the node doesn't exist, and it is not the initial node in a full path,
|
||||
// then make a directory (We cannot make the initial (volume) node).
|
||||
if (!spec.Exists() && *currentStart != kSeparator)
|
||||
spec.CreateDirectory(mode);
|
||||
if (!spec.Exists())
|
||||
{
|
||||
NS_ASSERTION(spec.Exists(), "Could not create the directory?");
|
||||
break;
|
||||
}
|
||||
currentStart = ++currentEnd;
|
||||
currentEnd = strchr(currentStart, kSeparator);
|
||||
if (!currentEnd)
|
||||
break;
|
||||
spec += currentStart; // "lengthen" the path, adding the next node.
|
||||
} while (currentEnd);
|
||||
}
|
||||
delete [] pathCopy;
|
||||
} // nsFileSpecHelpers::MakeAllDirectories
|
||||
|
||||
#endif // XP_PC || XP_UNIX
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
char* nsFileSpecHelpers::ReallocCat(char*& ioString, const char* inString1)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
char* newString = AllocCat(ioString, inString1);
|
||||
delete [] ioString;
|
||||
ioString = newString;
|
||||
return ioString;
|
||||
} // nsNativeFileSpec::ReallocCat
|
||||
|
||||
#if defined(XP_PC)
|
||||
#include "windows/nsFileSpecWin.cpp" // Windows-specific implementations
|
||||
@@ -149,26 +214,30 @@ char* nsFileSpecHelpers::GetLeaf(const char* inPath, char inSeparator)
|
||||
#endif
|
||||
|
||||
//========================================================================================
|
||||
// nsFileURL implementation
|
||||
// nsFileURL implementation
|
||||
//========================================================================================
|
||||
|
||||
#ifndef XP_MAC
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFileURL::nsFileURL(const char* inString)
|
||||
nsFileURL::nsFileURL(const char* inString, bool inCreateDirs)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mURL(nsFileSpecHelpers::StringDup(inString))
|
||||
#ifdef XP_MAC
|
||||
, mNativeFileSpec(inString + kFileURLPrefixLength)
|
||||
#endif
|
||||
: mURL(nsnull)
|
||||
{
|
||||
NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!");
|
||||
if (!inString)
|
||||
return;
|
||||
NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!");
|
||||
// Make canonical and absolute.
|
||||
nsFilePath path(inString + kFileURLPrefixLength, inCreateDirs);
|
||||
*this = path;
|
||||
} // nsFileURL::nsFileURL
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFileURL::nsFileURL(const nsFileURL& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mURL(nsFileSpecHelpers::StringDup(inOther.mURL))
|
||||
: mURL(nsFileSpecHelpers::StringDup(inOther.mURL))
|
||||
#ifdef XP_MAC
|
||||
, mNativeFileSpec(inOther.GetNativeSpec())
|
||||
, mNativeFileSpec(inOther.GetNativeSpec())
|
||||
#endif
|
||||
{
|
||||
} // nsFileURL::nsFileURL
|
||||
@@ -176,18 +245,18 @@ nsFileURL::nsFileURL(const nsFileURL& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFileURL::nsFileURL(const nsFilePath& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mURL(nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)inOther))
|
||||
: mURL(nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)inOther))
|
||||
#ifdef XP_MAC
|
||||
, mNativeFileSpec(inOther.GetNativeSpec())
|
||||
, mNativeFileSpec(inOther.GetNativeSpec())
|
||||
#endif
|
||||
{
|
||||
} // nsFileURL::nsFileURL
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFileURL::nsFileURL(const nsNativeFileSpec& inOther)
|
||||
: mURL(nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)nsFilePath(inOther)))
|
||||
: mURL(nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)nsFilePath(inOther)))
|
||||
#ifdef XP_MAC
|
||||
, mNativeFileSpec(inOther)
|
||||
, mNativeFileSpec(inOther)
|
||||
#endif
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
@@ -197,17 +266,17 @@ nsFileURL::nsFileURL(const nsNativeFileSpec& inOther)
|
||||
nsFileURL::~nsFileURL()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
delete [] mURL;
|
||||
delete [] mURL;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsFileURL::operator = (const char* inString)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::StringAssign(mURL, inString);
|
||||
NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!");
|
||||
nsFileSpecHelpers::StringAssign(mURL, inString);
|
||||
NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!");
|
||||
#ifdef XP_MAC
|
||||
mNativeFileSpec = inString + kFileURLPrefixLength;
|
||||
mNativeFileSpec = inString + kFileURLPrefixLength;
|
||||
#endif
|
||||
} // nsFileURL::operator =
|
||||
|
||||
@@ -215,9 +284,9 @@ void nsFileURL::operator = (const char* inString)
|
||||
void nsFileURL::operator = (const nsFileURL& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mURL = nsFileSpecHelpers::StringAssign(mURL, inOther.mURL);
|
||||
mURL = nsFileSpecHelpers::StringAssign(mURL, inOther.mURL);
|
||||
#ifdef XP_MAC
|
||||
mNativeFileSpec = inOther.GetNativeSpec();
|
||||
mNativeFileSpec = inOther.GetNativeSpec();
|
||||
#endif
|
||||
} // nsFileURL::operator =
|
||||
|
||||
@@ -225,10 +294,10 @@ void nsFileURL::operator = (const nsFileURL& inOther)
|
||||
void nsFileURL::operator = (const nsFilePath& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
delete [] mURL;
|
||||
mURL = nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)inOther);
|
||||
delete [] mURL;
|
||||
mURL = nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)inOther);
|
||||
#ifdef XP_MAC
|
||||
mNativeFileSpec = inOther.GetNativeSpec();
|
||||
mNativeFileSpec = inOther.GetNativeSpec();
|
||||
#endif
|
||||
} // nsFileURL::operator =
|
||||
|
||||
@@ -236,10 +305,10 @@ void nsFileURL::operator = (const nsFilePath& inOther)
|
||||
void nsFileURL::operator = (const nsNativeFileSpec& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
delete [] mURL;
|
||||
mURL = nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)nsFilePath(inOther));
|
||||
delete [] mURL;
|
||||
mURL = nsFileSpecHelpers::AllocCat(kFileURLPrefix, (const char*)nsFilePath(inOther));
|
||||
#ifdef XP_MAC
|
||||
mNativeFileSpec = inOther;
|
||||
mNativeFileSpec = inOther;
|
||||
#endif
|
||||
} // nsFileURL::operator =
|
||||
|
||||
@@ -251,26 +320,27 @@ nsOutputFileStream& operator << (nsOutputFileStream& s, const nsFileURL& url)
|
||||
}
|
||||
|
||||
//========================================================================================
|
||||
// nsFilePath implementation
|
||||
// nsFilePath implementation
|
||||
//========================================================================================
|
||||
|
||||
#ifndef XP_MAC
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFilePath::nsFilePath(const char* inString)
|
||||
nsFilePath::nsFilePath(const char* inString, bool inCreateDirs)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(nsFileSpecHelpers::StringDup(inString))
|
||||
#ifdef XP_MAC
|
||||
, mNativeFileSpec(inString)
|
||||
#endif
|
||||
: mPath(nsFileSpecHelpers::StringDup(inString))
|
||||
{
|
||||
NS_ASSERTION(strstr(inString, kFileURLPrefix) != inString, "URL passed as path");
|
||||
NS_ASSERTION(strstr(inString, kFileURLPrefix) != inString, "URL passed as path");
|
||||
// Make canonical and absolute.
|
||||
nsFileSpecHelpers::Canonify(mPath, inCreateDirs);
|
||||
}
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFilePath::nsFilePath(const nsFileURL& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(nsFileSpecHelpers::StringDup(inOther.mURL + kFileURLPrefixLength))
|
||||
: mPath(nsFileSpecHelpers::StringDup(inOther.mURL + kFileURLPrefixLength))
|
||||
#ifdef XP_MAC
|
||||
, mNativeFileSpec(inOther.GetNativeSpec())
|
||||
, mNativeFileSpec(inOther.GetNativeSpec())
|
||||
#endif
|
||||
{
|
||||
}
|
||||
@@ -288,7 +358,7 @@ nsFilePath::nsFilePath(const nsNativeFileSpec& inOther)
|
||||
nsFilePath::~nsFilePath()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
delete [] mPath;
|
||||
delete [] mPath;
|
||||
}
|
||||
|
||||
#ifdef XP_UNIX
|
||||
@@ -304,10 +374,13 @@ void nsFilePath::operator = (const nsNativeFileSpec& inOther)
|
||||
void nsFilePath::operator = (const char* inString)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
NS_ASSERTION(strstr(inString, kFileURLPrefix) != inString, "URL passed as path");
|
||||
nsFileSpecHelpers::StringAssign(mPath, inString);
|
||||
NS_ASSERTION(strstr(inString, kFileURLPrefix) != inString, "URL passed as path");
|
||||
#ifdef XP_MAC
|
||||
mNativeFileSpec = inString;
|
||||
mNativeFileSpec = inString;
|
||||
nsFileSpecHelpers::StringAssign(mPath, (const char*)nsFilePath(mNativeFileSpec));
|
||||
#else
|
||||
nsFileSpecHelpers::StringAssign(mPath, inString);
|
||||
nsFileSpecHelpers::Canonify(mPath, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -315,21 +388,21 @@ void nsFilePath::operator = (const char* inString)
|
||||
void nsFilePath::operator = (const nsFileURL& inOther)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::StringAssign(mPath, (const char*)nsFilePath(inOther));
|
||||
nsFileSpecHelpers::StringAssign(mPath, (const char*)nsFilePath(inOther));
|
||||
#ifdef XP_MAC
|
||||
mNativeFileSpec = inOther.GetNativeSpec();
|
||||
mNativeFileSpec = inOther.GetNativeSpec();
|
||||
#endif
|
||||
}
|
||||
|
||||
//========================================================================================
|
||||
// nsNativeFileSpec implementation
|
||||
// nsNativeFileSpec implementation
|
||||
//========================================================================================
|
||||
|
||||
#ifndef XP_MAC
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec()
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(NULL)
|
||||
: mPath(NULL)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
@@ -338,7 +411,7 @@ nsNativeFileSpec::nsNativeFileSpec()
|
||||
nsNativeFileSpec::nsNativeFileSpec(const nsFileURL& inURL)
|
||||
//----------------------------------------------------------------------------------------
|
||||
#ifndef XP_MAC
|
||||
: mPath(NULL)
|
||||
: mPath(NULL)
|
||||
#endif
|
||||
{
|
||||
*this = nsFilePath(inURL); // convert to unix path first
|
||||
@@ -348,44 +421,44 @@ nsNativeFileSpec::nsNativeFileSpec(const nsFileURL& inURL)
|
||||
void nsNativeFileSpec::MakeUnique(const char* inSuggestedLeafName)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (inSuggestedLeafName && *inSuggestedLeafName)
|
||||
SetLeafName(inSuggestedLeafName);
|
||||
if (inSuggestedLeafName && *inSuggestedLeafName)
|
||||
SetLeafName(inSuggestedLeafName);
|
||||
|
||||
MakeUnique();
|
||||
MakeUnique();
|
||||
} // nsNativeFileSpec::MakeUnique
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::MakeUnique()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!Exists())
|
||||
return;
|
||||
if (!Exists())
|
||||
return;
|
||||
|
||||
char* leafName = GetLeafName();
|
||||
if (!leafName)
|
||||
return;
|
||||
char* leafName = GetLeafName();
|
||||
if (!leafName)
|
||||
return;
|
||||
|
||||
char* lastDot = strrchr(leafName, '.');
|
||||
char* suffix = "";
|
||||
if (lastDot)
|
||||
{
|
||||
suffix = nsFileSpecHelpers::StringDup(lastDot); // include '.'
|
||||
*lastDot = '\0'; // strip suffix and dot.
|
||||
}
|
||||
const int kMaxRootLength
|
||||
= nsFileSpecHelpers::kMaxCoreLeafNameLength - strlen(suffix) - 1;
|
||||
if (strlen(leafName) > kMaxRootLength)
|
||||
leafName[kMaxRootLength] = '\0';
|
||||
for (short index = 1; index < 1000 && Exists(); index++)
|
||||
{
|
||||
// start with "Picture-1.jpg" after "Picture.jpg" exists
|
||||
char newName[nsFileSpecHelpers::kMaxFilenameLength + 1];
|
||||
sprintf(newName, "%s-%d%s", leafName, index, suffix);
|
||||
SetLeafName(newName);
|
||||
}
|
||||
if (*suffix)
|
||||
delete [] suffix;
|
||||
delete [] leafName;
|
||||
char* lastDot = strrchr(leafName, '.');
|
||||
char* suffix = "";
|
||||
if (lastDot)
|
||||
{
|
||||
suffix = nsFileSpecHelpers::StringDup(lastDot); // include '.'
|
||||
*lastDot = '\0'; // strip suffix and dot.
|
||||
}
|
||||
const int kMaxRootLength
|
||||
= nsFileSpecHelpers::kMaxCoreLeafNameLength - strlen(suffix) - 1;
|
||||
if (strlen(leafName) > kMaxRootLength)
|
||||
leafName[kMaxRootLength] = '\0';
|
||||
for (short index = 1; index < 1000 && Exists(); index++)
|
||||
{
|
||||
// start with "Picture-1.jpg" after "Picture.jpg" exists
|
||||
char newName[nsFileSpecHelpers::kMaxFilenameLength + 1];
|
||||
sprintf(newName, "%s-%d%s", leafName, index, suffix);
|
||||
SetLeafName(newName);
|
||||
}
|
||||
if (*suffix)
|
||||
delete [] suffix;
|
||||
delete [] leafName;
|
||||
} // nsNativeFileSpec::MakeUnique
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
@@ -428,10 +501,12 @@ nsNativeFileSpec::nsNativeFileSpec(const nsNativeFileSpec& inSpec)
|
||||
|
||||
#if defined(XP_UNIX) || defined(XP_PC)
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec(const char* inString)
|
||||
nsNativeFileSpec::nsNativeFileSpec(const char* inString, bool inCreateDirs)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(nsFileSpecHelpers::StringDup(inString))
|
||||
{
|
||||
// Make canonical and absolute.
|
||||
nsFileSpecHelpers::Canonify(mPath, inCreateDirs);
|
||||
}
|
||||
#endif //XP_UNIX,PC
|
||||
|
||||
@@ -440,7 +515,7 @@ nsNativeFileSpec::~nsNativeFileSpec()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
#ifndef XP_MAC
|
||||
delete [] mPath;
|
||||
delete [] mPath;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -472,3 +547,12 @@ nsOutputFileStream& operator << (nsOutputFileStream& s, const nsNativeFileSpec&
|
||||
}
|
||||
#endif // DEBUG && XP_UNIX
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec nsNativeFileSpec::operator + (const char* inRelativePath) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsNativeFileSpec result = *this;
|
||||
result += inRelativePath;
|
||||
return result;
|
||||
} // nsNativeFileSpec::operator +
|
||||
|
||||
|
||||
@@ -127,6 +127,10 @@
|
||||
|
||||
#ifdef XP_MAC
|
||||
#include <Files.h>
|
||||
#elif defined(XP_UNIX) || defined (XP_OS2)
|
||||
#include <dirent.h>
|
||||
#elif 0 // defined(XP_PC)
|
||||
#include "winfile.h"
|
||||
#endif
|
||||
|
||||
//========================================================================================
|
||||
@@ -150,7 +154,7 @@ class NS_BASE nsNativeFileSpec
|
||||
{
|
||||
public:
|
||||
nsNativeFileSpec();
|
||||
explicit nsNativeFileSpec(const char* inString);
|
||||
explicit nsNativeFileSpec(const char* inString, bool inCreateDirs = false);
|
||||
explicit nsNativeFileSpec(const nsFilePath& inPath);
|
||||
explicit nsNativeFileSpec(const nsFileURL& inURL);
|
||||
nsNativeFileSpec(const nsNativeFileSpec& inPath);
|
||||
@@ -177,12 +181,12 @@ class NS_BASE nsNativeFileSpec
|
||||
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.
|
||||
// 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);
|
||||
// Called for the spec of an alias. Modifies the spec to
|
||||
// point to the original. Sets mError.
|
||||
// Called for the spec of an alias. Modifies the spec to
|
||||
// point to the original. Sets mError.
|
||||
void MakeUnique(ConstStr255Param inSuggestedLeafName);
|
||||
StringPtr GetLeafPName() { return mSpec.name; }
|
||||
ConstStr255Param GetLeafPName() const { return mSpec.name; }
|
||||
@@ -194,14 +198,58 @@ class NS_BASE nsNativeFileSpec
|
||||
bool Valid() const { return true; } // Fixme.
|
||||
#endif // XP_MAC
|
||||
|
||||
friend NS_BASE nsOutputFileStream& operator << (nsOutputFileStream& s, const nsNativeFileSpec& spec);
|
||||
friend NS_BASE nsOutputFileStream& operator << (
|
||||
nsOutputFileStream& s,
|
||||
const nsNativeFileSpec& spec);
|
||||
|
||||
//--------------------------------------------------
|
||||
// Queries and path algebra. These do not modify the disk.
|
||||
//--------------------------------------------------
|
||||
|
||||
char* GetLeafName() const; // Allocated. Use delete [].
|
||||
void SetLeafName(const char* inLeafName);
|
||||
bool Exists() const;
|
||||
// inLeafName can be a relative path, so this allows
|
||||
// one kind of concatenation of "paths".
|
||||
|
||||
void GetParent(nsNativeFileSpec& 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,
|
||||
// however, that the top node is still not a name,
|
||||
// but a spec. Volumes on Macintosh can have identical
|
||||
// names. Perhaps could be used for an operator --() ?
|
||||
|
||||
nsNativeFileSpec 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.
|
||||
// This must be a directory for this to work. This differs
|
||||
// from SetLeafName(), since the latter will work
|
||||
// starting with a sibling of the directory and throws
|
||||
// away its leaf information, whereas this one assumes
|
||||
// this is a directory, and the relative path starts
|
||||
// "below" this.
|
||||
|
||||
void MakeUnique();
|
||||
void MakeUnique(const char* inSuggestedLeafName);
|
||||
|
||||
bool IsDirectory() const;
|
||||
// More stringent than Exists()
|
||||
bool IsFile() const;
|
||||
// More stringent than Exists()
|
||||
bool Exists() const;
|
||||
|
||||
//--------------------------------------------------
|
||||
// Creation and deletion of objects. These can modify the disk.
|
||||
//--------------------------------------------------
|
||||
|
||||
void CreateDirectory(int mode = 0700 /* for unix */);
|
||||
void Delete(bool inRecursive);
|
||||
|
||||
//--------------------------------------------------
|
||||
// Data
|
||||
//--------------------------------------------------
|
||||
|
||||
private:
|
||||
friend class nsFilePath;
|
||||
#ifdef XP_MAC
|
||||
@@ -221,7 +269,7 @@ class NS_BASE nsFileURL
|
||||
{
|
||||
public:
|
||||
nsFileURL(const nsFileURL& inURL);
|
||||
explicit nsFileURL(const char* inString);
|
||||
explicit nsFileURL(const char* inString, bool inCreateDirs = false);
|
||||
explicit nsFileURL(const nsFilePath& inPath);
|
||||
explicit nsFileURL(const nsNativeFileSpec& inPath);
|
||||
virtual ~nsFileURL();
|
||||
@@ -247,7 +295,7 @@ class NS_BASE nsFileURL
|
||||
operator char* ();
|
||||
operator const char* const ();
|
||||
private:
|
||||
friend class nsFilePath; // to allow construction of nsFilePath
|
||||
friend class nsFilePath; // to allow construction of nsFilePath
|
||||
char* mURL;
|
||||
#ifdef XP_MAC
|
||||
// Since the path on the macintosh does not uniquely specify a file (volumes
|
||||
@@ -264,7 +312,7 @@ class NS_BASE nsFilePath
|
||||
{
|
||||
public:
|
||||
nsFilePath(const nsFilePath& inPath);
|
||||
explicit nsFilePath(const char* inString);
|
||||
explicit nsFilePath(const char* inString, bool inCreateDirs = false);
|
||||
explicit nsFilePath(const nsFileURL& inURL);
|
||||
explicit nsFilePath(const nsNativeFileSpec& inPath);
|
||||
virtual ~nsFilePath();
|
||||
@@ -292,7 +340,7 @@ class NS_BASE nsFilePath
|
||||
|
||||
private:
|
||||
|
||||
char* mPath;
|
||||
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.
|
||||
@@ -300,4 +348,52 @@ class NS_BASE nsFilePath
|
||||
#endif
|
||||
}; // class nsFilePath
|
||||
|
||||
//========================================================================================
|
||||
class nsDirectoryIterator
|
||||
// Example:
|
||||
//
|
||||
// nsNativeFileSpec parentDir(...); // directory over whose children we shall iterate
|
||||
// for (nsDirectoryIterator i(parentDir); i; i++)
|
||||
// {
|
||||
// // do something with (const nsNativeFileSpec&)i
|
||||
// }
|
||||
//
|
||||
// or:
|
||||
//
|
||||
// for (nsDirectoryIterator i(parentDir, false); i; i--)
|
||||
// {
|
||||
// // do something with (const nsNativeFileSpec&)i
|
||||
// }
|
||||
//
|
||||
// Currently, the only platform on which backwards iteration actually goes backwards
|
||||
// is Macintosh. On other platforms, both styles will work, but will go forwards.
|
||||
//========================================================================================
|
||||
{
|
||||
public:
|
||||
nsDirectoryIterator(
|
||||
const nsNativeFileSpec& 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; }
|
||||
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; }
|
||||
private:
|
||||
nsNativeFileSpec mCurrent;
|
||||
bool mExists;
|
||||
|
||||
#if defined(XP_UNIX) // || defined(XP_PC) add when ready
|
||||
DIR* mDir;
|
||||
#elif defined(XP_MAC)
|
||||
OSErr SetToIndex();
|
||||
short mIndex;
|
||||
short mMaxIndex;
|
||||
#endif
|
||||
}; // class nsDirectoryIterator
|
||||
|
||||
#endif // _FILESPEC_H_
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "FullPath.h"
|
||||
#include "FileCopy.h"
|
||||
#include "MoreFilesExtras.h"
|
||||
#include "nsEscape.h"
|
||||
|
||||
#include <Aliases.h>
|
||||
@@ -39,14 +40,16 @@ namespace MacFileHelpers
|
||||
memcpy(dst, src, 1 + src[0]);
|
||||
}
|
||||
|
||||
void PLstrcpy(Str255 dst, const char* src, int inMaxLen);
|
||||
void PLstrcpy(Str255 dst, const char* src, int inMaxLen=255);
|
||||
void PLstrncpy(Str255 dst, const char* src, int inMaxLen);
|
||||
|
||||
void SwapSlashColon(char * s);
|
||||
OSErr FSSpecFromFullUnixPath(
|
||||
const char * unixPath,
|
||||
FSSpec& outSpec,
|
||||
Boolean resolveAlias,
|
||||
Boolean allowPartial = false);
|
||||
Boolean allowPartial = false,
|
||||
Boolean createDirs = false);
|
||||
char* MacPathFromUnixPath(const char* unixPath);
|
||||
char* EncodeMacPath(
|
||||
char* inPath, // NOT const - gets clobbered
|
||||
@@ -54,7 +57,8 @@ namespace MacFileHelpers
|
||||
Boolean doEscape );
|
||||
OSErr FSSpecFromPathname(
|
||||
const char* inPathNamePtr,
|
||||
FSSpec& outSpec);
|
||||
FSSpec& outSpec,
|
||||
Boolean inCreateDirs);
|
||||
char* PathNameFromFSSpec(
|
||||
const FSSpec& inSpec,
|
||||
Boolean wantLeafName );
|
||||
@@ -81,7 +85,7 @@ namespace MacFileHelpers
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void MacFileHelpers::PLstrcpy(Str255 dst, const char* src, int inMax)
|
||||
//========================================================================================
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
int srcLength = strlen(src);
|
||||
NS_ASSERTION(srcLength <= inMax, "Oops, string is too long!");
|
||||
@@ -91,6 +95,17 @@ void MacFileHelpers::PLstrcpy(Str255 dst, const char* src, int inMax)
|
||||
memcpy(&dst[1], src, srcLength);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void MacFileHelpers::PLstrncpy(Str255 dst, const char* src, int inMax)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
int srcLength = strlen(src);
|
||||
if (srcLength > inMax)
|
||||
srcLength = inMax;
|
||||
dst[0] = srcLength;
|
||||
memcpy(&dst[1], src, srcLength);
|
||||
}
|
||||
|
||||
//-----------------------------------
|
||||
void MacFileHelpers::SwapSlashColon(char * s)
|
||||
//-----------------------------------
|
||||
@@ -218,7 +233,10 @@ char* MacFileHelpers::MacPathFromUnixPath(const char* unixPath)
|
||||
} // MacFileHelpers::MacPathFromUnixPath
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
OSErr MacFileHelpers::FSSpecFromPathname(const char* inPathNamePtr, FSSpec& outSpec)
|
||||
OSErr MacFileHelpers::FSSpecFromPathname(
|
||||
const char* inPathNamePtr,
|
||||
FSSpec& outSpec,
|
||||
Boolean inCreateDirs)
|
||||
// FSSpecFromPathname reverses PathNameFromFSSpec.
|
||||
// It returns a FSSpec given a c string which is a mac pathname.
|
||||
//----------------------------------------------------------------------------------------
|
||||
@@ -226,22 +244,55 @@ OSErr MacFileHelpers::FSSpecFromPathname(const char* inPathNamePtr, FSSpec& outS
|
||||
OSErr err;
|
||||
// Simplify this routine to use FSMakeFSSpec if length < 255. Otherwise use the MoreFiles
|
||||
// routine FSpLocationFromFullPath, which allocates memory, to handle longer pathnames.
|
||||
if (strlen(inPathNamePtr) < 255)
|
||||
|
||||
size_t inLength = strlen(inPathNamePtr);
|
||||
if (inLength < 255)
|
||||
{
|
||||
Str255 path;
|
||||
|
||||
int pos = 0;
|
||||
while ( (path[++pos] = *inPathNamePtr++) != 0 )
|
||||
;
|
||||
path[0] = pos-1; // save the length of the string (pos is the next open spot)
|
||||
|
||||
err = ::FSMakeFSSpec(0, 0, path, &outSpec);
|
||||
Str255 ppath;
|
||||
MacFileHelpers::PLstrcpy(ppath, inPathNamePtr);
|
||||
err = ::FSMakeFSSpec(0, 0, ppath, &outSpec);
|
||||
}
|
||||
else
|
||||
err = FSpLocationFromFullPath(strlen(inPathNamePtr), inPathNamePtr, &outSpec);
|
||||
err = FSpLocationFromFullPath(inLength, inPathNamePtr, &outSpec);
|
||||
|
||||
if (err == dirNFErr && inCreateDirs)
|
||||
{
|
||||
const char* path = inPathNamePtr;
|
||||
outSpec.vRefNum = 0;
|
||||
outSpec.parID = 0;
|
||||
do {
|
||||
// Locate the colon that terminates the node.
|
||||
// But if we've a partial path (starting with a colon), find the second one.
|
||||
const char* nextColon = strchr(path + (*path == ':'), ':');
|
||||
// Well, if there are no more colons, point to the end of the string.
|
||||
if (!nextColon)
|
||||
nextColon = path + strlen(path);
|
||||
|
||||
// Make a pascal string out of this node. Include initial
|
||||
// and final colon, if any!
|
||||
Str255 ppath;
|
||||
MacFileHelpers::PLstrncpy(ppath, path, nextColon - path + 1);
|
||||
|
||||
// Use this string as a relative path using the directory created
|
||||
// on the previous round (or directory 0,0 on the first round).
|
||||
err = ::FSMakeFSSpec(outSpec.vRefNum, outSpec.parID, ppath, &outSpec);
|
||||
|
||||
// If this was the leaf node, then we are done.
|
||||
if (!*nextColon)
|
||||
break;
|
||||
|
||||
// If we got "file not found", then
|
||||
// we need to create a directory.
|
||||
if (err == fnfErr && *nextColon)
|
||||
err = FSpDirCreate(&outSpec, smCurrentScript, &outSpec.parID);
|
||||
// For some reason, this usually returns fnfErr, even though it works.
|
||||
if (err != noErr && err != fnfErr)
|
||||
return err;
|
||||
path = nextColon; // next round
|
||||
} while (1);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
} // MacFileHelpers::FSSpecFromPathname
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
OSErr MacFileHelpers::CreateFolderInFolder(
|
||||
@@ -320,7 +371,8 @@ OSErr MacFileHelpers::FSSpecFromFullUnixPath(
|
||||
const char * unixPath,
|
||||
FSSpec& outSpec,
|
||||
Boolean resolveAlias,
|
||||
Boolean allowPartial)
|
||||
Boolean allowPartial,
|
||||
Boolean createDirs)
|
||||
// File spec from URL. Reverses GetURLFromFileSpec
|
||||
// Its input is only the <path> part of the URL
|
||||
// JRM 97/01/08 changed this so that if it's a partial path (doesn't start with '/'),
|
||||
@@ -338,7 +390,7 @@ OSErr MacFileHelpers::FSSpecFromFullUnixPath(
|
||||
{
|
||||
NS_ASSERTION(*unixPath == '/' /*full path*/, "Not a full Unix path!");
|
||||
}
|
||||
err = FSSpecFromPathname(macPath, outSpec);
|
||||
err = FSSpecFromPathname(macPath, outSpec, createDirs);
|
||||
if (err == fnfErr)
|
||||
err = noErr;
|
||||
Boolean dummy;
|
||||
@@ -468,11 +520,12 @@ nsNativeFileSpec::nsNativeFileSpec(const nsNativeFileSpec& inSpec)
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec(const char* inString)
|
||||
nsNativeFileSpec::nsNativeFileSpec(const char* inString, bool inCreateDirs)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mError = MacFileHelpers::FSSpecFromFullUnixPath(inString, mSpec, true, true);
|
||||
// allow a partial path
|
||||
mError = MacFileHelpers::FSSpecFromFullUnixPath(
|
||||
inString, mSpec, true, true, inCreateDirs);
|
||||
// allow a partial path, create as necessary
|
||||
if (mError == fnfErr)
|
||||
mError = noErr;
|
||||
} // nsNativeFileSpec::nsNativeFileSpec
|
||||
@@ -537,9 +590,13 @@ bool nsNativeFileSpec::Exists() const
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::SetLeafName(const char* inLeafName)
|
||||
// In leaf name can actually be a partial path...
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
MacFileHelpers::PLstrcpy(mSpec.name, inLeafName, nsFileSpecHelpers::kMaxFilenameLength);
|
||||
// what about long relative paths? Hmm?
|
||||
Str255 partialPath;
|
||||
MacFileHelpers::PLstrcpy(partialPath, inLeafName);
|
||||
mError = FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, partialPath, &mSpec);
|
||||
} // nsNativeFileSpec::SetLeafName
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
@@ -579,10 +636,86 @@ void nsNativeFileSpec::ResolveAlias(bool& wasAliased)
|
||||
wasAliased = (wasAliased2 != false);
|
||||
} // nsNativeFileSpec::ResolveAlias
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::IsFile() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
long dirID;
|
||||
Boolean isDirectory;
|
||||
return (noErr == FSpGetDirectoryID(&mSpec, &dirID, &isDirectory) && !isDirectory);
|
||||
} // nsNativeFileSpec::IsFile
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::IsDirectory() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
long dirID;
|
||||
Boolean isDirectory;
|
||||
return (noErr == FSpGetDirectoryID(&mSpec, &dirID, &isDirectory) && isDirectory);
|
||||
} // nsNativeFileSpec::IsDirectory
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::GetParent(nsNativeFileSpec& outSpec) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (mError == noErr)
|
||||
outSpec.mError = FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, NULL, outSpec);
|
||||
} // nsNativeFileSpec::GetParent
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator += (const char* inRelativePath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
long dirID;
|
||||
Boolean isDirectory;
|
||||
mError = FSpGetDirectoryID(&mSpec, &dirID, &isDirectory);
|
||||
if (mError == noErr && isDirectory)
|
||||
{
|
||||
mError = FSMakeFSSpec(mSpec.vRefNum, dirID, "\pG'day", *this);
|
||||
if (mError == noErr)
|
||||
SetLeafName(inRelativePath);
|
||||
}
|
||||
} // nsNativeFileSpec::operator +=
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::CreateDirectory(int /* unix mode */)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
long ignoredDirID;
|
||||
FSpDirCreate(&mSpec, smCurrentScript, &ignoredDirID);
|
||||
} // nsNativeFileSpec::CreateDirectory
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::Delete(bool inRecursive)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (inRecursive)
|
||||
{
|
||||
// MoreFilesExtras
|
||||
mError = DeleteDirectory(
|
||||
mSpec.vRefNum,
|
||||
mSpec.parID,
|
||||
const_cast<unsigned char*>(mSpec.name));
|
||||
}
|
||||
else
|
||||
mError = FSpDelete(&mSpec);
|
||||
} // nsNativeFileSpec::Delete
|
||||
|
||||
|
||||
//========================================================================================
|
||||
// Macintosh nsFilePath implementation
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFilePath::nsFilePath(const char* inString, bool inCreateDirs)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mPath(nsnull)
|
||||
, mNativeFileSpec(inString, inCreateDirs)
|
||||
{
|
||||
// Make canonical and absolute.
|
||||
char * path = MacFileHelpers::PathNameFromFSSpec( mNativeFileSpec, TRUE );
|
||||
mPath = MacFileHelpers::EncodeMacPath(path, true, true);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFilePath::nsFilePath(const nsNativeFileSpec& inSpec)
|
||||
//----------------------------------------------------------------------------------------
|
||||
@@ -601,3 +734,118 @@ void nsFilePath::operator = (const nsNativeFileSpec& inSpec)
|
||||
mPath = MacFileHelpers::EncodeMacPath(path, true, true);
|
||||
mNativeFileSpec = inSpec;
|
||||
} // nsFilePath::operator =
|
||||
|
||||
//========================================================================================
|
||||
// nsFileURL implementation
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsFileURL::nsFileURL(const char* inString, bool inCreateDirs)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mURL(nsnull)
|
||||
, mNativeFileSpec(inString + kFileURLPrefixLength, inCreateDirs)
|
||||
{
|
||||
NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!");
|
||||
// Make canonical and absolute.
|
||||
char* path = MacFileHelpers::PathNameFromFSSpec( mNativeFileSpec, TRUE );
|
||||
char* escapedPath = MacFileHelpers::EncodeMacPath(path, true, true);
|
||||
mURL = nsFileSpecHelpers::StringDup(kFileURLPrefix, kFileURLPrefixLength + strlen(escapedPath));
|
||||
strcat(mURL, escapedPath);
|
||||
delete [] escapedPath;
|
||||
} // nsFileURL::nsFileURL
|
||||
|
||||
//========================================================================================
|
||||
// nsDirectoryIterator
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator::nsDirectoryIterator(
|
||||
const nsNativeFileSpec& inDirectory
|
||||
, int inIterateDirection)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mCurrent(inDirectory)
|
||||
, mExists(false)
|
||||
, mIndex(-1)
|
||||
{
|
||||
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&();
|
||||
Str255 outName;
|
||||
MacFileHelpers::PLstrcpy(outName, inSpec.name);
|
||||
pb.hFileInfo.ioNamePtr = outName;
|
||||
pb.hFileInfo.ioVRefNum = inSpec.vRefNum;
|
||||
pb.hFileInfo.ioDirID = inSpec.parID;
|
||||
pb.hFileInfo.ioFDirIndex = 0; // use ioNamePtr and ioDirID
|
||||
|
||||
OSErr err = PBGetCatInfoSync( &pb );
|
||||
|
||||
// test that we have got a directory back, not a file
|
||||
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&();
|
||||
currentSpec.vRefNum = inSpec.vRefNum;
|
||||
currentSpec.parID = dipb->ioDrDirID;
|
||||
mMaxIndex = pb.dirInfo.ioDrNmFls;
|
||||
if (inIterateDirection > 0)
|
||||
{
|
||||
mIndex = 0; // ready to increment
|
||||
++(*this); // the pre-increment operator
|
||||
}
|
||||
else
|
||||
{
|
||||
mIndex = mMaxIndex + 1; // ready to decrement
|
||||
--(*this); // the pre-decrement operator
|
||||
}
|
||||
} // nsDirectoryIterator::nsDirectoryIterator
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
OSErr nsDirectoryIterator::SetToIndex()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
CInfoPBRec cipb;
|
||||
DirInfo *dipb=(DirInfo *)&cipb;
|
||||
Str255 objectName;
|
||||
dipb->ioCompletion = NULL;
|
||||
dipb->ioFDirIndex = mIndex;
|
||||
// Sorry about this, there seems to be a bug in CWPro 4:
|
||||
FSSpec& currentSpec = mCurrent.nsNativeFileSpec::operator FSSpec&();
|
||||
dipb->ioVRefNum = currentSpec.vRefNum; /* Might need to use vRefNum, not sure*/
|
||||
dipb->ioDrDirID = currentSpec.parID;
|
||||
dipb->ioNamePtr = objectName;
|
||||
OSErr err = PBGetCatInfoSync(&cipb);
|
||||
if (err == noErr)
|
||||
err = FSMakeFSSpec(currentSpec.vRefNum, currentSpec.parID, objectName, ¤tSpec);
|
||||
mExists = err == noErr;
|
||||
return err;
|
||||
} // nsDirectoryIterator::SetToIndex()
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator& nsDirectoryIterator::operator -- ()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mExists = false;
|
||||
while (--mIndex > 0)
|
||||
{
|
||||
OSErr err = SetToIndex();
|
||||
if (err == noErr)
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
} // nsDirectoryIterator::operator --
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator& nsDirectoryIterator::operator ++ ()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mExists = false;
|
||||
if (mIndex >= 0) // probably trying to use a file as a directory!
|
||||
while (++mIndex <= mMaxIndex)
|
||||
{
|
||||
OSErr err = SetToIndex();
|
||||
if (err == noErr)
|
||||
break;
|
||||
}
|
||||
return *this;
|
||||
} // nsDirectoryIterator::operator ++
|
||||
|
||||
@@ -16,27 +16,205 @@
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
// This file is included by nsFileSpec.cpp, and includes the Unix-specific
|
||||
// implementations.
|
||||
// This file is included by nsFileSpec.cpp, and includes the Unix-specific
|
||||
// implementations.
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/dir.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsFileSpecHelpers::Canonify(char*& ioPath, bool inMakeDirs)
|
||||
// Canonify, make absolute, and check whether directories exist
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!ioPath)
|
||||
return;
|
||||
if (inMakeDirs)
|
||||
{
|
||||
const mode_t mode = 0700;
|
||||
nsFileSpecHelpers::MakeAllDirectories(ioPath, mode);
|
||||
}
|
||||
char buffer[MAXPATHLEN];
|
||||
errno = 0;
|
||||
*buffer = '\0';
|
||||
char* canonicalPath = realpath(ioPath, buffer);
|
||||
if (!canonicalPath)
|
||||
{
|
||||
// Linux's realpath() is pathetically buggy. If the reason for the nil
|
||||
// result is just that the leaf does not exist, strip the leaf off,
|
||||
// process that, and then add the leaf back.
|
||||
char* allButLeaf = nsFileSpecHelpers::StringDup(ioPath);
|
||||
if (!allButLeaf)
|
||||
return;
|
||||
char* lastSeparator = strrchr(allButLeaf, '/');
|
||||
if (lastSeparator)
|
||||
{
|
||||
*lastSeparator = '\0';
|
||||
canonicalPath = realpath(allButLeaf, buffer);
|
||||
strcat(buffer, "/");
|
||||
// Add back the leaf
|
||||
strcat(buffer, ++lastSeparator);
|
||||
}
|
||||
delete [] allButLeaf;
|
||||
}
|
||||
if (!canonicalPath && *ioPath != '/' && !inMakeDirs)
|
||||
{
|
||||
// Well, if it's a relative path, hack it ourselves.
|
||||
canonicalPath = realpath(".", buffer);
|
||||
if (canonicalPath)
|
||||
{
|
||||
strcat(canonicalPath, "/");
|
||||
strcat(canonicalPath, ioPath);
|
||||
}
|
||||
}
|
||||
if (canonicalPath)
|
||||
nsFileSpecHelpers::StringAssign(ioPath, canonicalPath);
|
||||
} // nsFileSpecHelpers::Canonify
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::SetLeafName(const char* inLeafName)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::LeafReplace(mPath, '/', inLeafName);
|
||||
nsFileSpecHelpers::LeafReplace(mPath, '/', inLeafName);
|
||||
} // nsNativeFileSpec::SetLeafName
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
char* nsNativeFileSpec::GetLeafName() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return nsFileSpecHelpers::GetLeaf(mPath, '/');
|
||||
return nsFileSpecHelpers::GetLeaf(mPath, '/');
|
||||
} // nsNativeFileSpec::GetLeafName
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::Exists() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return false; // fixme
|
||||
struct stat st;
|
||||
return 0 == stat(mPath, &st);
|
||||
} // nsNativeFileSpec::Exists
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::IsFile() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
struct stat st;
|
||||
return 0 == stat(mPath, &st) && S_ISREG(st.st_mode);
|
||||
} // nsNativeFileSpec::IsFile
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::IsDirectory() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
struct stat st;
|
||||
return 0 == stat(mPath, &st) && S_ISDIR(st.st_mode);
|
||||
} // nsNativeFileSpec::IsDirectory
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::GetParent(nsNativeFileSpec& outSpec) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::StringAssign(outSpec.mPath, mPath);
|
||||
char* cp = strrchr(outSpec.mPath, '/');
|
||||
if (cp)
|
||||
*cp = '\0';
|
||||
} // nsNativeFileSpec::GetParent
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator += (const char* inRelativePath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!inRelativePath || !mPath)
|
||||
return;
|
||||
|
||||
if (mPath[strlen(mPath) - 1] != '/')
|
||||
char* newPath = nsFileSpecHelpers::ReallocCat(mPath, "/");
|
||||
SetLeafName(inRelativePath);
|
||||
} // nsNativeFileSpec::operator +=
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::CreateDirectory(int mode)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// Note that mPath is canonical!
|
||||
mkdir(mPath, mode);
|
||||
} // nsNativeFileSpec::CreateDirectory
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::Delete(bool inRecursive)
|
||||
// To check if this worked, call Exists() afterwards, see?
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (IsDirectory())
|
||||
{
|
||||
if (inRecursive)
|
||||
{
|
||||
for (nsDirectoryIterator i(*this); i; i++)
|
||||
{
|
||||
nsNativeFileSpec& child = (nsNativeFileSpec&)i;
|
||||
child.Delete(inRecursive);
|
||||
}
|
||||
}
|
||||
rmdir(mPath);
|
||||
}
|
||||
else
|
||||
remove(mPath);
|
||||
} // nsNativeFileSpec::Delete
|
||||
|
||||
//========================================================================================
|
||||
// nsDirectoryIterator
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator::nsDirectoryIterator(
|
||||
const nsNativeFileSpec& inDirectory
|
||||
, int inIterateDirection)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mCurrent(inDirectory)
|
||||
, mDir(nsnull)
|
||||
, mExists(false)
|
||||
{
|
||||
mCurrent += "sysygy"; // prepare the path for SetLeafName
|
||||
mDir = opendir((const char*)nsFilePath(inDirectory));
|
||||
++(*this);
|
||||
} // nsDirectoryIterator::nsDirectoryIterator
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator::~nsDirectoryIterator()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (mDir)
|
||||
closedir(mDir);
|
||||
} // nsDirectoryIterator::nsDirectoryIterator
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator& nsDirectoryIterator::operator ++ ()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mExists = false;
|
||||
if (!mDir)
|
||||
return *this;
|
||||
char* dot = ".";
|
||||
char* dotdot = "..";
|
||||
struct dirent* entry = readdir(mDir);
|
||||
if (entry && strcmp(entry->d_name, dot) == 0)
|
||||
entry = readdir(mDir);
|
||||
if (entry && strcmp(entry->d_name, dotdot) == 0)
|
||||
entry = readdir(mDir);
|
||||
if (entry)
|
||||
{
|
||||
mExists = true;
|
||||
mCurrent.SetLeafName(entry->d_name);
|
||||
}
|
||||
return *this;
|
||||
} // nsDirectoryIterator::operator ++
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator& nsDirectoryIterator::operator -- ()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return ++(*this); // can't do it backwards.
|
||||
} // nsDirectoryIterator::operator --
|
||||
|
||||
@@ -19,6 +19,17 @@
|
||||
// This file is included by nsFileSpec.cp, and includes the Windows-specific
|
||||
// implementations.
|
||||
|
||||
#include <stat.h>
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsFileSpecHelpers::Canonify(char*& ioPath, bool inMakeDirs)
|
||||
// Canonify, make absolute, and check whether directories exist
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("Please, some Winhead please write this!");
|
||||
return ioPath;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsNativeFileSpec::nsNativeFileSpec(const nsFilePath& inPath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
@@ -31,9 +42,17 @@ nsNativeFileSpec::nsNativeFileSpec(const nsFilePath& inPath)
|
||||
void nsNativeFileSpec::operator = (const nsFilePath& inPath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// Convert '/' to '\'
|
||||
nsFileSpecHelpers::StringAssign(mPath, (const char*)inPath);
|
||||
for (char* cp = mPath; *cp; cp++)
|
||||
// Strip the leading slash, which should
|
||||
// leave us pointing to a drive letter.
|
||||
nsFileSpecHelpers::StringAssign(mPath, (const char*)inPath + 1);
|
||||
|
||||
// Convert the vertical slash to a colon
|
||||
char* cp = mPath + 1;
|
||||
if (strstr(cp, "|/") == cp)
|
||||
*cp = ':';
|
||||
|
||||
// Convert '/' to '\'.
|
||||
while (*++cp)
|
||||
{
|
||||
if (*cp == '/')
|
||||
*cp = '\\';
|
||||
@@ -79,6 +98,138 @@ char* nsNativeFileSpec::GetLeafName() const
|
||||
bool nsNativeFileSpec::Exists() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return false; // fixme
|
||||
struct stat st;
|
||||
return 0 == stat(mPath, &st);
|
||||
} // nsNativeFileSpec::Exists
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::IsFile() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
struct stat st;
|
||||
return 0 == stat(mPath, &st) && S_ISREG(st.st_mode);
|
||||
} // nsNativeFileSpec::IsFile
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
bool nsNativeFileSpec::IsDirectory() const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
struct stat st;
|
||||
return 0 == stat(mPath, &st) && S_ISDIR(st.st_mode);
|
||||
} // nsNativeFileSpec::IsDirectory
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::GetParent(nsNativeFileSpec& outSpec) const
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
nsFileSpecHelpers::StringAssign(outSpec.mPath, mPath);
|
||||
char* cp = strrchr(outSpec.mPath, '\\');
|
||||
if (cp)
|
||||
*cp = '\0';
|
||||
} // nsNativeFileSpec::GetParent
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::operator += (const char* inRelativePath)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (!inRelativePath || !mPath)
|
||||
return;
|
||||
|
||||
if (mPath[strlen(mPath) - 1] != '\\')
|
||||
char* newPath = nsFileSpecHelpers::ReallocCat(mPath, "\\");
|
||||
SetLeafName(inRelativePath);
|
||||
} // nsNativeFileSpec::operator +=
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::CreateDirectory()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// Note that mPath is canonical!
|
||||
NS_NOTYETIMPLEMENTED("Please, some Winhead please fix this!");
|
||||
mkdir(mPath, mode);
|
||||
} // nsNativeFileSpec::CreateDirectory
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void nsNativeFileSpec::Delete(bool inRecursive)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
if (IsDirectory())
|
||||
{
|
||||
if (inRecursive)
|
||||
{
|
||||
for (nsDirectoryIterator i(*this); i; i++)
|
||||
{
|
||||
const nsNativeFileSpec& child = (nsNativeFileSpec&)i;
|
||||
child.Delete(inRecursive);
|
||||
}
|
||||
}
|
||||
NS_NOTYETIMPLEMENTED("Please, some Winhead please fix this!");
|
||||
rmdir(mPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("Please, some Winhead please write this!");
|
||||
remove(mPath);
|
||||
}
|
||||
} // nsNativeFileSpec::Delete
|
||||
|
||||
//========================================================================================
|
||||
// nsDirectoryIterator
|
||||
//========================================================================================
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator::nsDirectoryIterator(
|
||||
const nsNativeFileSpec& inDirectory
|
||||
, int inIterateDirection)
|
||||
//----------------------------------------------------------------------------------------
|
||||
: mCurrent(inDirectory)
|
||||
#if 0 // Some kind winhead please build, test, and remove when ready.
|
||||
, mDir(nsnull)
|
||||
#endif // XP_PC -- ifdef to be removed.
|
||||
, mExists(false)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("Please, some kind Winhead please check this!");
|
||||
mCurrent += "foo";
|
||||
#if 0 // Some kind winhead please build, test, and remove when ready.
|
||||
mDir = opendir(mPath);
|
||||
#endif // XP_PC -- ifdef to be removed.
|
||||
++(*this);
|
||||
} // nsDirectoryIterator::nsDirectoryIterator
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator::~nsDirectoryIterator()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("Please, some kind Winhead please check this!");
|
||||
#if 0 // Some kind winhead please build, test, and remove when ready.
|
||||
if (mDir)
|
||||
closedir(mDir);
|
||||
#endif // XP_PC -- ifdef to be removed.
|
||||
} // nsDirectoryIterator::nsDirectoryIterator
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator& nsDirectoryIterator::operator ++ ()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
mExists = false;
|
||||
NS_NOTYETIMPLEMENTED("Please, some kind Winhead please check this!");
|
||||
#if 0 // Some kind winhead please build, test, and remove when ready.
|
||||
if (!mDir)
|
||||
return *this;
|
||||
struct dirent* entry = readdir(mDir);
|
||||
if (entry)
|
||||
{
|
||||
mExists = true;
|
||||
mCurrent.SetLeafName(entry->d_name);
|
||||
}
|
||||
#endif // XP_PC -- ifdef to be removed.
|
||||
return *this;
|
||||
} // nsDirectoryIterator::operator ++
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
nsDirectoryIterator& nsDirectoryIterator::operator -- ()
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
return ++(*this); // can't do it backwards.
|
||||
} // nsDirectoryIterator::operator --
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ void FilesTest::WriteStuff(nsOutputFileStream& s)
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
// Initialize a URL from a string without suffix. Change the path to suit your machine.
|
||||
nsFileURL fileURL("file:///Development/MPW/MPW%20Shell");
|
||||
nsFileURL fileURL("file:///Development/MPW/MPW%20Shell", false);
|
||||
s << "File URL initialized to: \"" << fileURL << "\""<< nsEndl;
|
||||
|
||||
// Initialize a Unix path from a URL
|
||||
@@ -44,7 +44,7 @@ void FilesTest::WriteStuff(nsOutputFileStream& s)
|
||||
} // WriteStuff
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
void main()
|
||||
int main()
|
||||
// For use with DEBUG defined.
|
||||
//----------------------------------------------------------------------------------------
|
||||
{
|
||||
@@ -59,38 +59,59 @@ void main()
|
||||
FilesTest::WriteStuff(nsOut);
|
||||
nsOut << nsEndl << nsEndl;
|
||||
|
||||
// Test of nsOutputFileStream
|
||||
|
||||
nsFilePath myTextFilePath("iotest.txt");
|
||||
// - Test of nsOutputFileStream
|
||||
|
||||
nsFilePath myTextFilePath("mumble/iotest.txt", true); // relative path.
|
||||
const char* pathAsString = (const char*)myTextFilePath;
|
||||
if (*pathAsString != '/')
|
||||
{
|
||||
nsOut << "WRITING IDENTICAL OUTPUT TO " << (const char*)myTextFilePath << nsEndl << nsEndl;
|
||||
nsOut
|
||||
<< "ERROR: after initializing the path object with a relative path,"
|
||||
<< "\n the path consisted of the string "
|
||||
<< "\n\t" << pathAsString
|
||||
<< "\n which is not a canonical full path!"
|
||||
<< nsEndl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
nsNativeFileSpec mySpec(myTextFilePath);
|
||||
{
|
||||
nsOut << "WRITING IDENTICAL OUTPUT TO " << pathAsString << nsEndl << nsEndl;
|
||||
nsOutputFileStream testStream(myTextFilePath);
|
||||
if (!testStream.is_open())
|
||||
{
|
||||
nsOut
|
||||
<< "ERROR: File "
|
||||
<< (const char*)myTextFilePath
|
||||
<< pathAsString
|
||||
<< " could not be opened for output"
|
||||
<< nsEndl;
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
FilesTest::WriteStuff(testStream);
|
||||
} // <-- Scope closes the stream (and the file).
|
||||
|
||||
// Test of nsInputFileStream
|
||||
if (!mySpec.Exists() || mySpec.IsDirectory() || !mySpec.IsFile())
|
||||
{
|
||||
nsOut
|
||||
<< "ERROR: File "
|
||||
<< pathAsString
|
||||
<< " is not a file (cela n'est pas un pipe)"
|
||||
<< nsEndl;
|
||||
return -1;
|
||||
}
|
||||
// - Test of nsInputFileStream
|
||||
|
||||
{
|
||||
nsOut << "READING BACK DATA FROM " << (const char*)myTextFilePath << nsEndl << nsEndl;
|
||||
nsOut << "READING BACK DATA FROM " << pathAsString << nsEndl << nsEndl;
|
||||
nsInputFileStream testStream2(myTextFilePath);
|
||||
if (!testStream2.is_open())
|
||||
{
|
||||
nsOut
|
||||
<< "ERROR: File "
|
||||
<< (const char*)myTextFilePath
|
||||
<< pathAsString
|
||||
<< " could not be opened for input"
|
||||
<< nsEndl;
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
char line[1000];
|
||||
|
||||
@@ -101,4 +122,101 @@ void main()
|
||||
nsOut << line << nsEndl;
|
||||
}
|
||||
} // <-- Scope closes the stream (and the file).
|
||||
|
||||
// - Test of GetParent()
|
||||
|
||||
nsNativeFileSpec parent;
|
||||
mySpec.GetParent(parent);
|
||||
nsFilePath parentPath(parent);
|
||||
nsOut
|
||||
<< "GetParent() on "
|
||||
<< "\n\t" << pathAsString
|
||||
<< "\n yields "
|
||||
<< "\n\t" << (const char*)parentPath
|
||||
<< nsEndl;
|
||||
|
||||
// - Test of non-recursive delete
|
||||
|
||||
nsOut
|
||||
<< "Attempting to delete "
|
||||
<< "\n\t" << (const char*)parentPath
|
||||
<< "\n without recursive option (should fail)"
|
||||
<< nsEndl;
|
||||
parent.Delete(false);
|
||||
if (parent.Exists())
|
||||
nsOut << "Test passed." << nsEndl;
|
||||
else
|
||||
{
|
||||
nsOut
|
||||
<< "ERROR: File "
|
||||
<< "\n\t" << (const char*)parentPath
|
||||
<< "\n has been deleted without the recursion option,"
|
||||
<< "\n and is a nonempty directory!"
|
||||
<< nsEndl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// - Test of recursive delete
|
||||
|
||||
nsOut
|
||||
<< "Deleting "
|
||||
<< "\n\t" << (const char*)parentPath
|
||||
<< "\n with recursive option"
|
||||
<< nsEndl;
|
||||
parent.Delete(true);
|
||||
if (parent.Exists())
|
||||
{
|
||||
nsOut
|
||||
<< "ERROR: Directory "
|
||||
<< "\n\t" << (const char*)parentPath
|
||||
<< "\n has NOT been deleted despite the recursion option!"
|
||||
<< nsEndl;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
nsOut << "Test passed." << nsEndl;
|
||||
|
||||
// - Test of CreateDirectory
|
||||
|
||||
nsOut
|
||||
<< "Testing CreateDirectory() using"
|
||||
<< "\n\t" << (const char*)parentPath
|
||||
<< nsEndl;
|
||||
|
||||
parent.CreateDirectory();
|
||||
if (parent.Exists())
|
||||
nsOut << "Test passed." << nsEndl;
|
||||
else
|
||||
{
|
||||
nsOut << "ERROR: Test failed." << nsEndl;
|
||||
return -1;
|
||||
}
|
||||
parent.Delete(true);
|
||||
|
||||
#ifndef XP_PC // uncomment when tested and ready.
|
||||
|
||||
// - Test of directory iterator
|
||||
|
||||
nsNativeFileSpec grandparent;
|
||||
parent.GetParent(grandparent); // should be the original default directory.
|
||||
nsFilePath grandparentPath(grandparent);
|
||||
|
||||
nsOut << "Forwards listing of " << (const char*)grandparentPath << ":" << nsEndl;
|
||||
for (nsDirectoryIterator i(grandparent, +1); i; i++)
|
||||
{
|
||||
char* itemName = ((nsNativeFileSpec&)i).GetLeafName();
|
||||
nsOut << '\t' << itemName << nsEndl;
|
||||
delete [] itemName;
|
||||
}
|
||||
|
||||
nsOut << "Backwards listing of " << (const char*)grandparentPath << ":" << nsEndl;
|
||||
for (nsDirectoryIterator i(grandparent, -1); i; i--)
|
||||
{
|
||||
char* itemName = ((nsNativeFileSpec&)i).GetLeafName();
|
||||
nsOut << '\t' << itemName << nsEndl;
|
||||
delete [] itemName;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
} // main
|
||||
|
||||
Reference in New Issue
Block a user