Bug 247981 necko depends on libpr0n

r=pavlov sr=darin
This commit is contained in:
cbiesinger%web.de 2004-07-19 18:53:02 +00:00
parent fd60db1bcd
commit 0c7a7ecb91
11 changed files with 125 additions and 46 deletions

View File

@ -151,11 +151,15 @@ static NS_METHOD ImageRegisterProc(nsIComponentManager *aCompMgr,
nsCOMPtr<nsICategoryManager> catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv));
if (NS_FAILED(rv))
return rv;
for (int i = 0; i < sizeof(gImageMimeTypes)/sizeof(*gImageMimeTypes); i++) {
for (unsigned i = 0; i < sizeof(gImageMimeTypes)/sizeof(*gImageMimeTypes); i++) {
catMan->AddCategoryEntry("Gecko-Content-Viewers", gImageMimeTypes[i],
"@mozilla.org/content/document-loader-factory;1",
PR_TRUE, PR_TRUE, nsnull);
}
catMan->AddCategoryEntry("content-sniffing-services", "@mozilla.org/image/loader;1",
"@mozilla.org/image/loader;1", PR_TRUE, PR_TRUE,
nsnull);
return NS_OK;
}
@ -167,7 +171,7 @@ static NS_METHOD ImageUnregisterProc(nsIComponentManager *aCompMgr,
nsCOMPtr<nsICategoryManager> catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv));
if (NS_FAILED(rv))
return rv;
for (int i = 0; i < sizeof(gImageMimeTypes)/sizeof(*gImageMimeTypes); i++)
for (unsigned i = 0; i < sizeof(gImageMimeTypes)/sizeof(*gImageMimeTypes); i++)
catMan->DeleteCategoryEntry("Gecko-Content-Viewers", gImageMimeTypes[i], PR_TRUE);
return NS_OK;

View File

@ -58,7 +58,7 @@ interface nsISimpleEnumerator;
* @version 0.3
* @see imagelib2
*/
[scriptable, uuid(4c8cf1e0-1dd2-11b2-aff9-c51cdbfcb6da)]
[scriptable, uuid(a32826ff-9e56-4425-a811-97a8dba64ff5)]
interface imgILoader : nsISupports
{
/**
@ -109,12 +109,4 @@ interface imgILoader : nsISupports
* @return true if a decoder is available, false otherwise
*/
boolean supportImageWithMimeType(in string mimeType);
/**
* Checks if a decoder for the given contents is available.
* @param contents The first few bytes of the image
* @param length The length of contents
* @return The Content Type of the Image or null if no decoder was found.
*/
string supportImageWithContents(in string contents, in unsigned long length);
};

View File

