diff options
Diffstat (limited to 'src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecMac.cpp')
-rw-r--r-- | src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecMac.cpp | 1471 |
1 files changed, 1471 insertions, 0 deletions
diff --git a/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecMac.cpp b/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecMac.cpp new file mode 100644 index 00000000..fd208fb7 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/obsolete/nsFileSpecMac.cpp @@ -0,0 +1,1471 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// This file is included by nsFile.cp, and includes the Macintosh-specific +// implementations. + + +#include <string.h> + +#include "prtypes.h" +#include "nscore.h" + +#include "FullPath.h" +#include "FileCopy.h" +#include "MoreFilesExtras.h" + +#include <Aliases.h> +#include <Folders.h> +#include <Math64.h> +#include <TextUtils.h> +#include <Processes.h> +#include <limits.h> // ULONG_MAX + +#include "nsFileSpec.h" +#include "nsEscape.h" +#include "nsXPIDLString.h" + + +const unsigned char* kAliasHavenFolderName = "\pnsAliasHaven"; + +//======================================================================================== +namespace MacFileHelpers +//======================================================================================== +{ + inline void PLstrcpy(Str255 dst, ConstStr255Param src) + { + memcpy(dst, src, 1 + src[0]); + } + + void PLstrcpy(Str255 dst, const char* src, int inMaxLen=255); + void PLstrncpy(Str255 dst, const char* src, int inMaxLen); + + void SwapSlashColon(char * s); + OSErr FSSpecFromUnixPath( + const char * unixPath, + FSSpec& ioSpec, + Boolean hexDecode, + Boolean resolveAlias, + Boolean allowPartial = false, + Boolean createDirs = false); + char* MacPathFromUnixPath( + const char* unixPath, + Boolean hexDecode); + char* EncodeMacPath( + char* inPath, // NOT const - gets clobbered + Boolean prependSlash, + Boolean doEscape ); + OSErr FSSpecFromPathname( + const char* inPathNamePtr, + FSSpec& ioSpec, + Boolean inCreateDirs); + char* PathNameFromFSSpec( + const FSSpec& inSpec ); + OSErr CreateFolderInFolder( + short refNum, // Parent directory/volume + long dirID, + ConstStr255Param folderName, // Name of the new folder + short& outRefNum, // Volume of the created folder + long& outDirID); // + + // Some routines to support an "alias haven" directory. Aliases in this directory + // are never resolved. There is a ResolveAlias here that respects that. This is + // to support attaching of aliases in mail. + void EnsureAliasHaven(); + void SetNoResolve(Boolean inResolve); + PRBool IsAliasSafe(const FSSpec& inSpec); + OSErr MakeAliasSafe(FSSpec& inOutSpec); + OSErr ResolveAliasFile(FSSpec& inOutSpec, Boolean& wasAliased); + + Boolean sNoResolve = false; + long sAliasHavenDirID = 0; + short sAliasHavenVRefNum = 0; +} // namespace MacFileHelpers + +//---------------------------------------------------------------------------------------- +void MacFileHelpers::PLstrcpy(Str255 dst, const char* src, int inMax) +//---------------------------------------------------------------------------------------- +{ + int srcLength = strlen(src); + NS_ASSERTION(srcLength <= inMax, "Oops, string is too long!"); + if (srcLength > inMax) + srcLength = inMax; + dst[0] = srcLength; + memcpy(&dst[1], src, srcLength); +} + +//---------------------------------------------------------------------------------------- +void MacFileHelpers::PLstrncpy(Str255 dst, const char* src, int inMax) +//---------------------------------------------------------------------------------------- +{ + int srcLength = strlen(src); + if (srcLength > inMax) + srcLength = inMax; + dst[0] = srcLength; + memcpy(&dst[1], src, srcLength); +} + +//----------------------------------- +void MacFileHelpers::SwapSlashColon(char * s) +//----------------------------------- + +{ + while (*s) + { + if (*s == '/') + *s++ = ':'; + else if (*s == ':') + *s++ = '/'; + else + *s++; + } +} // MacFileHelpers::SwapSlashColon + +//----------------------------------- +char* MacFileHelpers::EncodeMacPath( + char* inPath, // NOT const, gets clobbered + Boolean prependSlash, + Boolean doEscape ) +// Transforms Macintosh style path into Unix one +// Method: Swap ':' and '/', hex escape the result +//----------------------------------- +{ + if (inPath == nsnull) + return nsnull; + int pathSize = strlen(inPath); + + // XP code sometimes chokes if there's a final slash in the unix path. + // Since correct mac paths to folders and volumes will end in ':', strip this + // first. + char* c = inPath + pathSize - 1; + if (*c == ':') + { + *c = 0; + pathSize--; + } + + char * newPath = nsnull; + char * finalPath = nsnull; + + if (prependSlash) + { + newPath = new char[pathSize + 2]; + newPath[0] = ':'; // It will be converted to '/' + memcpy(&newPath[1], inPath, pathSize + 1); + } + else + { + newPath = new char[pathSize + 1]; + strcpy(newPath, inPath); + } + if (newPath) + { + SwapSlashColon( newPath ); + if (doEscape) + { + finalPath = nsEscape(newPath, url_Path); + delete [] newPath; + } + else + finalPath = newPath; + } + delete [] inPath; + return finalPath; +} // MacFileHelpers::EncodeMacPath + +//---------------------------------------------------------------------------------------- +inline void MacFileHelpers::SetNoResolve(Boolean inResolve) +//---------------------------------------------------------------------------------------- +{ + sNoResolve = inResolve; +} // MacFileHelpers::SetNoResolve + +//---------------------------------------------------------------------------------------- +OSErr MacFileHelpers::MakeAliasSafe(FSSpec& inOutSpec) +// Pass in the spec of an alias. This copies the file to the safe haven folder, and +// returns the spec of the copy to the caller +//---------------------------------------------------------------------------------------- +{ + EnsureAliasHaven(); + nsFileSpec dstDirSpec(sAliasHavenVRefNum, sAliasHavenDirID, "\p"); + + // Make sure its name is unique + nsFileSpec havenSpec(sAliasHavenVRefNum, sAliasHavenDirID, "\pG'day"); + if (havenSpec.Valid()) + havenSpec.MakeUnique(inOutSpec.name); + // Copy the file into the haven directory + if (havenSpec.Valid()) + { + OSErr err = ::FSpFileCopy( + &inOutSpec, + dstDirSpec, + havenSpec.GetLeafPName(), + nil, 0, true); + // Return the spec of the copy to the caller. + if (err != noErr) + return err; + inOutSpec = havenSpec; + } + return noErr; +} // MacFileHelpers::MakeAliasSafe + +//---------------------------------------------------------------------------------------- +char* MacFileHelpers::MacPathFromUnixPath(const char* unixPath, Boolean hexDecode) +//---------------------------------------------------------------------------------------- +{ + // Relying on the fact that the unix path is always longer than the mac path: + size_t len = strlen(unixPath); + char* result = new char[len + 2]; // ... but allow for the initial colon in a partial name + // REMEMBER: at the end we call SwapSlashColon, so bear that in mind when you see + // this code using '/' as a separator in what is supposed to be a Macintosh path! + if (result) + { + char* dst = result; + const char* src = unixPath; + if (*src == '/') // * full path + src++; + else if (strchr(src, '/') && *src != '.') + { + // * partial path, and not just a leaf name. The '.' test is there because + // the loop below will add sufficient colons in that case. + *dst++ = '/'; + } + // Copy src to dst, but watch out for .. and . + char c = '/'; + do + { + char cprev = c; // remember the previous char (initially /) + c = *src++; + if (c == '.' && cprev == '/') + { + char* dstSaved = dst; + // Special cases: "." and "..". Convert to ':' and '::' + *dst++ = '/'; // . becomes : + c = *src++; + if (c == '.') + { + *dst++ = '/'; // .. becomes :: + c = *src++; + } + if (c == '/') + { + // ../ becomes :: so just skip the slash + // ./ becomes : " " " " " + src++; + } + else if (c) + { + // Oh. A file called ".foo" or "..foo" + // Back up and just do the normal thing. + src -= (dst - dstSaved); + dst = dstSaved; + // Since c is not '/', we won't do this stuff on the + // next iteration. + } + continue; + } + else if (c == '/' && cprev == '/') + { + // Hmm. A 'run on' path with two slashes right next to each other. + // This is an illegal path, but, hey, we'll be tough and try to + // deal with it (especially since '::' has loaded semantics in + // a Mac path) + continue; + } + *dst++ = c; + } while (c); + if (hexDecode) + nsUnescape(result); // Hex Decode + MacFileHelpers::SwapSlashColon(result); + } + return result; +} // MacFileHelpers::MacPathFromUnixPath + +//---------------------------------------------------------------------------------------- +OSErr MacFileHelpers::FSSpecFromPathname( + const char* inPathNamePtr, + FSSpec& ioSpec, // used as in-parameter for a relative path. + Boolean inCreateDirs) +// FSSpecFromPathname reverses PathNameFromFSSpec. +// It returns a FSSpec given a c string which is a mac pathname. +//---------------------------------------------------------------------------------------- +{ + OSErr err; + // Simplify this routine to use FSMakeFSSpec if length < 255. Otherwise use the MoreFiles + // routine FSpLocationFromFullPath, which allocates memory, to handle longer pathnames. + + short inVRefNum = ioSpec.vRefNum; + long inParID = ioSpec.parID; + + size_t inLength = strlen(inPathNamePtr); + bool isRelative = (strchr(inPathNamePtr, ':') == 0 || *inPathNamePtr == ':'); +#ifdef NS_DEBUG + // Attempt to catch people sending unix paths in to routines that expect native ones. + NS_ASSERTION(strchr(inPathNamePtr, '/') == 0, + "Possible unix path where native path is required"); +#endif + if (inLength < 255) + { + Str255 pascalpath; + MacFileHelpers::PLstrcpy(pascalpath, inPathNamePtr); + if (isRelative) + err = ::FSMakeFSSpec(inVRefNum, inParID, pascalpath, &ioSpec); + else + err = ::FSMakeFSSpec(0, 0, pascalpath, &ioSpec); + } + else if (!isRelative) + err = FSpLocationFromFullPath(inLength, inPathNamePtr, &ioSpec); + else + err = bdNamErr; + + if ((err == dirNFErr || err == bdNamErr) && inCreateDirs) + { + const char* path = inPathNamePtr; + if (isRelative) + { + ioSpec.vRefNum = inVRefNum; + ioSpec.parID = inParID; + } + else + { + ioSpec.vRefNum = 0; + ioSpec.parID = 0; + } + do { + // Locate the colon that terminates the node. + // But if we've a partial path (starting with a colon), find the second one. + const char* nextColon = strchr(path + (*path == ':'), ':'); + // Well, if there are no more colons, point to the end of the string. + if (!nextColon) + nextColon = path + strlen(path); + + // Make a pascal string out of this node. Include initial + // and final colon, if any! + Str255 ppath; + MacFileHelpers::PLstrncpy(ppath, path, nextColon - path + 1); + + // Use this string as a relative path using the directory created + // on the previous round (or directory 0,0 on the first round). + err = ::FSMakeFSSpec(ioSpec.vRefNum, ioSpec.parID, ppath, &ioSpec); + + // If this was the leaf node, then we are done. + if (!*nextColon) + break; + + // Since there's more to go, we have to get the directory ID, which becomes + // the parID for the next round. + if (err == noErr) + { + // The directory (or perhaps a file) exists. Find its dirID. + long dirID; + Boolean isDirectory; + err = ::FSpGetDirectoryID(&ioSpec, &dirID, &isDirectory); + if (!isDirectory) + return dupFNErr; // oops! a file exists with that name. + if (err) + return err; + ioSpec.parID = dirID; + } + else if (err == fnfErr) + { + // If we got "file not found", then + // we need to create a directory. + err = ::FSpDirCreate(&ioSpec, smCurrentScript, &ioSpec.parID); + // For some reason, this usually returns fnfErr, even though it works. + if (err == fnfErr) + err = noErr; + } + if (err != noErr) + return err; + path = nextColon; // next round + } while (1); + } + return err; +} // MacFileHelpers::FSSpecFromPathname + +//---------------------------------------------------------------------------------------- +OSErr MacFileHelpers::CreateFolderInFolder( + short refNum, // Parent directory/volume + long dirID, + ConstStr255Param folderName, // Name of the new folder + short& outRefNum, // Volume of the created folder + long& outDirID) // +// Creates a folder named 'folderName' inside a folder. +// The errors returned are same as PBDirCreate +//---------------------------------------------------------------------------------------- +{ + HFileParam hpb; + hpb.ioVRefNum = refNum; + hpb.ioDirID = dirID; + hpb.ioNamePtr = (StringPtr)&folderName; + + OSErr err = PBDirCreateSync((HParmBlkPtr)&hpb); + if (err == noErr) + { + outRefNum = hpb.ioVRefNum; + outDirID = hpb.ioDirID; + } + else + { + outRefNum = 0; + outDirID = 0; + } + return err; +} // MacFileHelpers::CreateFolderInFolder + +//---------------------------------------------------------------------------------------- +void MacFileHelpers::EnsureAliasHaven() +//---------------------------------------------------------------------------------------- +{ + // Alias Haven is a directory in which we never resolve aliases. + if (sAliasHavenVRefNum != 0) + return; + + + FSSpec temp; + if (FindFolder(0, kTemporaryFolderType, true, & temp.vRefNum, &temp.parID) == noErr) + { + CreateFolderInFolder( + temp.vRefNum, // Parent directory/volume + temp.parID, + kAliasHavenFolderName, // Name of the new folder + sAliasHavenVRefNum, // Volume of the created folder + sAliasHavenDirID); + } +} // MacFileHelpers::EnsureAliasHaven + +//---------------------------------------------------------------------------------------- +PRBool MacFileHelpers::IsAliasSafe(const FSSpec& inSpec) +// Returns true if the alias is in the alias haven directory, or if alias resolution +// has been turned off. +//---------------------------------------------------------------------------------------- +{ + return sNoResolve + || (inSpec.parID == sAliasHavenDirID && inSpec.vRefNum == sAliasHavenVRefNum); +} // MacFileHelpers::IsAliasSafe + +//---------------------------------------------------------------------------------------- +OSErr MacFileHelpers::ResolveAliasFile(FSSpec& inOutSpec, Boolean& wasAliased) +//---------------------------------------------------------------------------------------- +{ + wasAliased = false; + if (IsAliasSafe(inOutSpec)) + return noErr; + Boolean dummy; + return ::ResolveAliasFile(&inOutSpec, TRUE, &dummy, &wasAliased); +} // MacFileHelpers::ResolveAliasFile + +//----------------------------------- +OSErr MacFileHelpers::FSSpecFromUnixPath( + const char * unixPath, + FSSpec& ioSpec, + Boolean hexDecode, + Boolean resolveAlias, + Boolean allowPartial, + Boolean createDirs) +// File spec from URL. Reverses GetURLFromFileSpec +// Its input is only the <path> part of the URL +// JRM 97/01/08 changed this so that if it's a partial path (doesn't start with '/'), +// then it is combined with inOutSpec's vRefNum and parID to form a new spec. +//----------------------------------- +{ + if (unixPath == nsnull) + return badFidErr; + char* macPath = MacPathFromUnixPath(unixPath, hexDecode); + if (!macPath) + return memFullErr; + + OSErr err = noErr; + if (!allowPartial) + { + NS_ASSERTION(*unixPath == '/' /*full path*/, "Not a full Unix path!"); + } + err = FSSpecFromPathname(macPath, ioSpec, createDirs); + if (err == fnfErr) + err = noErr; + Boolean dummy; + if (err == noErr && resolveAlias) // Added + err = MacFileHelpers::ResolveAliasFile(ioSpec, dummy); + delete [] macPath; + NS_ASSERTION(err==noErr||err==fnfErr||err==dirNFErr||err==nsvErr, "Not a path!"); + return err; +} // MacFileHelpers::FSSpecFromLocalUnixPath + +//----------------------------------- +char* MacFileHelpers::PathNameFromFSSpec( const FSSpec& inSpec ) +// Returns a full pathname to the given file +// Returned value is allocated with new [], and must be freed with delete [] +// For consistency and to work under OS X this creates an nsILocalFileMac and has it do the work. +//----------------------------------- +{ + char* result = nil; + nsresult rv; + + FSSpec nonConstSpec = inSpec; + nsCAutoString path; + nsCOMPtr<nsILocalFileMac> macFile; + + rv = NS_NewLocalFileWithFSSpec(&nonConstSpec, PR_TRUE, getter_AddRefs(macFile)); + if (NS_FAILED(rv)) return nsnull; + nsCOMPtr<nsILocalFile> localFile(do_QueryInterface(macFile, &rv)); + if (NS_FAILED(rv)) return nsnull; + rv = localFile->GetNativePath(path); + if (NS_FAILED(rv)) return nsnull; + PRInt32 strLen = path.Length(); + result = new char [strLen + 1]; + if (!result) return nsnull; + memcpy(result, path.get(), strLen); + result[ strLen ] = 0; + + return result; +} // MacFileHelpers::PathNameFromFSSpec + + +#pragma mark - + +//======================================================================================== +// Macintosh nsFileSpec implementation +//======================================================================================== + +//---------------------------------------------------------------------------------------- +nsFileSpec::nsFileSpec() +//---------------------------------------------------------------------------------------- +{ +// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!"); + Clear(); +} + +//---------------------------------------------------------------------------------------- +nsFileSpec::nsFileSpec(const FSSpec& inSpec, PRBool resolveAlias) +//---------------------------------------------------------------------------------------- +: mSpec(inSpec) +, mError(NS_OK) +{ +// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!"); + if (resolveAlias) + { + PRBool dummy; + ResolveSymlink(dummy); + } +} + +//---------------------------------------------------------------------------------------- +void nsFileSpec::operator = (const FSSpec& inSpec) +//---------------------------------------------------------------------------------------- +{ + mSpec = inSpec; + mError = NS_OK; +} + +//---------------------------------------------------------------------------------------- +nsFileSpec::nsFileSpec(const nsFileSpec& inSpec) +//---------------------------------------------------------------------------------------- +: mSpec(inSpec.mSpec) +, mError(inSpec.Error()) +{ +// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!"); +} + +//---------------------------------------------------------------------------------------- +nsFileSpec::nsFileSpec(const char* inNativePathString, PRBool inCreateDirs) +//---------------------------------------------------------------------------------------- +{ +// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!"); + Clear(); // this sets mError to NS_ERROR_NOT_INITIALIZED + + if (inNativePathString) + { + mError = NS_FILE_RESULT(MacFileHelpers::FSSpecFromPathname( + inNativePathString, mSpec, inCreateDirs)); + if (mError == NS_FILE_RESULT(fnfErr)) + mError = NS_OK; + } + +} // nsFileSpec::nsFileSpec + +//---------------------------------------------------------------------------------------- +nsFileSpec::nsFileSpec(const nsString& inNativePathString, PRBool inCreateDirs) +//---------------------------------------------------------------------------------------- +{ +// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!"); + Clear(); // this sets mError to NS_ERROR_NOT_INITIALIZED + + mError = NS_FILE_RESULT( + MacFileHelpers::FSSpecFromPathname( + NS_LossyConvertUCS2toASCII(inNativePathString).get(), + mSpec, inCreateDirs)); + if (mError == NS_FILE_RESULT(fnfErr)) + mError = NS_OK; + +} // nsFileSpec::nsFileSpec + +//---------------------------------------------------------------------------------------- +nsFileSpec::nsFileSpec(short vRefNum, long parID, ConstStr255Param fileName, PRBool resolveAlias) +//---------------------------------------------------------------------------------------- +{ +// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!"); + mError = NS_FILE_RESULT(::FSMakeFSSpec(vRefNum, parID, fileName, &mSpec)); + if (mError == NS_FILE_RESULT(fnfErr)) + mError = NS_OK; + + if (resolveAlias) + { + PRBool dummy; + ResolveSymlink(dummy); + } +} + +//---------------------------------------------------------------------------------------- +nsFileSpec::nsFileSpec(const nsFilePath& inPath) +//---------------------------------------------------------------------------------------- +{ +// NS_ASSERTION(0, "nsFileSpec is unsupported - use nsIFile!"); + *this = inPath.GetFileSpec(); +} + +//---------------------------------------------------------------------------------------- +void nsFileSpec::operator = (const char* inString) +//---------------------------------------------------------------------------------------- +{ + Clear(); // this sets mError to NS_ERROR_NOT_INITIALIZED + + if (inString) + { + mError = NS_FILE_RESULT(MacFileHelpers::FSSpecFromPathname(inString, mSpec, true)); + if (mError == NS_FILE_RESULT(fnfErr)) + mError = NS_OK; + } + +} // nsFileSpec::operator = + +//---------------------------------------------------------------------------------------- +void nsFileSpec::operator = (const nsFileSpec& inSpec) +//---------------------------------------------------------------------------------------- +{ + mPath.SetToEmpty(); + mSpec.vRefNum = inSpec.mSpec.vRefNum; + mSpec.parID = inSpec.mSpec.parID; + + PRInt32 copySize = inSpec.mSpec.name[0] + 1; + if (copySize > sizeof(inSpec.mSpec.name)) + copySize = sizeof(inSpec.mSpec.name); + memcpy(mSpec.name, inSpec.mSpec.name, copySize); + mError = inSpec.Error(); // note that the error is propagated +} // nsFileSpec::operator = + +//---------------------------------------------------------------------------------------- +void nsFileSpec::operator = (const nsFilePath& inPath) +//---------------------------------------------------------------------------------------- +{ + *this = inPath.GetFileSpec(); +} // nsFileSpec::operator = + +//---------------------------------------------------------------------------------------- +inline void nsFileSpec::Clear() +//---------------------------------------------------------------------------------------- +{ + mPath.SetToEmpty(); + mSpec.vRefNum = 0; + mSpec.parID = 0; + mSpec.name[0] = 0; + mError = NS_ERROR_NOT_INITIALIZED; +} + +//---------------------------------------------------------------------------------------- +PRBool nsFileSpec::Exists() const +//---------------------------------------------------------------------------------------- +{ + if (NS_FAILED(mError)) return PR_FALSE; + FSSpec temp; + return ::FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, mSpec.name, &temp) == noErr; +} // nsFileSpec::Exists() + +//---------------------------------------------------------------------------------------- +void nsFileSpec::GetModDate(TimeStamp& outStamp) const +//---------------------------------------------------------------------------------------- +{ + CInfoPBRec pb; + if (GetCatInfo(pb) == noErr) + outStamp = ((DirInfo*)&pb)->ioDrMdDat; // The mod date is in the same spot for files and dirs. + else + outStamp = 0; +} // nsFileSpec::GetModDate + +//---------------------------------------------------------------------------------------- +PRUint32 nsFileSpec::GetFileSize() const +//---------------------------------------------------------------------------------------- +{ + CInfoPBRec pb; + if (noErr == GetCatInfo(pb)) + return (PRUint32)((HFileInfo*)&pb)->ioFlLgLen; + return 0; +} // nsFileSpec::GetFileSize + +//---------------------------------------------------------------------------------------- +void nsFileSpec::SetLeafName(const char* inLeafName) +// In leaf name can actually be a partial path... +//---------------------------------------------------------------------------------------- +{ + NS_ASSERTION(inLeafName, "Attempt to set leaf name with a null string"); + + mPath.SetToEmpty(); + + if (inLeafName) + { + // what about long relative paths? Hmm? We don't have a routine for this anywhere. + Str255 partialPath; + MacFileHelpers::PLstrcpy(partialPath, inLeafName); + mError = NS_FILE_RESULT( + ::FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, partialPath, &mSpec)); + if (mError == NS_FILE_RESULT(fnfErr)) + mError = NS_OK; + } + +} // nsFileSpec::SetLeafName + +//---------------------------------------------------------------------------------------- +char* nsFileSpec::GetLeafName() const +// Result needs to be nsCRT::free()ed. +//---------------------------------------------------------------------------------------- +{ + char leaf[sizeof(mSpec.name)]; + memcpy(leaf, &mSpec.name[1], mSpec.name[0]); + leaf[mSpec.name[0]] = '\0'; + return nsCRT::strdup(leaf); +} // nsFileSpec::GetLeafName + +//---------------------------------------------------------------------------------------- +void nsFileSpec::MakeAliasSafe() +//---------------------------------------------------------------------------------------- +{ + mPath.SetToEmpty(); + mError = NS_FILE_RESULT(MacFileHelpers::MakeAliasSafe(mSpec)); +} // nsFileSpec::MakeAliasSafe + +//---------------------------------------------------------------------------------------- +void nsFileSpec::MakeUnique(ConstStr255Param inSuggestedLeafName) +//---------------------------------------------------------------------------------------- +{ + mPath.SetToEmpty(); + if (inSuggestedLeafName[0] > 0) + MacFileHelpers::PLstrcpy(mSpec.name, inSuggestedLeafName); + + MakeUnique(); +} // nsFileSpec::MakeUnique + +//---------------------------------------------------------------------------------------- +PRBool nsFileSpec::IsFile() const +//---------------------------------------------------------------------------------------- +{ + long dirID; + Boolean isDirectory; + return (noErr == ::FSpGetDirectoryID(&mSpec, &dirID, &isDirectory) && !isDirectory); +} // nsFileSpec::IsFile + +//---------------------------------------------------------------------------------------- +PRBool nsFileSpec::IsDirectory() const +//---------------------------------------------------------------------------------------- +{ + long dirID; + Boolean isDirectory; + return (noErr == ::FSpGetDirectoryID(&mSpec, &dirID, &isDirectory) && isDirectory); +} // nsFileSpec::IsDirectory + +//---------------------------------------------------------------------------------------- +PRBool nsFileSpec::IsHidden() const +//---------------------------------------------------------------------------------------- +{ + CInfoPBRec cInfo; + PRBool hidden = PR_FALSE; + + if (noErr == GetCatInfo(cInfo)) + if (cInfo.hFileInfo.ioFlFndrInfo.fdFlags & kIsInvisible) + hidden = PR_TRUE; + + return hidden; +} // nsFileSpec::IsHidden + +//---------------------------------------------------------------------------------------- +PRBool nsFileSpec::IsSymlink() const +//---------------------------------------------------------------------------------------- +{ + CInfoPBRec cInfo; + PRBool hidden = PR_FALSE; + + if (noErr == GetCatInfo(cInfo)) + if (cInfo.hFileInfo.ioFlFndrInfo.fdFlags & kIsAlias) + hidden = PR_TRUE; + + return hidden; +} // nsFileSpec::IsSymlink + +//---------------------------------------------------------------------------------------- +nsresult nsFileSpec::ResolveSymlink(PRBool& wasAliased) +//---------------------------------------------------------------------------------------- +{ + Boolean wasAliased2; // Type conversion Boolean <--> PRBool + OSErr err = MacFileHelpers::ResolveAliasFile(mSpec, wasAliased2); + if (wasAliased2) + { + mError = NS_FILE_RESULT(err); + wasAliased = PR_TRUE; + } + else + wasAliased = PR_FALSE; + + return mError; +} // nsFileSpec::ResolveSymlink + +//---------------------------------------------------------------------------------------- +void nsFileSpec::GetParent(nsFileSpec& outSpec) const +//---------------------------------------------------------------------------------------- +{ + if (NS_SUCCEEDED(mError)) + outSpec.mError = NS_FILE_RESULT(::FSMakeFSSpec(mSpec.vRefNum, mSpec.parID, nsnull, outSpec)); +} // nsFileSpec::GetParent + +//---------------------------------------------------------------------------------------- +void nsFileSpec::operator += (const char* inRelativePath) +//---------------------------------------------------------------------------------------- +{ + NS_ASSERTION(inRelativePath, "Attempt to append relative path with null path"); + + // Invalidate the path cache string, since we're changing ourselves. + mPath.SetToEmpty(); + + // if we are already bad, don't allow appendage + if (NS_FAILED(Error())) + { + NS_WARNING("trying to append to a bad nsFileSpec"); + return; + } + + // Find the dirID of the directory described by this spec + long dirID; + Boolean isDirectory; + mError = NS_FILE_RESULT(::FSpGetDirectoryID(&mSpec, &dirID, &isDirectory)); + if (NS_FAILED(mError) || !isDirectory || !inRelativePath) + return; + // mSpec.vRefNum is already correct. + mSpec.parID = dirID; + + // Next, determine if it is a UNIX or Mac style path. Now, Macintosh relative paths + // are either leaf names (in which the distinction between unix and macintosh + // relative paths disappears) or they start with a colon. If we find an initial colon, + // then assume it's a macintosh path. + // If it is a UNIX path (including just a leaf name), we will also look for ':' and + // assert if we find one. + if (*inRelativePath != ':') + { + // Looks like a UNIX path (including possibly just a leaf name) + NS_ASSERTION(strchr(inRelativePath, ':') == nsnull, "Can not determine path type"); + // Convert unix path (which is unencoded) to a spec + mError = NS_FILE_RESULT( + MacFileHelpers::FSSpecFromUnixPath(inRelativePath, mSpec, false, false, true, true)); + } + else + { + // We must be a mac path! + mError = NS_FILE_RESULT(MacFileHelpers::FSSpecFromPathname(inRelativePath, mSpec, true)); + } + if (mError == NS_FILE_RESULT(fnfErr)) + mError = NS_OK; + +} // nsFileSpec::operator += + +//---------------------------------------------------------------------------------------- +void nsFileSpec::CreateDirectory(int /* unix mode */) +//---------------------------------------------------------------------------------------- +{ + long ignoredDirID; + OSErr err = ::FSpDirCreate(&mSpec, smCurrentScript, &ignoredDirID); + // it's OK if the dir already exists + if (err != noErr && IsDirectory()) + err = noErr; + + mError = NS_FILE_RESULT(err); + +} // nsFileSpec::CreateDirectory + +//---------------------------------------------------------------------------------------- +void nsFileSpec::Delete(PRBool inRecursive) const +//---------------------------------------------------------------------------------------- +{ + OSErr anErr; + + nsresult& mutableError = const_cast<nsFileSpec*>(this)->mError; + if (inRecursive) + { + // MoreFilesExtras + anErr = ::DeleteDirectory( + mSpec.vRefNum, + mSpec.parID, + const_cast<unsigned char*>(mSpec.name)); + } + else + anErr = ::FSpDelete(&mSpec); + + if (anErr == fnfErr) // deleting a file that doesn't exist isn't an error! + anErr = noErr; + + mutableError = NS_FILE_RESULT(anErr); + +} // nsFileSpec::Delete + +//---------------------------------------------------------------------------------------- +void nsFileSpec::RecursiveCopy(nsFileSpec newDir) const +//---------------------------------------------------------------------------------------- +{ + if (IsDirectory()) + { + if (!(newDir.Exists())) + { + newDir.CreateDirectory(); + } + + for (nsDirectoryIterator i(*this, PR_FALSE); i.Exists(); i++) + { + nsFileSpec& child = (nsFileSpec&)i; + + if (child.IsDirectory()) + { + nsFileSpec tmpDirSpec(newDir); + + char *leafname = child.GetLeafName(); + tmpDirSpec += leafname; + nsCRT::free(leafname); + + child.RecursiveCopy(tmpDirSpec); + } + else + { + child.RecursiveCopy(newDir); + } + } + } + else + { + nsFileSpec& filePath = (nsFileSpec&) *this; + + if (!(newDir.Exists())) + { + newDir.CreateDirectory(); + } + + filePath.CopyToDir(newDir); + } +} // nsFileSpec::RecursiveCopy + +//---------------------------------------------------------------------------------------- +nsresult nsFileSpec::Truncate(PRInt32 aNewLength) const +//---------------------------------------------------------------------------------------- +{ + short refNum; + OSErr err; + + // First see if we have an internal error set + if (NS_FAILED(mError)) + return mError; + + // Need to open the file to trunc + if (::FSpOpenDF(&mSpec, fsWrPerm, &refNum) != noErr) + return NS_FILE_FAILURE; + + err = ::SetEOF(refNum, aNewLength); + + // Close the file unless we got an error that it was already closed + if (err != fnOpnErr) + (void)::FSClose(refNum); + + if (err != noErr) + return NS_FILE_FAILURE; + + return NS_OK; +} // nsFileSpec::Truncate + +//---------------------------------------------------------------------------------------- +nsresult nsFileSpec::Rename(const char* inNewName) +//---------------------------------------------------------------------------------------- +{ + NS_ASSERTION(inNewName, "Attempt to rename with null new name"); + + if (strchr(inNewName, '/')) + return NS_FILE_FAILURE; // no relative paths here! + + Str255 pName; + MacFileHelpers::PLstrcpy(pName, inNewName); + if (::FSpRename(&mSpec, pName) != noErr) + return NS_FILE_FAILURE; + SetLeafName(inNewName); + return NS_OK; +} // nsFileSpec::Rename + +//---------------------------------------------------------------------------------------- +nsresult nsFileSpec::CopyToDir(const nsFileSpec& newParentDir) const +//---------------------------------------------------------------------------------------- +{ + // We can only copy into a directory, and (for now) can not copy entire directories + + if (!newParentDir.IsDirectory() || (IsDirectory() ) ) + return NS_FILE_FAILURE; + + nsresult rv = NS_FILE_RESULT(::FSpFileCopy(&mSpec, + &newParentDir.mSpec, + const_cast<StringPtr>(GetLeafPName()), + nsnull, + 0, + true)); + + return rv; + +} // nsFileSpec::CopyToDir + +//---------------------------------------------------------------------------------------- +nsresult nsFileSpec::MoveToDir(const nsFileSpec& newParentDir) +//---------------------------------------------------------------------------------------- +{ + // We can only move into a directory + + if (!newParentDir.IsDirectory()) + return NS_FILE_FAILURE; + + nsresult result = NS_FILE_RESULT(::FSpMoveRenameCompat(&mSpec, + &newParentDir.mSpec, + const_cast<StringPtr>(GetLeafPName()))); + + if ( NS_SUCCEEDED(result) ) + { + char* leafName = GetLeafName(); + *this = newParentDir + leafName; + nsCRT::free(leafName); + } + return result; +} // nsFileSpec::MoveToDir + +//---------------------------------------------------------------------------------------- +nsresult nsFileSpec::Execute(const char* /*args - how can this be cross-platform? problem! */ ) const +//---------------------------------------------------------------------------------------- +{ + if (IsDirectory()) + return NS_FILE_FAILURE; + + LaunchParamBlockRec launchThis; + launchThis.launchAppSpec = const_cast<FSSpec*>(&mSpec); + launchThis.launchAppParameters = nsnull; // args; + /* launch the thing */ + launchThis.launchBlockID = extendedBlock; + launchThis.launchEPBLength = extendedBlockLen; + launchThis.launchFileFlags = nsnull; + launchThis.launchControlFlags = launchContinue + launchNoFileFlags + launchUseMinimum; + launchThis.launchControlFlags += launchDontSwitch; + + nsresult result = NS_FILE_RESULT(::LaunchApplication(&launchThis)); + return result; + +} // nsFileSpec::Execute + +//---------------------------------------------------------------------------------------- +OSErr nsFileSpec::GetCatInfo(CInfoPBRec& outInfo) const +//---------------------------------------------------------------------------------------- +{ + DirInfo *dipb=(DirInfo *)&outInfo; + dipb->ioCompletion = nsnull; + dipb->ioFDirIndex = 0; // use dirID and name + dipb->ioVRefNum = mSpec.vRefNum; + dipb->ioDrDirID = mSpec.parID; + dipb->ioNamePtr = const_cast<nsFileSpec*>(this)->mSpec.name; + return PBGetCatInfoSync(&outInfo); +} // nsFileSpec::GetCatInfo() + +//---------------------------------------------------------------------------------------- +OSErr nsFileSpec::SetFileTypeAndCreator(OSType type, OSType creator) +//---------------------------------------------------------------------------------------- +{ + FInfo info; + OSErr err = ::FSpGetFInfo(&mSpec, &info); + if (err != noErr) + return err; + info.fdType = type; + info.fdCreator = creator; + err = ::FSpSetFInfo(&mSpec, &info); + return err; +} + +//---------------------------------------------------------------------------------------- +OSErr nsFileSpec::GetFileTypeAndCreator(OSType* type, OSType* creator) +//---------------------------------------------------------------------------------------- +{ + FInfo info; + OSErr err = ::FSpGetFInfo(&mSpec, &info); + if (err != noErr) + return err; + *type = info.fdType; + *creator = info.fdCreator; + return noErr; +} + +//---------------------------------------------------------------------------------------- +PRInt64 nsFileSpec::GetDiskSpaceAvailable() const +//---------------------------------------------------------------------------------------- +{ + PRInt64 space64Bits; + + LL_I2L(space64Bits , LONG_MAX); + + XVolumeParam pb; + pb.ioCompletion = nsnull; + pb.ioVolIndex = 0; + pb.ioNamePtr = nsnull; + pb.ioVRefNum = mSpec.vRefNum; + + // PBXGetVolInfoSync works on HFS+ volumes too! + OSErr err = ::PBXGetVolInfoSync(&pb); + + if (err == noErr) + { +#ifdef HAVE_LONG_LONG + space64Bits = pb.ioVFreeBytes; +#else + const UnsignedWide& freeBytes = UInt64ToUnsignedWide(pb.ioVFreeBytes); + space64Bits.lo = freeBytes.lo; + space64Bits.hi = freeBytes.hi; +#endif + } + + return space64Bits; +} // nsFileSpec::GetDiskSpace() + +//---------------------------------------------------------------------------------------- +const char* nsFileSpec::GetCString() const +// This is the only conversion to const char* that is provided, and it allows the +// path to be "passed" to NSPR file routines. This practice is VERY EVIL and should only +// be used to support legacy code. Using it guarantees bugs on Macintosh. The string is +// cached and freed by the nsFileSpec destructor, so do not delete (or free) it. +//---------------------------------------------------------------------------------------- +{ + if (mPath.IsEmpty()) + { + char* path = MacFileHelpers::PathNameFromFSSpec(mSpec); + if (path != NULL) { + const_cast<nsFileSpec*>(this)->mPath = path; // operator =() copies the string!!! + delete[] path; + } else { + const_cast<nsFileSpec*>(this)->mError = NS_ERROR_OUT_OF_MEMORY; + } + } + return mPath; +} + +#pragma mark - + +//======================================================================================== +// Macintosh nsFilePath implementation +//======================================================================================== + +//---------------------------------------------------------------------------------------- +static void AssignFromPath(nsFilePath& ioPath, const char* inString, PRBool inCreateDirs) +//---------------------------------------------------------------------------------------- +{ + NS_ASSERTION(inString, "AssignFromPath called with null inString"); + NS_ASSERTION(strstr(inString, kFileURLPrefix) != inString, "URL passed as path"); + + FSSpec spec; + spec.vRefNum = 0; + spec.parID = 0; + spec.name[0] = 0; + MacFileHelpers::FSSpecFromUnixPath( + inString, + spec, + false, + true, // resolve alias + true, + inCreateDirs); + // Now we have a spec, + // Invoke operator = (const nsFileSpec&) to do the rest. + // Why didn't we just say mPath = inString to get the path? Well, we want it to be + // canonical and absolute. + ioPath = spec; +} + +//---------------------------------------------------------------------------------------- +nsFilePath::nsFilePath(const char* inString, PRBool inCreateDirs) +//---------------------------------------------------------------------------------------- +{ + AssignFromPath(*this, inString, inCreateDirs); +} //nsFilePath::nsFilePath + +//---------------------------------------------------------------------------------------- +nsFilePath::nsFilePath(const nsString& inString, PRBool inCreateDirs) +//---------------------------------------------------------------------------------------- +{ + AssignFromPath(*this, NS_LossyConvertUCS2toASCII(inString).get(), + inCreateDirs); +} + +//---------------------------------------------------------------------------------------- +void nsFilePath::operator = (const char* inString) +//---------------------------------------------------------------------------------------- +{ + AssignFromPath(*this, inString, PR_FALSE); +} + +//---------------------------------------------------------------------------------------- +nsFilePath::nsFilePath(const nsFileSpec& inSpec) +//---------------------------------------------------------------------------------------- +{ + *this = inSpec; +} + +//---------------------------------------------------------------------------------------- +nsFilePath::nsFilePath(const nsFileURL& inOther) +//---------------------------------------------------------------------------------------- +{ + *this = inOther; +} + +//---------------------------------------------------------------------------------------- +void nsFilePath::operator = (const nsFileSpec& inSpec) +//---------------------------------------------------------------------------------------- +{ + char * path = MacFileHelpers::PathNameFromFSSpec(inSpec); + path = MacFileHelpers::EncodeMacPath(path, true, false); + mPath = path; + nsCRT::free(path); + mFileSpec = inSpec; +} // nsFilePath::operator = + +//---------------------------------------------------------------------------------------- +void nsFilePath::operator = (const nsFileURL& inOther) +//---------------------------------------------------------------------------------------- +{ + char * path = MacFileHelpers::PathNameFromFSSpec(inOther.mFileSpec); + path = MacFileHelpers::EncodeMacPath(path, true, false); + mPath = path; + nsCRT::free(path); + mFileSpec = inOther.GetFileSpec(); +} + +#pragma mark - + +//======================================================================================== +// nsFileURL implementation +//======================================================================================== + +//---------------------------------------------------------------------------------------- +nsFileURL::nsFileURL(const char* inString, PRBool inCreateDirs) +//---------------------------------------------------------------------------------------- +: mURL(inString) +{ + NS_ASSERTION(inString, "nsFileURL constructed with null inString"); + NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!"); + mFileSpec.mError = NS_FILE_RESULT(MacFileHelpers::FSSpecFromUnixPath( + inString + kFileURLPrefixLength, + mFileSpec.mSpec, + true, // need to decode + false, // resolve alias + false, // must be a full path + inCreateDirs)); + if (mFileSpec.mError == NS_FILE_RESULT(fnfErr)) + mFileSpec.mError = NS_OK; +} // nsFileURL::nsFileURL + +//---------------------------------------------------------------------------------------- +nsFileURL::nsFileURL(const nsString& inString, PRBool inCreateDirs) +//---------------------------------------------------------------------------------------- +: mURL(nsnull) +{ + NS_LossyConvertUCS2toASCII cstring(inString); + mURL = cstring.get(); + NS_ASSERTION(strstr(cstring.get(), kFileURLPrefix) == cstring.get(), + "Not a URL!"); + mFileSpec.mError = NS_FILE_RESULT(MacFileHelpers::FSSpecFromUnixPath( + cstring.get() + kFileURLPrefixLength, + mFileSpec.mSpec, + true, // need to decode + false, // resolve alias + false, // must be a full path + inCreateDirs)); + if (mFileSpec.mError == NS_FILE_RESULT(fnfErr)) + mFileSpec.mError = NS_OK; +} // nsFileURL::nsFileURL + +//---------------------------------------------------------------------------------------- +nsFileURL::nsFileURL(const nsFilePath& inOther) +//---------------------------------------------------------------------------------------- +{ + *this = inOther.GetFileSpec(); +} // nsFileURL::nsFileURL + +//---------------------------------------------------------------------------------------- +nsFileURL::nsFileURL(const nsFileSpec& inOther) +//---------------------------------------------------------------------------------------- +{ + *this = inOther; +} // nsFileURL::nsFileURL + +//---------------------------------------------------------------------------------------- +void nsFileURL::operator = (const nsFilePath& inOther) +//---------------------------------------------------------------------------------------- +{ + *this = inOther.GetFileSpec(); +} // nsFileURL::operator = + +//---------------------------------------------------------------------------------------- +void nsFileURL::operator = (const nsFileSpec& inOther) +//---------------------------------------------------------------------------------------- +{ + mFileSpec = inOther; + char* path = MacFileHelpers::PathNameFromFSSpec( mFileSpec ); + char* encodedPath = MacFileHelpers::EncodeMacPath(path, true, true); + nsSimpleCharString encodedURL(kFileURLPrefix); + encodedURL += encodedPath; + nsCRT::free(encodedPath); + mURL = encodedURL; + if (encodedURL[encodedURL.Length() - 1] != '/' && inOther.IsDirectory()) + mURL += "/"; +} // nsFileURL::operator = + +//---------------------------------------------------------------------------------------- +void nsFileURL::operator = (const char* inString) +//---------------------------------------------------------------------------------------- +{ + NS_ASSERTION(inString, "nsFileURL operator= constructed with null inString"); + + mURL = inString; + NS_ASSERTION(strstr(inString, kFileURLPrefix) == inString, "Not a URL!"); + mFileSpec.mError = NS_FILE_RESULT(MacFileHelpers::FSSpecFromUnixPath( + inString + kFileURLPrefixLength, + mFileSpec.mSpec, + true, // need to decode + true, // resolve alias + false, // must be a full path + false)); // don't create dirs. + if (mFileSpec.mError == NS_FILE_RESULT(fnfErr)) + mFileSpec.mError = NS_OK; +} // nsFileURL::operator = + +#pragma mark - + +//======================================================================================== +// nsDirectoryIterator +//======================================================================================== + +//---------------------------------------------------------------------------------------- +nsDirectoryIterator::nsDirectoryIterator( + const nsFileSpec& inDirectory +, PRBool resolveSymLinks) +//---------------------------------------------------------------------------------------- + : mCurrent(inDirectory) + , mExists(false) + , mResoveSymLinks(resolveSymLinks) + , mIndex(-1) +{ + CInfoPBRec pb; + OSErr err = inDirectory.GetCatInfo(pb); + + // test that we have got a directory back, not a file + DirInfo* dipb = (DirInfo*)&pb; + if (err != noErr || !( dipb->ioFlAttrib & 0x0010)) + return; + // Sorry about this, there seems to be a bug in CWPro 4: + FSSpec& currentSpec = mCurrent.nsFileSpec::operator FSSpec&(); + mVRefNum = currentSpec.vRefNum; + mParID = dipb->ioDrDirID; + mMaxIndex = pb.dirInfo.ioDrNmFls; + mIndex = 0; // ready to increment + ++(*this); // the pre-increment operator + +} // nsDirectoryIterator::nsDirectoryIterator + +//---------------------------------------------------------------------------------------- +OSErr nsDirectoryIterator::SetToIndex() +//---------------------------------------------------------------------------------------- +{ + CInfoPBRec cipb; + DirInfo *dipb=(DirInfo *)&cipb; + Str255 objectName; + dipb->ioCompletion = nsnull; + dipb->ioFDirIndex = mIndex; + // Sorry about this, there seems to be a bug in CWPro 4: + FSSpec& currentSpec = mCurrent.nsFileSpec::operator FSSpec&(); + dipb->ioVRefNum = mVRefNum; /* Might need to use vRefNum, not sure*/ + dipb->ioDrDirID = mParID; + dipb->ioNamePtr = objectName; + OSErr err = PBGetCatInfoSync(&cipb); + FSSpec temp; + if (err == noErr) + err = FSMakeFSSpec(mVRefNum, mParID, objectName, &temp); + mCurrent = temp; // use the operator: it clears the string cache. + mExists = err == noErr; + + if (mExists && mResoveSymLinks) + { + PRBool ignore; + mCurrent.ResolveSymlink(ignore); + } + return err; +} // nsDirectoryIterator::SetToIndex() + +//---------------------------------------------------------------------------------------- +nsDirectoryIterator& nsDirectoryIterator::operator -- () +//---------------------------------------------------------------------------------------- +{ + mExists = false; + while (--mIndex > 0) + { + OSErr err = SetToIndex(); + if (err == noErr) + break; + } + return *this; +} // nsDirectoryIterator::operator -- + +//---------------------------------------------------------------------------------------- +nsDirectoryIterator& nsDirectoryIterator::operator ++ () +//---------------------------------------------------------------------------------------- +{ + mExists = false; + if (mIndex >= 0) // probably trying to use a file as a directory! + while (++mIndex <= mMaxIndex) + { + OSErr err = SetToIndex(); + if (err == noErr) + break; + } + return *this; +} // nsDirectoryIterator::operator ++ + |