iphone - Objective-C code to generate a relative path given a file and a directory -
given file path , directory path nsstring
s, have objective-c code generate path file, relative directory?
for example, given directory /tmp/foo
, file /tmp/bar/test.txt
, code should produce ../bar/test.txt
.
i know python, @ least, has method this: os.path.relpath
.
rather continue defend why need this, decided write , share. based off of implementation of python's os.path.relpath
@ http://mail.python.org/pipermail/python-list/2009-august/1215220.html
@implementation nsstring (paths) - (nsstring*)stringwithpathrelativeto:(nsstring*)anchorpath { nsarray *pathcomponents = [self pathcomponents]; nsarray *anchorcomponents = [anchorpath pathcomponents]; nsinteger componentsincommon = min([pathcomponents count], [anchorcomponents count]); (nsinteger = 0, n = componentsincommon; < n; i++) { if (![[pathcomponents objectatindex:i] isequaltostring:[anchorcomponents objectatindex:i]]) { componentsincommon = i; break; } } nsuinteger numberofparentcomponents = [anchorcomponents count] - componentsincommon; nsuinteger numberofpathcomponents = [pathcomponents count] - componentsincommon; nsmutablearray *relativecomponents = [nsmutablearray arraywithcapacity: numberofparentcomponents + numberofpathcomponents]; (nsinteger = 0; < numberofparentcomponents; i++) { [relativecomponents addobject:@".."]; } [relativecomponents addobjectsfromarray: [pathcomponents subarraywithrange:nsmakerange(componentsincommon, numberofpathcomponents)]]; return [nsstring pathwithcomponents:relativecomponents]; } @end
note there cases won't correctly handle. happens handle cases need. here skimpy unit test used verify correctness:
@implementation nsstringpathstests - (void)testrelativepaths { stassertequalobjects([@"/a" stringwithpathrelativeto:@"/"], @"a", @""); stassertequalobjects([@"a/b" stringwithpathrelativeto:@"a"], @"b", @""); stassertequalobjects([@"a/b/c" stringwithpathrelativeto:@"a"], @"b/c", @""); stassertequalobjects([@"a/b/c" stringwithpathrelativeto:@"a/b"], @"c", @""); stassertequalobjects([@"a/b/c" stringwithpathrelativeto:@"a/d"], @"../b/c", @""); stassertequalobjects([@"a/b/c" stringwithpathrelativeto:@"a/d/e"], @"../../b/c", @""); stassertequalobjects([@"/a/b/c" stringwithpathrelativeto:@"/d/e/f"], @"../../../a/b/c", @""); } @end
Comments
Post a Comment