@ -102,7 +102,7 @@ static void PrintImageDecoders()
}
#endif
NS_IMPL_ISUPPORTS1(imgLoader, imgILoader)
NS_IMPL_ISUPPORTS2(imgLoader, imgILoader, nsIContentSniffer)
imgLoader::imgLoader()
{
@ -727,18 +727,17 @@ NS_IMETHODIMP imgLoader::SupportImageWithMimeType(const char* aMimeType, PRBool
return reg->IsContractIDRegistered(decoderId.get(), _retval);
}
NS_IMETHODIMP imgLoader::SupportImageWithContents(const char* aContents, PRUint32 aLength, char** aContentType)
NS_IMETHODIMP imgLoader::GetMIMETypeFromContent(const PRUint8* aContents, PRUint32 aLength, nsACString& aContentType)
{
return GetMimeTypeFromContent(aContents, aLength, aContentType);
return GetMimeTypeFromContent((const char*)aContents, aLength, aContentType);
}
/* static */
nsresult imgLoader::GetMimeTypeFromContent(const char* aContents, PRUint32 aLength, char** aContentType)
nsresult imgLoader::GetMimeTypeFromContent(const char* aContents, PRUint32 aLength, nsACString& aContentType)
{
*aContentType = nsnull;
/* Is it a GIF? */
if (aLength >= 4 && !nsCRT::strncmp(aContents, "GIF8", 4)) {
*aContentType = nsCRT::strndup("image/gif", 9);
aContentType.AssignLiteral("image/gif");
}
/* or a PNG? */
@ -747,7 +746,7 @@ nsresult imgLoader::GetMimeTypeFromContent(const char* aContents, PRUint32 aLeng
(unsigned char)aContents[2]==0x4E &&
(unsigned char)aContents[3]==0x47))
{
*aContentType = nsCRT::strndup("image/png", 9);
aContentType.AssignLiteral("image/png");
}
/* maybe a JPEG (JFIF)? */
@ -762,7 +761,7 @@ nsresult imgLoader::GetMimeTypeFromContent(const char* aContents, PRUint32 aLeng
((unsigned char)aContents[1])==0xD8 &&
((unsigned char)aContents[2])==0xFF)
{
*aContentType = nsCRT::strndup("image/jpeg", 10);
aContentType.AssignLiteral("image/jpeg");
}
/* or how about ART? */
@ -774,31 +773,27 @@ nsresult imgLoader::GetMimeTypeFromContent(const char* aContents, PRUint32 aLeng
((unsigned char) aContents[1])==0x47 &&
((unsigned char) aContents[4])==0x00 )
{
*aContentType = nsCRT::strndup("image/x-jg", 10);
aContentType.AssignLiteral("image/x-jg");
}
else if (aLength >= 2 && !nsCRT::strncmp(aContents, "BM", 2)) {
*aContentType = nsCRT::strndup("image/bmp", 9);
aContentType.AssignLiteral("image/bmp");
}
// ICOs always begin with a 2-byte 0 followed by a 2-byte 1.
else if (aLength >= 4 && !memcmp(aContents, "\000\000\001\000", 4)) {
*aContentType = nsCRT::strndup("image/x-icon", 12);
aContentType.AssignLiteral("image/x-icon");
}
else if (aLength >= 8 && !nsCRT::strncmp(aContents, "#define ", 8)) {
*aContentType = nsCRT::strndup("image/x-xbitmap", 15);
aContentType.AssignLiteral("image/x-xbitmap");
}
else {
/* none of the above? I give up */
/* don't raise an exception, simply return null */
return NS_OK;
return NS_ERROR_NOT_AVAILABLE;
}
if (*aContentType)
return NS_OK;
return NS_ERROR_OUT_OF_MEMORY;
}
/**

View File

@ -38,6 +38,7 @@
* ***** END LICENSE BLOCK ***** */
#include "imgILoader.h"
#include "nsIContentSniffer.h"
#ifdef LOADER_THREADSAFE
#include "prlock.h"
@ -57,16 +58,17 @@ class nsILoadGroup;
{0xa5, 0xb8, 0x95, 0x1f, 0x13, 0xc8, 0x46, 0xf7} \
}
class imgLoader : public imgILoader
class imgLoader : public imgILoader, public nsIContentSniffer
{
public:
NS_DECL_ISUPPORTS
NS_DECL_IMGILOADER
NS_DECL_NSICONTENTSNIFFER
imgLoader();
virtual ~imgLoader();
static nsresult GetMimeTypeFromContent(const char* aContents, PRUint32 aLength, char** aContentType);
static nsresult GetMimeTypeFromContent(const char* aContents, PRUint32 aLength, nsACString& aContentType);
private:
nsresult CreateNewProxyForRequest(imgRequest *aRequest, nsILoadGroup *aLoadGroup,

View File

@ -844,5 +844,5 @@ static NS_METHOD sniff_mimetype_callback(nsIInputStream* in,
void
imgRequest::SniffMimeType(const char *buf, PRUint32 len)
{
imgLoader::GetMimeTypeFromContent(buf, len, getter_Copies(mContentType));
imgLoader::GetMimeTypeFromContent(buf, len, mContentType);
}

View File

@ -134,7 +134,7 @@ private:
PRUint32 mImageStatus;
PRUint32 mState;
nsXPIDLCString mContentType;
nsCString mContentType;
nsCOMPtr<nsICacheEntryDescriptor> mCacheEntry; /* we hold on to this to this so long as we have observers */

View File

@ -104,6 +104,7 @@ XPIDLSRCS = \
nsIMultiPartChannel.idl \
nsIExternalProtocolHandler.idl \
nsIAuthModule.idl \
nsIContentSniffer.idl \
$(NULL)
EXPORTS = \

View File

@ -0,0 +1,56 @@
/* ***** 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 necko content sniffer interface.
*
* The Initial Developer of the Original Code is
* Christian Biesinger <cbiesinger@web.de>.
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either 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 ***** */
#include "nsISupports.idl"
/**
* Content sniffer interface. Components implementing this interface can
* determine a MIME type from a chunk of bytes.
*/
[scriptable, uuid(a5710331-74ec-45fb-aa85-ed3bc7c36924)]
interface nsIContentSniffer : nsISupports
{
/**
* Given a chunk of data, determines a MIME type.
*
* @param aData Data to check
* @param aLength Length of the data
*
* @throw NS_ERROR_NOT_AVAILABLE if no MIME type could be determinted.
*/
ACString getMIMETypeFromContent([const,array,size_is(aLength)] in octet aData,
in unsigned long aLength);
};

View File

@ -53,7 +53,6 @@ REQUIRES = xpcom \
util \
pref \
uconv \
imglib2 \
necko2 \
$(ZLIB_REQUIRES) \
$(NULL)

View File

@ -47,7 +47,9 @@
#include "nsXPIDLString.h"
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "imgILoader.h"
#include "nsICategoryManager.h"
#include "nsISupportsPrimitives.h"
#include "nsIContentSniffer.h"
#include "nsCRT.h"
@ -346,7 +348,7 @@ void nsUnknownDecoder::DetermineContentType(nsIRequest* aRequest)
}
}
if (SniffForImageMimeType(aRequest)) {
if (TryContentSniffers(aRequest)) {
return;
}
@ -363,19 +365,47 @@ void nsUnknownDecoder::DetermineContentType(nsIRequest* aRequest)
LastDitchSniff(aRequest);
}
PRBool nsUnknownDecoder::SniffForImageMimeType(nsIRequest* aRequest)
PRBool nsUnknownDecoder::TryContentSniffers(nsIRequest* aRequest)
{
// Just ask libpr0n
nsCOMPtr<imgILoader> loader(do_GetService("@mozilla.org/image/loader;1"));
if (!loader) return PR_FALSE;
// Enumerate content sniffers
nsCOMPtr<nsICategoryManager> catMan(do_GetService("@mozilla.org/categorymanager;1"));
if (!catMan) {
return PR_FALSE;
}
char* temp;
nsresult rv = loader->SupportImageWithContents(mBuffer, mBufferLen, &temp);
if (NS_FAILED(rv) || !temp) return PR_FALSE;
nsCOMPtr<nsISimpleEnumerator> sniffers;
catMan->EnumerateCategory("content-sniffing-services", getter_AddRefs(sniffers));
if (!sniffers) {
return PR_FALSE;
}
mContentType.Adopt(temp);
PRBool hasMore;
while (NS_SUCCEEDED(sniffers->HasMoreElements(&hasMore)) && hasMore) {
nsCOMPtr<nsISupports> elem;
sniffers->GetNext(getter_AddRefs(elem));
NS_ASSERTION(elem, "No element even though hasMore returned true!?");
nsCOMPtr<nsISupportsCString> sniffer_id(do_QueryInterface(elem));
NS_ASSERTION(sniffer_id, "element is no nsISupportsCString!?");
nsCAutoString contractid;
nsresult rv = sniffer_id->GetData(contractid);
if (NS_FAILED(rv)) {
continue;
}
nsCOMPtr<nsIContentSniffer> sniffer(do_GetService(contractid.get()));
if (!sniffer) {
continue;
}
rv = sniffer->GetMIMETypeFromContent((const PRUint8*)mBuffer, mBufferLen, mContentType);
if (NS_SUCCEEDED(rv)) {
return PR_TRUE;
}
}
return PR_FALSE;
}
PRBool nsUnknownDecoder::SniffForHTML(nsIRequest* aRequest)
{

View File

@ -88,7 +88,7 @@ protected:
// Various sniffer functions. Returning PR_TRUE means that a type
// was determined; PR_FALSE means no luck.
PRBool SniffForImageMimeType(nsIRequest* aRequest);
PRBool TryContentSniffers(nsIRequest* aRequest);
PRBool SniffForHTML(nsIRequest* aRequest);
PRBool SniffForXML(nsIRequest* aRequest);