Home modules.gotpike.org
Username: Password: [Create Account]
[Forgot Password?]
Return to module

File Contents

Contents of /Public_Parser_XML2-1.42/XMLReader.cmod:

/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 * $Id: XMLReader.cmod,v 1.20 2006-10-03 21:50:11 hww3 Exp $
 */

/*
 * File licensing and authorship information block.
 *
 * Version: MPL 1.1/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Initial Developer of the Original Code is
 *
 * Bill Welliver <hww3@riverweb.com>
 *
 * Portions created by the Initial Developer are Copyright (C) Bill Welliver
 * All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of the LGPL, and not to allow others to use your version
 * of this file under the terms of the MPL, indicate your decision by
 * deleting the provisions above and replace them with the notice
 * and other provisions required by the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL or the LGPL.
 *
 * Significant Contributors to this file are:
 *
 *
 */

#define THIS_IS_XML2_XMLREADER 1

#include "xml2.h"

/*! @module Public
 */

/*! @module Parser
 */

/*! @module XML2
 */

/*! @class XMLReader
 *!
 *! A simplified parser for XML documents. Similar to the C# XMLReader 
 *! class.
 */
#ifdef HAVE_LIBXML_XMLREADER_H

PIKECLASS XMLReader
program_flags PROGRAM_USES_PARENT;
{

  CVAR XMLREADER_OBJECT_DATA   *object_data;

PIKEFUN string _sprintf(int type, mixed t)
{
  char * desc;

  push_text("XMLReader()");
}

/*! @decl void set_autoencode(int a)
 *!
 *! turns autoencoding of data to UTF-8 on or off. If you know
 *! that your input to non-constructor functions is UTF-8,
 *! you can turn autoencode off, thereby saving conversion 
 *! time. Otherwise, all input is assumed to be unencoded Pike
 *! strings (which may be wide).
 *!
 */
PIKEFUN void set_autoencode(int a)
{
  THIS->object_data->autoencode = a;
  pop_stack();
}

/*! @decl int read()
 *!
 *! reads the next node of the document and loads its data.
 *!
 *! returns 1 if a node was read, 0 if no additional nodes are available,
 *!  and throws an error if a parse error occurred.
 */
PIKEFUN int read()
{
  int res;

  if(THIS->object_data == NULL || THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  res = xmlTextReaderRead(THIS->object_data->reader);
  if(res == 1) /* we got data to process! */
  {
    push_int(1);
    return;
  }
  else if (res == 0)
  {
    push_int(0);
    return;
  }
  else
  {
    Pike_error("unable to parse, result code: %d!\n", res);
  }
}

/*! @decl int node_type()
 *! 
 *!  returns the type of the current node. Types are described here:
 *!   http://dotgnu.org/pnetlib-doc/System/Xml/XmlNodeType.html
 */
PIKEFUN int node_type()
{
  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  RETURN xmlTextReaderNodeType(THIS->object_data->reader);
}

/*! @decl Node expand()
 *!
 */

PIKEFUN object expand()
{
  xmlNodePtr node;
struct object * xnode;
  struct Node_struct * ns;
  NODE_OBJECT_DATA * od;

  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  node = xmlTextReaderExpand(THIS->object_data->reader);

  if(node == NULL)
  {
    Pike_error("error expanding node!\n");
  }

  xnode = NEW_NODE();
  ns = OBJ2_NODE((xnode));
  od = (NODE_OBJECT_DATA *)(ns->object_data);
  od->transient = 1;
  od->refs = malloc(sizeof(INT32));
  (* od->refs)=1;

  od->node = node;

  push_object(xnode);  
}

/*! @decl int depth()
 *! 
 *!   returns the depth of the current node within the tree.
 */
PIKEFUN int depth()
{
  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  RETURN xmlTextReaderDepth(THIS->object_data->reader);
}

/*! @decl int has_attributes()
 *! 
 *!  Does the node have attributes?
 */
PIKEFUN int has_attributes()
{
  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  RETURN xmlTextReaderHasAttributes(THIS->object_data->reader);
}

/*! @decl int attribute_count()
 *! 
 *!  returns the number of attributes associated with the current node.
 */
PIKEFUN int attribute_count()
{
  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  RETURN xmlTextReaderAttributeCount(THIS->object_data->reader);
}

/*! @decl int next_sibling()
 *! 
 */
PIKEFUN int next_sibling()
{
  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  RETURN xmlTextReaderNextSibling(THIS->object_data->reader);
}

/*! @decl int next()
 *! 
 */
PIKEFUN int next()
{
  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  RETURN xmlTextReaderNext(THIS->object_data->reader);
}

/*! @decl int element()
 *! 
 */
PIKEFUN int element()
{
  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  RETURN xmlTextReaderMoveToElement(THIS->object_data->reader);
}

/*! @decl int first_attribute()
 *! 
 */
PIKEFUN int first_attribute()
{
  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  RETURN xmlTextReaderMoveToFirstAttribute(THIS->object_data->reader);
}

/*! @decl int next_attribute()
 *! 
 */
PIKEFUN int next_attribute()
{
  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  RETURN xmlTextReaderMoveToNextAttribute(THIS->object_data->reader);
}

/*! @decl int attribute_no()
 *! 
 */
PIKEFUN int attribute_no(int no)
{
  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  RETURN xmlTextReaderMoveToAttributeNo(THIS->object_data->reader, no);
}

/*! @decl int attribute_ns(string localName, string namespaceURI)
 *! 
 */
PIKEFUN int attribute_ns(string localName, string namespaceURI)
{
  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  f_rconvert_string_utf8(1);
  namespaceURI = Pike_sp[-1].u.string;

  stack_swap_n(2);

  localName = Pike_sp[-1].u.string;
  f_rconvert_string_utf8(1);

  RETURN xmlTextReaderMoveToAttributeNs(THIS->object_data->reader, 
    (const xmlChar *)localName->str, (const xmlChar *)namespaceURI->str);
}

/*! @decl int attribute(string name)
 *! 
 */
PIKEFUN int attribute(string name)
{
  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  f_rconvert_string_utf8(1);
  name = Pike_sp[-1].u.string;

  RETURN xmlTextReaderMoveToAttribute(THIS->object_data->reader, 
    (const xmlChar *)name->str);
}


/*! @decl int has_value()
 *! 
 */
PIKEFUN int has_value()
{
  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  RETURN xmlTextReaderHasValue(THIS->object_data->reader);
}

/*! @decl int is_default()
 *! 
 */
PIKEFUN int is_default()
{
  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  RETURN xmlTextReaderIsDefault(THIS->object_data->reader);
}

/*! @decl int is_namespace_decl()
 *! 
 */
PIKEFUN int is_namespace_decl()
{
  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

#if HAVE_XMLTEXTREADERISNAMESPACEDECL
  RETURN xmlTextReaderIsNamespaceDecl(THIS->object_data->reader);
#else
  Pike_error("This XMLReader does not have xmlTextReaderIsNamespaceDecl.\n");
#endif /* HAVE_XMLTEXTREADERISNAMESPACEDECL */
}

/*! @decl int is_empty_element()
 *! 
 */
PIKEFUN int is_empty_element()
{
  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  RETURN xmlTextReaderIsEmptyElement(THIS->object_data->reader);
}

/*! @decl int is_valid()
 *! 
 */
PIKEFUN int is_valid()
{
  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  RETURN xmlTextReaderIsValid(THIS->object_data->reader);
}

/*! @decl int parser_column_number()
 *! 
 */
PIKEFUN int parser_column_number()
{
  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }
#ifdef HAVE_XMLTEXTREADERGETPARSERCOLUMNNUMBER
  RETURN xmlTextReaderGetParserColumnNumber(THIS->object_data->reader);
#else
  RETURN -1;
#endif /* HAVE_XMLTEXTREADERGETPARSERCOLUMNNUMBER */
}

/*! @decl int parser_line_number()
 *! 
 */
PIKEFUN int parser_line_number()
{
  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }
#ifdef HAVE_XMLTEXTREADERGETPARSERLINENUMBER
  RETURN xmlTextReaderGetParserLineNumber(THIS->object_data->reader);
#else
  RETURN -1;
#endif /* HAVE_XMLTEXTREADERGETPARSERLINENUMBER */
}

