31054 'TEXT' file which contains non ASCII does not open correctly

git-svn-id: svn://10.0.0.236/trunk@65311 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
davidm%netscape.com
2000-04-05 03:03:50 +00:00
parent 3c6f758b9e
commit 5fc312c27f
15 changed files with 295 additions and 421 deletions

View File

@@ -109,41 +109,20 @@ public:
*contentLength = -1;
}
else {
char* fileName;
rv = mFile->GetLeafName(&fileName);
if (NS_FAILED(rv)) return rv;
if (fileName != nsnull) {
PRInt32 len = nsCRT::strlen(fileName);
const char* ext = nsnull;
for (PRInt32 i = len; i >= 0; i--) {
if (fileName[i] == '.') {
ext = &fileName[i + 1];
break;
}
}
if (ext) {
NS_WITH_SERVICE(nsIMIMEService, mimeServ, kMIMEServiceCID, &rv);
if (NS_SUCCEEDED(rv)) {
rv = mimeServ->GetTypeFromExtension(ext, contentType);
}
}
else
rv = NS_ERROR_FAILURE;
nsCRT::free(fileName);
} else {
rv = NS_ERROR_FAILURE;
}
if (NS_FAILED(rv)) {
// if all else fails treat it as text/html?
*contentType = nsCRT::strdup(DEFAULT_TYPE);
if (*contentType == nsnull)
rv = NS_ERROR_OUT_OF_MEMORY;
else
rv = NS_OK;
}
NS_WITH_SERVICE(nsIMIMEService, mimeServ, kMIMEServiceCID, &rv);
if (NS_SUCCEEDED(rv)) {
rv = mimeServ->GetTypeFromFile(mFile, contentType);
}
if (NS_FAILED(rv)) {
// if all else fails treat it as text/html?
*contentType = nsCRT::strdup(DEFAULT_TYPE);
if (*contentType == nsnull)
rv = NS_ERROR_OUT_OF_MEMORY;
else
rv = NS_OK;
}
}
PR_LOG(gFileTransportLog, PR_LOG_DEBUG,
("nsFileTransport: logically opening %s: type=%s len=%d",

View File

@@ -32,6 +32,7 @@ XPIDL_MODULE = mimetype
XPIDLSRCS = \
nsIMIMEService.idl \
nsIMIMEInfo.idl \
nsIMIMEDataSource.idl \
$(NULL)
EXPORTS = \

View File

@@ -29,6 +29,7 @@ XPIDL_MODULE = mimetype
XPIDLSRCS = \
.\nsIMIMEInfo.idl \
.\nsIMIMEService.idl \
.\nsIMIMEDataSource.idl \
$(NULL)
EXPORTS = \

View File

@@ -31,6 +31,18 @@
#include "nsISupports.idl"
#include "nsIURI.idl"
%{C++
#define NS_MIMEINFO_CID \
{ /* {95df6583-0001-11d4-a12b-a66ef662f0bc} */ \
0x95df6583, \
0x0001, \
0x11d4, \
{ 0xa1, 0x2b, 0xa6, 0x6e, 0xf6, 0x62, 0xf0, 0xbc } \
}
#define NS_MIMEINFO_PROGID \
"component:||netscape|mimeinfo"
%}
[scriptable, uuid(6A57EAE0-2FE8-11d3-A164-0050041CAF44)]
interface nsIMIMEInfo : nsISupports {
/* Gives you an array of file types associated with this type.
@@ -55,18 +67,23 @@ interface nsIMIMEInfo : nsISupports {
* @return The first extension.
*/
string FirstExtension();
/*
* Append a given extension to the set of extensions
*/
void AppendExtension(in string aExtension);
/* The MIME type of this MIMEInfo.
*
* @return String representing the MIME type.
*/
readonly attribute string MIMEType;
attribute string MIMEType;
/* A human readable description of the MIME info
*
* @return The description
*/
readonly attribute wstring Description;
attribute wstring Description;
/* Gives you arbitrary data about the MIMEInfo. An example
* of this is a generic image graphically representing
@@ -76,7 +93,13 @@ interface nsIMIMEInfo : nsISupports {
* @return A URI representing the data location.
*/
readonly attribute nsIURI DataURI;
/*
* Mac Type and creator types
*/
attribute PRUint32 MacType;
attribute PRUint32 MacCreator;
/* Returns whether or not these two MIME infos are logically
* equivelent maintaining the one-to-many relationship between
* MIME types and file extensions.

View File

@@ -18,6 +18,7 @@
* Rights Reserved.
*
* Contributor(s): Judson Valeski
* : David Matiskella
*/
/* The MIME service is responsible for mapping file extensions to MIME-types
@@ -34,7 +35,8 @@
#include "nsISupports.idl"
#include "nsIMIMEInfo.idl"
#include "nsIURI.idl"
#include "nsISupportsArray.idl"
#include "nsIMIMEDataSource.idl"
#include "nsIFile.idl"
%{C++
#define NS_MIMESERVICE_CID \
@@ -81,51 +83,15 @@ interface nsIMIMEService : nsISupports {
* @return The MIME type, if any.
*/
string GetTypeFromURI(in nsIURI aURI);
/* Adds a MIME mapping to the database.
*
* @param MIME type to be registered.
* @param File extension to be associated.
* @param Description of this MIME type.
* @param Data URI typically used to retrieve an image
* graphically representing the MIME type.
*
*/
void AddMapping(in string aMIMEType, in string aExtension, in string aDesc, in nsIURI aURI);
/* Removes a MIME mapping from the database. All file extensions
* associated with this mapping are removed as well.
*
* @param MIME type to be removed.
* @return NS_OK
*/
void RemoveMapping(in string aMIMEType);
/* Maps a file extension (don't include leading dot) to a MIME entry.
*
* @param MIME type to associate this extension with.
* @param File extension to associate with MIME type.
* @return NS_ERROR_FAILURE if the MIME entry doesn't exist, or for
* general fialure. NS_OK otherwise.
*/
void AppendExtension(in string aMIMEType, in string aExtension);
/* Removes a file extension association with a MIME entry.
*
* @param The file extension to be removed.
* @return NS_ERROR_FAILURE if the MIME entry doesn't exist, or for
* general failure. NS_OK otherwise.
*/
void RemoveExtension(in string aExtension);
/* Enumerates all the MIME types in the database. Each entry
* is represented as an nsIMIMEInfo interface.
*
* @return All the registered MIME types.
*/
nsIBidirectionalEnumerator EnumerateEntries();
/* Makes the current mappings persistent.
*/
void Serialize();
//
string GetTypeFromFile ( in nsIFile aFile );
/*
* The data sources
*/
readonly attribute nsIMIMEDataSource XMLDataSource;
readonly attribute nsIMIMEDataSource NativeDataSource;
};

View File

@@ -36,6 +36,7 @@ CPPSRCS = \
nsMIMEInfoImpl.cpp \
nsMIMEService.cpp \
nsMIMEServiceModule.cpp \
nsXMLMIMEDataSource.cpp \
$(NULL)
EXTRA_DSO_LDOPTS += $(MOZ_COMPONENT_LIBS)

View File

@@ -38,6 +38,7 @@ CPP_OBJS = \
.\$(OBJDIR)\nsMIMEInfoImpl.obj \
.\$(OBJDIR)\nsMIMEService.obj \
.\$(OBJDIR)\nsMIMEServiceModule.obj \
.\$(OBJDIR)\nsXMLMIMEDataSource.obj \
$(NULL)
LOCAL_INCLUDES=-I.

View File

@@ -27,9 +27,12 @@
NS_IMPL_THREADSAFE_ISUPPORTS1(nsMIMEInfoImpl, nsIMIMEInfo);
// nsMIMEInfoImpl methods
nsMIMEInfoImpl::nsMIMEInfoImpl(const char *aMIMEType) {
nsMIMEInfoImpl::nsMIMEInfoImpl() {
NS_INIT_REFCNT();
}
nsMIMEInfoImpl::nsMIMEInfoImpl(const char *aMIMEType): mMIMEType( aMIMEType ) {
NS_INIT_REFCNT();
mMIMEType = getter_AddRefs(NS_NewAtom(aMIMEType));
}
PRUint32
@@ -66,7 +69,7 @@ nsMIMEInfoImpl::ExtensionExists(const char *aExtension, PRBool *_retval) {
if (!aExtension) return NS_ERROR_NULL_POINTER;
for (PRUint8 i=0; i < extCount; i++) {
nsCString* ext = mExtensions.CStringAt(i);
nsCString* ext = (nsCString*)mExtensions.CStringAt(i);
if (ext->Equals(aExtension)) {
found = PR_TRUE;
break;
@@ -87,17 +90,29 @@ nsMIMEInfoImpl::FirstExtension(char **_retval) {
return NS_OK;
}
NS_IMETHODIMP nsMIMEInfoImpl::AppendExtension(const char *aExtension)
{
mExtensions.AppendCString( aExtension );
return NS_OK;
}
NS_IMETHODIMP
nsMIMEInfoImpl::GetMIMEType(char * *aMIMEType) {
if (!aMIMEType) return NS_ERROR_NULL_POINTER;
nsAutoString strMIMEType;
mMIMEType->ToString(strMIMEType);
*aMIMEType = strMIMEType.ToNewCString();
*aMIMEType = mMIMEType.ToNewCString();
if (!*aMIMEType) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsMIMEInfoImpl::SetMIMEType(const char* aMIMEType) {
if (!aMIMEType) return NS_ERROR_NULL_POINTER;
mMIMEType = aMIMEType;
return NS_OK;
}
NS_IMETHODIMP
nsMIMEInfoImpl::GetDescription(PRUnichar * *aDescription) {
if (!aDescription) return NS_ERROR_NULL_POINTER;
@@ -107,6 +122,12 @@ nsMIMEInfoImpl::GetDescription(PRUnichar * *aDescription) {
return NS_OK;
}
NS_IMETHODIMP nsMIMEInfoImpl::SetDescription(const PRUnichar * aDescription)
{
mDescription = aDescription;
return NS_OK;
}
NS_IMETHODIMP
nsMIMEInfoImpl::GetDataURI(nsIURI * *aDataURI) {
return mURI->Clone(aDataURI);
@@ -120,9 +141,31 @@ nsMIMEInfoImpl::Equals(nsIMIMEInfo *aMIMEInfo, PRBool *_retval) {
nsresult rv = aMIMEInfo->GetMIMEType(getter_Copies(type));
if (NS_FAILED(rv)) return rv;
// STRING USE WARNING: perhaps |type1| should be an |nsCAutoString|? -- scc
nsAutoString type1;
mMIMEType->ToString(type1);
*_retval = type1.EqualsWithConversion(type);
*_retval = mMIMEType.EqualsWithConversion(type);
return NS_OK;
}
NS_IMETHODIMP nsMIMEInfoImpl::GetMacType(PRUint32 *aMacType)
{
*aMacType = mMacType;
return NS_OK;
}
NS_IMETHODIMP nsMIMEInfoImpl::SetMacType(PRUint32 aMacType)
{
mMacType = aMacType;
return NS_OK;
}
NS_IMETHODIMP nsMIMEInfoImpl::GetMacCreator(PRUint32 *aMacCreator)
{
*aMacCreator = mMacCreator;
return NS_OK;
}
NS_IMETHODIMP nsMIMEInfoImpl::SetMacCreator(PRUint32 aMacCreator)
{
mMacCreator = aMacCreator;
return NS_OK;
}

View File

@@ -34,6 +34,7 @@ class nsMIMEInfoImpl : public nsIMIMEInfo {
NS_DECL_NSIMIMEINFO
// nsMIMEInfoImpl methods
nsMIMEInfoImpl();
nsMIMEInfoImpl(const char *aMIMEType);
virtual ~nsMIMEInfoImpl() {};
PRUint32 GetExtCount(); // returns the number of extensions associated.
@@ -42,9 +43,9 @@ class nsMIMEInfoImpl : public nsIMIMEInfo {
nsCStringArray mExtensions; // array of file extensions associated w/ this MIME obj
nsAutoString mDescription; // human readable description
nsCOMPtr<nsIURI> mURI; // URI pointing to data associated w/ this obj
PRUint32 mMacType, mMacCreator; // Mac file type and creator
protected:
nsCOMPtr<nsIAtom> mMIMEType;
nsString mMIMEType;
};

View File

@@ -40,14 +40,13 @@
#include "nsIURL.h"
#include "nsCOMPtr.h"
#include "nsXPIDLString.h"
#include "nsMimeTypes.h"
PRBool PR_CALLBACK DeleteEntry(nsHashKey *aKey, void *aData, void* closure) {
nsMIMEInfoImpl *entry = (nsMIMEInfoImpl*)aData;
NS_ASSERTION(entry, "mapping problem");
NS_RELEASE(entry);
return PR_TRUE;
};
#ifdef XP_MAC
#include "nsILocalFileMac.h"
#endif
// nsISupports methods
NS_IMPL_THREADSAFE_ISUPPORTS1(nsMIMEService, nsIMIMEService);
@@ -70,305 +69,56 @@ nsMIMEService::nsMIMEService() {
}
nsMIMEService::~nsMIMEService() {
mInfoObjects->Reset(DeleteEntry, nsnull);
delete mInfoObjects;
}
nsresult
nsMIMEService::Init() {
nsresult rv = NS_OK;
mInfoObjects = new nsHashtable();
if (!mInfoObjects) return NS_ERROR_OUT_OF_MEMORY;
rv = NS_NewISupportsArray(getter_AddRefs(mInfoArray));
if (NS_FAILED(rv)) return rv;
return InitFromHack();
}
/* This bad boy needs to retrieve a url, and parse the data coming back, and
* add entries into the mInfoArray.
*/
nsresult
nsMIMEService::InitFromURI(nsIURI *aUri) {
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult
nsMIMEService::InitFromFile(const char *aFileName) {
#if 0
nsFileSpec dirSpec;
nsIFileSpec* spec = NS_LocateFileOrDirectory(nsSpecialFileSpec::App_UserProfileDirectory50);
if (!spec) return NS_ERROR_FAILURE;
spec->GetFileSpec(&dirSpec);
nsInputFileStream inStream(dirSpec + aFileName);
if (!inStream.is_open()) {
return NS_OK;
}
// digest the file.
#endif
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMIMEService::AddMapping(const char* mimeType,
const char* extension,
const char* description,
nsIURI* dataURI)
{
nsresult rv = NS_OK;
// setup the new MIMEInfo object.
nsMIMEInfoImpl* anInfo = new nsMIMEInfoImpl(mimeType);
if (!anInfo) return NS_ERROR_OUT_OF_MEMORY;
anInfo->mExtensions.AppendCString(extension);
anInfo->mDescription.AssignWithConversion(description);
anInfo->mURI = dataURI;
// The entry is mapped many-to-one and the MIME type is the root mapping.
// First remove any existing mapping.
rv = RemoveMapping(mimeType);
if (NS_FAILED(rv)) return rv;
// Next add the new root MIME mapping.
nsStringKey key(mimeType);
nsMIMEInfoImpl* oldInfo = (nsMIMEInfoImpl*)mInfoObjects->Put(&key, anInfo);
NS_ASSERTION(!oldInfo, "we just removed the entry, we shouldn't have one");
NS_ADDREF(anInfo);
rv = mInfoArray->AppendElement(anInfo); // update the root array.
if (NS_FAILED(rv)) return rv;
// Finally add an extension mapping.
key = extension;
oldInfo = (nsMIMEInfoImpl*)mInfoObjects->Put(&key, anInfo);
NS_ASSERTION(!oldInfo, "file extension mappings should have been cleaned up in the RemoveMapping call");
NS_ADDREF(anInfo);
return NS_OK;
}
// used to cleanup any file extension mappings when
// a root MIME entry is removed.
PRBool removeExts(nsCString& aElement, void *aData) {
nsHashtable* infoObjects = (nsHashtable*)aData;
NS_ASSERTION(infoObjects, "hash table botched up");
nsStringKey key(aElement);
nsMIMEInfoImpl* info = (nsMIMEInfoImpl*)infoObjects->Remove(&key);
NS_RELEASE(info);
return PR_TRUE;
}
NS_IMETHODIMP
nsMIMEService::RemoveMapping(const char* aMIMEType) {
nsresult rv = NS_OK;
nsStringKey key(aMIMEType);
// First remove the root MIME mapping.
nsMIMEInfoImpl* info = (nsMIMEInfoImpl*)mInfoObjects->Remove(&key);
if (!info) return NS_OK;
rv = mInfoArray->RemoveElement(info); // update the root array.
if (NS_FAILED(rv)) return rv;
// Next remove any file association mappings.
rv = info->mExtensions.EnumerateForwards(removeExts, mInfoObjects);
NS_RELEASE(info);
if (NS_FAILED(rv)) return rv;
return NS_OK;
}
NS_IMETHODIMP
nsMIMEService::AppendExtension(const char* mimeType, const char* extension) {
nsStringKey key(mimeType);
nsMIMEInfoImpl* info = (nsMIMEInfoImpl*)mInfoObjects->Get(&key);
if (!info) return NS_ERROR_FAILURE;
info->mExtensions.AppendCString(extension);
// Add another file extension mapping.
key = extension;
nsMIMEInfoImpl* oldInfo = (nsMIMEInfoImpl*)mInfoObjects->Put(&key, info);
NS_IF_RELEASE(oldInfo); // overwrite any existing mapping.
NS_ADDREF(info);
return NS_OK;
}
NS_IMETHODIMP
nsMIMEService::RemoveExtension(const char* aExtension) {
nsresult rv = NS_OK;
nsStringKey key(aExtension);
// First remove the extension mapping.
nsMIMEInfoImpl* info = (nsMIMEInfoImpl*)mInfoObjects->Remove(&key);
if (!info) return NS_ERROR_FAILURE;
// Next remove the root MIME mapping from the array and hash
// IFF this was the only file extension mapping left.
// STRING USE WARNING: this particular use really needs to be examined -- scc
nsCAutoString keyString;
keyString.AssignWithConversion(key.GetString().GetUnicode());
PRBool removed = info->mExtensions.RemoveCString(keyString);
NS_ASSERTION(removed, "mapping problem");
if (info->GetExtCount() == 0) {
// it's empty, remove the root mapping from hash and array.
nsXPIDLCString mimeType;
rv = info->GetMIMEType(getter_Copies(mimeType));
if (NS_FAILED(rv)) return rv;
key = (const char*)mimeType;
nsMIMEInfoImpl* rootEntry = (nsMIMEInfoImpl*)mInfoObjects->Remove(&key);
NS_ASSERTION(rootEntry, "mapping miss-hap");
rv = mInfoArray->RemoveElement(rootEntry); // update the root array
if (NS_FAILED(rv)) return rv;
NS_RELEASE(rootEntry);
}
NS_RELEASE(info);
return NS_OK;
}
NS_IMETHODIMP
nsMIMEService::EnumerateEntries(nsIBidirectionalEnumerator* *aEnumerator) {
return NS_NewISupportsArrayEnumerator(mInfoArray, aEnumerator);
}
NS_IMETHODIMP
nsMIMEService::Serialize() {
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult
nsMIMEService::InitFromHack() {
nsresult rv;
rv = AddMapping(TEXT_PLAIN, "txt", "Text File", nsnull);
if (NS_FAILED(rv)) return rv;
rv = AppendExtension(TEXT_PLAIN, "text");
if (NS_FAILED(rv)) return rv;
rv = AddMapping(APPLICATION_OCTET_STREAM, "exe", "Binary Executable", nsnull);
if (NS_FAILED(rv)) return rv;
rv = AppendExtension(APPLICATION_OCTET_STREAM, "bin");
if (NS_FAILED(rv)) return rv;
#if defined(VMS)
rv = AppendExtension(APPLICATION_OCTET_STREAM, "sav");
if (NS_FAILED(rv)) return rv;
rv = AppendExtension(APPLICATION_OCTET_STREAM, "bck");
if (NS_FAILED(rv)) return rv;
rv = AppendExtension(APPLICATION_OCTET_STREAM, "pcsi");
if (NS_FAILED(rv)) return rv;
rv = AppendExtension(APPLICATION_OCTET_STREAM, "pcsi-dcx_axpexe");
if (NS_FAILED(rv)) return rv;
rv = AppendExtension(APPLICATION_OCTET_STREAM, "pcsi-dcx_vaxexe");
if (NS_FAILED(rv)) return rv;
#endif
rv = AddMapping(TEXT_HTML, "htm", "Hyper Text Markup Language", nsnull);
if (NS_FAILED(rv)) return rv;
rv = AppendExtension(TEXT_HTML, "html");
if (NS_FAILED(rv)) return rv;
rv = AppendExtension(TEXT_HTML, "shtml");
if (NS_FAILED(rv)) return rv;
rv = AppendExtension(TEXT_HTML, "ehtml");
if (NS_FAILED(rv)) return rv;
rv = AddMapping(TEXT_RDF, "rdf", "Resource Description Framework", nsnull);
if (NS_FAILED(rv)) return rv;
rv = AddMapping(TEXT_XUL, "xul", "XML-Based User Interface Language", nsnull);
if (NS_FAILED(rv)) return rv;
rv = AddMapping(TEXT_XML, "xml", "Extensible Markup Language", nsnull);
if (NS_FAILED(rv)) return rv;
rv = AddMapping(TEXT_CSS, "css", "Style Sheet", nsnull);
if (NS_FAILED(rv)) return rv;
rv = AddMapping(APPLICATION_JAVASCRIPT, "js", "Javascript Source File", nsnull);
if (NS_FAILED(rv)) return rv;
rv = AddMapping(MESSAGE_RFC822, "eml", "RFC-822 data", nsnull);
if (NS_FAILED(rv)) return rv;
rv = AddMapping(IMAGE_GIF, "gif", "GIF Image", nsnull);
if (NS_FAILED(rv)) return rv;
rv = AddMapping(IMAGE_JPG, "jpeg", "JPEG Image", nsnull);
if (NS_FAILED(rv)) return rv;
rv = AppendExtension(IMAGE_JPG, "jpg");
if (NS_FAILED(rv)) return rv;
rv = AddMapping(IMAGE_PNG, "png", "PNG Image", nsnull);
if (NS_FAILED(rv)) return rv;
rv = AddMapping(IMAGE_ART, "art", "ART Image", nsnull);
if (NS_FAILED(rv)) return rv;
rv = AddMapping(IMAGE_TIFF, "tiff", "TIFF Image", nsnull);
if (NS_FAILED(rv)) return rv;
rv = AppendExtension(IMAGE_TIFF, "tif");
if (NS_FAILED(rv)) return rv;
rv = AddMapping(APPLICATION_POSTSCRIPT, "ps", "Postscript File", nsnull);
if (NS_FAILED(rv)) return rv;
rv = AppendExtension(APPLICATION_POSTSCRIPT, "eps");
if (NS_FAILED(rv)) return rv;
rv = AppendExtension(APPLICATION_POSTSCRIPT, "ai");
if (NS_FAILED(rv)) return rv;
rv = AddMapping(TEXT_RTF, "rtf", "Rich Text Format", nsnull);
if (NS_FAILED(rv)) return rv;
rv = AppendExtension(TEXT_RTF, "rtf");
if (NS_FAILED(rv)) return rv;
rv = AddMapping(TEXT_CPP, "cpp", "CPP file", nsnull);
if (NS_FAILED(rv)) return rv;
rv = AppendExtension(TEXT_CPP, "cpp");
if (NS_FAILED(rv)) return rv;
return NS_OK;
rv = nsComponentManager::CreateInstance(NS_XMLMIMEDATASOURCE_PROGID, nsnull, nsIMIMEDataSource::GetIID(), getter_AddRefs(mXML) );
// Create native
nsComponentManager::CreateInstance(NS_NATIVEMIMEDATASOURCE_PROGID, nsnull, nsIMIMEDataSource::GetIID(), getter_AddRefs(mNative) );
return rv;
}
// nsIMIMEService methods
NS_IMETHODIMP
nsMIMEService::GetFromExtension(const char *aFileExt, nsIMIMEInfo **_retval) {
// for now we're assuming file extensions are case insensitive.
nsCAutoString fileExt(aFileExt);
fileExt.ToLowerCase();
nsStringKey key(fileExt.GetBuffer());
nsMIMEInfoImpl *entry = (nsMIMEInfoImpl*)mInfoObjects->Get(&key);
if (!entry) return NS_ERROR_FAILURE;
NS_ADDREF(entry);
*_retval = NS_STATIC_CAST(nsIMIMEInfo*, entry);
return NS_OK;
nsresult rv;
if( !mXML || NS_FAILED (rv = mXML->GetFromExtension( aFileExt, _retval ) ) )
{
if ( mNative )
rv = mNative->GetFromExtension( aFileExt, _retval );
}
return rv;
}
NS_IMETHODIMP
nsMIMEService::GetFromMIMEType(const char *aMIMEType, nsIMIMEInfo **_retval) {
nsresult rv =NS_ERROR_FAILURE;
if( !mXML || NS_FAILED (rv = mXML->GetFromMIMEType( aMIMEType, _retval ) ) )
{
if ( mNative )
rv = mNative->GetFromMIMEType( aMIMEType, _retval );
}
return rv;
}
// Helper routines implemented in terms of the above
NS_IMETHODIMP
nsMIMEService::GetTypeFromExtension(const char *aFileExt, char **aContentType) {
nsresult rv = NS_OK;;
nsCOMPtr<nsIMIMEInfo> info;
rv = GetFromExtension(aFileExt, getter_AddRefs(info));
if (NS_FAILED(rv)) return rv;
return info->GetMIMEType(aContentType);
rv = info->GetMIMEType(aContentType);
return rv;
}
NS_IMETHODIMP
@@ -377,6 +127,29 @@ nsMIMEService::GetTypeFromURI(nsIURI *aURI, char **aContentType) {
// first try to get a url out of the uri so we can skip post
// filename stuff (i.e. query string)
nsCOMPtr<nsIURL> url = do_QueryInterface(aURI, &rv);
#ifdef XP_MAC
if ( NS_SUCCEEDED( rv ) )
{
nsXPIDLCString fileExt;
url->GetFileExtension(getter_Copies(fileExt));
nsresult rv2;
nsCOMPtr<nsIFileURL> fileurl = do_QueryInterface( url, &rv2 );
if ( NS_SUCCEEDED ( rv2 ) )
{
nsCOMPtr <nsIFile> file;
rv2 = fileurl->GetFile( getter_AddRefs( file ) );
if ( NS_SUCCEEDED( rv2 ) )
{
rv2 = GetTypeFromFile( file, aContentType );
if( NS_SUCCEEDED ( rv2 ) )
return rv2;
}
}
}
#endif
if (NS_SUCCEEDED(rv)) {
nsXPIDLCString ext;
rv = url->GetFileExtension(getter_Copies(ext));
@@ -407,16 +180,66 @@ nsMIMEService::GetTypeFromURI(nsIURI *aURI, char **aContentType) {
return rv;
}
NS_IMETHODIMP
nsMIMEService::GetFromMIMEType(const char *aMIMEType, nsIMIMEInfo **_retval) {
nsCAutoString MIMEType(aMIMEType);
MIMEType.ToLowerCase();
NS_IMETHODIMP nsMIMEService::GetTypeFromFile( nsIFile* aFile, char **aContentType )
{
nsresult rv;
nsCOMPtr<nsIMIMEInfo> info;
// Get the Extension
char* fileName;
const char* ext = nsnull;
rv = aFile->GetLeafName(&fileName);
if (NS_FAILED(rv)) return rv;
if (fileName != nsnull) {
PRInt32 len = nsCRT::strlen(fileName);
for (PRInt32 i = len; i >= 0; i--) {
if (fileName[i] == '.') {
ext = &fileName[i + 1];
break;
}
}
}
nsCString fileExt( ext );
nsCRT::free(fileName);
// Handle the mac case
#ifdef XP_MAC
nsCOMPtr<nsILocalFileMac> macFile;
macFile = do_QueryInterface( aFile, &rv );
if ( NS_SUCCEEDED( rv ) )
{
PRUint32 type, creator;
macFile->GetFileTypeAndCreator( (OSType*)&type,(OSType*) &creator );
if( !mXML || NS_FAILED (rv = mXML->GetFromTypeCreator( type, creator, fileExt, getter_AddRefs(info) ) ) )
{
if ( mNative )
rv = mNative->GetFromTypeCreator( type, creator, fileExt, getter_AddRefs(info) );
}
if ( NS_SUCCEEDED( rv) )
{
return info->GetMIMEType(aContentType);
}
}
#endif
// Windows, unix and mac when no type match occured.
nsStringKey key(MIMEType.GetBuffer());
nsMIMEInfoImpl *entry = (nsMIMEInfoImpl*)mInfoObjects->Get(&key);
if (!entry) return NS_ERROR_FAILURE;
NS_ADDREF(entry);
*_retval = NS_STATIC_CAST(nsIMIMEInfo*, entry);
return NS_OK;
return GetTypeFromExtension( fileExt, aContentType );
}
// get a specific data source
NS_IMETHODIMP
nsMIMEService::GetXMLDataSource(nsIMIMEDataSource * *aXMLDataSource){
*aXMLDataSource = mXML;
NS_IF_ADDREF( *aXMLDataSource );
return NS_OK;
}
NS_IMETHODIMP
nsMIMEService::GetNativeDataSource(nsIMIMEDataSource * *aNativeDataSource)
{
*aNativeDataSource = mNative;
NS_IF_ADDREF( *aNativeDataSource );
return NS_OK;
}

View File

@@ -18,6 +18,7 @@
* Rights Reserved.
*
* Contributor(s): Judson Valeski
* : David Matiskella
*/
/*
@@ -29,11 +30,8 @@
#define ___nsIMIMEService__h___
#include "nsIMIMEService.h"
#include "nsIMIMEDataSource.h"
#include "nsCOMPtr.h"
#include "nsIURI.h"
#include "nsHashtable.h"
#include "nsISupportsArray.h"
class nsMIMEService : public nsIMIMEService {
@@ -43,19 +41,12 @@ class nsMIMEService : public nsIMIMEService {
// nsMIMEService methods
nsMIMEService();
virtual ~nsMIMEService();
nsresult Init();
static NS_METHOD Create(nsISupports* aOuter, const nsIID& aIID, void* *aResult);
private:
nsresult InitFromURI(nsIURI *aUri);
nsresult InitFromFile(const char *aFileName);
nsresult InitFromHack();
nsHashtable *mInfoObjects; // used for fast access and
// multi index lookups
nsCOMPtr<nsISupportsArray> mInfoArray; // used for enumeration
nsresult Init();
nsCOMPtr<nsIMIMEDataSource> mXML;
nsCOMPtr<nsIMIMEDataSource> mNative;
};
#endif // ___nsIMIMEService__h___

View File

@@ -27,9 +27,12 @@
NS_IMPL_THREADSAFE_ISUPPORTS1(nsMIMEInfoImpl, nsIMIMEInfo);
// nsMIMEInfoImpl methods
nsMIMEInfoImpl::nsMIMEInfoImpl(const char *aMIMEType) {
nsMIMEInfoImpl::nsMIMEInfoImpl() {
NS_INIT_REFCNT();
}
nsMIMEInfoImpl::nsMIMEInfoImpl(const char *aMIMEType): mMIMEType( aMIMEType ) {
NS_INIT_REFCNT();
mMIMEType = getter_AddRefs(NS_NewAtom(aMIMEType));
}
PRUint32
@@ -66,7 +69,7 @@ nsMIMEInfoImpl::ExtensionExists(const char *aExtension, PRBool *_retval) {
if (!aExtension) return NS_ERROR_NULL_POINTER;
for (PRUint8 i=0; i < extCount; i++) {
nsCString* ext = mExtensions.CStringAt(i);
nsCString* ext = (nsCString*)mExtensions.CStringAt(i);
if (ext->Equals(aExtension)) {
found = PR_TRUE;
break;
@@ -87,17 +90,29 @@ nsMIMEInfoImpl::FirstExtension(char **_retval) {
return NS_OK;
}
NS_IMETHODIMP nsMIMEInfoImpl::AppendExtension(const char *aExtension)
{
mExtensions.AppendCString( aExtension );
return NS_OK;
}
NS_IMETHODIMP
nsMIMEInfoImpl::GetMIMEType(char * *aMIMEType) {
if (!aMIMEType) return NS_ERROR_NULL_POINTER;
nsAutoString strMIMEType;
mMIMEType->ToString(strMIMEType);
*aMIMEType = strMIMEType.ToNewCString();
*aMIMEType = mMIMEType.ToNewCString();
if (!*aMIMEType) return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
NS_IMETHODIMP
nsMIMEInfoImpl::SetMIMEType(const char* aMIMEType) {
if (!aMIMEType) return NS_ERROR_NULL_POINTER;
mMIMEType = aMIMEType;
return NS_OK;
}
NS_IMETHODIMP
nsMIMEInfoImpl::GetDescription(PRUnichar * *aDescription) {
if (!aDescription) return NS_ERROR_NULL_POINTER;
@@ -107,6 +122,12 @@ nsMIMEInfoImpl::GetDescription(PRUnichar * *aDescription) {
return NS_OK;
}
NS_IMETHODIMP nsMIMEInfoImpl::SetDescription(const PRUnichar * aDescription)
{
mDescription = aDescription;
return NS_OK;
}
NS_IMETHODIMP
nsMIMEInfoImpl::GetDataURI(nsIURI * *aDataURI) {
return mURI->Clone(aDataURI);
@@ -120,9 +141,31 @@ nsMIMEInfoImpl::Equals(nsIMIMEInfo *aMIMEInfo, PRBool *_retval) {
nsresult rv = aMIMEInfo->GetMIMEType(getter_Copies(type));
if (NS_FAILED(rv)) return rv;
// STRING USE WARNING: perhaps |type1| should be an |nsCAutoString|? -- scc
nsAutoString type1;
mMIMEType->ToString(type1);
*_retval = type1.EqualsWithConversion(type);
*_retval = mMIMEType.EqualsWithConversion(type);
return NS_OK;
}
NS_IMETHODIMP nsMIMEInfoImpl::GetMacType(PRUint32 *aMacType)
{
*aMacType = mMacType;
return NS_OK;
}
NS_IMETHODIMP nsMIMEInfoImpl::SetMacType(PRUint32 aMacType)
{
mMacType = aMacType;
return NS_OK;
}
NS_IMETHODIMP nsMIMEInfoImpl::GetMacCreator(PRUint32 *aMacCreator)
{
*aMacCreator = mMacCreator;
return NS_OK;
}
NS_IMETHODIMP nsMIMEInfoImpl::SetMacCreator(PRUint32 aMacCreator)
{
mMacCreator = aMacCreator;
return NS_OK;
}

View File

@@ -34,6 +34,7 @@ class nsMIMEInfoImpl : public nsIMIMEInfo {
NS_DECL_NSIMIMEINFO
// nsMIMEInfoImpl methods
nsMIMEInfoImpl();
nsMIMEInfoImpl(const char *aMIMEType);
virtual ~nsMIMEInfoImpl() {};
PRUint32 GetExtCount(); // returns the number of extensions associated.
@@ -42,9 +43,9 @@ class nsMIMEInfoImpl : public nsIMIMEInfo {
nsCStringArray mExtensions; // array of file extensions associated w/ this MIME obj
nsAutoString mDescription; // human readable description
nsCOMPtr<nsIURI> mURI; // URI pointing to data associated w/ this obj
PRUint32 mMacType, mMacCreator; // Mac file type and creator
protected:
nsCOMPtr<nsIAtom> mMIMEType;
nsString mMIMEType;
};