]> err.no Git - sope/blob - sope-core/NGExtensions/FdExt.subproj/NSString+XMLEscaping.m
fixed incompatibility of new logging framework with OGo
[sope] / sope-core / NGExtensions / FdExt.subproj / NSString+XMLEscaping.m
1 /*
2   Copyright (C) 2000-2003 SKYRIX Software AG
3
4   This file is part of OGo
5
6   OGo 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   OGo 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 OGo; 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 // $Id$
22
23 #include "NSString+misc.h"
24 #include "common.h"
25
26 @implementation NSString(XMLEscaping)
27
28 - (NSString *)stringByEscapingXMLStringUsingCharacters {
29   register unsigned i, len, j;
30   register unichar  *chars, *buf;
31   unsigned escapeCount;
32   
33   if ((len = [self length]) == 0) return @"";
34   
35   chars = malloc((len + 3) * sizeof(unichar));
36   [self getCharacters:chars];
37   
38   /* check for characters to escape ... */
39   for (i = 0, escapeCount = 0; i < len; i++) {
40     switch (chars[i]) {
41       case '&': case '"': case '<': case '>':
42         escapeCount++;
43         break;
44       default:
45         if (chars[i] > 127)
46           escapeCount++;
47         break;
48     }
49   }
50   if (escapeCount == 0 ) {
51     /* nothing to escape ... */
52     if (chars) free(chars);
53     return [[self copy] autorelease];
54   }
55   
56   buf = malloc(((len + 3) * sizeof(unichar)) +
57                (escapeCount * 8 * sizeof(unichar)));
58   for (i = 0, j = 0; i < len; i++) {
59     switch (chars[i]) {
60       /* escape special chars */
61       case '&':
62         buf[j] = '&'; j++; buf[j] = 'a'; j++; buf[j] = 'm'; j++;
63         buf[j] = 'p'; j++; buf[j] = ';'; j++;
64         break;
65       case '"':
66         buf[j] = '&'; j++; buf[j] = 'q'; j++; buf[j] = 'u'; j++;
67         buf[j] = 'o'; j++; buf[j] = 't'; j++; buf[j] = ';'; j++;
68         break;
69       case '<':
70         buf[j] = '&'; j++; buf[j] = 'l'; j++; buf[j] = 't'; j++;
71         buf[j] = ';'; j++;
72         break;
73       case '>':
74         buf[j] = '&'; j++; buf[j] = 'g'; j++; buf[j] = 't'; j++;
75         buf[j] = ';'; j++;
76         break;
77         
78       default:
79         /* escape big chars */
80         if (chars[i] > 127) {
81           unsigned char nbuf[16];
82           unsigned int k;
83           
84           sprintf(nbuf, "&#%i;", (int)chars[i]);
85           for (k = 0; nbuf[k] != '\0'; k++) {
86             buf[j] = nbuf[k];
87             j++;
88           }
89         }
90         else {
91           /* nothing to escape */
92           buf[j] = chars[i];
93           j++;
94         }
95         break;
96     }
97   }
98   
99   self = [NSString stringWithCharacters:buf length:j];
100   
101   if (chars) free(chars);
102   if (buf)   free(buf);
103   return self;
104 }
105
106 - (NSString *)stringByEscapingXMLString {
107   return [self stringByEscapingXMLStringUsingCharacters];
108 }
109
110 - (NSString *)stringByEscapingXMLAttributeValue {
111   return [self stringByEscapingHTMLAttributeValue];
112 }
113
114 /* XML FQNs */
115
116 - (BOOL)xmlIsFQN {
117   if ([self length] == 0) return NO;
118   return [self characterAtIndex:0] == '{' ? YES : NO;
119 }
120
121 - (NSString *)xmlNamespaceURI {
122   NSRange r;
123   
124   r = [self rangeOfString:@"}" options:(NSLiteralSearch | NSBackwardsSearch)];
125   if (r.length == 0) return nil;
126   if ([self characterAtIndex:0] != '{') return nil;
127   
128   r.length   = (r.location - 1);
129   r.location = 1;
130   return [self substringWithRange:r];
131 }
132
133 - (NSString *)xmlLocalName {
134   NSRange r;
135   
136   r = [self rangeOfString:@"}" options:(NSLiteralSearch | NSBackwardsSearch)];
137   if (r.length == 0) return nil;
138   if ([self characterAtIndex:0] != '{') return nil;
139   
140   return [self substringFromIndex:(r.location + r.length)];
141 }
142
143 @end /* NSString(XMLEscaping) */