/*! @decl int get_parser_prop(int prop)
 *! 
 *! @param prop
 *!   the property to get
 */
PIKEFUN int get_parser_prop(int prop)
{
  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  RETURN xmlTextReaderGetParserProp(THIS->object_data->reader, prop);
}

/*! @decl int set_parser_prop(int prop, int value)
 *! 
 *! @param prop
 *!   the property to set
 *!
 *! @param value
 *!   the value to set
 */
PIKEFUN int set_parser_prop(int prop, int value)
{
  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  RETURN xmlTextReaderSetParserProp(THIS->object_data->reader, prop, value);
}

/*! @decl string name()
 *! 
 */
PIKEFUN string name()
{
  xmlChar * c;

  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  c = xmlTextReaderName(THIS->object_data->reader);
  if(c != NULL)
  {
    push_text(c);
    xmlFree(c);
  }
  else
    push_int(0);
}

/*! @decl string get_attribute(string name)
 *! 
 */
PIKEFUN string get_attribute(string name)
{
  xmlChar * c;

  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  f_rconvert_string_utf8(1);
  name = Pike_sp[-1].u.string;

  c = xmlTextReaderGetAttribute(THIS->object_data->reader, name->str);
  if(c != NULL)
  {
    push_text(c);
    xmlFree(c);
  }
  else
    push_int(0);
}


