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 "pyxSAXDriver.h"
24 #include <SaxObjC/SaxException.h>
25 #include <SaxObjC/SaxAttributes.h>
26 #include <SaxObjC/SaxDocumentHandler.h>
27 #import <Foundation/Foundation.h>
29 #if NeXT_Foundation_LIBRARY || APPLE_Foundation_LIBRARY
30 # include <FoundationExt/NSObjectMacros.h>
31 # include <FoundationExt/MissingMethods.h>
34 static NSString *SaxDeclHandlerProperty =
35 @"http://xml.org/sax/properties/declaration-handler";
36 static NSString *SaxLexicalHandlerProperty =
37 @"http://xml.org/sax/properties/lexical-handler";
39 static NSString *SaxDOMNodeProperty =
40 @"http://xml.org/sax/properties/dom-node";
41 static NSString *SaxXMLStringProperty =
42 @"http://xml.org/sax/properties/xml-string";
45 @implementation pyxSAXDriver
48 self->nsStack = [[NSMutableArray alloc] init];
50 /* feature defaults */
51 self->fNamespaces = YES;
52 self->fNamespacePrefixes = NO;
58 RELEASE(self->nsStack);
61 RELEASE(self->declHandler);
62 RELEASE(self->lexicalHandler);
63 RELEASE(self->contentHandler);
64 RELEASE(self->dtdHandler);
65 RELEASE(self->errorHandler);
66 RELEASE(self->entityResolver);
72 - (void)setProperty:(NSString *)_name to:(id)_value {
73 if ([_name isEqualToString:SaxLexicalHandlerProperty]) {
74 ASSIGN(self->lexicalHandler, _value);
77 if ([_name isEqualToString:SaxDeclHandlerProperty]) {
78 ASSIGN(self->declHandler, _value);
82 [SaxNotRecognizedException raise:@"PropertyException"
83 format:@"don't know property %@", _name];
85 - (id)property:(NSString *)_name {
86 if ([_name isEqualToString:SaxLexicalHandlerProperty])
87 return self->lexicalHandler;
88 if ([_name isEqualToString:SaxDeclHandlerProperty])
89 return self->declHandler;
91 [SaxNotRecognizedException raise:@"PropertyException"
92 format:@"don't know property %@", _name];
98 - (void)setFeature:(NSString *)_name to:(BOOL)_value {
99 if ([_name isEqualToString:@"http://xml.org/sax/features/namespaces"]) {
100 self->fNamespaces = _value;
104 if ([_name isEqualToString:
105 @"http://xml.org/sax/features/namespace-prefixes"]) {
106 self->fNamespacePrefixes = _value;
110 [SaxNotRecognizedException raise:@"FeatureException"
111 format:@"don't know feature %@", _name];
113 - (BOOL)feature:(NSString *)_name {
114 if ([_name isEqualToString:@"http://xml.org/sax/features/namespaces"])
115 return self->fNamespaces;
117 if ([_name isEqualToString:
118 @"http://xml.org/sax/features/namespace-prefixes"])
119 return self->fNamespacePrefixes;
121 [SaxNotRecognizedException raise:@"FeatureException"
122 format:@"don't know feature %@", _name];
129 - (void)setDocumentHandler:(id<NSObject,SaxDocumentHandler>)_handler {
130 SaxDocumentHandlerAdaptor *a;
132 a = [[SaxDocumentHandlerAdaptor alloc] initWithDocumentHandler:_handler];
133 [self setContentHandler:a];
138 - (void)setDTDHandler:(id<NSObject,SaxDTDHandler>)_handler {
139 ASSIGN(self->dtdHandler, _handler);
141 - (id<NSObject,SaxDTDHandler>)dtdHandler {
142 return self->dtdHandler;
145 - (void)setErrorHandler:(id<NSObject,SaxErrorHandler>)_handler {
146 ASSIGN(self->errorHandler, _handler);
148 - (id<NSObject,SaxErrorHandler>)errorHandler {
149 return self->errorHandler;
152 - (void)setEntityResolver:(id<NSObject,SaxEntityResolver>)_handler {
153 ASSIGN(self->entityResolver, _handler);
155 - (id<NSObject,SaxEntityResolver>)entityResolver {
156 return self->entityResolver;
159 - (void)setContentHandler:(id<NSObject,SaxContentHandler>)_handler {
160 ASSIGN(self->contentHandler, _handler);
162 - (id<NSObject,SaxContentHandler>)contentHandler {
163 return self->contentHandler;
168 - (void)parseFromSource:(id)_source {
169 NSAutoreleasePool *pool;
172 if ([_source isKindOfClass:[NSString class]]) {
173 lines = [_source componentsSeparatedByString:@"\n"];
175 else if ([_source isKindOfClass:[NSData class]]) {
176 _source = [[NSString alloc]
178 encoding:[NSString defaultCStringEncoding]];
179 lines = [_source componentsSeparatedByString:@"\n"];
183 SaxParseException *e;
186 ui = [NSDictionary dictionaryWithObjectsAndKeys:
187 _source ? _source : @"<nil>", @"source",
191 e = (id)[SaxParseException exceptionWithName:@"SaxIOException"
192 reason:@"can't handle data-source"
195 [self->errorHandler fatalError:e];
199 pool = [[NSAutoreleasePool alloc] init];
201 /* start parsing lines */
206 e = [lines objectEnumerator];
207 while ((line = [e nextObject])) {
209 if ([line hasPrefix:@"("]) {
210 NSMutableDictionary *ns = nil;
212 NSDictionary *nsDict = nil;
214 /* not yet finished ! */
216 startTag = [line substringFromIndex:1];
217 line = [e nextObject];
218 while ([line hasPrefix:@"A"]) {
220 NSString *rawName, *value;
223 line = [line substringFromIndex:1];
225 if ((idx = [line indexOfString:@" "]) == NSNotFound) {
230 rawName = [line substringToIndex:idx];
231 value = [line substringFromIndex:(idx + 1)];
234 if ([rawName hasPrefix:@"xmlns"]) {
235 /* a namespace declaration */
236 if (ns == nil) ns = [[NSMutableDictionary alloc] init];
238 if ([rawName hasPrefix:@"xmlns:"]) {
239 /* eg <x xmlns:nl="http://www.w3.org"/> */
240 NSString *prefix, *uri;
242 prefix = [rawName substringFromIndex:6];
245 [ns setObject:uri forKey:prefix];
247 if (self->fNamespaces)
248 [self->contentHandler startPrefixMapping:prefix uri:uri];
251 /* eg <x xmlns="http://www.w3.org"/> */
252 [ns setObject:value forKey:@":"];
256 /* start tag finished */
258 RELEASE(ns); ns = nil;
260 /* manage namespace stack */
263 nsDict = [NSDictionary dictionary];
265 [self->nsStack addObject:nsDict];
267 /* to be completed ! */
278 - (void)parseFromSystemId:(NSString *)_sysId {
281 /* _sysId is a URI */
282 if (![_sysId hasPrefix:@"file://"]) {
283 SaxParseException *e;
286 ui = [NSDictionary dictionaryWithObjectsAndKeys:
287 _sysId ? _sysId : @"<nil>", @"systemID",
291 e = (id)[SaxParseException exceptionWithName:@"SaxIOException"
292 reason:@"can't handle system-id"
295 [self->errorHandler fatalError:e];
299 /* cut off file:// */
300 _sysId = [_sysId substringFromIndex:7];
302 /* start parsing .. */
303 if ((s = [NSString stringWithContentsOfFile:_sysId]))
304 [self parseFromSource:s];
309 - (NSString *)replacementStringForEntityNamed:(NSString *)_entityName {
310 //NSLog(@"get entity: %@", _entityName);
311 return [[@"&" stringByAppendingString:_entityName]
312 stringByAppendingString:@";"];
315 /* namespace support */
317 - (NSString *)nsUriForPrefix:(NSString *)_prefix {
321 e = [self->nsStack reverseObjectEnumerator];
322 while ((ns = [e nextObject])) {
325 if ((uri = [ns objectForKey:_prefix]))
331 - (NSString *)defaultNamespace {
332 return [self nsUriForPrefix:@":"];
335 @end /* pyxSAXDriver */