webengine/osswebengine/WebKit/WebView/WebArchive.m
changeset 0 dd21522fd290
--- /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