@@ -186,11 +186,11 @@ OFString *str; pool = [[OFAutoreleasePool alloc] init]; str = transform_string(cache, self); [delegate xmlParser: self - foundString: str]; + didFindString: str]; [pool release]; } [cache setToCString: ""]; @@ -200,15 +200,15 @@ break; /* Tag was just opened */ case OF_XMLPARSER_TAG_OPENED: if (buf[i] == '/') { - last = i + 1; state = OF_XMLPARSER_IN_CLOSE_TAG_NAME; + last = i + 1; } else if(buf[i] == '!') { + state = OF_XMLPARSER_IN_CDATA_OR_COMMENT; last = i + 1; - state = OF_XMLPARSER_IN_COMMENT_1; } else { state = OF_XMLPARSER_IN_TAG_NAME; i--; } break; @@ -527,51 +527,152 @@ } else if (buf[i] != ' ' && buf[i] != '\n' && buf[i] != '\r') @throw [OFMalformedXMLException newWithClass: isa]; break; + + /* CDATA or comment */ + case OF_XMLPARSER_IN_CDATA_OR_COMMENT: + if (buf[i] == '-') + state = OF_XMLPARSER_IN_COMMENT_OPENING; + else if (buf[i] == '[') + state = OF_XMLPARSER_IN_CDATA_OPENING_1; + else + @throw [OFMalformedXMLException + newWithClass: isa]; + + last = i + 1; + break; + + /* CDATA */ + case OF_XMLPARSER_IN_CDATA_OPENING_1: + if (buf[i] == 'C') + state = OF_XMLPARSER_IN_CDATA_OPENING_2; + else + @throw [OFMalformedXMLException + newWithClass: isa]; + last = i + 1; + break; + case OF_XMLPARSER_IN_CDATA_OPENING_2: + if (buf[i] == 'D') + state = OF_XMLPARSER_IN_CDATA_OPENING_3; + else + @throw [OFMalformedXMLException + newWithClass: isa]; + last = i + 1; + break; + case OF_XMLPARSER_IN_CDATA_OPENING_3: + if (buf[i] == 'A') + state = OF_XMLPARSER_IN_CDATA_OPENING_4; + else + @throw [OFMalformedXMLException + newWithClass: isa]; + last = i + 1; + break; + case OF_XMLPARSER_IN_CDATA_OPENING_4: + if (buf[i] == 'T') + state = OF_XMLPARSER_IN_CDATA_OPENING_5; + else + @throw [OFMalformedXMLException + newWithClass: isa]; + last = i + 1; + break; + case OF_XMLPARSER_IN_CDATA_OPENING_5: + if (buf[i] == 'A') + state = OF_XMLPARSER_IN_CDATA_OPENING_6; + else + @throw [OFMalformedXMLException + newWithClass: isa]; + last = i + 1; + break; + case OF_XMLPARSER_IN_CDATA_OPENING_6: + if (buf[i] == '[') + state = OF_XMLPARSER_IN_CDATA_1; + else + @throw [OFMalformedXMLException + newWithClass: isa]; + last = i + 1; + break; + case OF_XMLPARSER_IN_CDATA_1: + if (buf[i] == ']') + state = OF_XMLPARSER_IN_CDATA_2; + break; + case OF_XMLPARSER_IN_CDATA_2: + if (buf[i] == ']') + state = OF_XMLPARSER_IN_CDATA_3; + else + state = OF_XMLPARSER_IN_CDATA_1; + break; + case OF_XMLPARSER_IN_CDATA_3: + if (buf[i] == '>') { + OFMutableString *cdata; + size_t len; + + pool = [[OFAutoreleasePool alloc] init]; + + [cache + appendCStringWithoutUTF8Checking: buf + last + length: i - last]; + cdata = [[cache mutableCopy] autorelease]; + len = [cdata length]; + + [cdata removeCharactersFromIndex: len - 2 + toIndex: len]; + [delegate xmlParser: self + didFindString: cdata]; + [pool release]; + + [cache setToCString: ""]; + + last = i + 1; + state = OF_XMLPARSER_OUTSIDE_TAG; + } else if (buf[i] != ']') + state = OF_XMLPARSER_IN_CDATA_1; + break; /* Comment */ - case OF_XMLPARSER_IN_COMMENT_1: - case OF_XMLPARSER_IN_COMMENT_2: + case OF_XMLPARSER_IN_COMMENT_OPENING: if (buf[i] != '-') @throw [OFMalformedXMLException newWithClass: isa]; last = i + 1; - state++; + state = OF_XMLPARSER_IN_COMMENT_1; + break; + case OF_XMLPARSER_IN_COMMENT_1: + if (buf[i] == '-') + state = OF_XMLPARSER_IN_COMMENT_2; + break; + case OF_XMLPARSER_IN_COMMENT_2: + state = (buf[i] == '-' ? OF_XMLPARSER_IN_COMMENT_3 : + OF_XMLPARSER_IN_COMMENT_1); break; case OF_XMLPARSER_IN_COMMENT_3: - if (buf[i] == '-') - state = OF_XMLPARSER_IN_COMMENT_4; - break; - case OF_XMLPARSER_IN_COMMENT_4: - if (buf[i] == '-') { + if (buf[i] == '>') { OFMutableString *comment; size_t len; pool = [[OFAutoreleasePool alloc] init]; [cache appendCStringWithoutUTF8Checking: buf + last length: i - last]; - comment = [[cache mutableCopy] autorelease]; len = [comment length]; - [comment removeCharactersFromIndex: len - 1 + [comment removeCharactersFromIndex: len - 2 toIndex: len]; - [comment removeLeadingAndTrailingWhitespaces]; [delegate xmlParser: self - foundComment: comment]; + didFindComment: comment]; [pool release]; [cache setToCString: ""]; last = i + 1; - state = OF_XMLPARSER_EXPECT_CLOSE; + state = OF_XMLPARSER_OUTSIDE_TAG; } else - state = OF_XMLPARSER_IN_COMMENT_3; + @throw [OFMalformedXMLException + newWithClass: isa]; break; } } @@ -580,14 +681,14 @@ if (len > 0 && state != OF_XMLPARSER_IN_TAG) [cache appendCStringWithoutUTF8Checking: buf + last length: len]; } -- (OFString*)foundUnknownEntityNamed: (OFString*)entity +- (OFString*)didFindUnknownEntityNamed: (OFString*)entity { return [delegate xmlParser: self - foundUnknownEntityNamed: entity]; + didFindUnknownEntityNamed: entity]; } @end @implementation OFString (OFXMLUnescaping) - (OFString*)stringByXMLUnescaping @@ -659,11 +760,11 @@ pool = [[OFAutoreleasePool alloc] init]; n = [OFString stringWithCString: entity length: len]; - tmp = [h foundUnknownEntityNamed: n]; + tmp = [h didFindUnknownEntityNamed: n]; if (tmp == nil) @throw [OFInvalidEncodingException newWithClass: isa]; @@ -703,20 +804,20 @@ namespace: (OFString*)ns { } - (void)xmlParser: (OFXMLParser*)parser - foundString: (OFString*)string + didFindString: (OFString*)string { } - (void)xmlParser: (OFXMLParser*)parser - foundComment: (OFString*)comment + didFindComment: (OFString*)comment { } -- (OFString*)xmlParser: (OFXMLParser*)parser - foundUnknownEntityNamed: (OFString*)entity +- (OFString*)xmlParser: (OFXMLParser*)parser + didFindUnknownEntityNamed: (OFString*)entity { return nil; } @end