@@ -25,28 +25,32 @@ int _OFString_PathAdditions_reference; @implementation OFString (PathAdditions) + (OFString *)pathWithComponents: (OFArray *)components { + OFMutableString *ret = [OFMutableString string]; void *pool = objc_autoreleasePoolPush(); - OFString *ret; - - if ([[components firstObject] isEqual: @"/"]) { - OFMutableArray OF_GENERIC(OFString *) *mutableComponents = - [[components mutableCopy] autorelease]; - - [mutableComponents replaceObjectAtIndex: 0 - withObject: @""]; - - components = mutableComponents; - } - - ret = [components componentsJoinedByString: @"/"]; - - [ret retain]; - objc_autoreleasePoolPop(pool); - return [ret autorelease]; + bool first = true; + + for (OFString *component in components) { + if ([component length] == 0) + continue; + + if (!first && [component isEqual: @"/"]) + continue; + + if (!first && ![ret hasSuffix: @"/"]) + [ret appendString: @"/"]; + + [ret appendString: component]; + + first = false; + } + + objc_autoreleasePoolPop(pool); + + return ret; } - (bool)isAbsolutePath { return [self hasPrefix: @"/"]; @@ -62,27 +66,25 @@ if (pathCStringLength == 0) { objc_autoreleasePoolPop(pool); return ret; } - if (cString[pathCStringLength - 1] == '/') - pathCStringLength--; - for (i = 0; i < pathCStringLength; i++) { if (cString[i] == '/') { - [ret addObject: - [OFString stringWithUTF8String: cString + last - length: i - last]]; + if (i == 0) + [ret addObject: @"/"]; + else if (i - last != 0) + [ret addObject: [OFString + stringWithUTF8String: cString + last + length: i - last]]; + last = i + 1; } } - [ret addObject: [OFString stringWithUTF8String: cString + last - length: i - last]]; - - if ([[ret firstObject] isEqual: @""]) - [ret replaceObjectAtIndex: 0 - withObject: @"/"]; + if (i - last != 0) + [ret addObject: [OFString stringWithUTF8String: cString + last + length: i - last]]; [ret makeImmutable]; objc_autoreleasePoolPop(pool);