Converting file paths from absolute to relative and rev. ?
19/09/04 08:57
Is there any NSString methods to convert file paths to relative to absolute and absolute to relative ?
Probably many Cocoa developers have developed their own, but we don't have reference to any public source code...
In C
Tamacom
In Perl
CPAN
In C++:
Qt
OpenOffice
In Objective-C, you may give a try to this code:
@implementation NSString(RelAbsPathExtension)
- (NSArray *)canonPathComponents
{
NSArray *pathComps = [[self stringByStandardizingPath] pathComponents] ;
NSString *pathComp ;
NSEnumerator *aEnum = [pathComps reverseObjectEnumerator] ;
NSMutableArray *canonComps = [NSMutableArray arrayWithCapacity:[pathComps count]] ;
if (![[pathComps objectAtIndex:0] isEqualToString:@"/"]) {
// relative path to current working directory
char path[MAXPATHLEN+1] ;
char *p ;
p = getwd(path) ;
if (p == NULL)
return nil ;
return [self canonPathComponentsRelativeTo:[NSString stringWithUTF8String:p]] ;
}
while ((pathComp = [aEnum nextObject]) != nil) {
if ([pathComp isEqualToString:@".."]) {
// we skip this one
pathComp = [aEnum nextObject] ;
}
else
[canonComps addObject:pathComp] ;
}
return [NSArray arrayWithReverseArray:canonComps] ;
}
- (NSArray *)canonPathComponentsRelativeTo:(NSString *)inBasePath
{
NSArray *pathComps = [[[inBasePath stringByStandardizingPath] stringByAppendingString:[self stringByStandardizingPath]] pathComponents] ;
NSString *pathComp ;
NSEnumerator *aEnum = [pathComps reverseObjectEnumerator] ;
NSMutableArray *canonComps = [NSMutableArray arrayWithCapacity:[pathComps count]] ;
if (![[pathComps objectAtIndex:0] isEqualToString:@"/"]) {
return nil ;
}
while ((pathComp = [aEnum nextObject]) != nil) {
if ([pathComp isEqualToString:@".."]) {
// we skip this one
pathComp = [aEnum nextObject] ;
}
else
[canonComps addObject:pathComp] ;
}
return [NSArray arrayWithReverseArray:canonComps] ;
}
- (NSString *)stringByMakingPathRelativeTo:(NSString *)inBase
{
NSArray *selfComps = [self canonPathComponents] ;
if (![[selfComps objectAtIndex:0] isEqualToString:@"/"]) {
return [[self copy] autorelease] ;
}
if (![inBase hasPrefix:@"/"]) {
errno = EINVAL ;
return nil ;
}
NSArray *baseComps = [inBase canonPathComponents] ;
NSString *selfPath = [selfComps componentsJoinedByString:@"/"] ;
NSString *basePath = [baseComps componentsJoinedByString:@"/"] ;
if ([selfPath hasPrefix:basePath]) {
return [selfPath substringFromIndex:[basePath length]+1] ;
}
int i ;
NSMutableString *result = [NSMutableString stringWithString:@".."];
for(i=2;i<[baseComps count];i++)
[result appendString:@"/.."] ;
return [result stringByAppendingString:[NSString pathWithComponents:selfComps]] ;
}
- (NSString *)stringByMakingPathAbsoluteWithBase:(NSString *)inBase
{
if (![inBase hasPrefix:@"/"]) {
errno = EINVAL ;
return nil ;
}
return [NSString pathWithComponents:[[inBase stringByAppendingPathComponent:self] canonPathComponents]] ;
}
@end
In C
Tamacom
In Perl
CPAN
In C++:
Qt
OpenOffice
In Objective-C, you may give a try to this code:
@implementation NSString(RelAbsPathExtension)
- (NSArray *)canonPathComponents
{
NSArray *pathComps = [[self stringByStandardizingPath] pathComponents] ;
NSString *pathComp ;
NSEnumerator *aEnum = [pathComps reverseObjectEnumerator] ;
NSMutableArray *canonComps = [NSMutableArray arrayWithCapacity:[pathComps count]] ;
if (![[pathComps objectAtIndex:0] isEqualToString:@"/"]) {
// relative path to current working directory
char path[MAXPATHLEN+1] ;
char *p ;
p = getwd(path) ;
if (p == NULL)
return nil ;
return [self canonPathComponentsRelativeTo:[NSString stringWithUTF8String:p]] ;
}
while ((pathComp = [aEnum nextObject]) != nil) {
if ([pathComp isEqualToString:@".."]) {
// we skip this one
pathComp = [aEnum nextObject] ;
}
else
[canonComps addObject:pathComp] ;
}
return [NSArray arrayWithReverseArray:canonComps] ;
}
- (NSArray *)canonPathComponentsRelativeTo:(NSString *)inBasePath
{
NSArray *pathComps = [[[inBasePath stringByStandardizingPath] stringByAppendingString:[self stringByStandardizingPath]] pathComponents] ;
NSString *pathComp ;
NSEnumerator *aEnum = [pathComps reverseObjectEnumerator] ;
NSMutableArray *canonComps = [NSMutableArray arrayWithCapacity:[pathComps count]] ;
if (![[pathComps objectAtIndex:0] isEqualToString:@"/"]) {
return nil ;
}
while ((pathComp = [aEnum nextObject]) != nil) {
if ([pathComp isEqualToString:@".."]) {
// we skip this one
pathComp = [aEnum nextObject] ;
}
else
[canonComps addObject:pathComp] ;
}
return [NSArray arrayWithReverseArray:canonComps] ;
}
- (NSString *)stringByMakingPathRelativeTo:(NSString *)inBase
{
NSArray *selfComps = [self canonPathComponents] ;
if (![[selfComps objectAtIndex:0] isEqualToString:@"/"]) {
return [[self copy] autorelease] ;
}
if (![inBase hasPrefix:@"/"]) {
errno = EINVAL ;
return nil ;
}
NSArray *baseComps = [inBase canonPathComponents] ;
NSString *selfPath = [selfComps componentsJoinedByString:@"/"] ;
NSString *basePath = [baseComps componentsJoinedByString:@"/"] ;
if ([selfPath hasPrefix:basePath]) {
return [selfPath substringFromIndex:[basePath length]+1] ;
}
int i ;
NSMutableString *result = [NSMutableString stringWithString:@".."];
for(i=2;i<[baseComps count];i++)
[result appendString:@"/.."] ;
return [result stringByAppendingString:[NSString pathWithComponents:selfComps]] ;
}
- (NSString *)stringByMakingPathAbsoluteWithBase:(NSString *)inBase
{
if (![inBase hasPrefix:@"/"]) {
errno = EINVAL ;
return nil ;
}
return [NSString pathWithComponents:[[inBase stringByAppendingPathComponent:self] canonPathComponents]] ;
}
@end