2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
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
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.
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
22 #include "pyxSAXDriver.h"
23 #include <SaxObjC/SaxException.h>
24 #include <SaxObjC/SaxAttributes.h>
25 #include <SaxObjC/SaxDocumentHandler.h>
26 #import <Foundation/Foundation.h>
28 #if NeXT_Foundation_LIBRARY || APPLE_Foundation_LIBRARY
29 # include <FoundationExt/NSObjectMacros.h>
30 # include <FoundationExt/MissingMethods.h>
33 static NSString *SaxDeclHandlerProperty =
34 @"http://xml.org/sax/properties/declaration-handler";
35 static NSString *SaxLexicalHandlerProperty =
36 @"http://xml.org/sax/properties/lexical-handler";
38 static NSString *SaxDOMNodeProperty =
39 @"http://xml.org/sax/properties/dom-node";
40 static NSString *SaxXMLStringProperty =
41 @"http://xml.org/sax/properties/xml-string";
44 @implementation pyxSAXDriver
47 self->nsStack = [[NSMutableArray alloc] init];
49 /* feature defaults */
50 self->fNamespaces = YES;
51 self->fNamespacePrefixes = NO;
57 RELEASE(self->nsStack);
60 RELEASE(self->declHandler);
61 RELEASE(self->lexicalHandler);
62 RELEASE(self->contentHandler);
63 RELEASE(self->dtdHandler);
64 RELEASE(self->errorHandler);
65 RELEASE(self->entityResolver);
71 - (void)setProperty:(NSString *)_name to:(id)_value {
72 if ([_name isEqualToString:SaxLexicalHandlerProperty]) {
73 ASSIGN(self->lexicalHandler, _value);
76 if ([_name isEqualToString:SaxDeclHandlerProperty]) {
77 ASSIGN(self->declHandler, _value);
81 [SaxNotRecognizedException raise:@"PropertyException"
82 format:@"don't know property %@", _name];
84 - (id)property:(NSString *)_name {
85 if ([_name isEqualToString:SaxLexicalHandlerProperty])
86 return self->lexicalHandler;
87 if ([_name isEqualToString:SaxDeclHandlerProperty])
88 return self->declHandler;
90 [SaxNotRecognizedException raise:@"PropertyException"
91 format:@"don't know property %@", _name];
97 - (void)setFeature:(NSString *)_name to:(BOOL)_value {
98 if ([_name isEqualToString:@"http://xml.org/sax/features/namespaces"]) {
99 self->fNamespaces = _value;
103 if ([_name isEqualToString:
104 @"http://xml.org/sax/features/namespace-prefixes"]) {
105 self->fNamespacePrefixes = _value;
109 [SaxNotRecognizedException raise:@"FeatureException"
110 format:@"don't know feature %@", _name];
112 - (BOOL)feature:(NSString *)_name {
113 if ([_name isEqualToString:@"http://xml.org/sax/features/namespaces"])
114 return self->fNamespaces;
116 if ([_name isEqualToString:
117 @"http://xml.org/sax/features/namespace-prefixes"])
118 return self->fNamespacePrefixes;
120 [SaxNotRecognizedException raise:@"FeatureException"
121 format:@"don't know feature %@", _name];
128 - (void)setDocumentHandler:(id<NSObject,SaxDocumentHandler>)_handler {
129 SaxDocumentHandlerAdaptor *a;
131 a = [[SaxDocumentHandlerAdaptor alloc] initWithDocumentHandler:_handler];
132 [self setContentHandler:a];
137 - (void)setDTDHandler:(id<NSObject,SaxDTDHandler>)_handler {
138 ASSIGN(self->dtdHandler, _handler);
140 - (id<NSObject,SaxDTDHandler>)dtdHandler {
141 return self->dtdHandler;
144 - (void)setErrorHandler:(id<NSObject,SaxErrorHandler>)_handler {
145 ASSIGN(self->errorHandler, _handler);
147 - (id<NSObject,SaxErrorHandler>)errorHandler {
148 return self->errorHandler;
151 - (void)setEntityResolver:(id<NSObject,SaxEntityResolver>)_handler {
152 ASSIGN(self->entityResolver, _handler);
154 - (id<NSObject,SaxEntityResolver>)entityResolver {
155 return self->entityResolver;
158 - (void)setContentHandler:(id<NSObject,SaxContentHandler>)_handler {
159 ASSIGN(self->contentHandler, _handler);
161 - (id<NSObject,SaxContentHandler>)contentHandler {
162 return self->contentHandler;
167 - (void)parseFromSource:(id)_source {
168 NSAutoreleasePool *pool;
171 if ([_source isKindOfClass:[NSString class]]) {
172 lines = [_source componentsSeparatedByString:@"\n"];
174 else if ([_source isKindOfClass:[NSData class]]) {
175 _source = [[NSString alloc]
177 encoding:[NSString defaultCStringEncoding]];
178 lines = [_source componentsSeparatedByString:@"\n"];
182 SaxParseException *e;
185 ui = [NSDictionary dictionaryWithObjectsAndKeys:
186 _source ? _source : @"<nil>", @"source",
190 e = (id)[SaxParseException exceptionWithName:@"SaxIOException"
191 reason:@"can't handle data-source"
194 [self->errorHandler fatalError:e];
198 pool = [[NSAutoreleasePool alloc] init];
200 /* start parsing lines */
205 e = [lines objectEnumerator];
206 while ((line = [e nextObject])) {
208 if ([line hasPrefix:@"("]) {
209 NSMutableDictionary *ns = nil;
211 NSDictionary *nsDict = nil;
213 /* not yet finished ! */
215 startTag = [line substringFromIndex:1];
216 line = [e nextObject];
217 while ([line hasPrefix:@"A"]) {
219 NSString *rawName, *value;
222 line = [line substringFromIndex:1];
224 if ((idx = [line indexOfString:@" "]) == NSNotFound) {
229 rawName = [line substringToIndex:idx];
230 value = [line substringFromIndex:(idx + 1)];
233 if ([rawName hasPrefix:@"xmlns"]) {
234 /* a namespace declaration */
235 if (ns == nil) ns = [[NSMutableDictionary alloc] init];
237 if ([rawName hasPrefix:@"xmlns:"]) {
238 /* eg <x xmlns:nl="http://www.w3.org"/> */
239 NSString *prefix, *uri;
241 prefix = [rawName substringFromIndex:6];
244 [ns setObject:uri forKey:prefix];
246 if (self->fNamespaces)
247 [self->contentHandler startPrefixMapping:prefix uri:uri];
250 /* eg <x xmlns="http://www.w3.org"/> */
251 [ns setObject:value forKey:@":"];
255 /* start tag finished */
257 RELEASE(ns); ns = nil;
259 /* manage namespace stack */
262 nsDict = [NSDictionary dictionary];
264 [self->nsStack addObject:nsDict];
266 /* to be completed ! */
277 - (void)parseFromSystemId:(NSString *)_sysId {
280 /* _sysId is a URI */
281 if (![_sysId hasPrefix:@"file://"]) {
282 SaxParseException *e;
285 ui = [NSDictionary dictionaryWithObjectsAndKeys:
286 _sysId ? _sysId : @"<nil>", @"systemID",
290 e = (id)[SaxParseException exceptionWithName:@"SaxIOException"
291 reason:@"can't handle system-id"
294 [self->errorHandler fatalError:e];
298 /* cut off file:// */
299 _sysId = [_sysId substringFromIndex:7];
301 /* start parsing .. */
302 if ((s = [NSString stringWithContentsOfFile:_sysId]))
303 [self parseFromSource:s];
308 - (NSString *)replacementStringForEntityNamed:(NSString *)_entityName {
309 //NSLog(@"get entity: %@", _entityName);
310 return [[@"&" stringByAppendingString:_entityName]
311 stringByAppendingString:@";"];
314 /* namespace support */
316 - (NSString *)nsUriForPrefix:(NSString *)_prefix {
320 e = [self->nsStack reverseObjectEnumerator];
321 while ((ns = [e nextObject])) {
324 if ((uri = [ns objectForKey:_prefix]))
330 - (NSString *)defaultNamespace {
331 return [self nsUriForPrefix:@":"];
334 @end /* pyxSAXDriver */