I suggest when we regenerate we build the URL by appending to a mutable string

sas this would be hugely more efficient.
This commit is contained in:
Richard Frith-Macdonald 2020-04-04 14:22:25 +01:00
parent d05b799740
commit 4ffce48b04

View file

@ -2408,21 +2408,26 @@ GS_PRIVATE_INTERNAL(NSURLComponents)
// Regenerate URL when components are changed... // Regenerate URL when components are changed...
- (void) _regenerateURL - (void) _regenerateURL
{ {
NSString *urlString = @""; NSMutableString *urlString;
NSInteger location = 0; NSString *component;
NSUInteger location;
NSUInteger len;
if (internal->_dirty == NO) if (internal->_dirty == NO)
{ {
return; return;
} }
urlString = [[NSMutableString alloc] initWithCapacity: 1000];
location = 0;
// Build up the URL from components... // Build up the URL from components...
if (internal->_scheme != nil) if (internal->_scheme != nil)
{ {
NSString *comp = [self percentEncodedScheme]; component = [self percentEncodedScheme];
NSInteger len = [comp length]; [urlString appendString: component];
urlString = [urlString stringByAppendingFormat: @"%@://", comp]; len = [component length];
internal->_rangeOfScheme = NSMakeRange(location, len); internal->_rangeOfScheme = NSMakeRange(location, len);
[urlString appendString: @"://"];
location += len + 3; location += len + 3;
} }
else else
@ -2434,76 +2439,87 @@ GS_PRIVATE_INTERNAL(NSURLComponents)
{ {
if (internal->_password != nil) if (internal->_password != nil)
{ {
NSString *comp1 = [self percentEncodedUser]; component = [self percentEncodedUser];
NSInteger len1 = [comp1 length]; len = [component length];
NSString *comp2 = [self percentEncodedPassword]; [urlString appendString: component];
NSInteger len2 = [comp2 length]; internal->_rangeOfUser = NSMakeRange(location, len);
urlString = [urlString stringByAppendingFormat: @"%@:%@@", comp1, comp2]; [urlString appendString: @":"];
internal->_rangeOfUser = NSMakeRange(location, len1); location += len + 1;
location += len1 + 1;
internal->_rangeOfPassword = NSMakeRange(location, len2); component = [self percentEncodedPassword];
location += len2 + 1; len = [component length];
[urlString appendString: component];
internal->_rangeOfUser = NSMakeRange(location, len);
[urlString appendString: @"@"];
location += len + 1;
} }
else else
{ {
NSString *comp = [self percentEncodedUser]; component = [self percentEncodedUser];
NSInteger len = [comp length]; len = [component length];
urlString = [urlString stringByAppendingFormat: @"%@@", comp]; [urlString appendString: component];
internal->_rangeOfUser = NSMakeRange(location, len); internal->_rangeOfUser = NSMakeRange(location, len);
[urlString appendString: @"@"];
location += len + 1; location += len + 1;
} }
} }
if (internal->_host != nil) if (internal->_host != nil)
{ {
NSString *comp = [self percentEncodedHost]; component = [self percentEncodedHost];
NSInteger len = [comp length]; len = [component length];
urlString = [urlString stringByAppendingFormat: @"%@", comp]; [urlString appendString: component];
internal->_rangeOfHost = NSMakeRange(location, len); internal->_rangeOfHost = NSMakeRange(location, len);
location += len; location += len;
} }
if (internal->_port != nil) if (internal->_port != nil)
{ {
NSString *comp = [[self port] stringValue]; component = [[self port] stringValue];
NSInteger len = [comp length]; len = [component length];
urlString = [urlString stringByAppendingFormat: @":%@", comp]; [urlString appendString: @":"];
location += 1; location += 1;
[urlString appendString: component];
internal->_rangeOfPort = NSMakeRange(location, len); internal->_rangeOfPort = NSMakeRange(location, len);
location += len; location += len;
} }
/* FIXME ... if the path is empty we still need a '/' do we not?
*/
if (internal->_path != nil) if (internal->_path != nil)
{ {
NSString *comp = [self percentEncodedPath]; component = [self percentEncodedPath];
NSInteger len = [comp length]; len = [component length];
urlString = [urlString stringByAppendingFormat: @"%@", comp]; [urlString appendString: component];
internal->_rangeOfPath = NSMakeRange(location, len); internal->_rangeOfPath = NSMakeRange(location, len);
location += len; location += len;
} }
if ([internal->_queryItems count] > 0) // if query items is nil, this will also return 0 if ([internal->_queryItems count] > 0)
{ {
NSString *comp = [self percentEncodedQuery]; component = [self percentEncodedQuery];
NSInteger len = [comp length]; len = [component length];
urlString = [urlString stringByAppendingFormat: @"?%@", comp]; [urlString appendString: @"?"];
location += 1; location += 1;
[urlString appendString: component];
internal->_rangeOfQuery = NSMakeRange(location, len); internal->_rangeOfQuery = NSMakeRange(location, len);
location += len; location += len;
} }
if (internal->_fragment != nil) if (internal->_fragment != nil)
{ {
NSString *comp = [self percentEncodedFragment]; component = [self percentEncodedFragment];
NSInteger len = [comp length]; len = [component length];
urlString = [urlString stringByAppendingFormat: @"#%@", comp]; [urlString appendString: @"#"];
location += 1; location += 1;
[urlString appendString: component];
internal->_rangeOfFragment = NSMakeRange(location, len); internal->_rangeOfFragment = NSMakeRange(location, len);
location += len; location += len;
} }
ASSIGNCOPY(internal->_url, [NSURL URLWithString: urlString]); ASSIGNCOPY(internal->_url, [NSURL URLWithString: urlString]);
internal->_dirty = NO; internal->_dirty = NO;
RELEASE(urlString);
} }
// Getting the URL // Getting the URL
@ -2609,6 +2625,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents)
NSString *name = [item name]; NSString *name = [item name];
NSString *value = [[item value] _stringByAddingPercentEscapesForQuery]; NSString *value = [[item value] _stringByAddingPercentEscapesForQuery];
NSString *itemString = [NSString stringWithFormat: @"%@=%@",name,value]; NSString *itemString = [NSString stringWithFormat: @"%@=%@",name,value];
if ([query length] > 0) if ([query length] > 0)
{ {
query = [query stringByAppendingString: @"&"]; query = [query stringByAppendingString: @"&"];