1#include "Parser.h"
2
3/*
4   I rewrote this very simple SAX-inspired Parser ...
5   Very basic, but for HelpViewer needs it's enough
6*/
7
8#define RESET(str) [str release]; str = [[NSMutableString alloc] init];
9
10@implementation Parser
11
12+ (void) parserWithHandler: (id) handler
13    withData: (NSData*) data
14{
15    //NSString* file = [NSString stringWithContentsOfFile: filename];
16    NSString* file = [[NSString alloc] initWithData: data encoding: NSISOLatin1StringEncoding];
17    NSMutableString* current = [[NSMutableString alloc] init];
18
19    //NSLog (@"on a charg� le fichier %@", filename);
20
21    if (file != nil)
22    {
23	int i;
24	BOOL Tag = NO;
25	BOOL EndingTag = NO;
26	BOOL AttributeStarted = NO;
27	NSString* TagName = nil;
28	NSString* KeyAttribute = nil;
29	NSMutableDictionary* TagAttributes = nil;
30
31	NSLog (@"file length : %d", [file length]);
32
33	for (i=0; i < [file length]; i++)
34	{
35	    unichar c = [file characterAtIndex: i];
36
37	    if (i %1000 == 0) NSLog (@"caract�res lus : %d", i);
38
39	    if ((!Tag) && (c == '<'))
40	    {
41		// We have a tag ...
42		Tag = YES;
43
44		// We send the previous characters to the handler
45		[handler characters: current];
46
47		// We recreate a current string
48		RESET (current);
49	    }
50	    else if ((Tag) && (c == '>'))
51	    {
52		// We close a tag ...
53		Tag = NO;
54
55		// We send the tag to the handler
56		if (EndingTag)
57		{
58		    NSLog (@"end tag name : %@", current);
59		    [handler endElement: current];
60		    EndingTag = NO;
61		}
62		else
63		{
64		    if (TagName == nil)
65		    {
66			// If no tag name, current == tag name ...
67			NSLog (@"no tag name : %@", current);
68			[handler startElement: current attributes: nil];
69		    }
70		    else
71		    {
72			NSLog (@"tag name : %@", TagName);
73			NSLog (@"attributes : %@", TagAttributes);
74			[handler startElement: TagName attributes: TagAttributes];
75		    }
76		    [TagName release]; TagName = nil;
77		    [KeyAttribute release]; KeyAttribute = nil;
78		    [TagAttributes release]; TagAttributes = nil;
79		}
80		RESET (current);
81	    }
82	    else
83	    {
84		// other character ...
85
86		if (Tag)
87		{
88		    if (c == '/')
89		    {
90			// We have a closing tag
91			// FIXME : this approach is not optimal and could be wrong
92			EndingTag = YES;
93		    }
94		    else if (c == ' ')
95		    {
96			if (TagName == nil)
97			{
98			    // We set the tag name
99			    TagName = [[NSString alloc] initWithString: current];
100			    RESET (current);
101			}
102		    }
103		    else if (c == '=')
104		    {
105			KeyAttribute = [NSString stringWithString: current];
106		        KeyAttribute = RETAIN ([NSString trimString: KeyAttribute]);
107			//KeyAttribute = [[NSString alloc] init];
108
109			RESET (current);
110			if (TagAttributes == nil)
111			{
112			    TagAttributes = [[NSMutableDictionary alloc] init];
113			}
114			AttributeStarted = NO;
115		    }
116		    else if (c == '"')
117		    {
118			if (AttributeStarted)
119			{
120			    [TagAttributes setObject: current forKey: KeyAttribute];
121			    [KeyAttribute release]; KeyAttribute = nil;
122			    RESET (current);
123			}
124			else
125			{
126			    AttributeStarted = YES;
127			    RESET (current);
128			}
129		    }
130		    else
131		    [current appendString : [NSString stringWithCharacters: &c length: 1]];
132		}
133		else
134		[current appendString : [NSString stringWithCharacters: &c length: 1]];
135	    }
136	}
137
138	NSLog (@"Parse termin� !");
139
140	[file release];
141	[current release];
142	[TagName release];
143	[KeyAttribute release];
144	[TagAttributes release];
145    }
146}
147
148@end
149