gboolean xml_reader_load_from_stream (XmlReader *reader, GInputStream *stream, GError **error) { g_return_val_if_fail (XML_IS_READER(reader), FALSE); xml_reader_clear (reader); reader->xml = xmlReaderForIO (xml_reader_io_read_cb, xml_reader_io_close_cb, stream, reader->uri, reader->encoding, XML_PARSE_RECOVER | XML_PARSE_NOBLANKS | XML_PARSE_COMPACT); if (!reader->xml) { g_set_error (error, XML_READER_ERROR, XML_READER_ERROR_INVALID, _("Could not parse XML from stream")); return FALSE; } reader->stream = g_object_ref (stream); xmlTextReaderSetErrorHandler (reader->xml, xml_reader_error_cb, reader); return TRUE; }
/* * call-seq: * from_io(io, url = nil, encoding = nil, options = 0) * * Create a new reader that parses +io+ */ static VALUE from_io(int argc, VALUE *argv, VALUE klass) { VALUE rb_io, rb_url, encoding, rb_options; const char * c_url = NULL; const char * c_encoding = NULL; int c_options = 0; rb_scan_args(argc, argv, "13", &rb_io, &rb_url, &encoding, &rb_options); if (!RTEST(rb_io)) rb_raise(rb_eArgError, "io cannot be nil"); if (RTEST(rb_url)) c_url = StringValuePtr(rb_url); if (RTEST(encoding)) c_encoding = StringValuePtr(encoding); if (RTEST(rb_options)) c_options = NUM2INT(rb_options); xmlTextReaderPtr reader = xmlReaderForIO( (xmlInputReadCallback)io_read_callback, (xmlInputCloseCallback)io_close_callback, (void *)rb_io, c_url, c_encoding, c_options ); if(reader == NULL) { xmlFreeTextReader(reader); rb_raise(rb_eRuntimeError, "couldn't create a parser"); } VALUE rb_reader = Data_Wrap_Struct(klass, NULL, dealloc, reader); rb_funcall(rb_reader, rb_intern("initialize"), 3, rb_io, rb_url, encoding); return rb_reader; }
xmlTextReaderPtr libabw::xmlReaderForStream(librevenge::RVNGInputStream *input) { xmlTextReaderPtr reader = xmlReaderForIO(abwxmlInputReadFunc, abwxmlInputCloseFunc, (void *)input, 0, 0, XML_PARSE_NOBLANKS|XML_PARSE_NOENT|XML_PARSE_NONET|XML_PARSE_RECOVER); xmlTextReaderSetErrorHandler(reader, abwxmlReaderErrorFunc, 0); return reader; }
bool XmlDocument::Create(IOStream *input, XmlDocument **r) { if (!LibXmlInitialized) { Error(StringPieceFromLiteral("XmlDocument::Create(): call LibXmlInit() first")); return false; } if (!input) return false; std::auto_ptr<XmlDocument> xml(new XmlDocument()); xml->libxml_stuff.reset(new LibXmlStuff()); xml->libxml_stuff->reader = xmlReaderForIO(_readCallback, _closeCallback, input, "url://", NULL, XML_PARSE_NOBLANKS | XML_PARSE_NONET | XML_PARSE_NOCDATA | XML_PARSE_COMPACT); if (!xml->libxml_stuff->reader) { Error(StringPieceFromLiteral("XmlDocument::Create(): xmlReaderForIO fails")); return false; } if (xmlTextReaderRead(xml->libxml_stuff->reader) != 1) { Error(StringPieceFromLiteral("XmlDocument::Create(): xmlTextReaderRead fails")); return false; } xmlNodePtr node = xmlTextReaderExpand(xml->libxml_stuff->reader); if ((!node) || (!node->doc)) return false; xml->libxml_stuff->xpath_context = xmlXPathNewContext(node->doc); if (!xml->libxml_stuff->xpath_context) return false; if (r) *r = xml.release(); return true; }
xmlTextReaderPtr inputUTF8(const char *name) { void *ctx = inputOpen(name); if (!ctx) { fprintf(stderr, "Input reader create failed for: %s\n", name); return NULL; } return xmlReaderForIO(readFileXML, inputCloseXML, (void *)ctx, NULL, NULL, 0); }
Variant HHVM_METHOD(XMLReader, open, const String& uri, const Variant& encoding /*= null_variant*/, int64_t options /*= 0*/) { auto* data = Native::data<XMLReader>(this_); const String& str_encoding = encoding.isNull() ? null_string : encoding.toString(); SYNC_VM_REGS_SCOPED(); if (data->m_ptr) { data->close(); } if (uri.empty()) { raise_warning("Empty string supplied as input"); return false; } else if (!FileUtil::checkPathAndWarn(uri, "XMLReader::open", 1)) { return init_null(); } String valid_file = libxml_get_valid_file_path(uri.c_str()); xmlTextReaderPtr reader = nullptr; if (!valid_file.empty()) { // Manually create the IO context to support custom stream wrappers. data->m_stream = File::Open(valid_file, "rb"); if (data->m_stream != nullptr && !data->m_stream->isInvalid()) { // The XML context is owned by the native data attached to 'this_'. // The File is also owned by the native data so it does not need // to be cleaned up by an XML callback. The libxml_streams_IO_nop_close // callback does nothing. reader = xmlReaderForIO(libxml_streams_IO_read, libxml_streams_IO_nop_close, &data->m_stream, valid_file.data(), str_encoding.data(), options); } } if (reader == nullptr) { raise_warning("Unable to open source data"); return false; } data->m_ptr = reader; return true; }
bool HHVM_METHOD(XMLReader, open, const String& uri, const Variant& encoding /*= null_variant*/, int64_t options /*= 0*/) { auto* data = Native::data<XMLReader>(this_); const String& str_encoding = encoding.isNull() ? null_string : encoding.toString(); SYNC_VM_REGS_SCOPED(); if (data->m_ptr) { data->close(); } if (uri.empty()) { raise_warning("Empty string supplied as input"); return false; } String valid_file = libxml_get_valid_file_path(uri.c_str()); xmlTextReaderPtr reader = nullptr; if (!valid_file.empty()) { // Manually create the IO context to support custom stream wrappers. auto stream = File::Open(valid_file, "rb"); if (!stream->isInvalid()) { reader = xmlReaderForIO(libxml_streams_IO_read, libxml_streams_IO_close, stream.get(), valid_file.data(), str_encoding.data(), options); // The xmlTextReaderPtr owns a reference to stream. if (reader) stream.get()->incRefCount(); } } if (reader == nullptr) { raise_warning("Unable to open source data"); return false; } data->m_ptr = reader; return true; }
/* call-seq: * XML::Reader.io(io) -> XML::Reader * XML::Reader.io(io, :encoding => XML::Encoding::UTF_8, * :options => XML::Parser::Options::NOENT) -> XML::Parser * * Creates a new reader by parsing the specified io object. * * You may provide an optional hash table to control how the * parsing is performed. Valid options are: * * base_uri - The base url for the parsed document. * encoding - The document encoding, defaults to nil. Valid values * are the encoding constants defined on XML::Encoding. * options - Controls the execution of the parser, defaults to 0. * Valid values are the constants defined on * XML::Parser::Options. Mutliple options can be combined * by using Bitwise OR (|). */ static VALUE rxml_reader_io(int argc, VALUE *argv, VALUE klass) { xmlTextReaderPtr xreader; VALUE result; VALUE io; VALUE options; char *xbaseurl = NULL; const char *xencoding = NULL; int xoptions = 0; rb_scan_args(argc, argv, "11", &io, &options); if (!NIL_P(options)) { VALUE baseurl = Qnil; VALUE encoding = Qnil; VALUE parserOptions = Qnil; Check_Type(options, T_HASH); baseurl = rb_hash_aref(options, BASE_URI_SYMBOL); xbaseurl = NIL_P(baseurl) ? NULL : StringValueCStr(baseurl); encoding = rb_hash_aref(options, ENCODING_SYMBOL); xencoding = NIL_P(encoding) ? NULL : xmlGetCharEncodingName(NUM2INT(encoding)); parserOptions = rb_hash_aref(options, OPTIONS_SYMBOL); xoptions = NIL_P(parserOptions) ? 0 : NUM2INT(parserOptions); } xreader = xmlReaderForIO((xmlInputReadCallback) rxml_read_callback, NULL, (void *) io, xbaseurl, xencoding, xoptions); if (xreader == NULL) rxml_raise(&xmlLastError); result = rxml_reader_wrap(xreader); /* Attach io object to parser so it won't get freed.*/ rb_ivar_set(result, IO_ATTR, io); return result; }
static xml_reader_t *ReaderCreate( xml_t *p_xml, stream_t *p_stream ) { xml_reader_t *p_reader; xml_reader_sys_t *p_sys; xmlTextReaderPtr p_libxml_reader; p_libxml_reader = xmlReaderForIO( StreamRead, NULL, p_stream, NULL, NULL, 0 ); if( !p_libxml_reader ) { msg_Err( p_xml, "failed to create XML parser" ); return NULL; } p_reader = malloc( sizeof(xml_reader_t) ); if( !p_reader ) { xmlFreeTextReader( p_libxml_reader ); return NULL; } p_reader->p_sys = p_sys = malloc( sizeof(xml_reader_sys_t) ); if( !p_sys ) { xmlFreeTextReader( p_libxml_reader ); free( p_reader ); return NULL; } p_reader->p_sys->p_reader = p_libxml_reader; p_reader->p_xml = p_xml; /* Set the error handler */ xmlTextReaderSetErrorHandler( p_libxml_reader, ReaderErrorHandler, p_reader ); p_reader->pf_read = ReaderRead; p_reader->pf_node_type = ReaderNodeType; p_reader->pf_name = ReaderName; p_reader->pf_value = ReaderValue; p_reader->pf_next_attr = ReaderNextAttr; p_reader->pf_use_dtd = ReaderUseDTD; return p_reader; }
xmlTextReaderPtr sanitizerOpen(const char *name) { struct Context *ctx = (struct Context *)malloc(sizeof(*ctx)); if (!ctx) return NULL; memset(ctx, 0, sizeof(*ctx)); ctx->verbose = 0; ctx->state = 1; ctx->pend = 0; ctx->file = inputOpen(name); if (!ctx->file) { fprintf(stderr, "Input reader create failed\n"); free(ctx); return NULL; } return xmlReaderForIO(sanitizerProcess, sanitizerClose, (void *)ctx, NULL, NULL, 0); }
/** * Class constructor: parses a given XML file and parse it with libxml2. * * @param filename XML file to parse. */ XmlReader::XmlReader(const std::string& filename) { PHYSFS_file* file = PHYSFS_openRead(filename.c_str()); if(file == 0) { std::stringstream msg; msg << "Couldn't open file '" << filename << "': " << PHYSFS_getLastError(); throw std::runtime_error(msg.str()); } reader = xmlReaderForIO(readCallback, closeCallback, file, 0, 0, XML_PARSE_NONET); if(reader == 0) { PHYSFS_close(file); std::stringstream msg; msg << "Couldn't parse file '" << filename << "'"; throw std::runtime_error(msg.str()); } while(read() && getNodeType() != XML_READER_TYPE_ELEMENT) ; }
bool XmlReader::Create(IOStream *input, XmlReader **r) { if (!LibXmlInitialized) { Error(StringPieceFromLiteral("XmlReader::Create(): call LibXmlInit first()")); return false; } if (!input) return false; std::auto_ptr<XmlReader> xml(new XmlReader()); xml->libxml_stuff.reset(new LibXmlStuff()); xml->libxml_stuff->reader = xmlReaderForIO(_readCallback, _closeCallback, input, "url://", NULL, XML_PARSE_NOBLANKS | XML_PARSE_NONET | XML_PARSE_NOCDATA | XML_PARSE_COMPACT); if (!xml->libxml_stuff->reader) { cpcl::Error(cpcl::StringPieceFromLiteral("XmlReader::Create(): xmlReaderForIO fails")); return false; } if (r) *r = xml.release(); return true; }
bool XMLConversion::SetupReader() { if(_reader) return true; //do not need to make a new reader //setup libxml2 for use in a potentially multithreaded //environment xmlInitParser(); //If the inputstream is not at the start (probably arising in fastsearch), //save its position and rewind so that the reader initialization is ok. //(Getting the requested object is handled in ReadXML(), when the format is known.) _requestedpos = GetInStream()->tellg(); if(_requestedpos < 0) _requestedpos = 0; if(_requestedpos) GetInStream()->seekg(0); //Set up a parser from an input stream _reader = xmlReaderForIO( ReadStream, //xmlInputReadCallback (static member function) NULL,//xmlInputCloseCallback (static member function) this, //context "", //URL NULL, //encoding 0); //options if (_reader == NULL) { cerr << "Cannot set up libxml2 reader" << endl; return false; } //A new reader immediately reads 4 bytes (presumably to determine //the encoding). _lastpos = GetInStream()->tellg(); return true; }
XmlTextReader::XmlTextReader(istream& is) { Init(xmlReaderForIO(xmlInputReadCallback, xmlInputCloseCallback, &is, 0, 0, XML_PARSE_NOBLANKS)); }
static rrd_t *parse_file( const char *filename) { xmlTextReaderPtr reader; int status; rrd_t *rrd; stdioXmlReaderContext *sctx = NULL; /* special handling for XML on stdin (like it is the case when using the pipe interface) */ if (strcmp(filename, "-") == 0) { sctx = (stdioXmlReaderContext *) malloc(sizeof(*sctx)); if (sctx == NULL) { rrd_set_error("parse_file: malloc failed."); return (NULL); } sctx->stream = stdin; sctx->freeOnClose = 1; sctx->closed = 0; sctx->eofchar = 0x1A; /* ctrl-Z */ xmlSetGenericErrorFunc(NULL, ignoringErrorFunc); reader = xmlReaderForIO(stdioXmlInputReadCallback, stdioXmlInputCloseCallback, sctx, filename, NULL, 0); } else { reader = xmlNewTextReaderFilename(filename); } if (reader == NULL) { if (sctx != NULL) free(sctx); rrd_set_error("Could not create xml reader for: %s",filename); return (NULL); } /* NOTE: from now on, sctx will get freed implicitly through * xmlFreeTextReader and its call to * stdioXmlInputCloseCallback. */ if (expect_element(reader,"rrd") != 0) { xmlFreeTextReader(reader); return (NULL); } rrd = (rrd_t *) malloc(sizeof(rrd_t)); if (rrd == NULL) { rrd_set_error("parse_file: malloc failed."); xmlFreeTextReader(reader); return (NULL); } memset(rrd, '\0', sizeof(rrd_t)); rrd->stat_head = (stat_head_t *) malloc(sizeof(stat_head_t)); if (rrd->stat_head == NULL) { rrd_set_error("parse_tag_rrd: malloc failed."); xmlFreeTextReader(reader); free(rrd); return (NULL); } memset(rrd->stat_head, '\0', sizeof(stat_head_t)); strncpy(rrd->stat_head->cookie, "RRD", sizeof(rrd->stat_head->cookie)); rrd->stat_head->float_cookie = FLOAT_COOKIE; rrd->live_head = (live_head_t *) malloc(sizeof(live_head_t)); if (rrd->live_head == NULL) { rrd_set_error("parse_tag_rrd: malloc failed."); xmlFreeTextReader(reader); free(rrd->stat_head); free(rrd); return (NULL); } memset(rrd->live_head, '\0', sizeof(live_head_t)); status = parse_tag_rrd(reader, rrd); xmlFreeTextReader(reader); if (status != 0) { local_rrd_free(rrd); rrd = NULL; } return (rrd); } /* rrd_t *parse_file */
bool IWORKParser::parse() { const shared_ptr<xmlTextReader> sharedReader(xmlReaderForIO(readFromStream, closeStream, m_input.get(), "", 0, 0), xmlFreeTextReader); if (!sharedReader) return false; xmlTextReaderPtr reader = sharedReader.get(); assert(reader); const IWORKTokenizer &tokenizer = getTokenizer(); stack<IWORKXMLContextPtr_t> contextStack; int ret = xmlTextReaderRead(reader); contextStack.push(createDocumentContext()); while ((1 == ret)) { switch (xmlTextReaderNodeType(reader)) { case XML_READER_TYPE_ELEMENT: { const int id = tokenizer.getQualifiedId(char_cast(xmlTextReaderConstLocalName(reader)), char_cast(xmlTextReaderConstNamespaceUri(reader))); IWORKXMLContextPtr_t newContext = contextStack.top()->element(id); if (!newContext) newContext = createDiscardContext(); const bool isEmpty = xmlTextReaderIsEmptyElement(reader); newContext->startOfElement(); if (xmlTextReaderHasAttributes(reader)) { ret = xmlTextReaderMoveToFirstAttribute(reader); while (1 == ret) { processAttribute(reader, newContext, tokenizer); ret = xmlTextReaderMoveToNextAttribute(reader); } } if (isEmpty) newContext->endOfElement(); else contextStack.push(newContext); break; } case XML_READER_TYPE_END_ELEMENT: { contextStack.top()->endOfElement(); contextStack.pop(); break; } case XML_READER_TYPE_TEXT : { xmlChar *const text = xmlTextReaderReadString(reader); contextStack.top()->text(char_cast(text)); xmlFree(text); break; } default: break; } ret = xmlTextReaderRead(reader); } while (!contextStack.empty()) // finish parsing in case of broken XML { contextStack.top()->endOfElement(); contextStack.pop(); } xmlTextReaderClose(reader); return true; }
int readxml ( const char *xmlfile, /* filename to read */ const struct elemdesc *elems, /* array terminated by entry with null elemname field */ const struct elemattr *attrs /* array terminated by entry with null elem field */ ) /* opens and reads an XML file according to the given element and attribute definitions. */ { enum { maxdepth = 10, /* should be enough */ }; int curstate = 0, statehistory[maxdepth]; xmlTextReaderPtr f; struct vfile fd; fd = varied_open(xmlfile, O_RDONLY, "XML file"); f = xmlReaderForIO(xml_varied_read, xml_varied_close, &fd, xmlfile, NULL, 0); if (!f) { fprintf(stderr, "ERR: Unable to open XML file %s\n", xmlfile); return 1; } /*if*/ while (true) { int r = xmlTextReaderRead(f); if (!r) { fprintf(stderr, "ERR: Read premature EOF\n"); return 1; } /*if*/ if (r != 1) { fprintf(stderr, "ERR: Error in parsing XML\n"); return 1; } /*if*/ switch (xmlTextReaderNodeType(f)) { case XML_READER_TYPE_SIGNIFICANT_WHITESPACE: case XML_READER_TYPE_WHITESPACE: case XML_READER_TYPE_COMMENT: /* ignore */ break; case XML_READER_TYPE_ELEMENT: { const char * const elemname = (const char *)xmlTextReaderName(f); int tagindex; assert(!parser_body); for (tagindex = 0; elems[tagindex].elemname; tagindex++) if ( curstate == elems[tagindex].parentstate && !strcmp(elemname, elems[tagindex].elemname) ) { // reading the attributes causes these values to change // so if you want to use them later, save them now const bool empty = xmlTextReaderIsEmptyElement(f); const int depth = xmlTextReaderDepth(f); if (depth >= maxdepth) { fprintf ( stderr, "ERR: max XML parsing depth of %d exceeded\n", maxdepth - 1 ); exit(1); } /*if*/ if (elems[tagindex].start) { elems[tagindex].start(); if (parser_err) return 1; } /*if*/ while (xmlTextReaderMoveToNextAttribute(f)) { const char * const nm = (const char *)xmlTextReaderName(f); const char * const v = (const char *)xmlTextReaderValue(f); int attrindex; for (attrindex = 0; attrs[attrindex].elem; attrindex++) if ( !strcmp(attrs[attrindex].elem, elems[tagindex].elemname) && !strcmp(attrs[attrindex].attr, nm) ) { attrs[attrindex].f(v); if (parser_err) return 1; break; } /*if*/ if (!attrs[attrindex].elem) { bool gotattr = false; fprintf ( stderr, "ERR: Cannot match attribute '%s' in tag '%s'." " Valid attributes are:\n", nm, elems[tagindex].elemname ); for (attrindex = 0; attrs[attrindex].elem; attrindex++) if (!strcmp(attrs[attrindex].elem, elems[tagindex].elemname)) { fprintf(stderr, "ERR: %s\n", attrs[attrindex]. attr); gotattr = true; } /*if*/ if (!gotattr) { fprintf(stderr, "ERR: (none)\n"); } /*if*/ return 1; } /*if*/ xmlFree((xmlChar *)nm); xmlFree((xmlChar *)v); } /*while*/ if (empty) { /* tag ends immediately */ if (elems[tagindex].end) { elems[tagindex].end(); if (parser_err) return 1; } /*if*/ } else { statehistory[depth] = tagindex; curstate = elems[tagindex].newstate; } /*if*/ break; } /*if; for*/ if (!elems[tagindex].elemname) { fprintf(stderr, "ERR: Cannot match start tag '%s'. Valid tags are:\n", elemname); for (tagindex = 0; elems[tagindex].elemname; tagindex++) if (curstate == elems[tagindex].parentstate) fprintf(stderr, "ERR: %s\n", elems[tagindex].elemname); return 1; } /*if*/ xmlFree((xmlChar *)elemname); } break; case XML_READER_TYPE_END_ELEMENT: { const int tagindex = statehistory[xmlTextReaderDepth(f)]; if (elems[tagindex].end) { elems[tagindex].end(); if (parser_err) return 1; } /*if*/ curstate = elems[tagindex].parentstate; /* Note I don't handle sub-tags mixed with content! */ free(parser_body); parser_body = 0; parser_acceptbody = false; if (!curstate) goto done_parsing; } break; case XML_READER_TYPE_TEXT: case XML_READER_TYPE_CDATA: { const char * const v = (const char *)xmlTextReaderValue(f); if (!parser_body) { // stupid buggy libxml2 2.5.4 that ships with RedHat 9.0! // we must manually check if this is just whitespace int i; for (i = 0; v[i]; i++) if ( v[i] != '\r' && v[i] != '\n' && v[i] != ' ' && v[i] != '\t' ) goto has_nonws_body; xmlFree((xmlChar *)v); break; } /*if*/ has_nonws_body: if (!parser_acceptbody) { fprintf(stderr, "ERR: text not allowed here\n"); return 1; } /*if*/ if (!parser_body) parser_body = strdup(v); /* first lot of tag content */ else { /* append to previous tag content */ parser_body = realloc(parser_body, strlen(parser_body) + strlen(v) + 1); strcat(parser_body, v); } /*if*/ xmlFree((xmlChar *)v); } break; default: fprintf(stderr, "ERR: Unknown XML node type %d\n", xmlTextReaderNodeType(f)); exit(1); } /*switch*/ } /*while*/ done_parsing: xmlFreeTextReader(f); return 0; } /*readxml*/
static GstylePalette * gstyle_palette_new_from_xml (GFile *file, GCancellable *cancellable, GError **error) { g_autoptr(GInputStream) stream = NULL; g_autofree gchar *uri = NULL; GstylePalette *palette = NULL; xmlTextReaderPtr reader; GError *tmp_error = NULL; gboolean has_colors = FALSE; gint ret = -1; g_assert (G_IS_FILE (file)); uri = g_file_get_uri (file); if (!(stream = G_INPUT_STREAM (g_file_read (file, cancellable, &tmp_error)))) goto finish; reader = xmlReaderForIO (gstyle_palette_io_read_cb, gstyle_palette_io_close_cb, stream, uri, NULL, XML_PARSE_RECOVER | XML_PARSE_NOBLANKS | XML_PARSE_COMPACT); if (reader != NULL) { GstyleColor *color; g_autofree gchar *id = NULL; g_autofree gchar *name = NULL; g_autofree gchar *domain = NULL; xmlTextReaderSetErrorHandler (reader, gstyle_palette_error_cb, NULL); if (xmlTextReaderRead(reader) && gstyle_palette_xml_get_header (reader, &id, &name, &domain)) { palette = g_object_new (GSTYLE_TYPE_PALETTE, "id", id, "domain", domain, "name", name, "file", file, NULL); ret = xmlTextReaderRead(reader); while (ret == 1) { if (xmlTextReaderNodeType (reader) == XML_READER_TYPE_END_ELEMENT) { ret = 0; break; } /* TODO: better naming */ color = gstyle_palette_xml_get_color (reader); if (color == NULL) { ret = -1; break; } gstyle_palette_add (palette, color, &tmp_error); g_object_unref (color); has_colors = TRUE; ret = xmlTextReaderRead(reader); } } if (ret != 0 || !has_colors) { g_clear_object (&palette); g_set_error (&tmp_error, GSTYLE_PALETTE_ERROR, GSTYLE_PALETTE_ERROR_PARSE, _("%s: failed to parse\n"), uri); } xmlTextReaderClose(reader); xmlFreeTextReader(reader); } else g_set_error (&tmp_error, GSTYLE_PALETTE_ERROR, GSTYLE_PALETTE_ERROR_FILE, _("Unable to open %s\n"), uri); finish: if (tmp_error) g_propagate_error (error, tmp_error); return palette; }
bool IWORKParser::parse() { const shared_ptr<xmlTextReader> sharedReader(xmlReaderForIO(readFromStream, closeStream, m_input.get(), "", nullptr, 0), xmlFreeTextReader); if (!sharedReader) return false; xmlTextReaderPtr reader = sharedReader.get(); assert(reader); const IWORKTokenizer &tokenizer = getTokenizer(); stack<IWORKXMLContextPtr_t> contextStack; int ret = xmlTextReaderRead(reader); contextStack.push(createDocumentContext()); bool keynoteDocTypeChecked=false; char const *defaultNS=nullptr; while ((1 == ret)) { switch (xmlTextReaderNodeType(reader)) { case XML_READER_TYPE_ELEMENT: { if (!keynoteDocTypeChecked) { // check for keynote 1 file with doctype node and not a namespace in first node keynoteDocTypeChecked=true; if (xmlTextReaderNodeType(reader)==XML_READER_TYPE_ELEMENT && xmlTextReaderConstNamespaceUri(reader)==nullptr) defaultNS="http://developer.apple.com/schemas/APXL"; } const int id = tokenizer.getQualifiedId(char_cast(xmlTextReaderConstLocalName(reader)), defaultNS ? defaultNS : char_cast(xmlTextReaderConstNamespaceUri(reader))); IWORKXMLContextPtr_t newContext = contextStack.top()->element(id); if (!newContext) newContext = createDiscardContext(); const bool isEmpty = xmlTextReaderIsEmptyElement(reader); newContext->startOfElement(); if (xmlTextReaderHasAttributes(reader)) { ret = xmlTextReaderMoveToFirstAttribute(reader); while (1 == ret) { processAttribute(reader, newContext, tokenizer); ret = xmlTextReaderMoveToNextAttribute(reader); } } if (isEmpty) newContext->endOfElement(); else contextStack.push(newContext); break; } case XML_READER_TYPE_END_ELEMENT: { contextStack.top()->endOfElement(); contextStack.pop(); break; } case XML_READER_TYPE_CDATA : { const xmlChar *text = xmlTextReaderConstValue(reader); if (text) contextStack.top()->CDATA(char_cast(text)); break; } case XML_READER_TYPE_TEXT : { xmlChar *const text = xmlTextReaderReadString(reader); contextStack.top()->text(char_cast(text)); xmlFree(text); break; } default: break; } ret = xmlTextReaderRead(reader); } while (!contextStack.empty()) // finish parsing in case of broken XML { contextStack.top()->endOfElement(); contextStack.pop(); } xmlTextReaderClose(reader); return true; }