mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-26 02:01:03 +00:00
* Source/include/NSString.h: declaration of categories: NSString (GSString) NSString(GSTrimming) NSMutableString (GSString) NSMutableString (GSTrimming) * Source/NSString.m: implementation of these categories * Source/include/NSObject.h: added ASSIGNCOPY Same as ASSIGN but copy the value * Source/include/NSURL.h: New class * Source/include/NSURLHandle.h: New class * Source/NSURL.m: New class [see the note in the file] * Source/NSURLHandle.m: New class [see the note in the file] * GNUMakefile: added NSURL.m and NSURLHandle.m git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@3699 72102866-910b-0410-8b05-ffd578937521
612 lines
18 KiB
Objective-C
612 lines
18 KiB
Objective-C
/* NSUrl.m - Class NSURL
|
|
Copyright (C) 1999 Free Software Foundation, Inc.
|
|
|
|
Written by: Manuel Guesdon <mguesdon@sbuilders.com>
|
|
Date: Jan 1999
|
|
|
|
This file is part of the GNUstep Library.
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public
|
|
License along with this library; if not, write to the Free
|
|
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
/*
|
|
Note from Manuel Guesdon:
|
|
* I've made some test to compare apple NSURL results
|
|
and GNUstep NSURL results but as there this class is not very documented, some
|
|
function may be incorrect
|
|
* I've put 2 functions to make tests. You can add your own tests
|
|
* Some functions are not implemented
|
|
*/
|
|
#include <config.h>
|
|
#include <base/behavior.h>
|
|
#include <Foundation/NSObject.h>
|
|
#include <Foundation/NSCoder.h>
|
|
#include <Foundation/NSArray.h>
|
|
#include <Foundation/NSDictionary.h>
|
|
#include <Foundation/NSString.h>
|
|
#include <Foundation/NSException.h>
|
|
#include <Foundation/NSConcreteNumber.h>
|
|
#include <Foundation/NSURLHandle.h>
|
|
#include <Foundation/NSURL.h>
|
|
|
|
NSString* NSURLFileScheme=@"file";
|
|
|
|
NSString* NSURLPartKey_host=@"host";
|
|
NSString* NSURLPartKey_port=@"port";
|
|
NSString* NSURLPartKey_user=@"user";
|
|
NSString* NSURLPartKey_password=@"password";
|
|
NSString* NSURLPartKey_path=@"path";
|
|
NSString* NSURLPartKey_fragment=@"fragment";
|
|
NSString* NSURLPartKey_parameterString=@"parameterString";
|
|
NSString* NSURLPartKey_query=@"query";
|
|
|
|
//===================================================================================
|
|
@implementation NSURL
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
+(id)fileURLWithPath:(NSString*)_path
|
|
{
|
|
return [[[NSURL alloc] initFileURLWithPath:_path]
|
|
autorelease];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
+(id)URLWithString:(NSString*)_urlString
|
|
{
|
|
return [[[NSURL alloc] initWithString:_urlString]
|
|
autorelease];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
+(id)URLWithString:(NSString*)_urlString
|
|
relativeToURL:(NSURL*)_baseURL
|
|
{
|
|
return [[[NSURL alloc] initWithString:_urlString
|
|
relativeToURL:_baseURL]
|
|
autorelease];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(id)initWithScheme:(NSString*)_scheme
|
|
host:(NSString*)_host
|
|
path:(NSString*)_path
|
|
{
|
|
NSString* _urlString=nil;
|
|
if (_host)
|
|
_urlString=[NSString stringWithFormat:@"%@://%@",_scheme,_host];
|
|
else
|
|
_urlString=[NSString stringWithFormat:@"%@:",_scheme];
|
|
if (_path)
|
|
_urlString=[_urlString stringByAppendingString:_path];
|
|
self=[self initWithString:_urlString];
|
|
return self;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
//Non Standard Function
|
|
-(id)initWithScheme:(NSString*)_scheme
|
|
host:(NSString*)_host
|
|
port:(NSNumber*)_port
|
|
path:(NSString*)_path
|
|
{
|
|
NSString* tmpHost=nil;
|
|
if (_port)
|
|
tmpHost=[NSString stringWithFormat:@"%@:%@",_host,_port];
|
|
else
|
|
tmpHost=_host;
|
|
self=[self initWithScheme:_scheme
|
|
host:tmpHost
|
|
path:_path];
|
|
return self;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
//Do a initWithScheme:NSFileScheme host:nil path:_path
|
|
-(id)initFileURLWithPath:(NSString*)_path
|
|
{
|
|
self=[self initWithScheme:NSURLFileScheme
|
|
host:nil
|
|
path:_path];
|
|
return self;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
// urlString is escaped
|
|
-(id)initWithString:(NSString*)_urlString
|
|
{
|
|
self=[self init];
|
|
ASSIGNCOPY(urlString,_urlString);
|
|
return self;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
//urlString!=nil
|
|
// urlString is escaped
|
|
-(id)initWithString:(NSString*)_urlString
|
|
relativeToURL:(NSURL*)_baseURL
|
|
{
|
|
self=[self init];
|
|
ASSIGNCOPY(urlString,_urlString);
|
|
ASSIGNCOPY(baseURL,_baseURL);
|
|
return self;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(void)dealloc
|
|
{
|
|
DESTROY(urlString);
|
|
DESTROY(baseURL);
|
|
[super dealloc];
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(id)copyWithZone: (NSZone*)zone
|
|
{
|
|
if (NSShouldRetainWithZone(self, zone) == NO)
|
|
return [[isa allocWithZone: zone] initWithString:urlString
|
|
relativeToURL:baseURL];
|
|
else
|
|
return [self retain];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(void)encodeWithCoder:(NSCoder*)aCoder
|
|
{
|
|
[super encodeWithCoder: aCoder];
|
|
[aCoder encodeObject:urlString];
|
|
[aCoder encodeObject:baseURL];
|
|
//FIXME? clients ?
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(id)initWithCoder: (NSCoder*)aCoder
|
|
{
|
|
self = [super initWithCoder: aCoder];
|
|
[aCoder decodeValueOfObjCType: @encode(id) at:&urlString];
|
|
[aCoder decodeValueOfObjCType: @encode(id) at:&baseURL];
|
|
//FIXME? clients ?
|
|
return self;
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(NSString*)description
|
|
{
|
|
NSString* dscr=urlString;
|
|
if (baseURL)
|
|
dscr=[dscr stringByAppendingFormat:@" -- %@",baseURL];
|
|
return dscr;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
// Non Standard Function
|
|
-(NSString*)baseURLAbsolutePart
|
|
{
|
|
if (baseURL)
|
|
{
|
|
NSString* suffix=[baseURL path];
|
|
NSString* tmp=nil;
|
|
if ([baseURL query])
|
|
suffix=[suffix stringByAppendingFormat:@"?%@",[baseURL query]];
|
|
// /test?aa=bb&cc=dd -- http://user:passwd@www.gnustep.org:80/apache
|
|
// ==> http://user:passwd@www.gnustep.org:80/
|
|
tmp=[[baseURL absoluteString]stringWithoutSuffix:suffix];
|
|
|
|
// ==> http://user:passwd@www.gnustep.org:80
|
|
if ([tmp hasSuffix:@"/"])
|
|
tmp=[tmp stringWithoutSuffix:@"/"];
|
|
return tmp;
|
|
}
|
|
else
|
|
return @"";
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(NSString*)absoluteString
|
|
{
|
|
NSString* absString=nil;
|
|
if (baseURL)
|
|
{
|
|
// /test?aa=bb&cc=dd -- http://user:passwd@www.gnustep.org:80/apache
|
|
// ==> http://user:passwd@www.gnustep.org:80
|
|
absString=[self baseURLAbsolutePart];
|
|
|
|
if ([urlString hasPrefix:@"/"])
|
|
absString=[absString stringByAppendingString:urlString];
|
|
else
|
|
absString=[absString stringByAppendingFormat:@"/%@",urlString];
|
|
}
|
|
else
|
|
absString=urlString;
|
|
return absString;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(NSString*)relativeString
|
|
{
|
|
return urlString;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(NSURL*)baseURL
|
|
{
|
|
return baseURL;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(NSURL*)absoluteURL
|
|
{
|
|
if (!baseURL)
|
|
return self;
|
|
else
|
|
return [NSURL URLWithString:[self absoluteString]];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(NSString*)scheme
|
|
{
|
|
NSString* scheme=nil;
|
|
NSString* absoluteString=[self absoluteString];
|
|
NSRange range=[absoluteString rangeOfString:@"://"];
|
|
if (range.length>0)
|
|
scheme=[absoluteString substringToIndex:range.location];
|
|
return scheme;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(NSString*)resourceSpecifier
|
|
{
|
|
NSString* absoluteString=[self absoluteString];
|
|
NSRange range=[absoluteString rangeOfString:@"://"];
|
|
if (range.length>0)
|
|
return [absoluteString substringFromIndex:range.location+1];
|
|
else
|
|
return absoluteString;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
//Non Standard Function
|
|
-(NSDictionary*)explode
|
|
{
|
|
NSMutableDictionary* elements=nil;
|
|
NSString* resourceSpecifier=[self resourceSpecifier];
|
|
if ([resourceSpecifier hasPrefix:@"//"])
|
|
{
|
|
int index=2;
|
|
NSRange range;
|
|
elements=[[NSMutableDictionary new] autorelease];
|
|
if (![[self scheme] isEqualToString:NSURLFileScheme])
|
|
{
|
|
range=[resourceSpecifier rangeOfString:@"/"
|
|
options:0
|
|
range:NSMakeRange(index,[resourceSpecifier length]-index)];
|
|
if (range.length>0)
|
|
{
|
|
NSString* userPasswordHostPort=[resourceSpecifier substringWithRange:NSMakeRange(index,range.location-index)];
|
|
NSString* userPassword=nil;
|
|
NSString* hostPort=nil;
|
|
index=range.location;
|
|
range=[userPasswordHostPort rangeOfString:@"@"];
|
|
if (range.length>0)
|
|
{
|
|
if (range.location>0)
|
|
userPassword=[userPasswordHostPort substringToIndex:range.location];
|
|
if (range.location+1<[userPasswordHostPort length])
|
|
hostPort=[userPasswordHostPort substringFromIndex:range.location+1];
|
|
}
|
|
else
|
|
hostPort=userPasswordHostPort;
|
|
if (userPassword)
|
|
{
|
|
range=[userPassword rangeOfString:@":"];
|
|
if (range.length>0)
|
|
{
|
|
if (range.location>0)
|
|
[elements setObject:[userPassword substringToIndex:range.location]
|
|
forKey:NSURLPartKey_user];
|
|
if (range.location+1<[userPassword length])
|
|
[elements setObject:[userPassword substringFromIndex:range.location+1]
|
|
forKey:NSURLPartKey_password];
|
|
}
|
|
else
|
|
[elements setObject:userPassword
|
|
forKey:NSURLPartKey_user];
|
|
};
|
|
|
|
if (hostPort)
|
|
{
|
|
range=[hostPort rangeOfString:@":"];
|
|
if (range.length>0)
|
|
{
|
|
if (range.location>0)
|
|
[elements setObject:[hostPort substringToIndex:range.location]
|
|
forKey:NSURLPartKey_host];
|
|
if (range.location+1<[hostPort length])
|
|
[elements setObject:[NSNumber valueFromString:
|
|
[hostPort substringFromIndex:range.location+1]]
|
|
forKey:NSURLPartKey_port];
|
|
}
|
|
else
|
|
[elements setObject:hostPort
|
|
forKey:NSURLPartKey_host];
|
|
};
|
|
};
|
|
}
|
|
else
|
|
index--; //To Take a /
|
|
range=[resourceSpecifier rangeOfString:@"?"
|
|
options:0
|
|
range:NSMakeRange(index,[resourceSpecifier length]-index)];
|
|
if (range.length>0)
|
|
{
|
|
if (range.location>0)
|
|
[elements setObject:[resourceSpecifier substringWithRange:NSMakeRange(index,range.location-index)]
|
|
forKey:NSURLPartKey_path];
|
|
if (range.location+1<[resourceSpecifier length])
|
|
[elements setObject:[resourceSpecifier substringFromIndex:range.location+1]
|
|
forKey:NSURLPartKey_query];
|
|
}
|
|
else
|
|
[elements setObject:[resourceSpecifier substringFromIndex:index]
|
|
forKey:NSURLPartKey_path];
|
|
}
|
|
else
|
|
{
|
|
[NSException raise:NSGenericException
|
|
format:@"'%@' is a bad URL",self];
|
|
};
|
|
return elements;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(NSString*)host
|
|
{
|
|
return [[self explode] objectForKey:NSURLPartKey_host];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(NSNumber*)port;
|
|
{
|
|
return [[self explode] objectForKey:NSURLPartKey_port];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(NSString*)user;
|
|
{
|
|
return [[self explode] objectForKey:NSURLPartKey_user];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(NSString*)password;
|
|
{
|
|
return [[self explode] objectForKey:NSURLPartKey_password];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(NSString*)path;
|
|
{
|
|
return [[self explode] objectForKey:NSURLPartKey_path];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(NSString*)fragment;
|
|
{
|
|
return [[self explode] objectForKey:NSURLPartKey_fragment];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(NSString*)parameterString;
|
|
{
|
|
return [[self explode] objectForKey:NSURLPartKey_parameterString];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(NSString*)query;
|
|
{
|
|
return [[self explode] objectForKey:NSURLPartKey_query];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(NSString*)relativePath
|
|
{
|
|
//FIXME?
|
|
return [self path];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(BOOL)isFileURL
|
|
{
|
|
return [[self scheme] isEqualToString:NSURLFileScheme];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(NSURL*)standardizedURL
|
|
{
|
|
//FIXME
|
|
[self notImplemented: _cmd];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(void) URLHandle:(NSURLHandle*)sender
|
|
resourceDataDidBecomeAvailable:(NSData*)newData
|
|
{
|
|
//FIXME
|
|
[self notImplemented: _cmd];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(void)URLHandleResourceDidBeginLoading:(NSURLHandle*)sender
|
|
{
|
|
//FIXME
|
|
[self notImplemented: _cmd];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(void)URLHandleResourceDidFinishLoading:(NSURLHandle*)sender
|
|
{
|
|
//FIXME
|
|
[self notImplemented: _cmd];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(void)URLHandleResourceDidCancelLoading:(NSURLHandle*)sender
|
|
{
|
|
//FIXME
|
|
[self notImplemented: _cmd];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(void) URLHandle:(NSURLHandle*)sender
|
|
resourceDidFailLoadingWithReason:(NSString*)reason
|
|
{
|
|
//FIXME
|
|
[self notImplemented: _cmd];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
//FIXME: delete these fn when NSURL will be validated
|
|
+(void)test
|
|
{
|
|
NSURL* url2;
|
|
NSURL* url3;
|
|
NSURL* url=[NSURL URLWithString:@"http://user:passwd@www.gnustep.org:80/apache"];
|
|
url2=[NSURL URLWithString:@"/test?aa=bb&cc=dd" relativeToURL:url];
|
|
url3=[NSURL URLWithString:@"test?aa=bb&cc=dd" relativeToURL:url];
|
|
NSLog(@"===url===");
|
|
[NSURL testPrint:url];
|
|
NSLog(@"===url2===");
|
|
[NSURL testPrint:url2];
|
|
NSLog(@"===url3===");
|
|
[NSURL testPrint:url3];
|
|
};
|
|
|
|
+(void)testPrint:(NSURL*)url
|
|
{
|
|
id _baseURL=nil;
|
|
id _urlString=nil;
|
|
void* _clients=0;
|
|
GSGetInstanceVariable(url,@"baseURL",&_baseURL);
|
|
GSGetInstanceVariable(url,@"urlString",&_urlString);
|
|
GSGetInstanceVariable(url,@"clients",&_clients);
|
|
NSLog(@"*BaseURL: %ld",(long)_baseURL);
|
|
NSLog(@"*BaseURL: %@",[_baseURL description]);
|
|
NSLog(@"*urlString: %@",_urlString);
|
|
NSLog(@"*clients: %ld",(long)_clients);
|
|
NSLog(@"*host: %@",[url host]);
|
|
NSLog(@"*port: %@",[url port]);
|
|
NSLog(@"*user: %@",[url user]);
|
|
NSLog(@"*password: %@",[url password]);
|
|
NSLog(@"*path: %@",[url path]);
|
|
NSLog(@"*fragment: %@",[url fragment]);
|
|
NSLog(@"*parameterString: %@",[url parameterString]);
|
|
NSLog(@"*query: %@",[url query]);
|
|
NSLog(@"*relativePath: %@",[url relativePath]);
|
|
NSLog(@"*absoluteString: %@",[url absoluteString]);
|
|
NSLog(@"*relativeString: %@",[url relativeString]);
|
|
NSLog(@"*baseURL: %@",[[url baseURL] description]);
|
|
NSLog(@"*absoluteURL: %@",[[url absoluteURL] description]);
|
|
NSLog(@"*scheme: %@",[url scheme]);
|
|
NSLog(@"*resourceSpecifier: %@",[url resourceSpecifier]);
|
|
NSLog(@"*description: %@",[url description]);
|
|
};
|
|
@end
|
|
|
|
//===================================================================================
|
|
@implementation NSURL (NSURLLoading)
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(NSData*)resourceDataUsingCache:(BOOL)shouldUseCache
|
|
{
|
|
//FIXME
|
|
[self notImplemented: _cmd];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(void)loadResourceDataNotifyingClient:(id)client
|
|
usingCache:(BOOL)shouldUseCache
|
|
{
|
|
//FIXME
|
|
[self notImplemented: _cmd];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(NSURLHandle*)URLHandleUsingCache:(BOOL)shouldUseCache
|
|
{
|
|
//FIXME
|
|
[self notImplemented: _cmd];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(BOOL)setResourceData:(NSData*)data
|
|
{
|
|
//FIXME
|
|
[self notImplemented: _cmd];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(id)propertyForKey:(NSString*)propertyKey
|
|
{
|
|
//FIXME
|
|
[self notImplemented: _cmd];
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(BOOL)setProperty:(id)property
|
|
forKey:(NSString*)propertyKey;
|
|
{
|
|
//FIXME
|
|
[self notImplemented: _cmd];
|
|
};
|
|
|
|
@end
|
|
|
|
//===================================================================================
|
|
@implementation NSObject (NSURLClient)
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(void) URL:(NSURL*)sender
|
|
resourceDataDidBecomeAvailable:(NSData*)newBytes
|
|
{
|
|
//FIXME
|
|
[self notImplemented: _cmd];
|
|
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(void)URLResourceDidFinishLoading:(NSURL*)sender
|
|
{
|
|
//FIXME
|
|
[self notImplemented: _cmd];
|
|
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(void)URLResourceDidCancelLoading:(NSURL*)sender
|
|
{
|
|
//FIXME
|
|
[self notImplemented: _cmd];
|
|
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
-(void) URL:(NSURL*)sender
|
|
resourceDidFailLoadingWithReason:(NSString*)reason
|
|
{
|
|
//FIXME
|
|
[self notImplemented: _cmd];
|
|
};
|
|
|
|
@end
|