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

📄 webarchive.mm

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 MM
字号:
/* * Copyright (C) 2005, 2006, 2007, 2008 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. */#import "WebArchive.h"#import "WebArchiveInternal.h"#import "WebKitLogging.h"#import "WebNSObjectExtras.h"#import "WebResourceInternal.h"#import "WebTypesInternal.h"#import <JavaScriptCore/InitializeThreading.h>#import <WebCore/ArchiveResource.h>#import <WebCore/LegacyWebArchive.h>#import <WebCore/ThreadCheck.h>#import <WebCore/WebCoreObjCExtras.h>using namespace WebCore;NSString *WebArchivePboardType = @"Apple Web Archive pasteboard type";static NSString * const WebMainResourceKey = @"WebMainResource";static NSString * const WebSubresourcesKey = @"WebSubresources";static NSString * const WebSubframeArchivesKey = @"WebSubframeArchives";@interface WebArchivePrivate : NSObject {@public    WebResource *cachedMainResource;    NSArray *cachedSubresources;    NSArray *cachedSubframeArchives;@private    RefPtr<LegacyWebArchive> coreArchive;}- (id)initWithCoreArchive:(PassRefPtr<LegacyWebArchive>)coreArchive;- (LegacyWebArchive*)coreArchive;- (void)setCoreArchive:(PassRefPtr<LegacyWebArchive>)newCoreArchive;@end@implementation WebArchivePrivate+ (void)initialize{    JSC::initializeThreading();#ifndef BUILDING_ON_TIGER    WebCoreObjCFinalizeOnMainThread(self);#endif}- (id)init{    self = [super init];    if (!self)        return nil;    coreArchive = LegacyWebArchive::create();    return self;}- (id)initWithCoreArchive:(PassRefPtr<LegacyWebArchive>)_coreArchive{    self = [super init];    if (!self || !_coreArchive) {        [self release];        return nil;    }    coreArchive = _coreArchive;    return self;}- (LegacyWebArchive*)coreArchive{    return coreArchive.get();}- (void)setCoreArchive:(PassRefPtr<LegacyWebArchive>)newCoreArchive{    ASSERT(coreArchive);    ASSERT(newCoreArchive);    coreArchive = newCoreArchive;}- (void)dealloc{    if (WebCoreObjCScheduleDeallocateOnMainThread([WebArchivePrivate class], self))        return;        [cachedMainResource release];    [cachedSubresources release];    [cachedSubframeArchives release];        [super dealloc];}@end@implementation WebArchive- (id)init{    WebCoreThreadViolationCheck();    self = [super init];    if (!self)        return nil;    _private = [[WebArchivePrivate alloc] init];    return self;}static BOOL isArrayOfClass(id object, Class elementClass){    if (![object isKindOfClass:[NSArray class]])        return NO;    NSArray *array = (NSArray *)object;    NSUInteger count = [array count];    for (NSUInteger i = 0; i < count; ++i)        if (![[array objectAtIndex:i] isKindOfClass:elementClass])            return NO;    return YES;}- (id)initWithMainResource:(WebResource *)mainResource subresources:(NSArray *)subresources subframeArchives:(NSArray *)subframeArchives{#ifdef MAIL_THREAD_WORKAROUND    if (needMailThreadWorkaround())        return [[self _webkit_invokeOnMainThread] initWithMainResource:mainResource subresources:subresources subframeArchives:subframeArchives];#endif    WebCoreThreadViolationCheck();    self = [super init];    if (!self)        return nil;    _private = [[WebArchivePrivate alloc] init];    _private->cachedMainResource = [mainResource retain];    if (!_private->cachedMainResource) {        [self release];        return nil;    }        if (!subresources || isArrayOfClass(subresources, [WebResource class]))        _private->cachedSubresources = [subresources retain];    else {        [self release];        return nil;    }    if (!subframeArchives || isArrayOfClass(subframeArchives, [WebArchive class]))        _private->cachedSubframeArchives = [subframeArchives retain];    else {        [self release];        return nil;    }        RefPtr<ArchiveResource> coreMainResource = mainResource ? [mainResource _coreResource] : 0;    Vector<PassRefPtr<ArchiveResource> > coreResources;    NSEnumerator *enumerator = [subresources objectEnumerator];    WebResource *subresource;    while ((subresource = [enumerator nextObject]) != nil)        coreResources.append([subresource _coreResource]);    Vector<PassRefPtr<LegacyWebArchive> > coreArchives;    enumerator = [subframeArchives objectEnumerator];    WebArchive *subframeArchive;    while ((subframeArchive = [enumerator nextObject]) != nil)        coreArchives.append([subframeArchive->_private coreArchive]);    [_private setCoreArchive:LegacyWebArchive::create(coreMainResource.release(), coreResources, coreArchives)];    if (![_private coreArchive]) {        [self release];        return nil;    }    return self;}- (id)initWithData:(NSData *)data{    WebCoreThreadViolationCheck();    self = [super init];    if (!self)        return nil;        #if !LOG_DISABLED    CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();#endif    _private = [[WebArchivePrivate alloc] init];    RefPtr<LegacyWebArchive> coreArchive = LegacyWebArchive::create(SharedBuffer::wrapNSData(data).get());    if (!coreArchive) {        [self release];        return nil;    }            [_private setCoreArchive:coreArchive.release()];        #if !LOG_DISABLED    CFAbsoluteTime end = CFAbsoluteTimeGetCurrent();    CFAbsoluteTime duration = end - start;#endif    LOG(Timing, "Parsing web archive with [NSPropertyListSerialization propertyListFromData::::] took %f seconds", duration);        return self;}- (id)initWithCoder:(NSCoder *)decoder{        WebResource *mainResource = nil;    NSArray *subresources = nil;    NSArray *subframeArchives = nil;        @try {        id object = [decoder decodeObjectForKey:WebMainResourceKey];        if ([object isKindOfClass:[WebResource class]])            mainResource = [object retain];        object = [decoder decodeObjectForKey:WebSubresourcesKey];        if (isArrayOfClass(object, [WebResource class]))            subresources = [object retain];        object = [decoder decodeObjectForKey:WebSubframeArchivesKey];        if (isArrayOfClass(object, [WebArchive class]))            subframeArchives = [object retain];    } @catch(id) {        [self release];        return nil;    }    return [self initWithMainResource:mainResource subresources:subresources subframeArchives:subframeArchives];}- (void)encodeWithCoder:(NSCoder *)encoder{    [encoder encodeObject:[self mainResource] forKey:WebMainResourceKey];    [encoder encodeObject:[self subresources] forKey:WebSubresourcesKey];    [encoder encodeObject:[self subframeArchives] forKey:WebSubframeArchivesKey];    }- (void)dealloc{    [_private release];    [super dealloc];}- (id)copyWithZone:(NSZone *)zone{    return [self retain];}- (WebResource *)mainResource{#ifdef MAIL_THREAD_WORKAROUND    if (needMailThreadWorkaround())        return [[self _webkit_invokeOnMainThread] mainResource];#endif    WebCoreThreadViolationCheck();    // Currently from WebKit API perspective, WebArchives are entirely immutable once created    // If they ever become mutable, we'll need to rethink this.     if (!_private->cachedMainResource) {        LegacyWebArchive* coreArchive = [_private coreArchive];        if (coreArchive)            _private->cachedMainResource = [[WebResource alloc] _initWithCoreResource:coreArchive->mainResource()];    }        return [[_private->cachedMainResource retain] autorelease];}- (NSArray *)subresources{#ifdef MAIL_THREAD_WORKAROUND    if (needMailThreadWorkaround())        return [[self _webkit_invokeOnMainThread] subresources];#endif    WebCoreThreadViolationCheck();    // Currently from WebKit API perspective, WebArchives are entirely immutable once created    // If they ever become mutable, we'll need to rethink this.         if (!_private->cachedSubresources) {        LegacyWebArchive* coreArchive = [_private coreArchive];        if (!coreArchive)            _private->cachedSubresources = [[NSArray alloc] init];        else {            const Vector<RefPtr<ArchiveResource> >& subresources(coreArchive->subresources());            NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithCapacity:subresources.size()];            _private->cachedSubresources = mutableArray;            for (unsigned i = 0; i < subresources.size(); ++i) {                WebResource *resource = [[WebResource alloc] _initWithCoreResource:subresources[i].get()];                if (resource) {                    [mutableArray addObject:resource];                    [resource release];                }            }        }    }        return [[_private->cachedSubresources retain] autorelease];}- (NSArray *)subframeArchives{#ifdef MAIL_THREAD_WORKAROUND    if (needMailThreadWorkaround())        return [[self _webkit_invokeOnMainThread] subframeArchives];#endif    WebCoreThreadViolationCheck();    // Currently from WebKit API perspective, WebArchives are entirely immutable once created    // If they ever become mutable, we'll need to rethink this.      if (!_private->cachedSubframeArchives) {        LegacyWebArchive* coreArchive = [_private coreArchive];        if (!coreArchive)            _private->cachedSubframeArchives = [[NSArray alloc] init];        else {            const Vector<RefPtr<Archive> >& subframeArchives(coreArchive->subframeArchives());            NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithCapacity:subframeArchives.size()];            _private->cachedSubframeArchives = mutableArray;            for (unsigned i = 0; i < subframeArchives.size(); ++i) {                WebArchive *archive = [[WebArchive alloc] _initWithCoreLegacyWebArchive:(LegacyWebArchive *)subframeArchives[i].get()];                [mutableArray addObject:archive];                [archive release];            }        }    }        return [[_private->cachedSubframeArchives retain] autorelease];}- (NSData *)data{    WebCoreThreadViolationCheck();#if !LOG_DISABLED    CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();#endif    RetainPtr<CFDataRef> data = [_private coreArchive]->rawDataRepresentation();    #if !LOG_DISABLED    CFAbsoluteTime end = CFAbsoluteTimeGetCurrent();    CFAbsoluteTime duration = end - start;#endif    LOG(Timing, "Serializing web archive to raw CFPropertyList data took %f seconds", duration);            return [[(NSData *)data.get() retain] autorelease];}@end@implementation WebArchive (WebInternal)- (id)_initWithCoreLegacyWebArchive:(PassRefPtr<WebCore::LegacyWebArchive>)coreLegacyWebArchive{    WebCoreThreadViolationCheck();    self = [super init];    if (!self)        return nil;        _private = [[WebArchivePrivate alloc] initWithCoreArchive:coreLegacyWebArchive];    if (!_private) {        [self release];        return nil;    }    return self;}- (WebCore::LegacyWebArchive *)_coreLegacyWebArchive{    WebCoreThreadViolationCheck();    return [_private coreArchive];}@end

⌨️ 快捷键说明

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