16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
#include "config.h"
#include <stdlib.h>
#include <string.h>
#import "OFString+URLEncoding.h"
#import "OFInvalidFormatException.h"
#import "OFOutOfMemoryException.h"
/* Reference for static linking */
int _OFString_URLEncoding_reference;
@implementation OFString (URLEncoding)
- (OFString *)stringByURLEncoding
{
return [self stringByURLEncodingWithAllowedCharacters:
"-._~!$&'()*+,;="];
}
- (OFString *)stringByURLEncodingWithAllowedCharacters: (const char *)allowed
{
void *pool = objc_autoreleasePoolPush();
const char *string = [self UTF8String];
size_t length = [self UTF8StringLength];
char *retCString, *retCString2;
size_t i = 0;
/*
* Worst case: 3 times longer than before.
* Oh, and we can't use [self allocWithSize:] here as self might be a
* @"" literal.
*/
if ((retCString = malloc(length * 3 + 1)) == NULL)
@throw [OFOutOfMemoryException exceptionWithRequestedSize:
length * 3 + 1];
while (length--) {
unsigned char c = *string++;
if (of_ascii_isalnum(c) || strchr(allowed, c) != NULL)
retCString[i++] = c;
else {
unsigned char high, low;
high = c >> 4;
low = c & 0x0F;
retCString[i++] = '%';
retCString[i++] =
(high > 9 ? high - 10 + 'A' : high + '0');
retCString[i++] =
(low > 9 ? low - 10 + 'A' : low + '0');
}
}
retCString[i] = '\0';
objc_autoreleasePoolPop(pool);
/* We don't care if it fails, as we only made it smaller. */
if ((retCString2 = realloc(retCString, i + 1)) == NULL)
retCString2 = retCString;
return [OFString stringWithUTF8StringNoCopy: retCString2
length: i
freeWhenDone: true];
}
- (OFString *)stringByURLDecoding
{
void *pool = objc_autoreleasePoolPush();
const char *string = [self UTF8String];
size_t length = [self UTF8StringLength];
|
>
|
<
|
<
<
|
|
<
|
|
>
>
>
|
|
>
<
>
|
<
|
<
<
<
|
<
<
<
<
<
<
|
<
<
|
>
|
<
|
<
|
|
>
>
|
<
>
<
<
<
|
<
<
<
|
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
#include "config.h"
#include <stdlib.h>
#include <string.h>
#import "OFString+URLEncoding.h"
#import "OFCharacterSet.h"
#import "OFInvalidFormatException.h"
#import "OFOutOfMemoryException.h"
/* Reference for static linking */
int _OFString_URLEncoding_reference;
@implementation OFString (URLEncoding)
- (OFString *)stringByURLEncodingWithAllowedCharacters:
(OFCharacterSet *)allowedCharacters
{
OFMutableString *ret = [OFMutableString string];
void *pool = objc_autoreleasePoolPush();
const of_unichar_t *characters = [self characters];
size_t length = [self length];
bool (*characterIsMember)(id, SEL, of_unichar_t) =
(bool (*)(id, SEL, of_unichar_t))[allowedCharacters
methodForSelector: @selector(characterIsMember:)];
for (size_t i = 0; i < length; i++) {
of_unichar_t c = characters[i];
if (characterIsMember(allowedCharacters,
@selector(characterIsMember:), c))
[ret appendCharacters: &c
length: 1];
else {
unsigned char high = c >> 4;
unsigned char low = c & 0x0F;
of_unichar_t escaped[3];
escaped[0] = '%';
escaped[1] = (high > 9 ? high - 10 + 'A' : high + '0');
escaped[2] = (low > 9 ? low - 10 + 'A' : low + '0');
[ret appendCharacters: escaped
length: 3];
}
}
objc_autoreleasePoolPop(pool);
return ret;
}
- (OFString *)stringByURLDecoding
{
void *pool = objc_autoreleasePoolPush();
const char *string = [self UTF8String];
size_t length = [self UTF8StringLength];
|