]> err.no Git - sope/blob - sope-xml/XmlRpc/NSMutableString+XmlRpcDecoder.m
fixed some comments
[sope] / sope-xml / XmlRpc / NSMutableString+XmlRpcDecoder.m
1 /*
2   Copyright (C) 2000-2005 SKYRIX Software AG
3
4   This file is part of SOPE.
5
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
9   later version.
10
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.
15
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
19   02111-1307, USA.
20 */
21
22 #include "common.h"
23
24 @implementation NSMutableString(XmlRpcDecoder)
25
26 - (void)appendXmlRpcString:(NSString *)_value {
27 #if 1 // TODO: to be tested !
28   unsigned i, j, len;
29   BOOL     didEscape = NO;
30   unichar  *buf, *escbuf = NULL;
31   
32   if ((len = [_value length]) == 0)
33     /* nothing to add ... */
34     return;
35     
36   if (len == 1) {
37     /* a single char */
38     unichar c;
39     
40     switch ((c = [_value characterAtIndex:0])) {
41       case '&': [self appendString:@"&"];  break;
42       case '<': [self appendString:@"&lt;"];   break;
43       case '>': [self appendString:@"&gt;"];   break;
44       case '"': [self appendString:@"&quot;"]; break;
45       default:  [self appendString:_value];    break;
46     }
47     return;
48   }
49   
50   buf = calloc(len + 2, sizeof(unichar));
51   [_value getCharacters:buf];
52   
53   for (i = 0, j = 0; i < len; i++) {
54     switch (buf[i]) {
55       case '&':
56       case '<':
57       case '>':
58       case '"': {
59         didEscape = YES;
60         if (escbuf == NULL) {
61           /* worst case: string consists of quotes */
62           escbuf = calloc(len * 6 + 2, sizeof(unichar));
63           memcpy(escbuf, buf, i * sizeof(unichar));
64           j = i;
65         }
66         escbuf[j++] = '&';
67         switch (buf[i]) {
68           case '&':
69             escbuf[j++] = 'a'; escbuf[j++] = 'm'; escbuf[j++] = 'p';
70             break;
71           case '<':
72             escbuf[j++] = 'l'; escbuf[j++] = 't';
73             break;
74           case '>':
75             escbuf[j++] = 'g'; escbuf[j++] = 't';
76             break;
77           case '"':
78             escbuf[j++] = 'q'; escbuf[j++] = 'u';
79             escbuf[j++] = 'o'; escbuf[j++] = 't';
80             break;
81         }
82         escbuf[j++] = ';';
83         break;
84       }
85       default:
86         if (escbuf)
87           escbuf[j++] = buf[i];
88         break;
89     }
90   }
91   
92   if (escbuf) {
93     NSString *s;
94     
95     s = [[NSString alloc] initWithCharacters:escbuf length:j];
96     [self appendString:s];
97     [s release];
98     free(escbuf);
99   }
100   else
101     [self appendString:_value];
102   
103   if (buf) free(buf);
104 #else
105 #warning UNICODE !!!
106   void (*addBytes)(id,SEL,const char *,unsigned);
107   id            dummy = nil;
108   unsigned      clen;
109   unsigned char *cbuf;
110   unsigned char *cstr;
111
112   if ([_value length] == 0) return;
113
114   clen = [_value cStringLength];
115   if (clen == 0) return; /* nothing to add .. */
116   
117   cbuf = cstr = malloc(clen + 1);
118   [_value getCString:cbuf]; cbuf[clen] = '\0';
119   dummy = [[NSMutableData alloc] initWithCapacity:2*clen];
120
121   addBytes = (void*)[dummy methodForSelector:@selector(appendBytes:length:)];
122   NSAssert(addBytes != NULL, @"could not get appendBytes:length: ..");
123   
124   while (*cstr) {
125     switch (*cstr) {
126       case '&':
127         addBytes(dummy, @selector(appendBytes:length:), "&amp;", 5);
128         break;
129       case '<':
130         addBytes(dummy, @selector(appendBytes:length:), "&lt;", 4);
131         break;
132       case '>':
133         addBytes(dummy, @selector(appendBytes:length:), "&gt;", 4);
134         break;
135       case '"':
136         addBytes(dummy, @selector(appendBytes:length:), "&quot;", 6);
137         break;
138       
139       default:
140         addBytes(dummy, @selector(appendBytes:length:), cstr, 1);
141         break;
142     }
143     cstr++;
144   }
145   free(cbuf);
146   {
147     NSString *tmp = nil;
148     
149     tmp = [[NSString alloc] initWithData:dummy
150                             encoding:[NSString defaultCStringEncoding]];
151     [self appendString:tmp];
152     [tmp release];
153   }
154 #endif
155 }
156
157 @end /* NSMutableString(XmlRpcDecoder) */