2 Copyright (C) 2000-2004 SKYRIX Software AG
4 This file is part of OpenGroupware.org.
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
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.
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
22 #include "SaxMethodCallHandler.h"
25 @interface NSObject(ToBeFixed)
27 - (id)performSelector:(SEL)_sel
34 @implementation SaxMethodCallHandler
36 static BOOL debugOn = NO;
39 if ((self = [super init])) {
40 self->delegate = self;
42 self->fqNameToStartSel = NSCreateMapTable(NSObjectMapKeyCallBacks,
43 NSNonOwnedPointerMapValueCallBacks,
45 self->selName = [[NSMutableString alloc] initWithCapacity:64];
46 self->tagStack = [[NSMutableArray alloc] initWithCapacity:16];
48 self->startKey = @"start_";
49 self->endKey = @"end_";
50 self->unknownNamespaceKey = @"any_";
52 self->ignoreLevel = -1;
58 NSFreeMapTable(self->fqNameToStartSel);
59 [self->tagStack release];
60 [self->unknownNamespaceKey release];
61 [self->startKey release];
62 [self->endKey release];
63 [self->selName release];
64 [self->namespaceToKey release];
68 - (void)registerNamespace:(NSString *)_namespace withKey:(NSString *)_key {
69 if (self->namespaceToKey == nil)
70 self->namespaceToKey = [[NSMutableDictionary alloc] initWithCapacity:16];
72 [self->namespaceToKey setObject:_key forKey:_namespace];
75 - (void)setDelegate:(id)_delegate {
76 NSResetMapTable(self->fqNameToStartSel);
78 self->delegate = _delegate;
81 return self->delegate;
84 - (void)setStartKey:(NSString *)_s {
85 id o = self->startKey;
86 self->startKey = [_s copy];
89 - (NSString *)startKey {
90 return self->startKey;
93 - (void)setEndKey:(NSString *)_s {
95 self->endKey = [_s copy];
98 - (NSString *)endKey {
102 - (void)setUnknownNamespaceKey:(NSString *)_s {
103 id o = self->unknownNamespaceKey;
104 self->unknownNamespaceKey = [_s copy];
107 - (NSString *)unknownNamespaceKey {
108 return self->unknownNamespaceKey;
111 - (NSArray *)tagStack {
112 return self->tagStack;
115 return [self->tagStack count];
118 - (void)ignoreChildren {
119 if (self->ignoreLevel == -1)
120 self->ignoreLevel = [self depth];
122 - (BOOL)doesIgnoreChildren {
123 if (self->ignoreLevel == -1)
126 return (int)[self depth] >= self->ignoreLevel ? YES : NO;
129 /* standard Sax callbacks */
131 - (void)endDocument {
133 [selName setString:@""];
136 static inline void _selAdd(SaxMethodCallHandler *self, NSString *_s) {
137 [self->selName appendString:_s];
139 static inline void _selAddEscaped(SaxMethodCallHandler *self, NSString *_s) {
140 const unsigned char *cstr;
141 register unsigned i, len;
142 BOOL needsEscape = NO;
144 if ((len = [_s cStringLength]) == 0)
148 for (i = 0; i < len; i++) {
149 register unsigned char c = cstr[i];
151 if (!(isalnum((int)c) || (c == '_'))) {
162 buf = malloc(len + 1);
163 for (i = 0, j = 0; i < len; i++) {
164 register unsigned char c = cstr[i];
166 if (isalnum((int)c) || (c == '_')) {
168 if (cstr[i - 1] == '-')
175 /* do nothing, leave out char */
180 s = [[NSString alloc] initWithCString:buf length:j];
181 [self->selName appendString:s];
185 [self->selName appendString:_s];
188 - (void)startElement:(NSString *)_localName
189 namespace:(NSString *)_ns
190 rawName:(NSString *)_rawName
191 attributes:(id<SaxAttributes>)_attrs
197 fqName = [[NSString alloc] initWithFormat:@"{%@}%@", _ns, _localName];
198 [self->tagStack addObject:fqName];
199 [fqName release]; // still retained by tagStack
201 if ((int)[self depth] > self->ignoreLevel)
204 if ((nskey = [self->namespaceToKey objectForKey:_ns]) == nil) {
205 /* unknown namespace */
207 NSLog(@"unknown namespace key %@ (tag=%@)", _ns, _rawName);
209 [self->selName setString:@""];
210 _selAdd(self, self->startKey);
212 else if ((sel = NSMapGet(self->fqNameToStartSel, fqName))) {
213 /* cached a selector .. */
214 [self->delegate performSelector:sel withObject:_attrs];
218 [self->selName setString:self->startKey];
219 _selAdd(self, nskey);
220 _selAddEscaped(self, _localName);
223 sel = NSSelectorFromString(self->selName);
224 if ([self->delegate respondsToSelector:sel]) {
225 /* ok, found correct selector */
226 [self->delegate performSelector:sel withObject:_attrs];
227 NSMapInsert(self->fqNameToStartSel, fqName, sel);
231 /* check for 'start_nskey_unknownTag:attributes:' */
232 [self->selName setString:self->startKey];
233 _selAdd(self, nskey);
234 _selAdd(self, @"unknownTag:attributes:");
235 sel = NSSelectorFromString(self->selName);
236 if ([self->delegate respondsToSelector:sel]) {
237 /* ok, found selector */
238 [self->delegate performSelector:sel
239 withObject:_localName
244 /* check for 'start_tag:namespace:attributes:' */
245 [self->selName setString:self->startKey];
246 _selAdd(self, @"tag:namespace:attributes:");
247 sel = NSSelectorFromString(self->selName);
248 if ([self->delegate respondsToSelector:sel]) {
249 /* ok, found selector */
250 [self->delegate performSelector:sel
251 withObject:_localName withObject:_ns
260 NSLog(@"%s: ignore tag: %@, sel %@", __PRETTY_FUNCTION__,
261 fqName, self->selName);
266 ; // required for MacOSX gcc
269 - (void)endElement:(NSString *)_localName
270 namespace:(NSString *)_ns
271 rawName:(NSString *)_rawName
276 if ((int)[self depth] > self->ignoreLevel) {
277 [self->tagStack removeLastObject];
280 self->ignoreLevel = -1;
282 if ((nskey = [self->namespaceToKey objectForKey:_ns]) == nil) {
283 /* unknown namespace */
285 NSLog(@"unknown namespace key %@ (tag=%@)", _ns, _rawName);
286 [selName setString:self->endKey];
289 [selName setString:self->endKey];
290 _selAdd(self, nskey);
291 _selAdd(self, _localName);
293 sel = NSSelectorFromString(self->selName);
294 if ([self->delegate respondsToSelector:sel]) {
295 /* ok, found correct selector */
296 [self->delegate performSelector:sel];
300 /* check for 'end_nskey_unknownTag:' */
301 [self->selName setString:self->endKey];
302 _selAdd(self, nskey);
303 _selAdd(self, @"unknownTag:");
304 sel = NSSelectorFromString(self->selName);
305 if ([self->delegate respondsToSelector:sel]) {
306 /* ok, found selector */
307 [self->delegate performSelector:sel withObject:_localName];
311 /* check for 'end_tag:namespace:attributes:' */
312 [self->selName setString:self->endKey];
313 _selAdd(self, @"tag:namespace:");
314 sel = NSSelectorFromString(self->selName);
315 if ([self->delegate respondsToSelector:sel]) {
316 /* ok, found selector */
317 [self->delegate performSelector:sel withObject:_localName withObject:_ns];
321 /* didn't find end tag .. */
324 [self->tagStack removeLastObject];
328 [self->tagStack removeLastObject];
331 @end /* SaxMethodCallHandler */