From 0425aadc78680e53000fd0108b540d6eca048516 Mon Sep 17 00:00:00 2001 From: gmcdonald Date: Sat, 13 Feb 2010 01:32:03 +0000 Subject: Moving axis svn, part of TLP move INFRA-2441 git-svn-id: http://svn.apache.org/repos/asf/axis/axis2/c/core/trunk@909681 13f79535-47bb-0310-9956-ffa450edef68 --- axiom/src/xpath/xpath.c | 462 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 462 insertions(+) create mode 100755 axiom/src/xpath/xpath.c (limited to 'axiom/src/xpath/xpath.c') diff --git a/axiom/src/xpath/xpath.c b/axiom/src/xpath/xpath.c new file mode 100755 index 0000000..38f422c --- /dev/null +++ b/axiom/src/xpath/xpath.c @@ -0,0 +1,462 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (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.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "xpath_internals.h" +#include "xpath_internals_parser.h" +#include "xpath_internals_engine.h" +#include "xpath_functions.h" +#include "xpath_streaming.h" + +/* Create XPath context */ +AXIS2_EXTERN axiom_xpath_context_t * AXIS2_CALL +axiom_xpath_context_create( + const axutil_env_t *env, + axiom_node_t * root_node) +{ + axiom_xpath_context_t* context; + + /*HACK: xpath impl requires a dummy root node in order to process properly.*/ + axiom_node_t * dummy_root; + dummy_root = axiom_node_create(env); + axiom_node_add_child(dummy_root, env, root_node); + + context = AXIS2_MALLOC(env->allocator, + sizeof(axiom_xpath_context_t)); + + context->env = env; + context->root_node = dummy_root; + context->node = dummy_root; + context->expr = NULL; + context->attribute = NULL; + context->namespaces = NULL; + context->functions = NULL; + + axiom_xpath_register_default_functions_set(context); + + return context; +} + +/* Compile XPath expression */ +AXIS2_EXTERN axiom_xpath_expression_t * AXIS2_CALL +axiom_xpath_compile_expression( + const axutil_env_t *env, + const axis2_char_t* xpath_expr) +{ + axiom_xpath_expression_t* expr; + + expr = AXIS2_MALLOC(env->allocator, + sizeof(axiom_xpath_expression_t)); + + expr->expr_str = axutil_strdup(env, xpath_expr); + + if (axiom_xpath_compile(env, expr) == AXIOM_XPATH_PARSE_ERROR) + { + AXIS2_FREE(env->allocator, expr->expr_str); + AXIS2_FREE(env->allocator, expr); + + return NULL; + } + else + { + return expr; + } +} + +/* Evaluate compiled XPath expression */ +AXIS2_EXTERN axiom_xpath_result_t * AXIS2_CALL +axiom_xpath_evaluate( + axiom_xpath_context_t *context, + axiom_xpath_expression_t *xpath_expr) +{ + axiom_xpath_expression_copy(context, xpath_expr); + + context->streaming = AXIS2_FALSE; + + return axiom_xpath_run(context); +} + +AXIS2_EXTERN axiom_xpath_result_t * AXIS2_CALL +axiom_xpath_evaluate_streaming( + axiom_xpath_context_t *context, + axiom_xpath_expression_t *xpath_expr) +{ + axiom_xpath_result_t *res; + + axiom_xpath_expression_copy(context, xpath_expr); + + if (axiom_xpath_streaming_check(context->env, xpath_expr)) + { + context->streaming = AXIS2_TRUE; + return axiom_xpath_run(context); + } + else + { + res = AXIS2_MALLOC( + context->env->allocator, sizeof(axiom_xpath_result_t)); + res->nodes = NULL; + res->flag = AXIOM_XPATH_ERROR_STREAMING_NOT_SUPPORTED; + + return res; + } +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_xpath_register_default_functions_set( + axiom_xpath_context_t *context) +{ + axiom_xpath_register_function( + context, "count", axiom_xpath_function_count); +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_xpath_register_function( + axiom_xpath_context_t *context, + axis2_char_t *name, + axiom_xpath_function_t func) +{ + if (name && func) + { + if (!context->functions) + { + context->functions = axutil_hash_make(context->env); + } + + axutil_hash_set(context->functions, name, AXIS2_HASH_KEY_STRING, func); + } +} + +AXIS2_EXTERN axiom_xpath_function_t AXIS2_CALL +axiom_xpath_get_function( + axiom_xpath_context_t *context, + axis2_char_t *name) +{ + axiom_xpath_function_t func = NULL; + + if(context->functions) + { + func = axutil_hash_get(context->functions, name, AXIS2_HASH_KEY_STRING); + } + + return func; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_xpath_register_namespace( + axiom_xpath_context_t *context, + axiom_namespace_t *ns) +{ + axis2_char_t *prefix = NULL; + + if (!context->namespaces) + { + context->namespaces = axutil_hash_make(context->env); + } + + prefix = axiom_namespace_get_prefix(ns, context->env); + + if (prefix) + { + axutil_hash_set( + context->namespaces, prefix, AXIS2_HASH_KEY_STRING, ns); + } +} + +AXIS2_EXTERN axiom_namespace_t * AXIS2_CALL +axiom_xpath_get_namespace( + axiom_xpath_context_t *context, + axis2_char_t *prefix) +{ + axiom_namespace_t *ns = NULL; + + if (context->namespaces) + { + ns = axutil_hash_get(context->namespaces, prefix, AXIS2_HASH_KEY_STRING); + } + + return ns; +} + +AXIS2_EXTERN void AXIS2_CALL +axiom_xpath_clear_namespaces( + axiom_xpath_context_t *context) +{ + axutil_hash_index_t *hi; + void *val; + + if (context->namespaces) + { + for (hi = axutil_hash_first(context->namespaces, context->env); + hi; + hi = axutil_hash_next(context->env, hi)) + { + axutil_hash_this(hi, NULL, NULL, &val); + axiom_namespace_free((axiom_namespace_t *)val, context->env); + } + + axutil_hash_free(context->namespaces, context->env); + } + + context->namespaces = NULL; +} + +/* Cast to boolean */ +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_xpath_cast_node_to_boolean( + const axutil_env_t *env, + axiom_xpath_result_node_t * node) +{ + if(node->type == AXIOM_XPATH_TYPE_BOOLEAN) + { + return *(axis2_bool_t *)node->value; + } + else if(node->type == AXIOM_XPATH_TYPE_NUMBER) + { + /* Cannot evaluate as *(double *)(node->value) == 1e-12 + since there might be an precision error */ + if(*(double *)(node->value) > 1e-12 || *(double *)(node->value) < -1e-12) + { + return AXIS2_TRUE; + } + else + { + return AXIS2_FALSE; + } + } + else if(node->value) + { + return AXIS2_TRUE; + } + else + { + return AXIS2_FALSE; + } +} + +/* Cast to double */ +AXIS2_EXTERN double AXIS2_CALL +axiom_xpath_cast_node_to_number( + const axutil_env_t *env, + axiom_xpath_result_node_t * node) +{ + if (node->type == AXIOM_XPATH_TYPE_BOOLEAN) + { + if (*(axis2_bool_t *)(node->value) == AXIS2_TRUE) + { + return 1.0; + } + else + { + return 0.0; + } + } + else if (node->type == AXIOM_XPATH_TYPE_NUMBER) + { + return *(double *)node->value; + } + else if (node->value) + { + return 1.0; + } + else + { + return 0.0; + } +} + +/* Cast to text */ +AXIS2_EXTERN axis2_char_t * AXIS2_CALL +axiom_xpath_cast_node_to_string( + const axutil_env_t *env, + axiom_xpath_result_node_t * node) +{ + axiom_element_t *ele; + axis2_char_t *res; + + if (!node->value) + { + return NULL; + } + + if (node->type == AXIOM_XPATH_TYPE_BOOLEAN) + { + if (*(axis2_bool_t *)(node->value) == AXIS2_TRUE) + { + return axutil_strdup(env, "true"); + } + else + { + return axutil_strdup(env, "false"); + } + } + else if (node->type == AXIOM_XPATH_TYPE_NUMBER) + { + /* Allocate 50 bytes */ + res = AXIS2_MALLOC(env->allocator, sizeof(axis2_char_t) * 50); + + sprintf(res, "%lf", *(double *)(node->value)); + + return res; + } + else if (node->type == AXIOM_XPATH_TYPE_TEXT) + { + return (axis2_char_t *)node->value; + } + else if (node->type == AXIOM_XPATH_TYPE_NODE) + { + ele = (axiom_element_t *)axiom_node_get_data_element( + (axiom_node_t *)(node->value), env); + + if (ele) + { + return axiom_element_get_text( + ele, env, (axiom_node_t *)(node->value)); + } + else + { + return NULL; + } + } + else if (node->type == AXIOM_XPATH_TYPE_ATTRIBUTE) + { + return axiom_attribute_get_value( + (axiom_attribute_t *)(node->value), env); + } + else if (node->type == AXIOM_XPATH_TYPE_NAMESPACE) + { + return axiom_namespace_get_prefix( + (axiom_namespace_t *)(node->value), env); + } + + return NULL; +} + +/* Cast to axiom node */ +AXIS2_EXTERN axiom_node_t * AXIS2_CALL +axiom_xpath_cast_node2axiom_node( + const axutil_env_t *env, + axiom_xpath_result_node_t * node) +{ + if (node->type == AXIOM_XPATH_TYPE_NODE && node->value) + { + return (axiom_node_t *)node->value; + } + else + { + return NULL; + } +} + +/* Free context */ +AXIS2_EXTERN void AXIS2_CALL +axiom_xpath_free_context( + const axutil_env_t *env, + axiom_xpath_context_t *context) +{ + if (context) + { + /* Free the expression if not freed */ + if (context->expr) + { + /* axiom_xpath_free_expression(env, context->expr); */ + + context->expr = NULL; + } + + if (context->root_node) + { + axiom_node_detach(axiom_node_get_first_child(context->root_node, context->env), context->env); + axiom_node_free_tree(context->root_node, context->env); + context->root_node = NULL; + } + + if (context->functions) + { + axutil_hash_free(context->functions, context->env); + context->functions = NULL; + } + + if(context->namespaces) + { + axiom_xpath_clear_namespaces(context); + context->namespaces = NULL; + } + + AXIS2_FREE(env->allocator, context); + } +} + +/* Free expression */ +AXIS2_EXTERN void AXIS2_CALL +axiom_xpath_free_expression( + const axutil_env_t *env, + axiom_xpath_expression_t * xpath_expr) +{ + if (xpath_expr) + { + if (xpath_expr->expr_str) + { + AXIS2_FREE(env->allocator, xpath_expr->expr_str); + + xpath_expr->expr_str = NULL; + } + + if (xpath_expr->operations) + { + axutil_array_list_free(xpath_expr->operations, env); + xpath_expr->operations = NULL; + } + + AXIS2_FREE(env->allocator, xpath_expr); + } +} + +/* Free result set */ +AXIS2_EXTERN void AXIS2_CALL +axiom_xpath_free_result( + const axutil_env_t *env, + axiom_xpath_result_t* result) +{ + if (result) + { + if (result->nodes) + { + axutil_array_list_free(result->nodes, env); + } + + AXIS2_FREE(env->allocator, result); + } +} + +/* Check if the expression can be evaluated on streaming XML */ +AXIS2_EXTERN axis2_bool_t AXIS2_CALL +axiom_xpath_streaming_check( + const axutil_env_t *env, + axiom_xpath_expression_t* expr) +{ + axiom_xpath_streaming_t r = AXIOM_XPATH_CHECK(expr->start); + + if(r == AXIOM_XPATH_STREAMING_NOT_SUPPORTED) + { + return AXIS2_FALSE; + } + else + { + return AXIS2_TRUE; + } +} + -- cgit v1.1-32-gdbae