This commit is contained in:
ccarlen%netscape.com 2000-11-14 15:58:54 +00:00
Родитель 76068584d5
Коммит 41f0fe6bb5
4 изменённых файлов: 152 добавлений и 5 удалений

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

@ -228,8 +228,24 @@ NS_IMETHODIMP FileImpl::Open(
PRBool ignoredResult;
original.ResolveSymlink(ignoredResult);
const FSSpec& spec = original.operator const FSSpec&();
if (nsprMode & PR_CREATE_FILE)
if (nsprMode & PR_CREATE_FILE) {
// In order to get the right file type/creator, do it with an nsILocalFileMac
// Don't propagate any errors in doing this. If any error, just use FSpCreate.
FSSpec nonConstSpec = spec;
nsCOMPtr<nsILocalFileMac> macFile;
nsresult res = NS_NewLocalFileWithFSSpec(&nonConstSpec, PR_FALSE, getter_AddRefs(macFile));
if (NS_SUCCEEDED(res)) {
nsCOMPtr<nsIFile> asFile(do_QueryInterface(macFile, &res));
if (NS_SUCCEEDED(res)) {
res = asFile->Create(nsIFile::NORMAL_FILE_TYPE, 0);
if (res == NS_ERROR_FILE_ALREADY_EXISTS)
res = NS_OK;
}
}
if (NS_FAILED(res))
err = FSpCreate(&spec, kCreator, 'TEXT', 0);
}
if (err == dupFNErr)
err = noErr;
if (err != noErr)

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

@ -53,6 +53,9 @@ class nsILocalFileMac : public nsISupports
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_ILOCALFILEMAC_IID)
// Use with SetFileTypeAndCreator to make creator be that of current process
enum { CURRENT_PROCESS_CREATOR = 0x8000000 };
// We need to be able to determine what init method was used as that
// will affect how we clone a nsILocalFileMac
NS_IMETHOD GetInitType(nsLocalFileMacInitType *type) = 0;
@ -82,6 +85,12 @@ public:
NS_IMETHOD GetFileTypeAndCreator(OSType *type, OSType *creator) = 0;
NS_IMETHOD SetFileTypeAndCreator(OSType type, OSType creator) = 0;
// Methods for setting the file type from other means. Just setting the
// type is probably enough. The creator is set to that of the current process
// by default. Failure is likely on these methods - take it lightly.
NS_IMETHOD SetFileTypeFromSuffix(const char *suffix) = 0;
NS_IMETHOD SetFileTypeFromMIMEType(const char *mimetype) = 0;
// Since Mac files can consist of both a data and resource fork we have a
// method that will return the combined size of both forks rather than just the
// size of the data fork as returned by GetFileSize()

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

