libs-base/Source/NSURL.m
mguesdon 8bf4e8bb10 Thu Feb 12 00:57:00 1999 Manuel Guesdon <mguesdon@sbuilders.com>
* 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
1999-02-13 00:50:41 +00:00

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