Exemple #1
0
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;
}
Exemple #2
0
/*
 * 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;
}
Exemple #3
0
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;
}
Exemple #4
0
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;
}
Exemple #5
0
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);
}
Exemple #6
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;
}
Exemple #7
0
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;
}
Exemple #8
0
/* 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;
}
Exemple #9
0
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)
        ;
}
Exemple #12
0
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;
  }
Exemple #14
0
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;
}
Exemple #17
0
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*/
Exemple #18
0
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;
}