@ -26,11 +26,14 @@
#include "nsCOMPtr.h"
#include "nsMemory.h"
#include "nsXPIDLString.h"
#include "nsLocalFileMac.h"
#include "nsISimpleEnumerator.h"
#include "nsIComponentManager.h"
#include "nsIInternetConfigService.h"
#include "nsIMIMEInfo.h"
#include "prtypes.h"
#include "prerror.h"
#include "pprio.h" // Include this rather than prio.h so we get def of PR_ImportFile
@ -62,6 +65,10 @@ extern "C"
#include <FSp_fopen.h>
}
#pragma mark [Constants]
const OSType kDefaultCreator = 'MOSS';
#pragma mark [static util funcs]
static inline void ClearFSSpec(FSSpec& aSpec)
@ -772,6 +779,9 @@ class nsDirEnumerator : public nsISimpleEnumerator
NS_IMPL_ISUPPORTS(nsDirEnumerator, NS_GET_IID(nsISimpleEnumerator));
#pragma mark -
OSType nsLocalFile::mgCurrentProcessSignature = 0;
#pragma mark [CTOR/DTOR]
nsLocalFile::nsLocalFile()
: mInitType(eNotInitialized)
@ -779,12 +789,16 @@ nsLocalFile::nsLocalFile()
, mHaveFileInfo(PR_FALSE)
, mFollowSymlinks(PR_FALSE)
, mType('????')
, mCreator('MOSS')
, mCreator(kDefaultCreator)
{
NS_INIT_REFCNT();
MakeDirty();
ClearFSSpec(mSpec);
DetermineCurrentProcessCreator();
if (mgCurrentProcessSignature != 0)
mCreator = mgCurrentProcessSignature;
}
nsLocalFile::~nsLocalFile()
@ -1037,7 +1051,10 @@ nsLocalFile::OpenNSPRFileDesc(PRInt32 flags, PRInt32 mode, PRFileDesc **_retval)
return MacErrorMapper(err);
if (flags & PR_CREATE_FILE)
{
SetOSTypeFromExtension();
err = ::FSpCreate(&spec, mCreator, mType, 0);
}
/* If opening with the PR_EXCL flag the existence of the file prior to opening is an error */
if ((flags & PR_EXCL) && (err == dupFNErr))
@ -1145,6 +1162,7 @@ nsLocalFile::Create(PRUint32 type, PRUint32 attributes)
switch (type)
{
case NORMAL_FILE_TYPE:
SetOSTypeFromExtension();
err = ::FSpCreate(&mResolvedSpec, mCreator, mType, smCurrentScript);
return (MacErrorMapper(err));
break;
@ -2606,6 +2624,9 @@ NS_IMETHODIMP nsLocalFile::SetFileTypeAndCreator(OSType type, OSType creator)
if (err != noErr)
return NS_ERROR_FILE_NOT_FOUND;
if (creator == CURRENT_PROCESS_CREATOR)
creator = (mgCurrentProcessSignature != 0) ? mgCurrentProcessSignature : kDefaultCreator;
// See if the user specified a type or creator before changing from what was read
if (type)
info.fdType = type;
@ -2619,6 +2640,33 @@ NS_IMETHODIMP nsLocalFile::SetFileTypeAndCreator(OSType type, OSType creator)
return NS_OK;
}
NS_IMETHODIMP nsLocalFile::SetFileTypeFromSuffix(const char *suffix)
{
NS_ENSURE_ARG(suffix);
return SetOSTypeFromExtension(suffix);
}
NS_IMETHODIMP nsLocalFile::SetFileTypeFromMIMEType(const char *mimetype)
{
NS_ENSURE_ARG(mimetype);
nsresult rv;
NS_WITH_SERVICE(nsIInternetConfigService, icService, NS_INTERNETCONFIGSERVICE_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv))
{
nsCOMPtr<nsIMIMEInfo> mimeInfo;
rv = icService->FillInMIMEInfo(mimetype, nsnull, getter_AddRefs(mimeInfo));
if (NS_SUCCEEDED(rv))
{
PRUint32 osType;
rv = mimeInfo->GetMacType(&osType);
if (NS_SUCCEEDED(rv))
mType = osType;
}
}
return rv;
}
NS_IMETHODIMP
nsLocalFile::GetFileSizeWithResFork(PRInt64 *aFileSize)
{
@ -2728,6 +2776,69 @@ nsLocalFile::OpenDocWithApp(nsILocalFile* aAppToOpenWith, PRBool aLaunchInBackgr
return rv;
}
nsresult nsLocalFile::SetOSTypeFromExtension(const char* extension)
{
nsresult rv;
nsXPIDLCString localExtBuf;
char *extPtr;
if (!extension)
{
rv = GetLeafName(getter_Copies(localExtBuf));
extPtr = strrchr(localExtBuf, '.');
if (!extPtr)
return NS_ERROR_FAILURE;
++extPtr;
}
else
{
extPtr = const_cast<char *>(extension); // really, we won't touch it
if (*extPtr == '.')
++extPtr;
}
NS_WITH_SERVICE(nsIInternetConfigService, icService, NS_INTERNETCONFIGSERVICE_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv))
{
nsCOMPtr<nsIMIMEInfo> mimeInfo;
rv = icService->GetMIMEInfoFromExtension(extPtr, getter_AddRefs(mimeInfo));
if (NS_SUCCEEDED(rv))
{
PRUint32 osType;
rv = mimeInfo->GetMacType(&osType);
if (NS_SUCCEEDED(rv))
mType = osType;
}
}
return rv;
}
nsresult nsLocalFile::DetermineCurrentProcessCreator()
{
nsresult rv = NS_OK;
if (mgCurrentProcessSignature == 0)
{
OSErr err;
ProcessSerialNumber psn;
ProcessInfoRec info;
psn.highLongOfPSN = 0;
psn.lowLongOfPSN = kCurrentProcess;
info.processInfoLength = sizeof(ProcessInfoRec);
info.processName = nil;
info.processAppSpec = nil;
err = ::GetProcessInformation(&psn, &info);
if (err == noErr)
mgCurrentProcessSignature = info.processSignature;
// Try again next time if error
else
rv = MacErrorMapper(err);
}
return NS_OK;
}
#pragma mark -

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

@ -71,6 +71,9 @@ public:
NS_IMETHOD GetFileTypeAndCreator(OSType *type, OSType *creator);
NS_IMETHOD SetFileTypeAndCreator(OSType type, OSType creator);
NS_IMETHOD SetFileTypeFromSuffix(const char *suffix);
NS_IMETHOD SetFileTypeFromMIMEType(const char *mimetype);
NS_IMETHOD GetFileSizeWithResFork(PRInt64 *aFileSize);
NS_IMETHOD LaunchAppWithDoc(nsILocalFile* aDocToLoad, PRBool aLaunchInBackground);
@ -92,6 +95,12 @@ protected:
OSErr GetTargetSpecCatInfo(CInfoPBRec& outInfo);
nsresult MoveCopy( nsIFile* newParentDir, const char* newName, PRBool isCopy );
// Passing nsnull for the extension uses leaf name
nsresult SetOSTypeFromExtension(const char* extension = nsnull);
static nsresult DetermineCurrentProcessCreator();
private:
// It's important we keep track of how we were initialized
@ -129,6 +138,8 @@ private:
OSType mType, mCreator;
static OSType mgCurrentProcessSignature;
};
#endif