2 Copyright (C) 2000-2003 SKYRIX Software AG
4 This file is part of OGo
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
23 #include "SaxMethodCallHandler.h"
26 @interface NSObject(ToBeFixed)
28 - (id)performSelector:(SEL)_sel
35 @implementation SaxMethodCallHandler
37 static BOOL debugOn = NO;
40 if ((self = [super init])) {
41 self->delegate = self;
43 self->fqNameToStartSel = NSCreateMapTable(NSObjectMapKeyCallBacks,
44 NSNonOwnedPointerMapValueCallBacks,
46 self->selName = [[NSMutableString alloc] initWithCapacity:64];
47 self->tagStack = [[NSMutableArray alloc] initWithCapacity:16];
49 self->startKey = @"start_";
50 self->endKey = @"end_";
51 self->unknownNamespaceKey = @"any_";
53 self->ignoreLevel = -1;
59 NSFreeMapTable(self->fqNameToStartSel);
60 [self->tagStack release];
61 [self->unknownNamespaceKey release];
62 [self->startKey release];
63 [self->endKey release];
64 [self->selName release];
65 [self->namespaceToKey release];
69 - (void)registerNamespace:(NSString *)_namespace withKey:(NSString *)_key {
70 if (self->namespaceToKey == nil)
71 self->namespaceToKey = [[NSMutableDictionary alloc] initWithCapacity:16];
73 [self->namespaceToKey setObject:_key forKey:_namespace];
76 - (void)setDelegate:(id)_delegate {
77 NSResetMapTable(self->fqNameToStartSel);
79 self->delegate = _delegate;
82 return self->delegate;
85 - (void)setStartKey:(NSString *)_s {
86 id o = self->startKey;
87 self->startKey = [_s copy];
90 - (NSString *)startKey {
91 return self->startKey;
94 - (void)setEndKey:(NSString *)_s {
96 self->endKey = [_s copy];
99 - (NSString *)endKey {
103 - (void)setUnknownNamespaceKey:(NSString *)_s {
104 id o = self->unknownNamespaceKey;
105 self->unknownNamespaceKey = [_s copy];
108 - (NSString *)unknownNamespaceKey {
109 return self->unknownNamespaceKey;
112 - (NSArray *)tagStack {
113 return self->tagStack;
116 return [self->tagStack count];
119 - (void)ignoreChildren {
120 if (self->ignoreLevel == -1)
121 self->ignoreLevel = [self depth];
123 - (BOOL)doesIgnoreChildren {
124 if (self->ignoreLevel == -1)
127 return (int)[self depth] >= self->ignoreLevel ? YES : NO;
130 /* standard Sax callbacks */
132 - (void)endDocument {
134 [selName setString:@""];
137 static inline void _selAdd(SaxMethodCallHandler *self, NSString *_s) {
138 [self->selName appendString:_s];
140 static inline void _selAddEscaped(SaxMethodCallHandler *self, NSString *_s) {
141 const unsigned char *cstr;
142 register unsigned i, len;
143 BOOL needsEscape = NO;
145 if ((len = [_s cStringLength]) == 0)
149 for (i = 0; i < len; i++) {
150 register unsigned char c = cstr[i];
152 if (!(isalnum((int)c) || (c == '_'))) {
163 buf = malloc(len + 1);
164 for (i = 0, j = 0; i < len; i++) {
165 register unsigned char c = cstr[i];
167 if (isalnum((int)c) || (c == '_')) {
169 if (cstr[i - 1] == '-')
176 /* do nothing, leave out char */
181 s = [[NSString alloc] initWithCString:buf length:j];
182 [self->selName appendString:s];
186 [self->selName appendString:_s];
189 - (void)startElement:(NSString *)_localName
190 namespace:(NSString *)_ns
191 rawName:(NSString *)_rawName
192 attributes:(id<SaxAttributes>)_attrs
198 fqName = [[NSString alloc] initWithFormat:@"{%@}%@", _ns, _localName];
199 [self->tagStack addObject:fqName];
200 [fqName release]; // still retained by tagStack
202 if ((int)[self depth] > self->ignoreLevel)
205 if ((nskey = [self->namespaceToKey objectForKey:_ns]) == nil) {
206 /* unknown namespace */
208 NSLog(@"unknown namespace key %@ (tag=%@)", _ns, _rawName);
210 [self->selName setString:@""];
211 _selAdd(self, self->startKey);
213 else if ((sel = NSMapGet(self->fqNameToStartSel, fqName))) {
214 /* cached a selector .. */
215 [self->delegate performSelector:sel withObject:_attrs];
219 [self->selName setString:self->startKey];
220 _selAdd(self, nskey);
221 _selAddEscaped(self, _localName);
224 sel = NSSelectorFromString(self->selName);
225 if ([self->delegate respondsToSelector:sel]) {
226 /* ok, found correct selector */
227 [self->delegate performSelector:sel withObject:_attrs];
228 NSMapInsert(self->fqNameToStartSel, fqName, sel);
232 /* check for 'start_nskey_unknownTag:attributes:' */
233 [self->selName setString:self->startKey];
234 _selAdd(self, nskey);
235 _selAdd(self, @"unknownTag:attributes:");
236 sel = NSSelectorFromString(self->selName);
237 if ([self->delegate respondsToSelector:sel]) {
238 /* ok, found selector */
239 [self->delegate performSelector:sel
240 withObject:_localName
245 /* check for 'start_tag:namespace:attributes:' */
246 [self->selName setString:self->startKey];
247 _selAdd(self, @"tag:namespace:attributes:");
248 sel = NSSelectorFromString(self->selName);
249 if ([self->delegate respondsToSelector:sel]) {
250 /* ok, found selector */
251 [self->delegate performSelector:sel
252 withObject:_localName withObject:_ns
261 NSLog(@"%s: ignore tag: %@, sel %@", __PRETTY_FUNCTION__,
262 fqName, self->selName);
267 ; // required for MacOSX gcc
270 - (void)endElement:(NSString *)_localName
271 namespace:(NSString *)_ns
272 rawName:(NSString *)_rawName
277 if ((int)[self depth] > self->ignoreLevel) {
278 [self->tagStack removeLastObject];
281 self->ignoreLevel = -1;
283 if ((nskey = [self->namespaceToKey objectForKey:_ns]) == nil) {
284 /* unknown namespace */
286 NSLog(@"unknown namespace key %@ (tag=%@)", _ns, _rawName);
287 [selName setString:self->endKey];
290 [selName setString:self->endKey];
291 _selAdd(self, nskey);
292 _selAdd(self, _localName);
294 sel = NSSelectorFromString(self->selName);
295 if ([self->delegate respondsToSelector:sel]) {
296 /* ok, found correct selector */
297 [self->delegate performSelector:sel];
301 /* check for 'end_nskey_unknownTag:' */
302 [self->selName setString:self->endKey];
303 _selAdd(self, nskey);
304 _selAdd(self, @"unknownTag:");
305 sel = NSSelectorFromString(self->selName);
306 if ([self->delegate respondsToSelector:sel]) {
307 /* ok, found selector */
308 [self->delegate performSelector:sel withObject:_localName];
312 /* check for 'end_tag:namespace:attributes:' */
313 [self->selName setString:self->endKey];
314 _selAdd(self, @"tag:namespace:");
315 sel = NSSelectorFromString(self->selName);
316 if ([self->delegate respondsToSelector:sel]) {
317 /* ok, found selector */
318 [self->delegate performSelector:sel withObject:_localName withObject:_ns];
322 /* didn't find end tag .. */
325 [self->tagStack removeLastObject];
329 [self->tagStack removeLastObject];
332 @end /* SaxMethodCallHandler */