2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
6 SOPE is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with SOPE; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 #include "NGUrlFormCoder.h"
25 #if !LIB_FOUNDATION_LIBRARY
26 static BOOL debugDecoding = NO;
29 static __inline__ int _valueOfHexChar(unsigned char _c) {
31 case '0': case '1': case '2': case '3': case '4':
32 case '5': case '6': case '7': case '8': case '9':
33 return (_c - 48); // 0-9 (ascii-char)'0' - 48 => (int)0
35 case 'A': case 'B': case 'C':
36 case 'D': case 'E': case 'F':
37 return (_c - 55); // A-F, A=10..F=15, 'A'=65..'F'=70
39 case 'a': case 'b': case 'c':
40 case 'd': case 'e': case 'f':
41 return (_c - 87); // a-f, a=10..F=15, 'a'=97..'f'=102
48 static __inline__ unsigned
49 _unescapeUrl(const char *_src, unsigned _len, char *_dest)
51 register unsigned i, i2;
53 for (i = 0, i2 = 0; i < _len; i++, i2++) {
54 register char c = _src[i];
57 case '+': // encoded space
61 case '%': // encoded hex ('%FF')
62 _dest[i2] = _valueOfHexChar(_src[i + 1]) * 16 +
63 _valueOfHexChar(_src[i + 2]);
64 i += 2; // skip the two hexchars
67 default: // normal char
72 return i2; // return unescaped length
75 static Class StrClass = Nil;
77 static __inline__ NSString *urlStringFromBuffer(const unsigned char *buffer,
80 // TODO: we assume ISO-Latin-1/Unicode encoding, which might be wrong
81 #if LIB_FOUNDATION_LIBRARY
82 return [[StrClass alloc] initWithCString:buffer length:len];
84 register signed int i;
88 s = malloc((len + 2) * sizeof(unichar));
89 for (i = len - 1; i >= 0; i--)
91 value = [[StrClass alloc] initWithCharacters:s length:len];
92 if (s != NULL) free(s);
95 NSLog(@"decoded data len %d value (len=%d): %@",
96 len, [value length], value);
102 NGHashMap *NGDecodeUrlFormParameters(const unsigned char *_buffer,
105 NGMutableHashMap *dict = nil;
108 if (_len == 0) return nil;
110 if (StrClass == Nil) StrClass = [NSString class];
111 dict = [[NGMutableHashMap alloc] initWithCapacity:16];
114 NSString *key = nil, *value = nil;
120 while ((pos < _len) && (_buffer[pos] != '='))
123 len = _unescapeUrl(&(_buffer[tmp]), (pos - tmp), buffer);
124 key = len > 0 ? urlStringFromBuffer(buffer, len) : @"";
126 if (pos < _len) { // value pending
127 NSCAssert(_buffer[pos] == '=', @"invalid parser state ..");
132 while ((pos < _len) && (_buffer[pos] != '&') && (_buffer[pos] != '?')) {
136 len = _unescapeUrl(&(_buffer[tmp]), (pos - tmp), buffer);
137 value = len > 0 ? urlStringFromBuffer(buffer, len) : @"";
140 if (_buffer[pos] == '&' || _buffer[pos] == '?') pos++;
146 /* store in dictionary */
148 [dict addObject:value forKey:key];
150 [key release]; key = nil;
151 [value release]; value = nil;
158 @implementation NSString(FormURLCoding)
160 - (NSString *)stringByApplyingURLEncoding {
161 /* NGExtensions/NSString+misc.h */
162 NSLog(@"Note: Called deprecated -stringByApplyingURLEncoding method "
163 @"(use -stringByEscapingURL instead)", __PRETTY_FUNCTION__);
164 return [self stringByEscapingURL];
167 @end /* NSString(FormURLCoding) */