diff --git a/Source/NSURL.m b/Source/NSURL.m index f8ebaaaf2..99f295e20 100644 --- a/Source/NSURL.m +++ b/Source/NSURL.m @@ -50,7 +50,6 @@ function may be incorrect NSString *_password; \ NSString *_path; \ NSNumber *_port; \ - NSString *_query; \ NSArray *_queryItems; \ NSString *_scheme; \ NSString *_user; \ @@ -2326,13 +2325,13 @@ GS_PRIVATE_INTERNAL(NSURLComponents) @implementation NSURLComponents // Creating URL components... -+ (instancetype) componentsWithString:(NSString *)urlString ++ (instancetype) componentsWithString: (NSString *)urlString { return [[NSURLComponents alloc] initWithString: urlString]; } -+ (instancetype) componentsWithURL:(NSURL *)url - resolvingAgainstBaseURL:(BOOL)resolve ++ (instancetype) componentsWithURL: (NSURL *)url + resolvingAgainstBaseURL: (BOOL)resolve { return [[NSURLComponents alloc] initWithURL: url resolvingAgainstBaseURL: resolve]; @@ -2357,7 +2356,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) return self; } -- (instancetype)initWithString:(NSString *)URLString +- (instancetype) initWithString: (NSString *)URLString { self = [self init]; if (self != nil) @@ -2367,13 +2366,14 @@ GS_PRIVATE_INTERNAL(NSURLComponents) return self; } -- (instancetype)initWithURL:(NSURL *)url - resolvingAgainstBaseURL:(BOOL)resolve +- (instancetype) initWithURL: (NSURL *)url + resolvingAgainstBaseURL: (BOOL)resolve { - NSURL *tempURL = url; self = [self init]; if (self != nil) { + NSURL *tempURL = url; + if (resolve) { tempURL = [url absoluteURL]; @@ -2385,7 +2385,6 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) dealloc { - RELEASE(internal->_url); RELEASE(internal->_fragment); RELEASE(internal->_host); RELEASE(internal->_password); @@ -2404,16 +2403,55 @@ GS_PRIVATE_INTERNAL(NSURLComponents) resolvingAgainstBaseURL: NO]; } +// Regenerate URL when components are changed... +- (NSURL *) _regenerateURL +{ + NSURL *u = nil; + if (internal->_dirty == NO) + { + return nil; + } + + u = [[NSURL alloc] initWithScheme: internal->_scheme + user: internal->_user + password: internal->_password + host: internal->_host + port: internal->_port + fullPath: internal->_path + parameterString: nil + query: [self query] + fragment: internal->_fragment]; + + { + // Find ranges + NSString *urlString = [u absoluteString]; +#define URL_COMPONENT_RANGE(part) \ + (part ? [urlString rangeOfString:part] : NSMakeRange(NSNotFound, 0)) + internal->_rangeOfFragment = URL_COMPONENT_RANGE(internal->_fragment); + internal->_rangeOfHost = URL_COMPONENT_RANGE(internal->_host); + internal->_rangeOfPassword = URL_COMPONENT_RANGE(internal->_password); + internal->_rangeOfPath = URL_COMPONENT_RANGE(internal->_path); + internal->_rangeOfPort = URL_COMPONENT_RANGE([internal->_port stringValue]); + internal->_rangeOfQuery = URL_COMPONENT_RANGE([self query]); + internal->_rangeOfScheme = URL_COMPONENT_RANGE(internal->_scheme); + internal->_rangeOfUser = URL_COMPONENT_RANGE(internal->_user); +#undef URL_COMPONENT_RANGE + } + + internal->_dirty = NO; + return u; +} + // Getting the URL - (NSString *) string { - return [[self _regenerateURL] absoluteString]; + return [[self URL] absoluteString]; } - (void) setString: (NSString *)urlString { NSURL *url = [NSURL URLWithString: urlString]; - [self setURL : url]; + [self setURL: url]; } - (NSURL *) URL @@ -2423,65 +2461,22 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setURL: (NSURL *)url { - // components... - ASSIGNCOPY(internal->_fragment, [url fragment]); - ASSIGNCOPY(internal->_host, [url host]); - ASSIGNCOPY(internal->_password, [url password]); - ASSIGNCOPY(internal->_path, [url path]); - ASSIGNCOPY(internal->_port, [url port]); - ASSIGNCOPY(internal->_query, [url query]); - ASSIGNCOPY(internal->_scheme, [url scheme]); - ASSIGNCOPY(internal->_user, [url user]); - - _dirty = YES; + // Set all the components... + [self setScheme: [url scheme]]; + [self setHost: [url host]]; + [self setPort: [url port]]; + [self setUser: [url user]]; + [self setPassword: [url password]]; + [self setPath: [url path]]; + [self setQuery: [url query]]; + [self setFragment: [url fragment]]; } -- (NSURL *)URLRelativeToURL: (NSURL *)baseURL +- (NSURL *) URLRelativeToURL: (NSURL *)baseURL { return nil; } -// Regenerate URL when components are changed... -- (NSURL *) _regenerateURL -{ - if (_dirty == NO) - { - return nil; - } - else - { - NSURL *u; - u = [[NSURL alloc] initWithScheme: internal->_scheme - user: internal->_user - password: internal->_password - host: internal->_host - port: internal->_port - fullPath: internal->_path - parameterString: nil - query: [self query] - fragment: internal->_fragment]; - - { - // Find ranges - NSString *urlString = [u absoluteString]; -#define URL_COMPONENT_RANGE(part) \ - (part ? [urlString rangeOfString:part] : NSMakeRange(NSNotFound, 0)) - internal->_rangeOfFragment = URL_COMPONENT_RANGE(internal->_fragment); - internal->_rangeOfHost = URL_COMPONENT_RANGE(internal->_host); - internal->_rangeOfPassword = URL_COMPONENT_RANGE(internal->_password); - internal->_rangeOfPath = URL_COMPONENT_RANGE(internal->_path); - internal->_rangeOfPort = URL_COMPONENT_RANGE([internal->_port stringValue]); - internal->_rangeOfQuery = URL_COMPONENT_RANGE(internal->_query); - internal->_rangeOfScheme = URL_COMPONENT_RANGE(internal->_scheme); - internal->_rangeOfUser = URL_COMPONENT_RANGE(internal->_user); -#undef URL_COMPONENT_RANGE - } - _dirty = NO; - - return u; - } - } - // Accessing Components in Native Format - (NSString *) fragment { @@ -2491,7 +2486,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setFragment: (NSString *)fragment { ASSIGNCOPY(internal->_fragment, fragment); - _dirty = YES; + internal->_dirty = YES; } - (NSString *) host @@ -2502,7 +2497,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setHost: (NSString *)host { ASSIGNCOPY(internal->_host, host); - _dirty = YES; + internal->_dirty = YES; } - (NSString *) password @@ -2513,7 +2508,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPassword: (NSString *)password { ASSIGNCOPY(internal->_password, password); - _dirty = YES; + internal->_dirty = YES; } - (NSString *) path @@ -2524,7 +2519,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPath: (NSString *)path { ASSIGNCOPY(internal->_path, path); - _dirty = YES; + internal->_dirty = YES; } - (NSNumber *) port @@ -2535,17 +2530,31 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPort: (NSNumber *)port { ASSIGNCOPY(internal->_port, port); - _dirty = YES; + internal->_dirty = YES; } - (NSString *) query { - return internal->_query; + NSString *query = @""; + NSEnumerator *en = [internal->_queryItems objectEnumerator]; + NSURLQueryItem *item = nil; + + while ((item = (NSURLQueryItem *)[en nextObject]) != nil) + { + NSString *name = [item name]; + NSString *value = [item value]; + NSString *itemString = [NSString stringWithFormat: @"%@=%@",name,value]; + if ([query length] > 0) + { + query = [query stringByAppendingString: @"&"]; + } + query = [query stringByAppendingString: itemString]; + } + return query; } - (void) setQuery: (NSString *)query { - ASSIGNCOPY(internal->_query, query); if (query != nil) { NSMutableArray *result = [NSMutableArray arrayWithCapacity: 5]; @@ -2564,6 +2573,10 @@ GS_PRIVATE_INTERNAL(NSURLComponents) } [self setQueryItems: result]; } + else + { + [self setQueryItems: nil]; + } } - (NSArray *) queryItems @@ -2573,25 +2586,9 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setQueryItems: (NSArray *)queryItems { - NSString *query = @""; - NSEnumerator *en = [queryItems objectEnumerator]; - NSURLQueryItem *item = nil; - - while ((item = (NSURLQueryItem *)[en nextObject]) != nil) - { - NSString *name = [item name]; - NSString *value = [[item value] _stringByAddingPercentEscapesForQuery]; - NSString *itemString = [NSString stringWithFormat: @"%@=%@",name,value]; - query = [query stringByAppendingString: itemString]; - if (item != [queryItems lastObject]) - { - query = [query stringByAppendingString: @"&"]; - } - } - - ASSIGNCOPY(internal->_query, query); // add query string... + ASSIGNCOPY(internal->_queryItems, queryItems); - _dirty = YES; + internal->_dirty = YES; } - (NSString *) scheme @@ -2602,7 +2599,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setScheme: (NSString *)scheme { ASSIGNCOPY(internal->_scheme, scheme); - _dirty = YES; + internal->_dirty = YES; } - (NSString *) user @@ -2613,7 +2610,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setUser: (NSString *)user { ASSIGNCOPY(internal->_user, user); - _dirty = YES; + internal->_dirty = YES; } // Accessing Components in PercentEncoded Format @@ -2625,8 +2622,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedFragment: (NSString *)fragment { - ASSIGNCOPY(internal->_fragment, [fragment stringByRemovingPercentEncoding]); - _dirty = YES; + [self setFragment: [fragment stringByRemovingPercentEncoding]]; } - (NSString *) percentEncodedHost @@ -2637,8 +2633,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedHost: (NSString *)host { - ASSIGNCOPY(internal->_host, [host stringByRemovingPercentEncoding]); - _dirty = YES; + [self setHost: [host stringByRemovingPercentEncoding]]; } - (NSString *) percentEncodedPassword @@ -2649,8 +2644,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedPassword: (NSString *)password { - ASSIGNCOPY(internal->_password, [password stringByRemovingPercentEncoding]); - _dirty = YES; + [self setPassword: [password stringByRemovingPercentEncoding]]; } - (NSString *) percentEncodedPath @@ -2661,41 +2655,55 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedPath: (NSString *)path { - ASSIGNCOPY(internal->_path, [path stringByRemovingPercentEncoding]); - _dirty = YES; + [self setPath: [path stringByRemovingPercentEncoding]]; } - (NSString *) percentEncodedQuery { - return internal->_query; + NSString *query = @""; + NSEnumerator *en = [internal->_queryItems objectEnumerator]; + NSURLQueryItem *item = nil; + + while ((item = (NSURLQueryItem *)[en nextObject]) != nil) + { + NSString *name = [[item name] _stringByAddingPercentEscapesForQuery]; + NSString *value = [[item value] _stringByAddingPercentEscapesForQuery]; + NSString *itemString = [NSString stringWithFormat: @"%@=%@",name,value]; + if ([query length] > 0) + { + query = [query stringByAppendingString: @"&"]; + } + query = [query stringByAppendingString: itemString]; + } + return query; } - (void) setPercentEncodedQuery: (NSString *)query { - ASSIGNCOPY(internal->_query, [query stringByRemovingPercentEncoding]); - _dirty = YES; + [self setQuery: [query stringByRemovingPercentEncoding]]; } - (NSArray *) percentEncodedQueryItems { + // FIXME return internal->_queryItems; } - (void) setPercentEncodedQueryItems: (NSArray *)queryItems { + // FIXME [self setQueryItems: queryItems]; } - (NSString *) percentEncodedScheme { - return [internal->_path stringByAddingPercentEncodingWithAllowedCharacters: + return [internal->_scheme stringByAddingPercentEncodingWithAllowedCharacters: [NSCharacterSet URLPathAllowedCharacterSet]]; } - (void) setPercentEncodedScheme: (NSString *)scheme { - ASSIGNCOPY(internal->_scheme, scheme); - _dirty = YES; + [self setScheme: [scheme stringByRemovingPercentEncoding]]; } - (NSString *) percentEncodedUser @@ -2706,8 +2714,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents) - (void) setPercentEncodedUser: (NSString *)user { - ASSIGNCOPY(internal->_user, [user stringByRemovingPercentEncoding]); - _dirty = YES; + [self setUser: [user stringByRemovingPercentEncoding]]; } // Locating components of the URL string representation