Overview
Comment: | Improve -[OFURL pathComponents] |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
b1d795b6502745a791344296a794ae21 |
User & Date: | js on 2019-04-07 19:30:11 |
Other Links: | manifest | tags |
Context
2019-04-07
| ||
22:36 | Improve file URL path handling on Windows/DOS check-in: 9e556d7dca user: js tags: trunk | |
19:30 | Improve -[OFURL pathComponents] check-in: b1d795b650 user: js tags: trunk | |
2019-04-06
| ||
20:35 | Improve path handling on Windows/DOS check-in: ec17b9225a user: js tags: trunk | |
Changes
Modified src/OFFileManager.m from [a70bd77335] to [f668bb35ed].
︙ | ︙ | |||
336 337 338 339 340 341 342 | [self createDirectoryAtURL: URL]; return; } @catch (OFCreateDirectoryFailedException *e) { /* * If we didn't fail because any of the parents is missing, * there is no point in trying to create the parents. */ | | | 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 | [self createDirectoryAtURL: URL]; return; } @catch (OFCreateDirectoryFailedException *e) { /* * If we didn't fail because any of the parents is missing, * there is no point in trying to create the parents. */ if (e.errNo != ENOENT) @throw e; } components = [URL.URLEncodedPath componentsSeparatedByString: @"/"]; for (OFString *component in components) { if (currentPath != nil) |
︙ | ︙ |
Modified src/OFURL.h from [b537389466] to [d5f7b8d500].
︙ | ︙ | |||
98 99 100 101 102 103 104 | */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *URLEncodedPath; /*! * @brief The path of the URL split into components. * | | | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *URLEncodedPath; /*! * @brief The path of the URL split into components. * * The first component must always be `/` to designate the root. */ @property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFArray OF_GENERIC(OFString *) *pathComponents; /*! * @brief The last path component of the URL. * |
︙ | ︙ |
Modified src/OFURL.m from [48639d0542] to [eacf437ac9].
︙ | ︙ | |||
928 929 930 931 932 933 934 | - (OFString *)URLEncodedPath { return _URLEncodedPath; } - (OFArray *)pathComponents { | > | > > > > > > > > > > > > > > > > > > | < < | | | | > | 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 | - (OFString *)URLEncodedPath { return _URLEncodedPath; } - (OFArray *)pathComponents { OFMutableArray *ret = [[[_URLEncodedPath componentsSeparatedByString: @"/"] mutableCopy] autorelease]; void *pool = objc_autoreleasePoolPush(); size_t count = ret.count; if (count > 0 && [ret.firstObject length] == 0) [ret replaceObjectAtIndex: 0 withObject: @"/"]; for (size_t i = 0; i < count; i++) { OFString *component = [ret objectAtIndex: i]; [ret replaceObjectAtIndex: i withObject: component.stringByURLDecoding]; } [ret makeImmutable]; objc_autoreleasePoolPop(pool); return ret; } - (OFString *)lastPathComponent { void *pool = objc_autoreleasePoolPush(); OFString *path = _URLEncodedPath; const char *UTF8String, *lastComponent; size_t length; OFString *ret; if (path == nil) { objc_autoreleasePoolPop(pool); return nil; } if ([path isEqual: @"/"]) { objc_autoreleasePoolPop(pool); return @"/"; } if ([path hasSuffix: @"/"]) path = [path substringWithRange: of_range(0, path.length - 1)]; UTF8String = lastComponent = path.UTF8String; length = path.UTF8StringLength; for (size_t i = 1; i <= length; i++) { if (UTF8String[length - i] == '/') { lastComponent = UTF8String + (length - i) + 1; break; } } ret = [OFString stringWithUTF8String: lastComponent length: length - (lastComponent - UTF8String)]; ret = [ret.stringByURLDecoding retain]; objc_autoreleasePoolPop(pool); return [ret autorelease]; } - (OFString *)query |
︙ | ︙ |
Modified tests/OFURLTests.m from [aa94b414c4] to [7afa9cebe7].
︙ | ︙ | |||
23 24 25 26 27 28 29 | static OFString *url_str = @"ht%3atp://us%3Aer:p%40w@ho%3Ast:1234/" @"pa%3Fth?que%23ry#frag%23ment"; @implementation TestsAppDelegate (OFURLTests) - (void)URLTests { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; | | | > | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | static OFString *url_str = @"ht%3atp://us%3Aer:p%40w@ho%3Ast:1234/" @"pa%3Fth?que%23ry#frag%23ment"; @implementation TestsAppDelegate (OFURLTests) - (void)URLTests { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFURL *u1, *u2, *u3, *u4, *u5; OFMutableURL *mu; TEST(@"+[URLWithString:]", R(u1 = [OFURL URLWithString: url_str]) && R(u2 = [OFURL URLWithString: @"http://foo:80"]) && R(u3 = [OFURL URLWithString: @"http://bar/"]) && R(u4 = [OFURL URLWithString: @"file:///etc/passwd"]) && R(u5 = [OFURL URLWithString: @"http://foo/bar/qux/foo%2fbar"])) EXPECT_EXCEPTION(@"+[URLWithString:] fails with invalid characters #1", OFInvalidFormatException, [OFURL URLWithString: @"ht,tp://foo"]) EXPECT_EXCEPTION(@"+[URLWithString:] fails with invalid characters #2", OFInvalidFormatException, |
︙ | ︙ | |||
133 134 135 136 137 138 139 | [u1.password isEqual: @"p@w"] && u4.password == nil) TEST(@"-[host]", [u1.host isEqual: @"ho:st"] && [u4 port] == nil) TEST(@"-[port]", [u1.port isEqual: [OFNumber numberWithUInt16: 1234]]) TEST(@"-[path]", [u1.path isEqual: @"/pa?th"] && [u4.path isEqual: @"/etc/passwd"]) TEST(@"-[pathComponents]", [u1.pathComponents isEqual: | | | > > | > | 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | [u1.password isEqual: @"p@w"] && u4.password == nil) TEST(@"-[host]", [u1.host isEqual: @"ho:st"] && [u4 port] == nil) TEST(@"-[port]", [u1.port isEqual: [OFNumber numberWithUInt16: 1234]]) TEST(@"-[path]", [u1.path isEqual: @"/pa?th"] && [u4.path isEqual: @"/etc/passwd"]) TEST(@"-[pathComponents]", [u1.pathComponents isEqual: [OFArray arrayWithObjects: @"/", @"pa?th", nil]] && [u4.pathComponents isEqual: [OFArray arrayWithObjects: @"/", @"etc", @"passwd", nil]] && [u5.pathComponents isEqual: [OFArray arrayWithObjects: @"/", @"bar", @"qux", @"foo/bar", nil]]) TEST(@"-[lastPathComponent]", [[[OFURL URLWithString: @"http://host/foo//bar/baz"] lastPathComponent] isEqual: @"baz"] && [[[OFURL URLWithString: @"http://host/foo//bar/baz/"] lastPathComponent] isEqual: @"baz"] && [[[OFURL URLWithString: @"http://host/foo/"] lastPathComponent] isEqual: @"foo"] && [[[OFURL URLWithString: @"http://host/"] lastPathComponent] isEqual: @"/"] && [u5.lastPathComponent isEqual: @"foo/bar"]) TEST(@"-[query]", [u1.query isEqual: @"que#ry"] && u4.query == nil) TEST(@"-[fragment]", [u1.fragment isEqual: @"frag#ment"] && u4.fragment == nil) TEST(@"-[copy]", R(u4 = [[u1 copy] autorelease])) |
︙ | ︙ |