Bug 564485: Support "WebPluginMIMETypesFilename" for getting plugin MIME types on Mac OS X. r=josh a=blocking-betaN+

This commit is contained in:
Scott Greenlay 2010-10-25 13:56:46 -04:00
parent 02f52a1b02
commit f6c3ba522a

View File

@ -171,69 +171,165 @@ static char* CFStringRefToUTF8Buffer(CFStringRef cfString)
return newBuffer;
}
class AutoCFTypeObject {
public:
AutoCFTypeObject(CFTypeRef object)
{
mObject = object;
}
~AutoCFTypeObject()
{
::CFRelease(mObject);
}
private:
CFTypeRef mObject;
};
static CFDictionaryRef ParsePlistForMIMETypesFilename(CFBundleRef bundle)
{
CFTypeRef mimeFileName = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginMIMETypesFilename"));
if (!mimeFileName || ::CFGetTypeID(mimeFileName) != ::CFStringGetTypeID()) {
return NULL;
}
FSRef homeDir;
if (::FSFindFolder(kUserDomain, kCurrentUserFolderType, kDontCreateFolder, &homeDir) != noErr) {
return NULL;
}
CFURLRef userDirURL = ::CFURLCreateFromFSRef(kCFAllocatorDefault, &homeDir);
if (!userDirURL) {
return NULL;
}
AutoCFTypeObject userDirURLAutorelease(userDirURL);
CFStringRef mimeFilePath = ::CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("Library/Preferences/%@"), static_cast<CFStringRef>(mimeFileName));
if (!mimeFilePath) {
return NULL;
}
AutoCFTypeObject mimeFilePathAutorelease(mimeFilePath);
CFURLRef mimeFileURL = ::CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorDefault, mimeFilePath, kCFURLPOSIXPathStyle, false, userDirURL);
if (!mimeFileURL) {
return NULL;
}
AutoCFTypeObject mimeFileURLAutorelease(mimeFileURL);
SInt32 errorCode = 0;
CFDataRef mimeFileData = NULL;
Boolean result = ::CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, mimeFileURL, &mimeFileData, NULL, NULL, &errorCode);
if (!result) {
return NULL;
}
AutoCFTypeObject mimeFileDataAutorelease(mimeFileData);
if (errorCode != 0) {
return NULL;
}
CFPropertyListRef propertyList = ::CFPropertyListCreateFromXMLData(kCFAllocatorDefault, mimeFileData, kCFPropertyListImmutable, NULL);
if (!propertyList) {
return NULL;
}
AutoCFTypeObject propertyListAutorelease(propertyList);
if (::CFGetTypeID(propertyList) != ::CFDictionaryGetTypeID()) {
return NULL;
}
CFTypeRef localizedName = ::CFDictionaryGetValue(static_cast<CFDictionaryRef>(propertyList), CFSTR("WebPluginLocalizationName"));
if (!localizedName || ::CFGetTypeID(localizedName) != ::CFStringGetTypeID()) {
return NULL;
}
CFLocaleRef currentLocale = ::CFLocaleCopyCurrent();
if (!currentLocale) {
return NULL;
}
AutoCFTypeObject currentLocaleAutorelease(currentLocale);
if (::CFStringCompare(static_cast<CFStringRef>(localizedName), ::CFLocaleGetIdentifier(currentLocale), 0) != kCFCompareEqualTo) {
return NULL;
}
CFTypeRef mimeTypes = ::CFDictionaryGetValue(static_cast<CFDictionaryRef>(propertyList), CFSTR("WebPluginMIMETypes"));
if (!mimeTypes || ::CFGetTypeID(mimeTypes) != ::CFDictionaryGetTypeID() || ::CFDictionaryGetCount(static_cast<CFDictionaryRef>(mimeTypes)) == 0) {
return NULL;
}
return static_cast<CFDictionaryRef>(::CFRetain(mimeTypes));
}
static void ParsePlistPluginInfo(nsPluginInfo& info, CFBundleRef bundle)
{
CFTypeRef mimeDict = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginMIMETypes"));
if (mimeDict && ::CFGetTypeID(mimeDict) == ::CFDictionaryGetTypeID() && ::CFDictionaryGetCount(static_cast<CFDictionaryRef>(mimeDict)) > 0) {
int mimeDictKeyCount = ::CFDictionaryGetCount(static_cast<CFDictionaryRef>(mimeDict));
CFDictionaryRef mimeDict = ParsePlistForMIMETypesFilename(bundle);
if (!mimeDict) {
CFTypeRef mimeTypes = ::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginMIMETypes"));
if (!mimeTypes || ::CFGetTypeID(mimeTypes) != ::CFDictionaryGetTypeID() || ::CFDictionaryGetCount(static_cast<CFDictionaryRef>(mimeTypes)) == 0)
return;
mimeDict = static_cast<CFDictionaryRef>(::CFRetain(mimeTypes));
}
AutoCFTypeObject mimeDictAutorelease(mimeDict);
int mimeDictKeyCount = ::CFDictionaryGetCount(mimeDict);
// Allocate memory for mime data
int mimeDataArraySize = mimeDictKeyCount * sizeof(char*);
info.fMimeTypeArray = static_cast<char**>(NS_Alloc(mimeDataArraySize));
if (!info.fMimeTypeArray)
return;
memset(info.fMimeTypeArray, 0, mimeDataArraySize);
info.fExtensionArray = static_cast<char**>(NS_Alloc(mimeDataArraySize));
if (!info.fExtensionArray)
return;
memset(info.fExtensionArray, 0, mimeDataArraySize);
info.fMimeDescriptionArray = static_cast<char**>(NS_Alloc(mimeDataArraySize));
if (!info.fMimeDescriptionArray)
return;
memset(info.fMimeDescriptionArray, 0, mimeDataArraySize);
// Allocate memory for mime data
int mimeDataArraySize = mimeDictKeyCount * sizeof(char*);
info.fMimeTypeArray = static_cast<char**>(NS_Alloc(mimeDataArraySize));
if (!info.fMimeTypeArray)
return;
memset(info.fMimeTypeArray, 0, mimeDataArraySize);
info.fExtensionArray = static_cast<char**>(NS_Alloc(mimeDataArraySize));
if (!info.fExtensionArray)
return;
memset(info.fExtensionArray, 0, mimeDataArraySize);
info.fMimeDescriptionArray = static_cast<char**>(NS_Alloc(mimeDataArraySize));
if (!info.fMimeDescriptionArray)
return;
memset(info.fMimeDescriptionArray, 0, mimeDataArraySize);
// Allocate memory for mime dictionary keys and values
nsAutoArrayPtr<CFTypeRef> keys(new CFTypeRef[mimeDictKeyCount]);
if (!keys)
return;
nsAutoArrayPtr<CFTypeRef> values(new CFTypeRef[mimeDictKeyCount]);
if (!values)
return;
// Allocate memory for mime dictionary keys and values
nsAutoArrayPtr<CFTypeRef> keys(new CFTypeRef[mimeDictKeyCount]);
if (!keys)
return;
nsAutoArrayPtr<CFTypeRef> values(new CFTypeRef[mimeDictKeyCount]);
if (!values)
return;
// Set the variant count now that we have safely allocated memory
info.fVariantCount = mimeDictKeyCount;
// Set the variant count now that we have safely allocated memory
info.fVariantCount = mimeDictKeyCount;
::CFDictionaryGetKeysAndValues(static_cast<CFDictionaryRef>(mimeDict), keys, values);
for (int i = 0; i < mimeDictKeyCount; i++) {
CFTypeRef mimeString = keys[i];
if (mimeString && ::CFGetTypeID(mimeString) == ::CFStringGetTypeID()) {
info.fMimeTypeArray[i] = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(mimeString));
}
else {
info.fVariantCount -= 1;
continue;
}
CFTypeRef mimeDict = values[i];
if (mimeDict && ::CFGetTypeID(mimeDict) == ::CFDictionaryGetTypeID()) {
CFTypeRef extensions = ::CFDictionaryGetValue(static_cast<CFDictionaryRef>(mimeDict), CFSTR("WebPluginExtensions"));
if (extensions && ::CFGetTypeID(extensions) == ::CFArrayGetTypeID()) {
int extensionCount = ::CFArrayGetCount(static_cast<CFArrayRef>(extensions));
CFMutableStringRef extensionList = ::CFStringCreateMutable(kCFAllocatorDefault, 0);
for (int j = 0; j < extensionCount; j++) {
CFTypeRef extension = ::CFArrayGetValueAtIndex(static_cast<CFArrayRef>(extensions), j);
if (extension && ::CFGetTypeID(extension) == ::CFStringGetTypeID()) {
if (j > 0)
::CFStringAppend(extensionList, CFSTR(","));
::CFStringAppend(static_cast<CFMutableStringRef>(extensionList), static_cast<CFStringRef>(extension));
}
::CFDictionaryGetKeysAndValues(mimeDict, keys, values);
for (int i = 0; i < mimeDictKeyCount; i++) {
CFTypeRef mimeString = keys[i];
if (mimeString && ::CFGetTypeID(mimeString) == ::CFStringGetTypeID()) {
info.fMimeTypeArray[i] = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(mimeString));
}
else {
info.fVariantCount -= 1;
continue;
}
CFTypeRef mimeDict = values[i];
if (mimeDict && ::CFGetTypeID(mimeDict) == ::CFDictionaryGetTypeID()) {
CFTypeRef extensions = ::CFDictionaryGetValue(static_cast<CFDictionaryRef>(mimeDict), CFSTR("WebPluginExtensions"));
if (extensions && ::CFGetTypeID(extensions) == ::CFArrayGetTypeID()) {
int extensionCount = ::CFArrayGetCount(static_cast<CFArrayRef>(extensions));
CFMutableStringRef extensionList = ::CFStringCreateMutable(kCFAllocatorDefault, 0);
for (int j = 0; j < extensionCount; j++) {
CFTypeRef extension = ::CFArrayGetValueAtIndex(static_cast<CFArrayRef>(extensions), j);
if (extension && ::CFGetTypeID(extension) == ::CFStringGetTypeID()) {
if (j > 0)
::CFStringAppend(extensionList, CFSTR(","));
::CFStringAppend(static_cast<CFMutableStringRef>(extensionList), static_cast<CFStringRef>(extension));
}
info.fExtensionArray[i] = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(extensionList));
::CFRelease(extensionList);
}
CFTypeRef description = ::CFDictionaryGetValue(static_cast<CFDictionaryRef>(mimeDict), CFSTR("WebPluginTypeDescription"));
if (description && ::CFGetTypeID(description) == ::CFStringGetTypeID())
info.fMimeDescriptionArray[i] = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(description));
info.fExtensionArray[i] = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(extensionList));
::CFRelease(extensionList);
}
CFTypeRef description = ::CFDictionaryGetValue(static_cast<CFDictionaryRef>(mimeDict), CFSTR("WebPluginTypeDescription"));
if (description && ::CFGetTypeID(description) == ::CFStringGetTypeID())
info.fMimeDescriptionArray[i] = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(description));
}
}
}