diff -r 000000000000 -r dd21522fd290 webengine/osswebengine/WebKit/WebView/WebArchive.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/osswebengine/WebKit/WebView/WebArchive.m Mon Mar 30 12:54:55 2009 +0300 @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2005, 2006, 2007 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 "WebKitLogging.h" +#import "WebResourcePrivate.h" +#import "WebTypesInternal.h" + +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 *mainResource; + NSArray *subresources; + NSArray *subframeArchives; +} +@end + +@implementation WebArchivePrivate + +- (void)dealloc +{ + [mainResource release]; + [subresources release]; + [subframeArchives release]; + [super dealloc]; +} + +@end + +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; +} + +@implementation WebArchive + +- (id)init +{ + self = [super init]; + if (!self) + return nil; + _private = [[WebArchivePrivate alloc] init]; + return self; +} + +- (id)initWithMainResource:(WebResource *)mainResource subresources:(NSArray *)subresources subframeArchives:(NSArray *)subframeArchives +{ + self = [self init]; + if (!self) + return nil; + + _private->mainResource = [mainResource retain]; + _private->subresources = [subresources retain]; + _private->subframeArchives = [subframeArchives retain]; + + if (!_private->mainResource) { + [self release]; + return nil; + } + + return self; +} + +- (id)_initWithPropertyList:(id)propertyList +{ + self = [self init]; + if (!self) + return nil; + + if (![propertyList isKindOfClass:[NSDictionary class]]) { + [self release]; + return nil; + } + + _private->mainResource = [[WebResource alloc] _initWithPropertyList:[propertyList objectForKey:WebMainResourceKey]]; + if (!_private->mainResource) { + [self release]; + return nil; + } + + _private->subresources = [[WebResource _resourcesFromPropertyLists:[propertyList objectForKey:WebSubresourcesKey]] retain]; + + NSEnumerator *enumerator = [[propertyList objectForKey:WebSubframeArchivesKey] objectEnumerator]; + NSMutableArray *subframeArchives = [[NSMutableArray alloc] init]; + NSDictionary *archivePropertyList; + while ((archivePropertyList = [enumerator nextObject]) != nil) { + WebArchive *archive = [[WebArchive alloc] _initWithPropertyList:archivePropertyList]; + if (archive) { + [subframeArchives addObject:archive]; + [archive release]; + } + } + _private->subframeArchives = subframeArchives; + + return self; +} + +- (id)initWithData:(NSData *)data +{ +#if !LOG_DISABLED + CFAbsoluteTime start = CFAbsoluteTimeGetCurrent(); +#endif + NSDictionary *propertyList = [NSPropertyListSerialization propertyListFromData:data + mutabilityOption:NSPropertyListImmutable + format:nil + errorDescription:nil]; +#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 _initWithPropertyList:propertyList]; +} + +- (id)initWithCoder:(NSCoder *)decoder +{ + self = [self init]; + if (!self) + return nil; + + @try { + id object = [decoder decodeObjectForKey:WebMainResourceKey]; + if ([object isKindOfClass:[WebResource class]]) + _private->mainResource = [object retain]; + object = [decoder decodeObjectForKey:WebSubresourcesKey]; + if (isArrayOfClass(object, [WebResource class])) + _private->subresources = [object retain]; + object = [decoder decodeObjectForKey:WebSubframeArchivesKey]; + if (isArrayOfClass(object, [WebArchive class])) + _private->subframeArchives = [object retain]; + } @catch(id) { + [self release]; + return nil; + } + + if (!_private->mainResource) { + [self release]; + return nil; + } + + return self; +} + +- (void)encodeWithCoder:(NSCoder *)encoder +{ + [encoder encodeObject:_private->mainResource forKey:WebMainResourceKey]; + [encoder encodeObject:_private->subresources forKey:WebSubresourcesKey]; + [encoder encodeObject:_private->subframeArchives forKey:WebSubframeArchivesKey]; +} + +- (void)dealloc +{ + [_private release]; + [super dealloc]; +} + +- (id)copyWithZone:(NSZone *)zone +{ + return [self retain]; +} + +- (WebResource *)mainResource +{ + return [[_private->mainResource retain] autorelease]; +} + +- (NSArray *)subresources +{ + return [[_private->subresources retain] autorelease]; +} + +- (NSArray *)subframeArchives +{ + return [[_private->subframeArchives retain] autorelease]; +} + +- (NSDictionary *)_propertyListRepresentation +{ + NSMutableDictionary *propertyList = [NSMutableDictionary dictionary]; + if (_private->mainResource) { + [propertyList setObject:[_private->mainResource _propertyListRepresentation] forKey:WebMainResourceKey]; + } + NSArray *propertyLists = [WebResource _propertyListsFromResources:_private->subresources]; + if ([propertyLists count] > 0) { + [propertyList setObject:propertyLists forKey:WebSubresourcesKey]; + } + NSEnumerator *enumerator = [_private->subframeArchives objectEnumerator]; + NSMutableArray *subarchivePropertyLists = [[NSMutableArray alloc] init]; + WebArchive *archive; + while ((archive = [enumerator nextObject]) != nil) { + [subarchivePropertyLists addObject:[archive _propertyListRepresentation]]; + } + if ([subarchivePropertyLists count] > 0) { + [propertyList setObject:subarchivePropertyLists forKey:WebSubframeArchivesKey]; + } + [subarchivePropertyLists release]; + return propertyList; +} + +- (NSData *)data +{ + NSDictionary *propertyList = [self _propertyListRepresentation]; +#if !LOG_DISABLED + CFAbsoluteTime start = CFAbsoluteTimeGetCurrent(); +#endif + NSData *data = [NSPropertyListSerialization dataFromPropertyList:propertyList format:NSPropertyListBinaryFormat_v1_0 errorDescription:nil]; +#if !LOG_DISABLED + CFAbsoluteTime end = CFAbsoluteTimeGetCurrent(); + CFAbsoluteTime duration = end - start; +#endif + LOG(Timing, "Serializing web archive with [NSPropertyListSerialization dataFromPropertyList:::] took %f seconds", duration); + return data; +} + +@end