#include "rbxs_pull.h" #include "rbxs_qname.h" #include "rbxs_pullattributeset.h" //*********************************************************************************** // GC //*********************************************************************************** void rbxs_pull_free(rbxs_pull *prbxs_pull) { if (prbxs_pull != NULL) { xmlFreeTextReader(prbxs_pull->reader); prbxs_pull->reader = NULL; free(prbxs_pull); } } void rbxs_pull_mark(rbxs_pull *prbxs_pull) { } //*********************************************************************************** // Methods //*********************************************************************************** VALUE rbxs_pull_inspect(VALUE self) { // Nix wissen was machen da! return(Qnil); } VALUE rbxs_pull_next(VALUE self) { rbxs_pull *prbxs_pull; Data_Get_Struct(self, rbxs_pull, prbxs_pull); if (xmlTextReaderRead(prbxs_pull->reader) >= 1) return self; else return Qnil; } VALUE rbxs_pull_name(VALUE self) { return(rbxs_qname_new(cSimpleQName,self,RBXS_PARSER_TYPE_READER)); } VALUE rbxs_pull_base(VALUE self) { char *base_uri; rbxs_pull *prbxs_pull; Data_Get_Struct(self, rbxs_pull, prbxs_pull); base_uri = xmlTextReaderBaseUri(prbxs_pull->reader); if (base_uri) return(rb_str_new2(base_uri)); else return(Qnil); } VALUE rbxs_pull_xml_lang(VALUE self) { char *xml_lang; rbxs_pull *prbxs_pull; Data_Get_Struct(self, rbxs_pull, prbxs_pull); xml_lang = xmlTextReaderXmlLang(prbxs_pull->reader); if (xml_lang) return(rb_str_new2(xml_lang)); else return(Qnil); } VALUE rbxs_pull_depth(VALUE self) { int depth; rbxs_pull *prbxs_pull; Data_Get_Struct(self, rbxs_pull, prbxs_pull); depth = xmlTextReaderDepth(prbxs_pull->reader); if (depth >= 0) return(INT2FIX(depth)); else return(Qnil); } VALUE rbxs_pull_attributes(VALUE self) { return rbxs_pullattributeset_new(cSimplePullAttributeSet,self); } VALUE rbxs_pull_emptyp(VALUE self) { rbxs_pull *prbxs_pull; Data_Get_Struct(self, rbxs_pull, prbxs_pull); return (xmlTextReaderIsEmptyElement(prbxs_pull->reader) ? Qtrue : Qfalse); } VALUE rbxs_pull_valuep(VALUE self) { rbxs_pull *prbxs_pull; Data_Get_Struct(self, rbxs_pull, prbxs_pull); return (xmlTextReaderHasValue(prbxs_pull->reader) ? Qtrue : Qfalse); } VALUE rbxs_pull_value(VALUE self) { rbxs_pull *prbxs_pull; char *value; Data_Get_Struct(self, rbxs_pull, prbxs_pull); value = xmlTextReaderValue(prbxs_pull->reader); if (value) { VALUE retval = rb_str_new2(value); xmlFree(value); return retval; } else return Qnil; } static VALUE type2symbol[18]; VALUE rbxs_pull_node_type(VALUE self) { rbxs_pull *prbxs_pull; int node_type; Data_Get_Struct(self, rbxs_pull, prbxs_pull); node_type = xmlTextReaderNodeType(prbxs_pull->reader); if (node_type < 0) return(Qnil); return ID2SYM(type2symbol[node_type]); } //*********************************************************************************** // Constructors //*********************************************************************************** VALUE rbxs_pull_new(VALUE class, VALUE what) { rbxs_pull *prbxs_pull; OpenFile *fptr; prbxs_pull = (rbxs_pull *)malloc(sizeof(rbxs_pull)); if (prbxs_pull == NULL ) rb_raise(rb_eNoMemError, "No memory left for XML::Simple::Pull struct"); switch (TYPE(what)) { case T_STRING: prbxs_pull->reader = xmlReaderForMemory(RSTRING(what)->ptr, RSTRING(what)->len, NULL, NULL, 0); break; case T_FILE: GetOpenFile(what,fptr); prbxs_pull->reader = xmlReaderForFd(fileno(fptr->f),NULL,NULL,0); break; default: rb_raise(rb_eArgError, "argument must me String or File"); } if (prbxs_pull->reader == NULL) rb_raise(rb_eRuntimeError, "Document could not be opend"); if (rb_block_given_p()) { VALUE self; self = Data_Wrap_Struct(class, rbxs_pull_mark, rbxs_pull_free, prbxs_pull); while (xmlTextReaderRead(prbxs_pull->reader)) { rb_yield(self); } return(Qnil); } return(Data_Wrap_Struct(class, rbxs_pull_mark, rbxs_pull_free, prbxs_pull)); } //*********************************************************************************** // Initialize class Pull //*********************************************************************************** VALUE cSimplePull; void init_rbxs_pull(void) { cSimplePull = rb_define_class_under( cSimple, "Pull", rb_cObject ); type2symbol[XML_READER_TYPE_NONE] = rb_intern("none"); type2symbol[XML_READER_TYPE_ELEMENT] = rb_intern("element"); type2symbol[XML_READER_TYPE_ATTRIBUTE] = rb_intern("attribute"); type2symbol[XML_READER_TYPE_TEXT] = rb_intern("text"); type2symbol[XML_READER_TYPE_CDATA] = rb_intern("cdata"); type2symbol[XML_READER_TYPE_ENTITY_REFERENCE] = rb_intern("entity_reference"); type2symbol[XML_READER_TYPE_ENTITY] = rb_intern("entity"); type2symbol[XML_READER_TYPE_PROCESSING_INSTRUCTION] = rb_intern("processing_instruction"); type2symbol[XML_READER_TYPE_COMMENT] = rb_intern("comment"); type2symbol[XML_READER_TYPE_DOCUMENT] = rb_intern("document"); type2symbol[XML_READER_TYPE_DOCUMENT_TYPE] = rb_intern("document_type"); type2symbol[XML_READER_TYPE_DOCUMENT_FRAGMENT] = rb_intern("document_fragment"); type2symbol[XML_READER_TYPE_NOTATION] = rb_intern("notation"); type2symbol[XML_READER_TYPE_WHITESPACE] = rb_intern("whitespace"); type2symbol[XML_READER_TYPE_SIGNIFICANT_WHITESPACE] = rb_intern("significant_whitespace"); type2symbol[XML_READER_TYPE_END_ELEMENT] = rb_intern("end_element"); type2symbol[XML_READER_TYPE_END_ENTITY] = rb_intern("end_entity"); type2symbol[XML_READER_TYPE_XML_DECLARATION] = rb_intern("xml_declaration"); rb_define_method(cSimplePull, "inspect", rbxs_pull_inspect, 0); rb_define_method(cSimplePull, "to_s", rbxs_pull_value, 0); rb_define_method(cSimplePull, "next", rbxs_pull_next, 0); rb_define_method(cSimplePull, "name", rbxs_pull_name, 0); rb_define_method(cSimplePull, "base", rbxs_pull_base ,0); rb_define_method(cSimplePull, "depth", rbxs_pull_depth ,0); rb_define_method(cSimplePull, "attributes", rbxs_pull_attributes ,0); rb_define_method(cSimplePull, "value?", rbxs_pull_valuep ,0); rb_define_method(cSimplePull, "value", rbxs_pull_value ,0); rb_define_method(cSimplePull, "empty?", rbxs_pull_emptyp ,0); rb_define_method(cSimplePull, "lang", rbxs_pull_xml_lang ,0); rb_define_method(cSimplePull, "node_type", rbxs_pull_node_type ,0); }