webengine/osswebengine/WebKit/WebView/WebResource.mm
changeset 0 dd21522fd290
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2  * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
       
     3  *
       
     4  * Redistribution and use in source and binary forms, with or without
       
     5  * modification, are permitted provided that the following conditions
       
     6  * are met:
       
     7  *
       
     8  * 1.  Redistributions of source code must retain the above copyright
       
     9  *     notice, this list of conditions and the following disclaimer. 
       
    10  * 2.  Redistributions in binary form must reproduce the above copyright
       
    11  *     notice, this list of conditions and the following disclaimer in the
       
    12  *     documentation and/or other materials provided with the distribution. 
       
    13  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
       
    14  *     its contributors may be used to endorse or promote products derived
       
    15  *     from this software without specific prior written permission. 
       
    16  *
       
    17  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
       
    18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       
    19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
       
    20  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
       
    21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
       
    22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
       
    23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
       
    24  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
       
    25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
       
    26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    27  */
       
    28 
       
    29 #import "WebResourcePrivate.h"
       
    30 
       
    31 #import "WebFrameBridge.h"
       
    32 #import "WebNSDictionaryExtras.h"
       
    33 #import "WebNSURLExtras.h"
       
    34 
       
    35 static NSString * const WebResourceDataKey =              @"WebResourceData";
       
    36 static NSString * const WebResourceFrameNameKey =         @"WebResourceFrameName";
       
    37 static NSString * const WebResourceMIMETypeKey =          @"WebResourceMIMEType";
       
    38 static NSString * const WebResourceURLKey =               @"WebResourceURL";
       
    39 static NSString * const WebResourceTextEncodingNameKey =  @"WebResourceTextEncodingName";
       
    40 static NSString * const WebResourceResponseKey =          @"WebResourceResponse";
       
    41 
       
    42 #define WebResourceVersion 1
       
    43 
       
    44 @interface WebResourcePrivate : NSObject
       
    45 {
       
    46 @public
       
    47     NSData *data;
       
    48     NSURL *URL;
       
    49     NSString *frameName;
       
    50     NSString *MIMEType;
       
    51     NSString *textEncodingName;
       
    52     NSURLResponse *response;
       
    53     BOOL shouldIgnoreWhenUnarchiving;
       
    54 }
       
    55 @end
       
    56 
       
    57 @implementation WebResourcePrivate
       
    58 
       
    59 - (void)dealloc
       
    60 {
       
    61     [data release];
       
    62     [URL release];
       
    63     [frameName release];
       
    64     [MIMEType release];
       
    65     [textEncodingName release];
       
    66     [response release];
       
    67     [super dealloc];
       
    68 }
       
    69 
       
    70 @end
       
    71 
       
    72 @implementation WebResource
       
    73 
       
    74 - (id)init
       
    75 {
       
    76     self = [super init];
       
    77     if (!self)
       
    78         return nil;
       
    79     _private = [[WebResourcePrivate alloc] init];
       
    80     return self;
       
    81 }
       
    82 
       
    83 - (id)initWithData:(NSData *)data URL:(NSURL *)URL MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)textEncodingName frameName:(NSString *)frameName
       
    84 {
       
    85     return [self _initWithData:data URL:URL MIMEType:MIMEType textEncodingName:textEncodingName frameName:frameName response:nil copyData:YES];
       
    86 }
       
    87 
       
    88 - (id)initWithCoder:(NSCoder *)decoder
       
    89 {
       
    90     self = [self init];
       
    91     if (!self)
       
    92         return nil;
       
    93 
       
    94     @try {
       
    95         id object = [decoder decodeObjectForKey:WebResourceDataKey];
       
    96         if ([object isKindOfClass:[NSData class]])
       
    97             _private->data = [object retain];
       
    98         object = [decoder decodeObjectForKey:WebResourceURLKey];
       
    99         if ([object isKindOfClass:[NSURL class]])
       
   100             _private->URL = [object retain];
       
   101         object = [decoder decodeObjectForKey:WebResourceMIMETypeKey];
       
   102         if ([object isKindOfClass:[NSString class]])
       
   103             _private->MIMEType = [object retain];
       
   104         object = [decoder decodeObjectForKey:WebResourceTextEncodingNameKey];
       
   105         if ([object isKindOfClass:[NSString class]])
       
   106             _private->textEncodingName = [object retain];
       
   107         object = [decoder decodeObjectForKey:WebResourceFrameNameKey];
       
   108         if ([object isKindOfClass:[NSString class]])
       
   109             _private->frameName = [object retain];
       
   110         object = [decoder decodeObjectForKey:WebResourceResponseKey];
       
   111         if ([object isKindOfClass:[NSURLResponse class]])
       
   112             _private->response = [object retain];
       
   113     } @catch(id) {
       
   114         [self release];
       
   115         return nil;
       
   116     }
       
   117 
       
   118     return self;
       
   119 }
       
   120 
       
   121 - (void)encodeWithCoder:(NSCoder *)encoder
       
   122 {
       
   123     [encoder encodeObject:_private->data forKey:WebResourceDataKey];
       
   124     [encoder encodeObject:_private->URL forKey:WebResourceURLKey];
       
   125     [encoder encodeObject:_private->MIMEType forKey:WebResourceMIMETypeKey];
       
   126     [encoder encodeObject:_private->textEncodingName forKey:WebResourceTextEncodingNameKey];
       
   127     [encoder encodeObject:_private->frameName forKey:WebResourceFrameNameKey];
       
   128     [encoder encodeObject:_private->response forKey:WebResourceResponseKey];
       
   129 }
       
   130 
       
   131 - (void)dealloc
       
   132 {
       
   133     [_private release];
       
   134     [super dealloc];
       
   135 }
       
   136 
       
   137 - (id)copyWithZone:(NSZone *)zone
       
   138 {
       
   139     return [self retain];
       
   140 }
       
   141 
       
   142 - (NSData *)data
       
   143 {
       
   144     return _private->data;
       
   145 }
       
   146 
       
   147 - (NSURL *)URL
       
   148 {
       
   149     return _private->URL;
       
   150 }
       
   151 
       
   152 - (NSString *)MIMEType
       
   153 {
       
   154     return _private->MIMEType;
       
   155 }
       
   156 
       
   157 - (NSString *)textEncodingName
       
   158 {
       
   159     return _private->textEncodingName;
       
   160 }
       
   161 
       
   162 - (NSString *)frameName
       
   163 {
       
   164     return _private->frameName;
       
   165 }
       
   166 
       
   167 - (id)description
       
   168 {
       
   169     return [NSString stringWithFormat:@"<%@ %@>", [self className], [self URL]];
       
   170 }
       
   171 
       
   172 @end
       
   173 
       
   174 @implementation WebResource (WebResourcePrivate)
       
   175 
       
   176 // SPI for Mail (5066325)
       
   177 - (void)_ignoreWhenUnarchiving
       
   178 {
       
   179     _private->shouldIgnoreWhenUnarchiving = YES;
       
   180 }
       
   181 
       
   182 - (BOOL)_shouldIgnoreWhenUnarchiving
       
   183 {
       
   184     return _private->shouldIgnoreWhenUnarchiving;
       
   185 }
       
   186 
       
   187 + (NSArray *)_resourcesFromPropertyLists:(NSArray *)propertyLists
       
   188 {
       
   189     if (![propertyLists isKindOfClass:[NSArray class]]) {
       
   190         return nil;
       
   191     }
       
   192     NSEnumerator *enumerator = [propertyLists objectEnumerator];
       
   193     NSMutableArray *resources = [NSMutableArray array];
       
   194     NSDictionary *propertyList;
       
   195     while ((propertyList = [enumerator nextObject]) != nil) {
       
   196         WebResource *resource = [[WebResource alloc] _initWithPropertyList:propertyList];
       
   197         if (resource) {
       
   198             [resources addObject:resource];
       
   199             [resource release];
       
   200         }
       
   201     }
       
   202     return resources;
       
   203 }
       
   204 
       
   205 + (NSArray *)_propertyListsFromResources:(NSArray *)resources
       
   206 {
       
   207     NSEnumerator *enumerator = [resources objectEnumerator];
       
   208     NSMutableArray *propertyLists = [NSMutableArray array];
       
   209     WebResource *resource;
       
   210     while ((resource = [enumerator nextObject]) != nil) {
       
   211         [propertyLists addObject:[resource _propertyListRepresentation]];
       
   212     }
       
   213     return propertyLists;
       
   214 }
       
   215 
       
   216 - (id)_initWithData:(NSData *)data 
       
   217                 URL:(NSURL *)URL 
       
   218            MIMEType:(NSString *)MIMEType 
       
   219    textEncodingName:(NSString *)textEncodingName 
       
   220           frameName:(NSString *)frameName 
       
   221            response:(NSURLResponse *)response
       
   222            copyData:(BOOL)copyData
       
   223 {
       
   224     [self init];    
       
   225     
       
   226     if (!data) {
       
   227         [self release];
       
   228         return nil;
       
   229     }
       
   230     _private->data = copyData ? [data copy] : [data retain];
       
   231     
       
   232     if (!URL) {
       
   233         [self release];
       
   234         return nil;
       
   235     }
       
   236     _private->URL = [URL copy];
       
   237     
       
   238     if (!MIMEType) {
       
   239         [self release];
       
   240         return nil;
       
   241     }
       
   242     _private->MIMEType = [MIMEType copy];
       
   243     
       
   244     _private->textEncodingName = [textEncodingName copy];
       
   245     _private->frameName = [frameName copy];
       
   246     _private->response = [response retain];
       
   247         
       
   248     return self;
       
   249 }
       
   250 
       
   251 - (id)_initWithData:(NSData *)data URL:(NSURL *)URL response:(NSURLResponse *)response
       
   252 {
       
   253     // Pass NO for copyData since the data doesn't need to be copied since we know that callers will no longer modify it.
       
   254     // Copying it will also cause a performance regression.
       
   255     return [self _initWithData:data
       
   256                            URL:URL
       
   257                       MIMEType:[response MIMEType]
       
   258               textEncodingName:[response textEncodingName]
       
   259                      frameName:nil
       
   260                       response:response
       
   261                       copyData:NO];    
       
   262 }
       
   263 
       
   264 - (id)_initWithPropertyList:(id)propertyList
       
   265 {
       
   266     if (![propertyList isKindOfClass:[NSDictionary class]]) {
       
   267         [self release];
       
   268         return nil;
       
   269     }
       
   270     
       
   271     NSURLResponse *response = nil;
       
   272     NSData *responseData = [propertyList objectForKey:WebResourceResponseKey];
       
   273     if ([responseData isKindOfClass:[NSData class]]) {
       
   274         NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:responseData];
       
   275         @try {
       
   276             id responseObject = [unarchiver decodeObjectForKey:WebResourceResponseKey];
       
   277             if ([responseObject isKindOfClass:[NSURLResponse class]])
       
   278                 response = responseObject;
       
   279             [unarchiver finishDecoding];
       
   280         } @catch(id) {
       
   281             response = nil;
       
   282         }
       
   283         [unarchiver release];
       
   284     }
       
   285 
       
   286     NSData *data = [propertyList objectForKey:WebResourceDataKey];
       
   287     NSString *URLString = [propertyList _webkit_stringForKey:WebResourceURLKey];
       
   288     return [self _initWithData:[data isKindOfClass:[NSData class]] ? data : nil
       
   289                            URL:URLString ? [NSURL _web_URLWithDataAsString:URLString] : nil
       
   290                       MIMEType:[propertyList _webkit_stringForKey:WebResourceMIMETypeKey]
       
   291               textEncodingName:[propertyList _webkit_stringForKey:WebResourceTextEncodingNameKey]
       
   292                      frameName:[propertyList _webkit_stringForKey:WebResourceFrameNameKey]
       
   293                       response:response
       
   294                       copyData:NO];
       
   295 }
       
   296 
       
   297 - (NSFileWrapper *)_fileWrapperRepresentation
       
   298 {
       
   299     NSFileWrapper *wrapper = [[[NSFileWrapper alloc] initRegularFileWithContents:_private->data] autorelease];
       
   300     NSString *preferredFilename = [_private->response suggestedFilename];
       
   301     if (!preferredFilename || ![preferredFilename length])
       
   302         preferredFilename = [_private->URL _webkit_suggestedFilenameWithMIMEType:_private->MIMEType];
       
   303     [wrapper setPreferredFilename:preferredFilename];
       
   304     return wrapper;
       
   305 }
       
   306 
       
   307 - (id)_propertyListRepresentation
       
   308 {
       
   309     NSMutableDictionary *propertyList = [NSMutableDictionary dictionary];
       
   310     [propertyList setObject:_private->data forKey:WebResourceDataKey];
       
   311     [propertyList setObject:[_private->URL _web_originalDataAsString] forKey:WebResourceURLKey];
       
   312     [propertyList setObject:_private->MIMEType forKey:WebResourceMIMETypeKey];
       
   313     if (_private->textEncodingName != nil) {
       
   314         [propertyList setObject:_private->textEncodingName forKey:WebResourceTextEncodingNameKey];
       
   315     }
       
   316     if (_private->frameName != nil) {
       
   317         [propertyList setObject:_private->frameName forKey:WebResourceFrameNameKey];
       
   318     }    
       
   319     if (_private->response != nil) {
       
   320         NSMutableData *responseData = [[NSMutableData alloc] init];
       
   321         NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:responseData];
       
   322         [archiver encodeObject:_private->response forKey:WebResourceResponseKey];
       
   323         [archiver finishEncoding];
       
   324         [archiver release];
       
   325         [propertyList setObject:responseData forKey:WebResourceResponseKey];
       
   326         [responseData release];
       
   327     }        
       
   328     return propertyList;
       
   329 }
       
   330 
       
   331 - (NSURLResponse *)_response
       
   332 {
       
   333     if (_private->response != nil) {
       
   334         return _private->response;
       
   335     }
       
   336     return [[[NSURLResponse alloc] initWithURL:_private->URL
       
   337                                       MIMEType:_private->MIMEType 
       
   338                          expectedContentLength:[_private->data length]
       
   339                               textEncodingName:_private->textEncodingName] autorelease];
       
   340 }
       
   341 
       
   342 - (NSString *)_stringValue
       
   343 {
       
   344     NSString *textEncodingName = [self textEncodingName];
       
   345     return [WebFrameBridge stringWithData:_private->data textEncodingName:textEncodingName];
       
   346 }
       
   347 
       
   348 @end