webengine/osswebengine/WebKit/WebView/WebResource.mm
changeset 0 dd21522fd290
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webengine/osswebengine/WebKit/WebView/WebResource.mm	Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,348 @@
+/*
+ * 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 "WebResourcePrivate.h"
+
+#import "WebFrameBridge.h"
+#import "WebNSDictionaryExtras.h"
+#import "WebNSURLExtras.h"
+
+static NSString * const WebResourceDataKey =              @"WebResourceData";
+static NSString * const WebResourceFrameNameKey =         @"WebResourceFrameName";
+static NSString * const WebResourceMIMETypeKey =          @"WebResourceMIMEType";
+static NSString * const WebResourceURLKey =               @"WebResourceURL";
+static NSString * const WebResourceTextEncodingNameKey =  @"WebResourceTextEncodingName";
+static NSString * const WebResourceResponseKey =          @"WebResourceResponse";
+
+#define WebResourceVersion 1
+
+@interface WebResourcePrivate : NSObject
+{
+@public
+    NSData *data;
+    NSURL *URL;
+    NSString *frameName;
+    NSString *MIMEType;
+    NSString *textEncodingName;
+    NSURLResponse *response;
+    BOOL shouldIgnoreWhenUnarchiving;
+}
+@end
+
+@implementation WebResourcePrivate
+
+- (void)dealloc
+{
+    [data release];
+    [URL release];
+    [frameName release];
+    [MIMEType release];
+    [textEncodingName release];
+    [response release];
+    [super dealloc];
+}
+
+@end
+
+@implementation WebResource
+
+- (id)init
+{
+    self = [super init];
+    if (!self)
+        return nil;
+    _private = [[WebResourcePrivate alloc] init];
+    return self;
+}
+
+- (id)initWithData:(NSData *)data URL:(NSURL *)URL MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)textEncodingName frameName:(NSString *)frameName
+{
+    return [self _initWithData:data URL:URL MIMEType:MIMEType textEncodingName:textEncodingName frameName:frameName response:nil copyData:YES];
+}
+
+- (id)initWithCoder:(NSCoder *)decoder
+{
+    self = [self init];
+    if (!self)
+        return nil;
+
+    @try {
+        id object = [decoder decodeObjectForKey:WebResourceDataKey];
+        if ([object isKindOfClass:[NSData class]])
+            _private->data = [object retain];
+        object = [decoder decodeObjectForKey:WebResourceURLKey];
+        if ([object isKindOfClass:[NSURL class]])
+            _private->URL = [object retain];
+        object = [decoder decodeObjectForKey:WebResourceMIMETypeKey];
+        if ([object isKindOfClass:[NSString class]])
+            _private->MIMEType = [object retain];
+        object = [decoder decodeObjectForKey:WebResourceTextEncodingNameKey];
+        if ([object isKindOfClass:[NSString class]])
+            _private->textEncodingName = [object retain];
+        object = [decoder decodeObjectForKey:WebResourceFrameNameKey];
+        if ([object isKindOfClass:[NSString class]])
+            _private->frameName = [object retain];
+        object = [decoder decodeObjectForKey:WebResourceResponseKey];
+        if ([object isKindOfClass:[NSURLResponse class]])
+            _private->response = [object retain];
+    } @catch(id) {
+        [self release];
+        return nil;
+    }
+
+    return self;
+}
+
+- (void)encodeWithCoder:(NSCoder *)encoder
+{
+    [encoder encodeObject:_private->data forKey:WebResourceDataKey];
+    [encoder encodeObject:_private->URL forKey:WebResourceURLKey];
+    [encoder encodeObject:_private->MIMEType forKey:WebResourceMIMETypeKey];
+    [encoder encodeObject:_private->textEncodingName forKey:WebResourceTextEncodingNameKey];
+    [encoder encodeObject:_private->frameName forKey:WebResourceFrameNameKey];
+    [encoder encodeObject:_private->response forKey:WebResourceResponseKey];
+}
+
+- (void)dealloc
+{
+    [_private release];
+    [super dealloc];
+}
+
+- (id)copyWithZone:(NSZone *)zone
+{
+    return [self retain];
+}
+
+- (NSData *)data
+{
+    return _private->data;
+}
+
+- (NSURL *)URL
+{
+    return _private->URL;
+}
+
+- (NSString *)MIMEType
+{
+    return _private->MIMEType;
+}
+
+- (NSString *)textEncodingName
+{
+    return _private->textEncodingName;
+}
+
+- (NSString *)frameName
+{
+    return _private->frameName;
+}
+
+- (id)description
+{
+    return [NSString stringWithFormat:@"<%@ %@>", [self className], [self URL]];
+}
+
+@end
+
+@implementation WebResource (WebResourcePrivate)
+
+// SPI for Mail (5066325)
+- (void)_ignoreWhenUnarchiving
+{
+    _private->shouldIgnoreWhenUnarchiving = YES;
+}
+
+- (BOOL)_shouldIgnoreWhenUnarchiving
+{
+    return _private->shouldIgnoreWhenUnarchiving;
+}
+
++ (NSArray *)_resourcesFromPropertyLists:(NSArray *)propertyLists
+{
+    if (![propertyLists isKindOfClass:[NSArray class]]) {
+        return nil;
+    }
+    NSEnumerator *enumerator = [propertyLists objectEnumerator];
+    NSMutableArray *resources = [NSMutableArray array];
+    NSDictionary *propertyList;
+    while ((propertyList = [enumerator nextObject]) != nil) {
+        WebResource *resource = [[WebResource alloc] _initWithPropertyList:propertyList];
+        if (resource) {
+            [resources addObject:resource];
+            [resource release];
+        }
+    }
+    return resources;
+}
+
++ (NSArray *)_propertyListsFromResources:(NSArray *)resources
+{
+    NSEnumerator *enumerator = [resources objectEnumerator];
+    NSMutableArray *propertyLists = [NSMutableArray array];
+    WebResource *resource;
+    while ((resource = [enumerator nextObject]) != nil) {
+        [propertyLists addObject:[resource _propertyListRepresentation]];
+    }
+    return propertyLists;
+}
+
+- (id)_initWithData:(NSData *)data 
+                URL:(NSURL *)URL 
+           MIMEType:(NSString *)MIMEType 
+   textEncodingName:(NSString *)textEncodingName 
+          frameName:(NSString *)frameName 
+           response:(NSURLResponse *)response
+           copyData:(BOOL)copyData
+{
+    [self init];    
+    
+    if (!data) {
+        [self release];
+        return nil;
+    }
+    _private->data = copyData ? [data copy] : [data retain];
+    
+    if (!URL) {
+        [self release];
+        return nil;
+    }
+    _private->URL = [URL copy];
+    
+    if (!MIMEType) {
+        [self release];
+        return nil;
+    }
+    _private->MIMEType = [MIMEType copy];
+    
+    _private->textEncodingName = [textEncodingName copy];
+    _private->frameName = [frameName copy];
+    _private->response = [response retain];
+        
+    return self;
+}
+
+- (id)_initWithData:(NSData *)data URL:(NSURL *)URL response:(NSURLResponse *)response
+{
+    // Pass NO for copyData since the data doesn't need to be copied since we know that callers will no longer modify it.
+    // Copying it will also cause a performance regression.
+    return [self _initWithData:data
+                           URL:URL
+                      MIMEType:[response MIMEType]
+              textEncodingName:[response textEncodingName]
+                     frameName:nil
+                      response:response
+                      copyData:NO];    
+}
+
+- (id)_initWithPropertyList:(id)propertyList
+{
+    if (![propertyList isKindOfClass:[NSDictionary class]]) {
+        [self release];
+        return nil;
+    }
+    
+    NSURLResponse *response = nil;
+    NSData *responseData = [propertyList objectForKey:WebResourceResponseKey];
+    if ([responseData isKindOfClass:[NSData class]]) {
+        NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:responseData];
+        @try {
+            id responseObject = [unarchiver decodeObjectForKey:WebResourceResponseKey];
+            if ([responseObject isKindOfClass:[NSURLResponse class]])
+                response = responseObject;
+            [unarchiver finishDecoding];
+        } @catch(id) {
+            response = nil;
+        }
+        [unarchiver release];
+    }
+
+    NSData *data = [propertyList objectForKey:WebResourceDataKey];
+    NSString *URLString = [propertyList _webkit_stringForKey:WebResourceURLKey];
+    return [self _initWithData:[data isKindOfClass:[NSData class]] ? data : nil
+                           URL:URLString ? [NSURL _web_URLWithDataAsString:URLString] : nil
+                      MIMEType:[propertyList _webkit_stringForKey:WebResourceMIMETypeKey]
+              textEncodingName:[propertyList _webkit_stringForKey:WebResourceTextEncodingNameKey]
+                     frameName:[propertyList _webkit_stringForKey:WebResourceFrameNameKey]
+                      response:response
+                      copyData:NO];
+}
+
+- (NSFileWrapper *)_fileWrapperRepresentation
+{
+    NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:_private->data] autorelease];
+    NSString *preferredFilename = [_private->response suggestedFilename];
+    if (!preferredFilename || ![preferredFilename length])
+        preferredFilename = [_private->URL _webkit_suggestedFilenameWithMIMEType:_private->MIMEType];
+    [wrapper setPreferredFilename:preferredFilename];
+    return wrapper;
+}
+
+- (id)_propertyListRepresentation
+{
+    NSMutableDictionary *propertyList = [NSMutableDictionary dictionary];
+    [propertyList setObject:_private->data forKey:WebResourceDataKey];
+    [propertyList setObject:[_private->URL _web_originalDataAsString] forKey:WebResourceURLKey];
+    [propertyList setObject:_private->MIMEType forKey:WebResourceMIMETypeKey];
+    if (_private->textEncodingName != nil) {
+        [propertyList setObject:_private->textEncodingName forKey:WebResourceTextEncodingNameKey];
+    }
+    if (_private->frameName != nil) {
+        [propertyList setObject:_private->frameName forKey:WebResourceFrameNameKey];
+    }    
+    if (_private->response != nil) {
+        NSMutableData *responseData = [[NSMutableData alloc] init];
+        NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:responseData];
+        [archiver encodeObject:_private->response forKey:WebResourceResponseKey];
+        [archiver finishEncoding];
+        [archiver release];
+        [propertyList setObject:responseData forKey:WebResourceResponseKey];
+        [responseData release];
+    }        
+    return propertyList;
+}
+
+- (NSURLResponse *)_response
+{
+    if (_private->response != nil) {
+        return _private->response;
+    }
+    return [[[NSURLResponse alloc] initWithURL:_private->URL
+                                      MIMEType:_private->MIMEType 
+                         expectedContentLength:[_private->data length]
+                              textEncodingName:_private->textEncodingName] autorelease];
+}
+
+- (NSString *)_stringValue
+{
+    NSString *textEncodingName = [self textEncodingName];
+    return [WebFrameBridge stringWithData:_private->data textEncodingName:textEncodingName];
+}
+
+@end