⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 legacywebarchive.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1.  Redistributions of source code must retain the above copyright *     notice, this list of conditions and the following disclaimer. * 2.  Redistributions in binary form must reproduce the above copyright *     notice, this list of conditions and the following disclaimer in the *     documentation and/or other materials provided with the distribution. * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of *     its contributors may be used to endorse or promote products derived *     from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include "config.h"#include "LegacyWebArchive.h"#include "CString.h"#include "Cache.h"#include "Document.h"#include "DocumentLoader.h"#include "Frame.h"#include "FrameLoader.h"#include "FrameTree.h"#include "HTMLFrameOwnerElement.h"#include "HTMLNames.h"#include "IconDatabase.h"#include "Image.h"#include "KURLHash.h"#include "Logging.h"#include "markup.h"#include "Node.h"#include "Range.h"#include "SelectionController.h"#include "SharedBuffer.h"#include <wtf/ListHashSet.h>#include <wtf/RetainPtr.h>namespace WebCore {static const CFStringRef LegacyWebArchiveMainResourceKey = CFSTR("WebMainResource");static const CFStringRef LegacyWebArchiveSubresourcesKey = CFSTR("WebSubresources");static const CFStringRef LegacyWebArchiveSubframeArchivesKey = CFSTR("WebSubframeArchives");static const CFStringRef LegacyWebArchiveResourceDataKey = CFSTR("WebResourceData");static const CFStringRef LegacyWebArchiveResourceFrameNameKey = CFSTR("WebResourceFrameName");static const CFStringRef LegacyWebArchiveResourceMIMETypeKey = CFSTR("WebResourceMIMEType");static const CFStringRef LegacyWebArchiveResourceURLKey = CFSTR("WebResourceURL");static const CFStringRef LegacyWebArchiveResourceTextEncodingNameKey = CFSTR("WebResourceTextEncodingName");static const CFStringRef LegacyWebArchiveResourceResponseKey = CFSTR("WebResourceResponse");static const CFStringRef LegacyWebArchiveResourceResponseVersionKey = CFSTR("WebResourceResponseVersion");static RetainPtr<CFDictionaryRef> createPropertyListRepresentationFromResource(ArchiveResource* resource, bool mainResource){    if (!resource) {        // The property list representation of a null/empty WebResource has the following 3 objects stored as nil        RetainPtr<CFMutableDictionaryRef> propertyList(AdoptCF, CFDictionaryCreateMutable(0, 3, 0, 0));        CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceDataKey, 0);        CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceURLKey, 0);        CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceMIMETypeKey, 0);        return propertyList;    }        RetainPtr<CFMutableDictionaryRef> propertyList(AdoptCF, CFDictionaryCreateMutable(0, 6, 0, &kCFTypeDictionaryValueCallBacks));        // Resource data can be empty, but must be represented by an empty CFDataRef    SharedBuffer* data = resource->data();    RetainPtr<CFDataRef> cfData;    if (data)        cfData.adoptCF(data->createCFData());    else        cfData.adoptCF(CFDataCreate(0, 0, 0));    CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceDataKey, cfData.get());        // Resource URL cannot be null    RetainPtr<CFStringRef> cfURL(AdoptCF, resource->url().string().createCFString());    if (cfURL)        CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceURLKey, cfURL.get());    else {        LOG(Archives, "LegacyWebArchive - NULL resource URL is invalid - returning null property list");        return 0;    }    // FrameName should be left out if empty for subresources, but always included for main resources    const String& frameName(resource->frameName());    if (!frameName.isEmpty() || mainResource) {        RetainPtr<CFStringRef> cfFrameName(AdoptCF, frameName.createCFString());        CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceFrameNameKey, cfFrameName.get());    }        // Set MIMEType, TextEncodingName, and ResourceResponse only if they actually exist    const String& mimeType(resource->mimeType());    if (!mimeType.isEmpty()) {        RetainPtr<CFStringRef> cfMIMEType(AdoptCF, mimeType.createCFString());        CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceMIMETypeKey, cfMIMEType.get());    }        const String& textEncoding(resource->textEncoding());    if (!textEncoding.isEmpty()) {        RetainPtr<CFStringRef> cfTextEncoding(AdoptCF, textEncoding.createCFString());        CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceTextEncodingNameKey, cfTextEncoding.get());    }    // Don't include the resource response for the main resource    if (!mainResource) {        RetainPtr<CFDataRef> resourceResponseData = propertyListDataFromResourceResponse(resource->response());        if (resourceResponseData)            CFDictionarySetValue(propertyList.get(), LegacyWebArchiveResourceResponseKey, resourceResponseData.get());        }        return propertyList;}static RetainPtr<CFDictionaryRef> createPropertyListRep(Archive* archive){    RetainPtr<CFMutableDictionaryRef> propertyList(AdoptCF, CFDictionaryCreateMutable(0, 3, 0, &kCFTypeDictionaryValueCallBacks));        RetainPtr<CFDictionaryRef> mainResourceDict = createPropertyListRepresentationFromResource(archive->mainResource(), true);    if (!mainResourceDict)        return 0;    CFDictionarySetValue(propertyList.get(), LegacyWebArchiveMainResourceKey, mainResourceDict.get());            RetainPtr<CFMutableArrayRef> subresourcesArray(AdoptCF, CFArrayCreateMutable(0, archive->subresources().size(), &kCFTypeArrayCallBacks));    const Vector<RefPtr<ArchiveResource> >& subresources(archive->subresources());    for (unsigned i = 0; i < subresources.size(); ++i) {        RetainPtr<CFDictionaryRef> subresource = createPropertyListRepresentationFromResource(subresources[i].get(), false);        if (subresource)            CFArrayAppendValue(subresourcesArray.get(), subresource.get());        else            LOG(Archives, "LegacyWebArchive - Failed to create property list for subresource");    }    if (CFArrayGetCount(subresourcesArray.get()))        CFDictionarySetValue(propertyList.get(), LegacyWebArchiveSubresourcesKey, subresourcesArray.get());    RetainPtr<CFMutableArrayRef> subframesArray(AdoptCF, CFArrayCreateMutable(0, archive->subframeArchives().size(), &kCFTypeArrayCallBacks));    const Vector<RefPtr<Archive> >& subframeArchives(archive->subframeArchives());    for (unsigned i = 0; i < subframeArchives.size(); ++i) {        RetainPtr<CFDictionaryRef> subframeArchive = createPropertyListRep(subframeArchives[i].get());        if (subframeArchive)            CFArrayAppendValue(subframesArray.get(), subframeArchive.get());        else            LOG(Archives, "LegacyWebArchive - Failed to create property list for subframe archive");    }    if (CFArrayGetCount(subframesArray.get()))        CFDictionarySetValue(propertyList.get(), LegacyWebArchiveSubframeArchivesKey, subframesArray.get());    return propertyList;}static ResourceResponse createResourceResponseFromPropertyListData(CFDataRef data, CFStringRef responseDataType){    ASSERT(data);    if (!data)        return ResourceResponse();        // If the ResourceResponseVersion (passed in as responseDataType) exists at all, this is a "new" webarchive that we can parse well in a cross platform manner    // If it doesn't exist, we will assume this is an "old" Cocoa-based WebArchive, and parse the ResourceResponse as such    if (!responseDataType)        return createResourceResponseFromMacArchivedData(data);            // FIXME: Parse the "new" format that the above comment references here    return ResourceResponse();}static PassRefPtr<ArchiveResource> createResource(CFDictionaryRef dictionary){    ASSERT(dictionary);    if (!dictionary)        return 0;            CFDataRef resourceData = static_cast<CFDataRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveResourceDataKey));    if (resourceData && CFGetTypeID(resourceData) != CFDataGetTypeID()) {        LOG(Archives, "LegacyWebArchive - Resource data is not of type CFData, cannot create invalid resource");        return 0;    }        CFStringRef frameName = static_cast<CFStringRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveResourceFrameNameKey));    if (frameName && CFGetTypeID(frameName) != CFStringGetTypeID()) {        LOG(Archives, "LegacyWebArchive - Frame name is not of type CFString, cannot create invalid resource");        return 0;    }        CFStringRef mimeType = static_cast<CFStringRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveResourceMIMETypeKey));    if (mimeType && CFGetTypeID(mimeType) != CFStringGetTypeID()) {        LOG(Archives, "LegacyWebArchive - MIME type is not of type CFString, cannot create invalid resource");        return 0;    }        CFStringRef url = static_cast<CFStringRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveResourceURLKey));    if (url && CFGetTypeID(url) != CFStringGetTypeID()) {        LOG(Archives, "LegacyWebArchive - URL is not of type CFString, cannot create invalid resource");        return 0;    }        CFStringRef textEncoding = static_cast<CFStringRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveResourceTextEncodingNameKey));    if (textEncoding && CFGetTypeID(textEncoding) != CFStringGetTypeID()) {        LOG(Archives, "LegacyWebArchive - Text encoding is not of type CFString, cannot create invalid resource");        return 0;    }    ResourceResponse response;        CFDataRef resourceResponseData = static_cast<CFDataRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveResourceResponseKey));    if (resourceResponseData) {        if (CFGetTypeID(resourceResponseData) != CFDataGetTypeID()) {            LOG(Archives, "LegacyWebArchive - Resource response data is not of type CFData, cannot create invalid resource");            return 0;        }                CFStringRef resourceResponseVersion = static_cast<CFStringRef>(CFDictionaryGetValue(dictionary, LegacyWebArchiveResourceResponseVersionKey));        if (resourceResponseVersion && CFGetTypeID(resourceResponseVersion) != CFStringGetTypeID()) {            LOG(Archives, "LegacyWebArchive - Resource response version is not of type CFString, cannot create invalid resource");            return 0;        }                response = createResourceResponseFromPropertyListData(resourceResponseData, resourceResponseVersion);    }        return ArchiveResource::create(SharedBuffer::create(CFDataGetBytePtr(resourceData), CFDataGetLength(resourceData)), KURL(url), mimeType, textEncoding, frameName, response);}PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(){    return adoptRef(new LegacyWebArchive);}PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(SharedBuffer* data){    LOG(Archives, "LegacyWebArchive - Creating from raw data");        RefPtr<LegacyWebArchive> archive = create();    if (!archive->init(data))        return 0;            return archive.release();}PassRefPtr<LegacyWebArchive> LegacyWebArchive::create(PassRefPtr<ArchiveResource> mainResource, Vector<PassRefPtr<ArchiveResource> >& subresources, Vector<PassRefPtr<LegacyWebArchive> >& subframeArchives){    ASSERT(mainResource);    if (!mainResource)        return 0;        RefPtr<LegacyWebArchive> archive = create();    archive->setMainResource(mainResource);        for (unsigned i = 0; i < subresources.size(); ++i)        archive->addSubresource(subresources[i]);        for (unsigned i = 0; i < subframeArchives.size(); ++i)        archive->addSubframeArchive(subframeArchives[i]);              return archive.release();}LegacyWebArchive::LegacyWebArchive(){}bool LegacyWebArchive::init(SharedBuffer* data){    ASSERT(data);    if (!data)        return false;            RetainPtr<CFDataRef> cfData(AdoptCF, data->createCFData());    if (!cfData)        return false;            CFStringRef errorString = 0;        RetainPtr<CFDictionaryRef> plist(AdoptCF, static_cast<CFDictionaryRef>(CFPropertyListCreateFromXMLData(0, cfData.get(), kCFPropertyListImmutable, &errorString)));    if (!plist) {#ifndef NDEBUG        const char* cError = errorString ? CFStringGetCStringPtr(errorString, kCFStringEncodingUTF8) : "unknown error";        LOG(Archives, "LegacyWebArchive - Error parsing PropertyList from archive data - %s", cError);#endif        if (errorString)            CFRelease(errorString);        return false;    }        if (CFGetTypeID(plist.get()) != CFDictionaryGetTypeID()) {        LOG(Archives, "LegacyWebArchive - Archive property list is not the expected CFDictionary, aborting invalid WebArchive");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -