File: Parser.m

package info (click to toggle)
helpviewer.app 0.4-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,940 kB
  • sloc: objc: 2,416; makefile: 12
file content (168 lines) | stat: -rw-r--r-- 4,234 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/*
    This file is part of HelpViewer (http://www.roard.com/helpviewer)
    Copyright (C) 2003 Nicolas Roard (nicolas@roard.com)

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the
    Free Software Foundation, Inc.  
    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
*/

#include "Parser.h"

/*
   I rewrote this very simple SAX-inspired Parser ...
   Very basic, but for HelpViewer needs it's enough 
*/

#define RESET(str) [str release]; str = [[NSMutableString alloc] init];

@implementation Parser

+ (void) parserWithHandler: (id) handler
    withData: (NSData*) data
{
    //NSString* file = [NSString stringWithContentsOfFile: filename];
    NSString* file = [[NSString alloc] initWithData: data encoding: NSISOLatin1StringEncoding];
    NSMutableString* current = [[NSMutableString alloc] init];

    //NSLog (@"on a charg le fichier %@", filename);

    if (file != nil)
    {
	int i;
	BOOL Tag = NO;
	BOOL EndingTag = NO;
	BOOL AttributeStarted = NO;
	NSString* TagName = nil;
	NSString* KeyAttribute = nil;
	NSMutableDictionary* TagAttributes = nil;

	NSLog (@"file length : %d", [file length]);

	for (i=0; i < [file length]; i++)
	{
	    unichar c = [file characterAtIndex: i];

	    if (i %1000 == 0) NSLog (@"caractres lus : %d", i);

	    if ((!Tag) && (c == '<'))
	    {
		// We have a tag ...
		Tag = YES;

		// We send the previous characters to the handler
		[handler characters: current];
		
		// We recreate a current string
		RESET (current);
	    }
	    else if ((Tag) && (c == '>')) 
	    {
		// We close a tag ...
		Tag = NO;

		// We send the tag to the handler
		if (EndingTag)
		{
		    NSLog (@"end tag name : %@", current);
		    [handler endElement: current];
		    EndingTag = NO;
		}
		else
		{
		    if (TagName == nil)
		    {
			// If no tag name, current == tag name ...
			NSLog (@"no tag name : %@", current);
			[handler startElement: current attributes: nil];
		    }
		    else
		    {
			NSLog (@"tag name : %@", TagName);
			NSLog (@"attributes : %@", TagAttributes);
			[handler startElement: TagName attributes: TagAttributes];
		    }
		    [TagName release]; TagName = nil;
		    [KeyAttribute release]; KeyAttribute = nil;
		    [TagAttributes release]; TagAttributes = nil;
		}
		RESET (current);
	    }
	    else 
	    {
		// other character ...

		if (Tag)
		{
		    if (c == '/')
		    {
			// We have a closing tag
			// FIXME : this approach is not optimal and could be wrong
			EndingTag = YES;
		    }
		    else if (c == ' ')
		    {
			if (TagName == nil)
			{
			    // We set the tag name
			    TagName = [[NSString alloc] initWithString: current];
			    RESET (current);
			}
		    }
		    else if (c == '=')
		    {
			KeyAttribute = [NSString stringWithString: current];
		        KeyAttribute = RETAIN ([NSString trimString: KeyAttribute]);
			//KeyAttribute = [[NSString alloc] init];

			RESET (current);
			if (TagAttributes == nil) 
			{
			    TagAttributes = [[NSMutableDictionary alloc] init];
			}
			AttributeStarted = NO;
		    }
		    else if (c == '"') 
		    {
			if (AttributeStarted)
			{
			    [TagAttributes setObject: current forKey: KeyAttribute];
			    [KeyAttribute release]; KeyAttribute = nil;
			    RESET (current);
			}
			else 
			{
			    AttributeStarted = YES;
			    RESET (current);
			}
		    }
		    else
		    [current appendString : [NSString stringWithCharacters: &c length: 1]];
		}
		else
		[current appendString : [NSString stringWithCharacters: &c length: 1]];
	    }
	}

	NSLog (@"Parse termin !");

	[file release];
	[current release];
	[TagName release]; 
	[KeyAttribute release]; 
	[TagAttributes release]; 
    }
}

@end