php-src/ext/qtdom/qtdom.c
2001-02-26 06:11:02 +00:00

294 lines
8.6 KiB
C

/*
+----------------------------------------------------------------------+
| PHP version 4.0 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2001 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 2.02 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available at through the world-wide-web at |
| http://www.php.net/license/2_02.txt. |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: |
| |
+----------------------------------------------------------------------+
*/
/* You should tweak config.m4 so this symbol (or some else suitable)
gets defined.
*/
#include "php.h"
#include "php_ini.h"
#include "qtdom.h"
#include "qtdom_qt.h"
#if HAVE_QTDOM
static zend_function_entry qdomdoc_class_functions[] = {
{NULL, NULL, NULL}
};
static zend_function_entry qdomnode_class_functions[] = {
{NULL, NULL, NULL}
};
/* If you declare any globals in php_qtdom.h uncomment this:
ZEND_DECLARE_MODULE_GLOBALS(qtdom)
*/
/* True global resources - no need for thread safety here */
static int le_qtdom;
/* Every user visible function must have an entry in qtdom_functions[].
*/
function_entry qtdom_functions[] = {
PHP_FE(qdom_tree, NULL)
PHP_FE(qdom_error, NULL)
{NULL, NULL, NULL} /* Must be the last line in qtdom_functions[] */
};
zend_module_entry qtdom_module_entry = {
"qtdom",
qtdom_functions,
PHP_MINIT(qtdom),
PHP_MSHUTDOWN(qtdom),
PHP_RINIT(qtdom), /* Replace with NULL if there's nothing to do at request start */
PHP_RSHUTDOWN(qtdom), /* Replace with NULL if there's nothing to do at request end */
PHP_MINFO(qtdom),
STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_QTDOM
ZEND_GET_MODULE(qtdom)
#endif
/* Remove comments and fill if you need to have entries in php.ini
PHP_INI_BEGIN()
PHP_INI_END()
*/
PHP_MINIT_FUNCTION(qtdom)
{
/* Remove comments if you have entries in php.ini
REGISTER_INI_ENTRIES();
*/
zend_class_entry qdomdoc_class_entry;
zend_class_entry qdomnode_class_entry;
INIT_CLASS_ENTRY(qdomdoc_class_entry, "QDomDocument", qdomdoc_class_functions);
INIT_CLASS_ENTRY(qdomnode_class_entry, "QDomNode", qdomnode_class_functions);
qdomdoc_class_entry_ptr = zend_register_internal_class(&qdomdoc_class_entry);
qdomnode_class_entry_ptr = zend_register_internal_class(&qdomnode_class_entry);
qdom_init();
return SUCCESS;
}
PHP_MSHUTDOWN_FUNCTION(qtdom)
{
/* Remove comments if you have entries in php.ini
UNREGISTER_INI_ENTRIES();
*/
qdom_shutdown();
return SUCCESS;
}
/* Remove if there's nothing to do at request start */
PHP_RINIT_FUNCTION(qtdom)
{
return SUCCESS;
}
/* Remove if there's nothing to do at request end */
PHP_RSHUTDOWN_FUNCTION(qtdom)
{
return SUCCESS;
}
PHP_MINFO_FUNCTION(qtdom)
{
php_info_print_table_start();
php_info_print_table_header(2, "qtdom support", "enabled");
php_info_print_table_end();
/* Remove comments if you have entries in php.ini
DISPLAY_INI_ENTRIES();
*/
}
/* Remove the following function when you have succesfully modified config.m4
so that your module can be compiled into PHP, it exists only for testing
purposes. */
/* Helper function for creating the attributes, returns the number of attributes found
or -1 if an error occured */
int qdom_find_attributes( zval **children, struct qdom_attribute *attr )
{
zval *child;
struct qdom_node *node;
int count;
int i;
count = 0;
MAKE_STD_ZVAL(*children);
if (array_init(*children) == FAILURE)
return -1;
for ( i = 0; i < attr->Count; ++i )
{
node = qdom_do_attribute_at( attr, i );
MAKE_STD_ZVAL(child);
object_init_ex(child, qdomnode_class_entry_ptr);
zend_hash_next_index_insert((*children)->value.ht, &child, sizeof(zval *), NULL);
add_property_stringl(child, "name", (char *) node->Name, strlen(node->Name), 1);
add_property_long(child, "type", node->Type);
add_property_stringl(child, "content", (char *) node->Content, strlen(node->Content), 1);
qdom_do_node_free( node );
++count;
}
return count;
}
/* Helper function for recursively going trough the QDomNode tree and creating
the same in PHP objects. Returns the number of children or -1 if an error
occured. */
int qdom_find_children( zval **children, struct qdom_node *orig_node )
{
zval *child;
struct qdom_node *node, *tmp_node, *child_node;
int count;
zval *n_children, *a_children;
count = 0;
node = qdom_do_copy_node( orig_node );
tmp_node = node;
/* node = orig_node; */
MAKE_STD_ZVAL(*children);
if (array_init(*children) == FAILURE)
return -1;
while( node )
{
int num_childs, num_attrs;
MAKE_STD_ZVAL(child);
object_init_ex(child, qdomnode_class_entry_ptr);
zend_hash_next_index_insert((*children)->value.ht, &child, sizeof(zval *), NULL);
add_property_stringl(child, "name", (char *) node->Name, strlen(node->Name), 1);
add_property_long(child, "type", node->Type);
if ( node->Type == 2 || node->Type == 3 || node->Type == 4 )
add_property_stringl(child, "content", (char *) node->Content, strlen(node->Content), 1);
num_attrs = qdom_do_node_attribute_count( node );
if ( num_attrs > 0 )
{
struct qdom_attribute *attr = qdom_do_node_attributes( node );
if ( qdom_find_attributes( &a_children, attr ) > 0 )
{
zend_hash_update(child->value.obj.properties,
"attributes", sizeof("attributes"),
(void *) &a_children, sizeof(zval *),
NULL);
}
qdom_do_attributes_free( attr );
/* add_property_long(child, "attributes", num_attrs ); */
}
num_childs = qdom_do_node_children_count( node );
if ( num_childs > 0 )
{
child_node = qdom_do_copy_node( node );
child_node = qdom_do_first_child( child_node );
if ( qdom_find_children( &n_children, child_node ) > 0 )
{
zend_hash_update(child->value.obj.properties,
"children", sizeof("children"),
(void *) &n_children, sizeof(zval *),
NULL);
}
qdom_do_node_free( child_node );
}
node = qdom_do_next_node( node );
++count;
}
qdom_do_node_free( tmp_node );
return count;
}
/* {{{ proto object qdom_tree( string )
creates a tree of an xml string */
PHP_FUNCTION(qdom_tree)
{
zval *arg;
char qt_ver1[200];
char *qt_ver = qt_ver1;
char *qdom_type_name;
struct qdom_doc *doc;
struct qdom_node *node;
zval *children;
if (ZEND_NUM_ARGS() != 1 || getParameters(ht, 1, &arg) == FAILURE)
{
WRONG_PARAM_COUNT;
}
convert_to_string(arg);
qdom_do_install_message_handler();
qdom_do_version( &qt_ver );
object_init_ex(return_value, qdomdoc_class_entry_ptr);
add_property_stringl(return_value, "version", (char *) qt_ver, strlen(qt_ver), 1);
doc = qdom_do_init( arg->value.str.val );
qdom_do_doc_type( doc, &qdom_type_name );
if ( qdom_type_name )
add_property_stringl(return_value, "doctype", (char *) qdom_type_name, strlen(qdom_type_name), 1);
node = doc->Children;
if ( qdom_find_children( &children, node ) > 0 )
{
add_property_long(return_value, "type", node->Type);
zend_hash_update(return_value->value.obj.properties, "children", sizeof("children"), (void *) &children, sizeof(zval *), NULL);
}
qdom_do_free( doc );
qdom_do_free_message_handler();
}
/* }}} */
/* {{{ proto string qdom_error()
Returns the error string from the last QDOM operation or FALSE if no errors occured.*/
PHP_FUNCTION(qdom_error)
{
char *error = qdom_error_log();
if ( error == 0 )
RETURN_FALSE;
RETURN_STRING( error, 1 );
}
/* }}} */
#endif /* HAVE_QTDOM */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
*/