/*! @decl string get_attribute_no(int no)
 *! 
 */
PIKEFUN string get_attribute_no(int no)
{
  xmlChar * c;

  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  c = xmlTextReaderGetAttributeNo(THIS->object_data->reader, no);
  if(c != NULL)
  {
    push_text(c);
    xmlFree(c);
  }
  else
    push_int(0);
}

/*! @decl string get_attribute_ns(string localName, string namespaceURI)
 *! 
 */
PIKEFUN string get_attribute(string localName, string namespaceURI)
{
  xmlChar * c;

  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  f_rconvert_string_utf8(1);
  namespaceURI = Pike_sp[-1].u.string;

  stack_swap_n(2);

  f_rconvert_string_utf8(1);
  localName = Pike_sp[-1].u.string;

  c = xmlTextReaderGetAttributeNs(THIS->object_data->reader, 
         localName->str, namespaceURI->str);
  if(c != NULL)
  {
    push_text(c);
    xmlFree(c);
  }
  else
    push_int(0);
}


/*! @decl string lookup_namespace(string|void prefix)
 *! 
 */
PIKEFUN string lookup_namespace(string prefix)
{
  xmlChar * c;

  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  f_rconvert_string_utf8(1);
  prefix = Pike_sp[-1].u.string;

  c = xmlTextReaderLookupNamespace(THIS->object_data->reader, prefix->str);
  if(c != NULL)
  {
    push_text(c);
    xmlFree(c);
  }
  else
    push_int(0);
}

PIKEFUN string lookup_namespace()
{
  xmlChar * c;

  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  c = xmlTextReaderLookupNamespace(THIS->object_data->reader, NULL);
  if(c != NULL)
  {
    push_text(c);
    xmlFree(c);
  }
  else
    push_int(0);
}

/*! @decl string xml_lang()
 *! 
 */
PIKEFUN string xml_lang()
{
  xmlChar * c;

  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  c = xmlTextReaderXmlLang(THIS->object_data->reader);
  if(c != NULL)
  {
    push_text(c);
    xmlFree(c);
  }
  else
    push_int(0);
}


/*! @decl string prefix()
 *! 
 */
PIKEFUN string prefix()
{
  xmlChar * c;

  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  c = xmlTextReaderPrefix(THIS->object_data->reader);
  if(c != NULL)
  {
    push_text(c);
    xmlFree(c);
  }
  else
    push_int(0);
}

/*! @decl string namespaceuri()
 *! 
 */
PIKEFUN string namespaceuri()
{
  xmlChar * c;

  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  c = xmlTextReaderNamespaceUri(THIS->object_data->reader);
  if(c != NULL)
  {
    push_text(c);
    xmlFree(c);
  }
  else
    push_int(0);
}
/*! @decl string baseuri()
 *! 
 */
PIKEFUN string baseuri()
{
  xmlChar * c;

  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  c = xmlTextReaderBaseUri(THIS->object_data->reader);
  if(c != NULL)
  {
    push_text(c);
    xmlFree(c);
  }
  else
    push_int(0);
}

/*! @decl string localname()
 *! 
 */
PIKEFUN string localname()
{
  xmlChar * c;

  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  c = xmlTextReaderLocalName(THIS->object_data->reader);
  if(c != NULL)
  {
    push_text(c);
    xmlFree(c);
  }
  else
    push_int(0);
}

