Index: src/OFXMLParser.h ================================================================== --- src/OFXMLParser.h +++ src/OFXMLParser.h @@ -15,10 +15,21 @@ @class OFXMLParser; @class OFArray; @class OFMutableArray; +#ifdef OF_HAVE_BLOCKS +typedef void (^of_xml_parser_element_start_block_t)(OFXMLParser *parser, + OFString *name, OFString *prefix, OFString *namespace, OFArray *attrs); +typedef void (^of_xml_parser_element_end_block_t)(OFXMLParser *parser, + OFString *name, OFString *prefix, OFString *namespace); +typedef void (^of_xml_parser_string_block_t)(OFXMLParser *parser, + OFString *string); +typedef OFString* (^of_xml_parser_unknown_entity_block_t)(OFXMLParser *parser, + OFString *entity); +#endif + /** * \brief A protocol that needs to be implemented by delegates for OFXMLParser. */ @protocol OFXMLParserDelegate /** @@ -136,14 +147,30 @@ OFMutableArray *attrs; OFString *attrName; OFString *attrPrefix; char delim; OFMutableArray *previous; +#ifdef OF_HAVE_BLOCKS + of_xml_parser_element_start_block_t elementStartHandler; + of_xml_parser_element_end_block_t elementEndHandler; + of_xml_parser_string_block_t charactersHandler; + of_xml_parser_string_block_t CDATAHandler; + of_xml_parser_string_block_t commentHandler; + of_xml_parser_unknown_entity_block_t unknownEntityHandler; +#endif } #ifdef OF_HAVE_PROPERTIES @property (retain) id delegate; +# ifdef OF_HAVE_BLOCKS +@property (copy) of_xml_parser_element_start_block_t elementStartHandler; +@property (copy) of_xml_parser_element_end_block_t elementEndHandler; +@property (copy) of_xml_parser_string_block_t charactersHandler; +@property (copy) of_xml_parser_string_block_t CDATAHandler; +@property (copy) of_xml_parser_string_block_t commentHandler; +@property (copy) of_xml_parser_unknown_entity_block_t unknownEntityHandler; +# endif #endif /** * \return A new, autoreleased OFXMLParser */ @@ -158,10 +185,84 @@ * Sets the delegate the OFXMLParser should use. * * \param delegate The delegate to use */ - (void)setDelegate: (id )delegate; + +#ifdef OF_HAVE_BLOCKS +/** + * \return The element start handler + */ +- (of_xml_parser_element_start_block_t)elementStartHandler; + +/** + * Sets the element start handler. + * + * \param block An element start handler + */ +- (void)setElementStartHandler: (of_xml_parser_element_start_block_t)block; + +/** + * \return The element end handler + */ +- (of_xml_parser_element_end_block_t)elementEndHandler; + +/** + * Sets the element end handler. + * + * \param block An element end handler + */ +- (void)setElementEndHandler: (of_xml_parser_element_end_block_t)block; + +/** + * \return The characters handler + */ +- (of_xml_parser_string_block_t)charactersHandler; + +/** + * Sets the characters handler. + * + * \param block A characters handler + */ +- (void)setCharactersHandler: (of_xml_parser_string_block_t)block; + +/** + * \return The CDATA handler + */ +- (of_xml_parser_string_block_t)CDATAHandler; + +/** + * Sets the CDATA handler. + * + * \param block A CDATA handler + */ +- (void)setCDATAHandler: (of_xml_parser_string_block_t)block; + +/** + * \return The comment handler + */ +- (of_xml_parser_string_block_t)commentHandler; + +/** + * Sets the comment handler. + * + * \param block A comment handler + */ +- (void)setCommentHandler: (of_xml_parser_string_block_t)block; + +/** + * \return The unknown entity handler + */ +- (of_xml_parser_unknown_entity_block_t)unknownEntityHandler; + +/** + * Sets the unknown entity handler. + * + * \param block An unknown entity handler + */ +- (void)setUnknownEntityHandler: (of_xml_parser_unknown_entity_block_t)block; +#endif /** * Parses a buffer with the specified size. * * \param buf The buffer to parse Index: src/OFXMLParser.m ================================================================== --- src/OFXMLParser.m +++ src/OFXMLParser.m @@ -115,10 +115,18 @@ [namespaces release]; [attrs release]; [attrName release]; [attrPrefix release]; [previous release]; +#ifdef OF_HAVE_BLOCKS + [elementStartHandler release]; + [elementEndHandler release]; + [charactersHandler release]; + [CDATAHandler release]; + [commentHandler release]; + [unknownEntityHandler release]; +#endif [super dealloc]; } - (id )delegate @@ -130,10 +138,104 @@ { [(id)delegate_ retain]; [(id)delegate release]; delegate = delegate_; } + +#ifdef OF_HAVE_BLOCKS +- (of_xml_parser_element_start_block_t)elementStartHandler +{ + of_xml_parser_element_start_block_t block = [elementStartHandler copy]; + [OFAutoreleasePool addObject: block]; + + return block; +} + +- (void)setElementStartHandler: (of_xml_parser_element_start_block_t)block +{ + block = [block copy]; + [elementStartHandler release]; + elementStartHandler = block; +} + +- (of_xml_parser_element_end_block_t)elementEndHandler +{ + of_xml_parser_element_end_block_t block = [elementEndHandler copy]; + [OFAutoreleasePool addObject: block]; + + return block; +} + +- (void)setElementEndHandler: (of_xml_parser_element_end_block_t)block +{ + block = [block copy]; + [elementEndHandler release]; + elementEndHandler = block; +} + +- (of_xml_parser_string_block_t)charactersHandler +{ + of_xml_parser_string_block_t block = [charactersHandler copy]; + [OFAutoreleasePool addObject: block]; + + return block; +} + +- (void)setCharactersHandler: (of_xml_parser_string_block_t)block +{ + block = [block copy]; + [charactersHandler release]; + charactersHandler = block; +} + +- (of_xml_parser_string_block_t)CDATAHandler +{ + of_xml_parser_string_block_t block = [CDATAHandler copy]; + [OFAutoreleasePool addObject: block]; + + return block; +} + +- (void)setCDATAHandler: (of_xml_parser_string_block_t)block +{ + block = [block copy]; + [CDATAHandler release]; + CDATAHandler = block; +} + +- (of_xml_parser_string_block_t)commentHandler +{ + of_xml_parser_string_block_t block = [commentHandler copy]; + [OFAutoreleasePool addObject: block]; + + return block; +} + +- (void)setCommentHandler: (of_xml_parser_string_block_t)block +{ + block = [block copy]; + [commentHandler release]; + commentHandler = block; +} + +- (of_xml_parser_unknown_entity_block_t)unknownEntityHandler +{ + of_xml_parser_unknown_entity_block_t block; + + block = [unknownEntityHandler copy]; + [OFAutoreleasePool addObject: block]; + + return block; +} + +- (void)setUnknownEntityHandler: (of_xml_parser_unknown_entity_block_t)block +{ + block = [block copy]; + [unknownEntityHandler release]; + unknownEntityHandler = block; +} +#endif - (void)parseBuffer: (const char*)buf withSize: (size_t)size { OFAutoreleasePool *pool; @@ -156,12 +258,19 @@ if ([cache cStringLength] > 0) { OFString *str; pool = [[OFAutoreleasePool alloc] init]; str = transform_string(cache, self); - [delegate parser: self - foundCharacters: str]; + +#ifdef OF_HAVE_BLOCKS + if (charactersHandler != nil) + charactersHandler(self, str); + else +#endif + [delegate parser: self + foundCharacters: str]; + [pool release]; } [cache setToCString: ""]; @@ -240,22 +349,34 @@ newWithClass: isa prefix: prefix]; pool = [[OFAutoreleasePool alloc] init]; - [delegate parser: self - didStartElement: name - withPrefix: prefix - namespace: ns - attributes: nil]; - - if (buf[i] == '/') - [delegate parser: self - didEndElement: name - withPrefix: prefix - namespace: ns]; - else +#ifdef OF_HAVE_BLOCKS + if (elementStartHandler != nil) + elementStartHandler(self, name, + prefix, ns, nil); + else +#endif + [delegate parser: self + didStartElement: name + withPrefix: prefix + namespace: ns + attributes: nil]; + + if (buf[i] == '/') { +#ifdef OF_HAVE_BLOCKS + if (elementEndHandler != nil) + elementEndHandler(self, + name, prefix, ns); + else +#endif + [delegate parser: self + didEndElement: name + withPrefix: prefix + namespace: ns]; + } else [previous addObject: [[cache copy] autorelease]]; [pool release]; @@ -324,14 +445,20 @@ newWithClass: isa prefix: prefix]; pool = [[OFAutoreleasePool alloc] init]; - [delegate parser: self - didEndElement: name - withPrefix: prefix - namespace: ns]; +#ifdef OF_HAVE_BLOCKS + if (elementEndHandler != nil) + elementEndHandler(self, name, prefix, + ns); + else +#endif + [delegate parser: self + didEndElement: name + withPrefix: prefix + namespace: ns]; [pool release]; [namespaces removeNObjects: 1]; [name release]; @@ -363,21 +490,33 @@ resolve_attr_namespace(attrs_c[j], prefix, ns, namespaces, isa); pool = [[OFAutoreleasePool alloc] init]; - [delegate parser: self - didStartElement: name - withPrefix: prefix - namespace: ns - attributes: attrs]; +#ifdef OF_HAVE_BLOCKS + if (elementStartHandler != nil) + elementStartHandler(self, name, prefix, + ns, attrs); + else +#endif + [delegate parser: self + didStartElement: name + withPrefix: prefix + namespace: ns + attributes: attrs]; if (buf[i] == '/') { - [delegate parser: self - didEndElement: name - withPrefix: prefix - namespace: ns]; +#ifdef OF_HAVE_BLOCKS + if (elementEndHandler != nil) + elementEndHandler(self, name, + prefix, ns); + else +#endif + [delegate parser: self + didEndElement: name + withPrefix: prefix + namespace: ns]; [namespaces removeNObjects: 1]; } else if (prefix != nil) { OFString *str = [OFString stringWithFormat: @"%s:%s", [prefix cString], @@ -603,12 +742,19 @@ cdata = [[cache mutableCopy] autorelease]; len = [cdata length]; [cdata removeCharactersFromIndex: len - 2 toIndex: len]; - [delegate parser: self - foundCDATA: cdata]; + +#ifdef OF_HAVE_BLOCKS + if (CDATAHandler != nil) + CDATAHandler(self, cdata); + else +#endif + [delegate parser: self + foundCDATA: cdata]; + [pool release]; [cache setToCString: ""]; last = i + 1; @@ -646,12 +792,19 @@ comment = [[cache mutableCopy] autorelease]; len = [comment length]; [comment removeCharactersFromIndex: len - 2 toIndex: len]; - [delegate parser: self - foundComment: comment]; + +#ifdef OF_HAVE_BLOCKS + if (commentHandler != nil) + commentHandler(self, comment); + else +#endif + [delegate parser: self + foundComment: comment]; + [pool release]; [cache setToCString: ""]; last = i + 1; @@ -672,10 +825,15 @@ } - (OFString*)string: (OFString*)string containsUnknownEntityNamed: (OFString*)entity { +#ifdef OF_HAVE_BLOCKS + if (unknownEntityHandler != nil) + return unknownEntityHandler(self, entity); +#endif + return [delegate parser: self foundUnknownEntityNamed: entity]; } @end