|
David@0
|
1 |
// |
|
David@0
|
2 |
// LMXParser.h |
|
David@0
|
3 |
// LMX |
|
David@0
|
4 |
// |
|
David@0
|
5 |
// Created by Peter Hosey on 2005-10-14. |
|
David@0
|
6 |
// Copyright 2005 Peter Hosey. All rights reserved. |
|
David@0
|
7 |
// |
|
David@0
|
8 |
|
|
David@0
|
9 |
#include <sys/types.h> |
|
David@0
|
10 |
|
|
David@0
|
11 |
@class NSString; |
|
David@0
|
12 |
|
|
David@0
|
13 |
enum LMXParseResult { |
|
David@0
|
14 |
LMXParsedCompletely = 0, //Element stack reached zero depth, and there was no more XML to parse |
|
David@0
|
15 |
LMXParsedIncomplete = -1, //Element stack is not empty; more data is wanted |
|
David@0
|
16 |
LMXParsedCompletelyWithExtraData = -2, //Element stack reached zero depth, but there's still XML to parse |
|
David@0
|
17 |
}; |
|
David@0
|
18 |
|
|
David@0
|
19 |
extern NSString *LMXStringFromParseResult(enum LMXParseResult result); |
|
David@0
|
20 |
extern enum LMXParseResult LMXParseResultFromString(NSString *result); |
|
David@0
|
21 |
|
|
David@0
|
22 |
@interface LMXParser : NSObject { |
|
David@0
|
23 |
NSMutableData *dataToParse; |
|
David@0
|
24 |
off_t currentIndex; |
|
David@0
|
25 |
|
|
David@0
|
26 |
NSMutableArray *elementStack; |
|
David@0
|
27 |
|
|
David@0
|
28 |
id delegate; |
|
David@0
|
29 |
void *contextInfo; |
|
David@0
|
30 |
|
|
David@0
|
31 |
//Parser state |
|
David@0
|
32 |
NSMutableString *characters; |
|
David@0
|
33 |
NSMutableString *currentToken; |
|
David@0
|
34 |
NSMutableString *entityName; |
|
David@0
|
35 |
NSMutableString *comment; |
|
David@0
|
36 |
NSString *systemID; |
|
David@0
|
37 |
NSMutableDictionary *overrideDict; //Stores any entities that we're using our own values instead of the DTD's values for |
|
David@0
|
38 |
NSMutableDictionary *cacheDict; //Caches entity values |
|
David@0
|
39 |
NSMutableDictionary *attributes; |
|
David@0
|
40 |
NSString *attributeValue; |
|
David@0
|
41 |
off_t charactersRunStartIndex, tokenRunStartIndex, entityNameRunStartIndex, commentRunStartIndex; |
|
David@0
|
42 |
off_t greaterThanIndex; |
|
David@0
|
43 |
unsigned reserved: 22; |
|
David@0
|
44 |
unsigned inComment: 1; |
|
David@0
|
45 |
//Start of a comment: <!-- |
|
David@0
|
46 |
// End of a comment: --> |
|
David@0
|
47 |
unsigned hasBang: 1; //With has{First,Second}Hyphen, indicates a comment may be about to start (if a < is encountered) |
|
David@0
|
48 |
unsigned hasSecondHyphen: 1; //With hasGreaterThan and hasFirstHyphen, part of the start of a comment |
|
David@0
|
49 |
unsigned hasFirstHyphen: 1; //With hasGreaterThan, 1/3 of the end of a comment; else, 1/3 of the start of a comment |
|
David@0
|
50 |
unsigned hasEqualSign: 1; //An attribute value has been recorded, and a = encountered |
|
David@0
|
51 |
unsigned couldBeEndTag: 1; //A / has been encountered |
|
David@0
|
52 |
unsigned isEmptyTag: 1; //A / was encountered immediately after a > |
|
David@0
|
53 |
unsigned inEntity: 1; //In between & and ; |
|
David@0
|
54 |
unsigned hasHashMark: 1; //A # was just encountered (if this is 1 when the & is encountered, it's a numeric entity; otherwise, the entity ends) |
|
David@0
|
55 |
unsigned noNonWhitespaceSinceTagEnd: 1; //Used by / to check for a <blah/> tag |
|
David@0
|
56 |
unsigned inTag: 1; //In between < and > |
|
David@0
|
57 |
unsigned parsing: 1; //Set to 0 by -pause |
|
David@0
|
58 |
char attributeQuoteChar; //One of '"', '\'', or '\0' |
|
David@0
|
59 |
} |
|
David@0
|
60 |
|
|
zacw@2830
|
61 |
//How to get an autoreleased parser in only one message instead of three: |
|
David@0
|
62 |
+ parser; |
|
David@0
|
63 |
|
|
David@0
|
64 |
- initWithData:(NSData *)data; |
|
David@0
|
65 |
|
|
David@0
|
66 |
#pragma mark - |
|
David@0
|
67 |
|
|
David@0
|
68 |
- (NSString *)systemID; |
|
David@0
|
69 |
- (void)setSystemID:(NSString *)sysID; |
|
David@0
|
70 |
- (void)overrideEntityNamed:(NSString *)name withValue:(NSData *)val; |
|
David@0
|
71 |
- (void)setOverriddenEntities:(NSDictionary *)entityDict; |
|
David@0
|
72 |
- (NSData *)dataForEntityNamed:(NSString *)name; |
|
David@0
|
73 |
|
|
David@0
|
74 |
#pragma mark - |
|
David@0
|
75 |
|
|
David@0
|
76 |
- (enum LMXParseResult)parseChunk:(NSData *)data; |
|
David@0
|
77 |
|
|
David@0
|
78 |
- (void)addData:(NSData *)data; //Add more data (in front of the existing data) without parsing |
|
David@0
|
79 |
- (enum LMXParseResult)parse; //Begin/resume parsing without adding more data |
|
David@0
|
80 |
|
|
David@0
|
81 |
#pragma mark - |
|
David@0
|
82 |
|
|
David@0
|
83 |
//Either or both of these can be called by the delegate. |
|
David@0
|
84 |
- (void)pause; |
|
David@0
|
85 |
- (enum LMXParseResult)resume; //Synonym for -parse |
|
David@0
|
86 |
|
|
David@0
|
87 |
//Calling -reset leaves the parser in the same state it was in (more or less) after it was inited. |
|
David@0
|
88 |
//*Don't* call this from the delegate. |
|
David@0
|
89 |
- (void)reset; |
|
David@0
|
90 |
|
|
David@0
|
91 |
#pragma mark - |
|
David@0
|
92 |
|
|
David@0
|
93 |
- delegate; |
|
David@0
|
94 |
- setDelegate:newDelegate; //Returns old delegate. |
|
David@0
|
95 |
|
|
David@0
|
96 |
- (void *)contextInfo; |
|
David@0
|
97 |
- (void)setContextInfo:(void *)newContextInfo; |
|
David@0
|
98 |
|
|
David@0
|
99 |
@end |
|
David@0
|
100 |
|
|
David@0
|
101 |
@interface LMXParser (LMXCompatibilityWithNSXMLParser) |
|
David@0
|
102 |
|
|
David@0
|
103 |
- initWithData:(NSData *)data; //Same as -init, -addData: |
|
David@0
|
104 |
|
|
David@0
|
105 |
- (void)abortParsing; //Compatibility synonym for -pause |
|
David@0
|
106 |
|
|
David@0
|
107 |
@end |
|
David@0
|
108 |
|
|
David@0
|
109 |
@interface NSObject (LMXParserDelegate) |
|
David@0
|
110 |
|
|
David@0
|
111 |
- (void)parserDidStartDocument:(LMXParser *)parser; |
|
David@0
|
112 |
|
|
David@0
|
113 |
- (void)parser:(LMXParser *)parser elementEnded:(NSString *)elementName; |
|
David@0
|
114 |
//Returns one or two UTF-16 code units, or nil. |
|
David@0
|
115 |
- (NSData *)parser:(LMXParser *)parser resolveExternalEntityName:(NSString *)entityName systemID:(NSString *)systemID; |
|
David@0
|
116 |
- (void)parser:(LMXParser *)parser foundCharacters:(NSString *)string; |
|
David@0
|
117 |
- (void)parser:(LMXParser *)parser elementStarted:(NSString *)elementName attributes:(NSDictionary *)attributes; |
|
David@0
|
118 |
|
|
David@0
|
119 |
- (void)parserDidEndDocument:(LMXParser *)parser; |
|
David@0
|
120 |
- (void)parser:(LMXParser *)parser finishedParsingChunk:(NSData *)chunkData withResult:(enum LMXParseResult)result; |
|
David@0
|
121 |
|
|
David@0
|
122 |
@end |