/*! @decl string value()
 *! 
 */
PIKEFUN string value()
{
  xmlChar * c;

  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  c = xmlTextReaderValue(THIS->object_data->reader);
  if(c != NULL)
  {
    push_text(c);
    xmlFree(c);
  }
  else
    push_int(0);
}

/*! @decl string string()
 *! 
 */
PIKEFUN string string()
{
  xmlChar * c;

  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  c = xmlTextReaderReadString(THIS->object_data->reader);
  if(c != NULL)
  {
    push_text(c);
    xmlFree(c);
  }
  else
    push_int(0);
}

/*! @decl string inner_xml()
 *! 
 */
PIKEFUN string inner_xml()
{
  xmlChar * c;

  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  c = xmlTextReaderReadInnerXml(THIS->object_data->reader);
  if(c != NULL)
  {
    push_text(c);
    xmlFree(c);
  }
  else
    push_int(0);
}

/*! @decl string outer_xml()
 *! 
 */
PIKEFUN string outer_xml()
{
  xmlChar * c;

  if(THIS->object_data->reader == NULL)
  {
    Pike_error("no xmlReader!\n");
  }

  c = xmlTextReaderReadOuterXml(THIS->object_data->reader);
  if(c != NULL)
  {
    push_text(c);
    xmlFree(c);
  }
  else
    push_int(0);
}

/*! @decl void create(string xml, string|void url, int|void options, string encoding)
 *!
 *!  note that xml is expected to be encoded according to the encoding directive in the
 *!  xml file, or as UTF-8. All other strings may be in Pike standard string format.
 */
PIKEFUN void create(string xml, string url, int options, string encoding)
{
  xmlTextReaderPtr reader;
/*
  xmlParserCtxtPtr ctxt;
  xmlSAXHandlerPtr sax;
 */

  stack_swap_n(2);
  f_rconvert_string_utf8(1);
  url = Pike_sp[-1].u.string;

  stack_swap_n(4);
  f_rconvert_string_utf8(1);
  encoding = Pike_sp[-1].u.string;

  reader = xmlReaderForMemory(xml->str, xml->len, url->str, 
               encoding->str, options);

  if(reader == NULL)
  {
    Pike_error("unable to get xmlReader\n");
  }

  add_ref(xml);
  THIS->object_data->xml = xml;
  THIS->object_data->reader = reader;

  pop_n_elems(args);
}

PIKEFUN void create(string xml, string url, int options)
{
  xmlTextReaderPtr reader;

  stack_swap_n(2);
  f_rconvert_string_utf8(1);
  url = Pike_sp[-1].u.string; 

  reader = xmlReaderForMemory(xml->str, xml->len, url->str, 
               NULL, options);

  if(reader == NULL)
  {
    Pike_error("unable to get xmlReader\n");
  }

  THIS->object_data->reader = reader;
  add_ref(xml);
  THIS->object_data->xml = xml;

  pop_n_elems(args);
}

PIKEFUN void create(string xml)
{
  push_text("noname.xml");
  push_int(0);

  f_XMLReader_create(3);
}

INIT
{
  XMLREADER_OBJECT_DATA * dta;

  dta = 
	(XMLREADER_OBJECT_DATA*)malloc(sizeof(XMLREADER_OBJECT_DATA));
    if (!dta)
        Pike_error("init_xmlreader: Out of memory!\n");

    dta->reader = NULL;
    dta->autoencode = 1;
    THIS->object_data = dta;
}

EXIT
{ 

  if(THIS->object_data->reader != NULL)
  {
    xmlFreeTextReader(THIS->object_data->reader);
    THIS->object_data->reader = NULL;
  }
  if(THIS->object_data->xml != NULL)
  {
    free_string(THIS->object_data->xml);
    THIS->object_data->xml = NULL;
  }
  if(THIS->object_data)
  {
    free(THIS->object_data);
    THIS->object_data = NULL;
  }
}
}

#endif /* HAVE_LIBXML_XMLREADER_H */
/*! @endclass
 */


/*! @endmodule
 */

/*! @endmodule
 */

/*! @endmodule
 */


void pike_init_xml2_xmlreader()
{
  INIT
}

void pike_exit_xml2_xmlreader()
{
  EXIT
}

gotpike.org | Copyright © 2004 - 2011 | Pike is a trademark of Department of Computer and Information Science, Linköping University