You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axis-cvs@ws.apache.org by du...@apache.org on 2008/11/20 22:26:09 UTC
svn commit: r719381 [2/5] - in /webservices/axis2/trunk/c/axiom: src/xpath/
test/xpath/
Modified: webservices/axis2/trunk/c/axiom/src/xpath/xpath_internals_engine.c
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/axiom/src/xpath/xpath_internals_engine.c?rev=719381&r1=719380&r2=719381&view=diff
==============================================================================
--- webservices/axis2/trunk/c/axiom/src/xpath/xpath_internals_engine.c (original)
+++ webservices/axis2/trunk/c/axiom/src/xpath/xpath_internals_engine.c Thu Nov 20 13:26:08 2008
@@ -1,1009 +1,1009 @@
-
-/*
- * 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 "xpath.h"
-#include "xpath_internals.h"
-#include "xpath_internals_engine.h"
-#include "xpath_internals_iterators.h"
-
-/* Evaluates the expath expression */
-axiom_xpath_result_t * axiom_xpath_run(axiom_xpath_context_t *context)
-{
- axiom_xpath_result_t* res;
-
- /* Initialize result ret */
- res = AXIS2_MALLOC(context->env->allocator,
- sizeof(axiom_xpath_result_t));
-
- res->flag = 0;
-
- res->nodes = axutil_array_list_create(context->env, 0);
-
- context->stack = axutil_stack_create(context->env);
-
- /* Expression is empty */
- if (context->expr->start == AXIOM_XPATH_PARSE_END)
- {
- return res;
- }
-
- axiom_xpath_evaluate_operation(context, context->expr->start);
-
- /* Add nodes to the result set from the stack */
- while (axutil_stack_size(context->stack, context->env) > 0)
- {
- axutil_array_list_add(
- res->nodes, context->env,
- axutil_stack_pop(context->stack, context->env));
- }
-
- return res;
-}
-
-/* Casting functions; these make use of the casting functions defined in xpath.h */
-void axiom_xpath_cast_boolean(
- axiom_xpath_result_node_t *node,
- axiom_xpath_context_t *context)
-{
- AXIOM_XPATH_CAST_SET_VALUE(
- axis2_bool_t, axiom_xpath_cast_node_to_boolean(context->env, node));
-
- node->type = AXIOM_XPATH_TYPE_BOOLEAN;
-}
-
-void axiom_xpath_cast_number(
- axiom_xpath_result_node_t *node,
- axiom_xpath_context_t *context)
-{
- AXIOM_XPATH_CAST_SET_VALUE(
- double, axiom_xpath_cast_node_to_number(context->env, node));
-
- node->type = AXIOM_XPATH_TYPE_NUMBER;
-}
-
-void axiom_xpath_cast_string(
- axiom_xpath_result_node_t *node,
- axiom_xpath_context_t *context)
-{
- node->value = axiom_xpath_cast_node_to_string(context->env, node);
-
- node->type = AXIOM_XPATH_TYPE_TEXT;
-}
-
-/* Evaluate whether two results are equal
- TODO: Comment */
-axis2_bool_t axiom_xpath_compare_equal(
- axiom_xpath_result_node_t *node1,
- axiom_xpath_result_node_t *node2,
- axiom_xpath_context_t *context)
-{
- if (node1->type == AXIOM_XPATH_TYPE_BOOLEAN
- || node2->type == AXIOM_XPATH_TYPE_BOOLEAN)
- {
- axiom_xpath_cast_boolean(node1, context);
- axiom_xpath_cast_boolean(node2, context);
-
- if (*(axis2_bool_t*)(node1->value) == *(axis2_bool_t*)(node2->value))
- {
- return AXIS2_TRUE;
- }
- else
- {
- return AXIS2_FALSE;
- }
- }
-
- if (node1->type == AXIOM_XPATH_TYPE_NUMBER
- || node2->type == AXIOM_XPATH_TYPE_NUMBER)
- {
- axiom_xpath_cast_number(node1, context);
- axiom_xpath_cast_number(node2, context);
-
- if (*(double *)(node1->value) == *(double *)(node2->value))
- {
- return AXIS2_TRUE;
- }
- else
- {
- return AXIS2_FALSE;
- }
- }
-
- axiom_xpath_cast_string(node1, context);
- axiom_xpath_cast_string(node2, context);
-
- if (axutil_strcmp(
- (axis2_char_t *)(node1->value),
- (axis2_char_t *)(node2->value)) == 0)
- {
- return AXIS2_TRUE;
- }
- else
- {
- return AXIS2_FALSE;
- }
-}
-
-/* Operators */
-
-/* Literal */
-int axiom_xpath_literal_operator(
- axiom_xpath_context_t *context,
- axiom_xpath_operation_t * op)
-{
- axiom_xpath_result_node_t *node;
-
- node = AXIS2_MALLOC(context->env->allocator,
- sizeof(axiom_xpath_result_node_t));
-
- /* Set the context node to NULL */
- /* This is not required; it gives some problems */
- /* context->node = NULL;*/
-
- node->value = op->par1;
- node->type = AXIOM_XPATH_TYPE_TEXT;
-
- axutil_stack_push(context->stack, context->env, node);
-
- return 1;
-}
-
-/* Number */
-int axiom_xpath_number_operator(
- axiom_xpath_context_t *context,
- axiom_xpath_operation_t * op)
-{
- axiom_xpath_result_node_t *node;
-
- node = AXIS2_MALLOC(context->env->allocator,
- sizeof(axiom_xpath_result_node_t));
-
- /* Set the context node to NULL */
- /* This is not required; it gives some problems */
- /* context->node = NULL;*/
-
- node->value = op->par1;
- node->type = AXIOM_XPATH_TYPE_NUMBER;
-
- axutil_stack_push(context->stack, context->env, node);
-
- return 1;
-}
-
-/* Path Expression */
-int axiom_xpath_path_expression_operator(
- axiom_xpath_context_t *context,
- axiom_xpath_operation_t * op)
-{
- int filter_res_n, n_nodes = 0;
- axiom_xpath_operation_t *rel_loc_op;
- axiom_xpath_operator_t rel_loc_func;
- axutil_array_list_t *arr;
- axiom_xpath_result_node_t *res_node;
- int i;
-
- /* Filter operation */
- if (op->op1 == AXIOM_XPATH_PARSE_END)
- {
- return 0;
- }
-
- filter_res_n = axiom_xpath_evaluate_operation(context, op->op1);
-
- /* Relative location path */
- if (op->op2 == AXIOM_XPATH_PARSE_END)
- {
- return filter_res_n;
- }
-
- rel_loc_op = AXIOM_XPATH_OPR_GET(op->op2);
- rel_loc_func = axiom_xpath_get_operator(rel_loc_op);
-
- /* Array list to add all results from the filter expression */
- arr = axutil_array_list_create(context->env, 0);
-
- for (i = 0; i < filter_res_n; i++)
- {
- axutil_array_list_add(
- arr,
- context->env,
- axutil_stack_pop(context->stack, context->env));
- }
-
- /* Evaluate relative location path for all results from the
- filter expression */
- for (i = 0; i < axutil_array_list_size(arr, context->env); i++)
- {
- res_node =
- (axiom_xpath_result_node_t *)axutil_array_list_get(
- arr, context->env, i);
-
- if (res_node->type != AXIOM_XPATH_TYPE_NODE)
- {
- continue;
- }
-
- context->node = (axiom_node_t *)res_node->value;
- context->position = i + 1;
- context->size = filter_res_n;
-
- n_nodes += rel_loc_func(context, rel_loc_op);
- }
-
- return n_nodes;
-}
-
-/* Equal Expression */
-int axiom_xpath_equalexpr_operator(
- axiom_xpath_context_t *context,
- axiom_xpath_operation_t * op)
-{
- axiom_xpath_result_node_t *node;
- int n_nodes[2];
- int i, j;
- int op12[2];
- axutil_array_list_t *arr[2];
-
- op12[0] = op->op1;
- op12[1] = op->op2;
-
- /* Evaluate both operands and get number of results */
- for (i = 0; i < 2; i++)
- {
- if (op12[i] == AXIOM_XPATH_PARSE_END)
- {
- continue;
- }
-
- n_nodes[i] = axiom_xpath_evaluate_operation(context, op12[i]);
- }
-
-
- for (i = 1; i >= 0; i--)
- {
- arr[i] = axutil_array_list_create(context->env, 0);
-
- for (j = 0; j < n_nodes[i]; j++)
- {
- axutil_array_list_add(
- arr[i],
- context->env,
- axutil_stack_pop(context->stack, context->env));
- }
- }
-
- node = AXIS2_MALLOC(context->env->allocator,
- sizeof(axiom_xpath_result_node_t));
-
- node->type = AXIOM_XPATH_TYPE_BOOLEAN;
- node->value = NULL;
-
- /* Checking equality
- - If any node from the first set is equal to any node from the second set
- the result is true */
- for (i = 0; i < n_nodes[0]; i++)
- {
- for (j = 0; j < n_nodes[1]; j++)
- {
- if (axiom_xpath_compare_equal(
- axutil_array_list_get(arr[0], context->env, i),
- axutil_array_list_get(arr[1], context->env, j),
- context))
- {
- AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, AXIS2_TRUE);
-
- axutil_stack_push(context->stack, context->env, node);
-
- return 1;
- }
- }
- }
-
- AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, AXIS2_FALSE);
-
- axutil_stack_push(context->stack, context->env, node);
-
- return 1;
-}
-
-/* Union */
-int axiom_xpath_union_operator(
- axiom_xpath_context_t *context,
- axiom_xpath_operation_t * op)
-{
- int n_nodes = 0;
- int i;
- int op12[2];
-
- op12[0] = op->op1;
- op12[1] = op->op2;
-
- for (i = 0; i < 2; i++)
- {
- if (op12[i] == AXIOM_XPATH_PARSE_END)
- {
- continue;
- }
-
- n_nodes += axiom_xpath_evaluate_operation(context, op12[i]);
- }
-
- return n_nodes;
-}
-
-/* Set context node depending on whether relative or absolute location path */
-int axiom_xpath_start_node_operator(
- axiom_xpath_context_t *context,
- axiom_xpath_operation_t * op)
-{
- int n_nodes = 0;
-
- if (op->op1 == AXIOM_XPATH_PARSE_END)
- {
- return 0;
- }
-
- if (op->opr == AXIOM_XPATH_OPERATION_ROOT_NODE)
- {
- context->node = context->root_node;
- n_nodes += axiom_xpath_evaluate_operation(context, op->op1);
- }
- else if (op->opr == AXIOM_XPATH_OPERATION_CONTEXT_NODE)
- {
- n_nodes += axiom_xpath_evaluate_operation(context, op->op1);
- }
-
- return n_nodes;
-}
-
-/* Step */
-int axiom_xpath_step_operator(
- axiom_xpath_context_t *context,
- axiom_xpath_operation_t * op)
-{
- axiom_xpath_operation_t * node_test_op;
- axiom_xpath_iterator_t iter;
- axiom_xpath_axis_t axis;
-
- if (op->op1 == AXIOM_XPATH_PARSE_END)
- {
-#ifdef AXIOM_XPATH_DEBUG
- printf("Node test operator empty\n");
-#endif
-
- return AXIOM_XPATH_EVALUATION_ERROR;
- }
-
- if (op->op2 == AXIOM_XPATH_PARSE_END)
- {
- return 0;
- }
-
- /* Get the name */
- node_test_op = AXIOM_XPATH_OPR_GET(op->op1);
-
- /* Get the axis */
- if (!node_test_op->par2)
- {
-#ifdef AXIOM_XPATH_DEBUG
- printf("axis is NULL in the step operator\n");
-#endif
- return AXIOM_XPATH_EVALUATION_ERROR;
- }
- axis = *((axiom_xpath_axis_t *)node_test_op->par2);
-
-
- /* Get the iteration for the axis */
- iter = axiom_xpath_get_iterator(axis);
-
- return iter(context,
- op->op1 /* node test */,
- op->op2 /* next step */,
- node_test_op->op1 /* predicate */);
-}
-
-/* Predicates */
-axis2_bool_t axiom_xpath_evaluate_predicate_condition(
- axiom_xpath_context_t *context,
- int n_nodes)
-{
- axiom_xpath_result_node_t *res;
- int i;
-
- if (n_nodes <= 0)
- {
- return AXIS2_FALSE;
- }
- else if (n_nodes > 1)
- {
- for (i = 0; i < n_nodes; i++)
- {
- axutil_stack_pop(context->stack, context->env);
- }
-
- return AXIS2_TRUE;
- }
- else
- {
- res = (axiom_xpath_result_node_t *)axutil_stack_pop(
- context->stack, context->env);
-
- if (res->type == AXIOM_XPATH_TYPE_NUMBER)
- {
- if (*(double *)(res->value) == context->position)
- {
- return AXIS2_TRUE;
- }
- else
- {
- return AXIS2_FAILURE;
- }
- }
- else if (res->type == AXIOM_XPATH_TYPE_BOOLEAN)
- {
- return *(axis2_bool_t *)(res->value);
- }
- else
- {
- return AXIS2_TRUE;
- }
- }
-}
-
-/* Predicate */
-int axiom_xpath_evaluate_predicate(
- axiom_xpath_context_t *context,
- int op_next,
- int op_predicate)
-{
- int n_res;
- axis2_bool_t res;
-
- axiom_xpath_operation_t * pred_op;
- axiom_node_t *context_node = context->node;
-
- if (op_predicate == AXIOM_XPATH_PARSE_END)
- {
- return axiom_xpath_evaluate_operation(context, op_next);
- }
- else
- {
- pred_op = AXIOM_XPATH_OPR_GET(op_predicate);
-
- pred_op->pos++;
-
- /* Evaluate the predicate */
- if (pred_op->op1 != AXIOM_XPATH_PARSE_END)
- {
- n_res = axiom_xpath_evaluate_operation(context, pred_op->op1);
- context->position = pred_op->pos;
-
- res = axiom_xpath_evaluate_predicate_condition(context, n_res);
- }
- else
- {
- res = AXIS2_TRUE;
- }
- /* A PredicateExpr is evaluated by evaluating the Expr and
- converting the result to a boolean. If the result is a number,
- the result will be converted to true if the number is equal to the
- context position and will be converted to false otherwise; if the
- result is not a number, then the result will be converted as if
- by a call to the boolean function. */
-
- /* Transform the result to number or boolean ? */
-
- if (res)
- {
- context->node = context_node;
-
- return axiom_xpath_evaluate_predicate(
- context, op_next, pred_op->op2);
- }
- }
-
- return 0;
-}
-
-/* Node test match */
-axis2_bool_t axiom_xpath_node_test_match(
- axiom_xpath_context_t *context,
- axiom_xpath_node_test_t *node_test)
-{
- axiom_types_t type;
- axiom_element_t *element = NULL;
- axis2_char_t *name = NULL;
- axiom_namespace_t *ns = NULL, *xpath_ns = NULL;
-
- if (!context->node && !context->attribute && !context->ns)
- {
-#ifdef AXIOM_XPATH_DEBUG
- printf("Both context node and attribute are NULL.");
- printf(" May be a literal or a number.\n");
-#endif
- return AXIS2_FALSE;
- }
- else if (context->node)
- {
- /* Test if the node matches */
- type = axiom_node_get_node_type(context->node, context->env);
-
- if (type == AXIOM_ELEMENT)
- {
- element = axiom_node_get_data_element(
- context->node, context->env);
-
- name = axiom_element_get_localname(
- element, context->env);
-
- ns = axiom_element_get_namespace(
- element, context->env, context->node);
- }
-
- if (node_test->type == AXIOM_XPATH_NODE_TEST_NONE)
- {
- return AXIS2_FALSE;
- }
- else
- {
- if (node_test->type == AXIOM_XPATH_NODE_TEST_ALL
- || node_test->type == AXIOM_XPATH_NODE_TEST_STANDARD)
- {
- if (type != AXIOM_ELEMENT)
- {
- return AXIS2_FALSE;
- }
-
- /* Check namespace */
- if (node_test->type == AXIOM_XPATH_NODE_TEST_ALL)
- {
- if (!ns && node_test->prefix)
- {
- return AXIS2_FALSE;
- }
- }
- else
- {
- if ((ns && !node_test->prefix)
- || (!ns && node_test->prefix))
- {
- return AXIS2_FALSE;
- }
- }
-
- if (ns && node_test->prefix)
- {
- xpath_ns =
- axiom_xpath_get_namespace(context, node_test->prefix);
-
- if (!xpath_ns)
- {
- return AXIS2_FALSE;
- }
-
- if (axutil_strcmp(
- axiom_namespace_get_uri(ns, context->env),
- axiom_namespace_get_uri(xpath_ns, context->env)))
- {
- return AXIS2_FALSE;
- }
- }
-
- /* Check local name */
- if (node_test->type == AXIOM_XPATH_NODE_TEST_ALL)
- {
- return AXIS2_TRUE;
- }
- else if (node_test->type == AXIOM_XPATH_NODE_TEST_STANDARD)
- {
- if (name && axutil_strcmp(node_test->name, name) == 0)
- {
- return AXIS2_TRUE;
- }
- else
- {
- return AXIS2_FALSE;
- }
- }
- }
- else if (node_test->type == AXIOM_XPATH_NODE_TYPE_COMMENT)
- {
- if (type == AXIOM_COMMENT)
- {
- return AXIS2_TRUE;
- }
- else
- {
- return AXIS2_FALSE;
- }
- }
- else if (node_test->type == AXIOM_XPATH_NODE_TYPE_PI)
- {
- if (type == AXIOM_PROCESSING_INSTRUCTION)
- {
- return AXIS2_TRUE;
- }
- else
- {
- return AXIS2_FALSE;
- }
- }
- else if (node_test->type == AXIOM_XPATH_NODE_TYPE_NODE)
- {
- if (type == AXIOM_ELEMENT)
- {
- return AXIS2_TRUE;
- }
- else
- {
- return AXIS2_FALSE;
- }
- }
- else if (node_test->type == AXIOM_XPATH_NODE_TYPE_TEXT)
- {
- if (type == AXIOM_TEXT)
- {
- return AXIS2_TRUE;
- }
- else
- {
- return AXIS2_FALSE;
- }
- }
- }
- }
- /* Attributes */
- else if (context->attribute)
- {
- name = axiom_attribute_get_localname(context->attribute, context->env);
- ns = axiom_attribute_get_namespace(context->attribute, context->env);
-
- if (node_test->type == AXIOM_XPATH_NODE_TEST_NONE)
- {
- return AXIS2_FALSE;
- }
- else
- {
- /* Check namespace */
- if (node_test->type == AXIOM_XPATH_NODE_TEST_ALL)
- {
- if (!ns && node_test->prefix)
- {
- return AXIS2_FALSE;
- }
- }
- else
- {
- if ((ns && !node_test->prefix) || (!ns && node_test->prefix))
- {
- return AXIS2_FALSE;
- }
- }
-
- if (ns && node_test->prefix)
- {
- xpath_ns =
- axiom_xpath_get_namespace(context, node_test->prefix);
-
- if (!xpath_ns)
- {
- return AXIS2_FALSE;
- }
-
- if (axutil_strcmp(axiom_namespace_get_uri(ns, context->env),
- axiom_namespace_get_uri(xpath_ns, context->env)))
- {
- return AXIS2_FALSE;
- }
- }
-
- /* Check local name */
- if (node_test->type == AXIOM_XPATH_NODE_TEST_ALL)
- {
- return AXIS2_TRUE;
- }
- else if (node_test->type == AXIOM_XPATH_NODE_TEST_STANDARD)
- {
- if (name && axutil_strcmp(node_test->name, name) == 0)
- {
- return AXIS2_TRUE;
- }
- else
- {
- return AXIS2_FALSE;
- }
- }
- }
- }
-
- /* Namespace */
- else if (context->ns)
- {
- /* Prefix is checked ??? If changed to uri the cast
- method in xpath.c needs to be changed as well */
- name = axiom_namespace_get_prefix(context->ns, context->env);
- ns = NULL;
-
- if (node_test->type == AXIOM_XPATH_NODE_TEST_NONE)
- {
- return AXIS2_FALSE;
- }
- else
- {
- /* Check namespace */
- if (node_test->type == AXIOM_XPATH_NODE_TEST_ALL)
- {
- if (!ns && node_test->prefix)
- {
- return AXIS2_FALSE;
- }
- }
- else
- {
- if ((ns && !node_test->prefix) || (!ns && node_test->prefix))
- {
- return AXIS2_FALSE;
- }
- }
-
- if (ns && node_test->prefix)
- {
- xpath_ns =
- axiom_xpath_get_namespace(context, node_test->prefix);
-
- if (!xpath_ns)
- {
- return AXIS2_FALSE;
- }
-
- if (axutil_strcmp(axiom_namespace_get_uri(ns, context->env),
- axiom_namespace_get_uri(xpath_ns, context->env)))
- {
- return AXIS2_FALSE;
- }
- }
-
- /* Check local name */
- if (node_test->type == AXIOM_XPATH_NODE_TEST_ALL)
- {
- return AXIS2_TRUE;
- }
- else if (node_test->type == AXIOM_XPATH_NODE_TEST_STANDARD)
- {
- if (name && axutil_strcmp(node_test->name, name) == 0)
- {
- return AXIS2_TRUE;
- }
- else
- {
- return AXIS2_FALSE;
- }
- }
- }
- }
-
- return AXIS2_FALSE;
-}
-
-int axiom_xpath_function_call_operator(
- axiom_xpath_context_t *context,
- axiom_xpath_operation_t * op)
-{
- axiom_xpath_function_t func = axiom_xpath_get_function(context, op->par1);
- int n_args = 0;
-
- if (!func)
- {
-#ifdef AXIOM_XPATH_DEBUG
- printf("Function %s not found\n", (char *)op->par1);
-#endif
-
- return AXIOM_XPATH_EVALUATION_ERROR;
- }
-
- if (op->op1 != AXIOM_XPATH_PARSE_END)
- {
- n_args = axiom_xpath_evaluate_operation(context, op->op1);
- }
-
- return func(context, n_args);
-}
-
-int axiom_xpath_argument_operator(
- axiom_xpath_context_t *context,
- axiom_xpath_operation_t * op)
-{
- int n_args = 0;
-
- if (op->op1 != AXIOM_XPATH_PARSE_END)
- {
- n_args += axiom_xpath_evaluate_operation(context, op->op1);
- }
-
- if (op->op2 != AXIOM_XPATH_PARSE_END)
- {
- n_args += axiom_xpath_evaluate_operation(context, op->op1);
- }
-
- return n_args;
-}
-
-/* Collect the current node to the results list */
-int axiom_xpath_collect_operator(
- axiom_xpath_context_t *context,
- axiom_xpath_operation_t * op)
-{
- axiom_xpath_result_node_t *node;
-
- node = AXIS2_MALLOC(context->env->allocator,
- sizeof(axiom_xpath_result_node_t));
-
- if (context->node)
- {
- if (context->streaming)
- {
- node->value = axiom_node_detach(context->node, context->env);
- }
- else
- {
- node->value = context->node;
- }
- node->type = AXIOM_XPATH_TYPE_NODE;
- }
- else if (context->attribute)
- {
- if (context->streaming)
- {
- node->value =
- axiom_attribute_clone(context->attribute, context->env);
- }
- else
- {
- node->value = context->attribute;
- }
- node->type = AXIOM_XPATH_TYPE_ATTRIBUTE;
- }
- else if (context->ns)
- {
- if (context->streaming)
- {
- node->value = axiom_namespace_clone(context->ns, context->env);
- }
- else
- {
- node->value = context->ns;
- }
- node->type = AXIOM_XPATH_TYPE_NAMESPACE;
- }
-
- axutil_stack_push(context->stack, context->env, node);
-
- return 1;
-}
-
-/* Returns a pointer to the respective processing function */
-axiom_xpath_operator_t axiom_xpath_get_operator(axiom_xpath_operation_t * op)
-{
- switch (op->opr)
- {
- case AXIOM_XPATH_OPERATION_STEP:
- return axiom_xpath_step_operator;
-
- case AXIOM_XPATH_OPERATION_ROOT_NODE:
- case AXIOM_XPATH_OPERATION_CONTEXT_NODE:
- return axiom_xpath_start_node_operator;
-
- case AXIOM_XPATH_OPERATION_RESULT:
- return axiom_xpath_collect_operator;
-
- case AXIOM_XPATH_OPERATION_UNION:
- return axiom_xpath_union_operator;
-
- case AXIOM_XPATH_OPERATION_EQUAL_EXPR:
- return axiom_xpath_equalexpr_operator;
-
- case AXIOM_XPATH_OPERATION_LITERAL:
- return axiom_xpath_literal_operator;
-
- case AXIOM_XPATH_OPERATION_NUMBER:
- return axiom_xpath_number_operator;
-
- case AXIOM_XPATH_OPERATION_PATH_EXPRESSION:
- return axiom_xpath_path_expression_operator;
-
- case AXIOM_XPATH_OPERATION_FUNCTION_CALL:
- return axiom_xpath_function_call_operator;
-
- case AXIOM_XPATH_OPERATION_ARGUMENT:
- return axiom_xpath_argument_operator;
-
- default:
-#ifdef AXIOM_XPATH_DEBUG
- printf("Unidentified operation.\n");
-#endif
-
- return NULL;
- }
-}
-
-/* Returns a pointer to the respective processing function */
-axiom_xpath_iterator_t axiom_xpath_get_iterator(axiom_xpath_axis_t axis)
-{
- switch (axis)
- {
- case AXIOM_XPATH_AXIS_CHILD:
- return axiom_xpath_child_iterator;
-
- case AXIOM_XPATH_AXIS_DESCENDANT:
- return axiom_xpath_descendant_iterator;
-
- case AXIOM_XPATH_AXIS_PARENT:
- return axiom_xpath_parent_iterator;
-
- case AXIOM_XPATH_AXIS_ANCESTOR:
- return axiom_xpath_ancestor_iterator;
-
- case AXIOM_XPATH_AXIS_FOLLOWING_SIBLING:
- return axiom_xpath_following_sibling_iterator;
-
- case AXIOM_XPATH_AXIS_PRECEDING_SIBLING:
- return axiom_xpath_preceding_sibling_iterator;
-
- case AXIOM_XPATH_AXIS_FOLLOWING:
- return axiom_xpath_following_iterator;
-
- case AXIOM_XPATH_AXIS_PRECEDING:
- return axiom_xpath_preceding_iterator;
-
- case AXIOM_XPATH_AXIS_ATTRIBUTE:
- return axiom_xpath_attribute_iterator;
-
- case AXIOM_XPATH_AXIS_NAMESPACE:
- return axiom_xpath_namespace_iterator;
-
- case AXIOM_XPATH_AXIS_SELF:
- return axiom_xpath_self_iterator;
-
- case AXIOM_XPATH_AXIS_DESCENDANT_OR_SELF:
- return axiom_xpath_descendant_self_iterator;
-
- case AXIOM_XPATH_AXIS_ANCESTOR_OR_SELF:
- return axiom_xpath_ancestor_self_iterator;
-
- default:
-#ifdef AXIOM_XPATH_DEBUG
- printf("Unidentified axis.\n");
-#endif
-
- return NULL;
- }
-}
-
-int axiom_xpath_evaluate_operation(axiom_xpath_context_t *context, int op)
-{
- axiom_xpath_operation_t * operation;
- axiom_xpath_operator_t function;
-
- /* Get a pointer to the operation */
- operation = AXIOM_XPATH_OPR_GET(op);
-
- /* Get the funciton which processes the operations */
- function = axiom_xpath_get_operator(operation);
-
- return function(context, operation);
-}
+
+/*
+ * 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 "xpath.h"
+#include "xpath_internals.h"
+#include "xpath_internals_engine.h"
+#include "xpath_internals_iterators.h"
+
+/* Evaluates the expath expression */
+axiom_xpath_result_t * axiom_xpath_run(axiom_xpath_context_t *context)
+{
+ axiom_xpath_result_t* res;
+
+ /* Initialize result ret */
+ res = AXIS2_MALLOC(context->env->allocator,
+ sizeof(axiom_xpath_result_t));
+
+ res->flag = 0;
+
+ res->nodes = axutil_array_list_create(context->env, 0);
+
+ context->stack = axutil_stack_create(context->env);
+
+ /* Expression is empty */
+ if (context->expr->start == AXIOM_XPATH_PARSE_END)
+ {
+ return res;
+ }
+
+ axiom_xpath_evaluate_operation(context, context->expr->start);
+
+ /* Add nodes to the result set from the stack */
+ while (axutil_stack_size(context->stack, context->env) > 0)
+ {
+ axutil_array_list_add(
+ res->nodes, context->env,
+ axutil_stack_pop(context->stack, context->env));
+ }
+
+ return res;
+}
+
+/* Casting functions; these make use of the casting functions defined in xpath.h */
+void axiom_xpath_cast_boolean(
+ axiom_xpath_result_node_t *node,
+ axiom_xpath_context_t *context)
+{
+ AXIOM_XPATH_CAST_SET_VALUE(
+ axis2_bool_t, axiom_xpath_cast_node_to_boolean(context->env, node));
+
+ node->type = AXIOM_XPATH_TYPE_BOOLEAN;
+}
+
+void axiom_xpath_cast_number(
+ axiom_xpath_result_node_t *node,
+ axiom_xpath_context_t *context)
+{
+ AXIOM_XPATH_CAST_SET_VALUE(
+ double, axiom_xpath_cast_node_to_number(context->env, node));
+
+ node->type = AXIOM_XPATH_TYPE_NUMBER;
+}
+
+void axiom_xpath_cast_string(
+ axiom_xpath_result_node_t *node,
+ axiom_xpath_context_t *context)
+{
+ node->value = axiom_xpath_cast_node_to_string(context->env, node);
+
+ node->type = AXIOM_XPATH_TYPE_TEXT;
+}
+
+/* Evaluate whether two results are equal
+ TODO: Comment */
+axis2_bool_t axiom_xpath_compare_equal(
+ axiom_xpath_result_node_t *node1,
+ axiom_xpath_result_node_t *node2,
+ axiom_xpath_context_t *context)
+{
+ if (node1->type == AXIOM_XPATH_TYPE_BOOLEAN
+ || node2->type == AXIOM_XPATH_TYPE_BOOLEAN)
+ {
+ axiom_xpath_cast_boolean(node1, context);
+ axiom_xpath_cast_boolean(node2, context);
+
+ if (*(axis2_bool_t*)(node1->value) == *(axis2_bool_t*)(node2->value))
+ {
+ return AXIS2_TRUE;
+ }
+ else
+ {
+ return AXIS2_FALSE;
+ }
+ }
+
+ if (node1->type == AXIOM_XPATH_TYPE_NUMBER
+ || node2->type == AXIOM_XPATH_TYPE_NUMBER)
+ {
+ axiom_xpath_cast_number(node1, context);
+ axiom_xpath_cast_number(node2, context);
+
+ if (*(double *)(node1->value) == *(double *)(node2->value))
+ {
+ return AXIS2_TRUE;
+ }
+ else
+ {
+ return AXIS2_FALSE;
+ }
+ }
+
+ axiom_xpath_cast_string(node1, context);
+ axiom_xpath_cast_string(node2, context);
+
+ if (axutil_strcmp(
+ (axis2_char_t *)(node1->value),
+ (axis2_char_t *)(node2->value)) == 0)
+ {
+ return AXIS2_TRUE;
+ }
+ else
+ {
+ return AXIS2_FALSE;
+ }
+}
+
+/* Operators */
+
+/* Literal */
+int axiom_xpath_literal_operator(
+ axiom_xpath_context_t *context,
+ axiom_xpath_operation_t * op)
+{
+ axiom_xpath_result_node_t *node;
+
+ node = AXIS2_MALLOC(context->env->allocator,
+ sizeof(axiom_xpath_result_node_t));
+
+ /* Set the context node to NULL */
+ /* This is not required; it gives some problems */
+ /* context->node = NULL;*/
+
+ node->value = op->par1;
+ node->type = AXIOM_XPATH_TYPE_TEXT;
+
+ axutil_stack_push(context->stack, context->env, node);
+
+ return 1;
+}
+
+/* Number */
+int axiom_xpath_number_operator(
+ axiom_xpath_context_t *context,
+ axiom_xpath_operation_t * op)
+{
+ axiom_xpath_result_node_t *node;
+
+ node = AXIS2_MALLOC(context->env->allocator,
+ sizeof(axiom_xpath_result_node_t));
+
+ /* Set the context node to NULL */
+ /* This is not required; it gives some problems */
+ /* context->node = NULL;*/
+
+ node->value = op->par1;
+ node->type = AXIOM_XPATH_TYPE_NUMBER;
+
+ axutil_stack_push(context->stack, context->env, node);
+
+ return 1;
+}
+
+/* Path Expression */
+int axiom_xpath_path_expression_operator(
+ axiom_xpath_context_t *context,
+ axiom_xpath_operation_t * op)
+{
+ int filter_res_n, n_nodes = 0;
+ axiom_xpath_operation_t *rel_loc_op;
+ axiom_xpath_operator_t rel_loc_func;
+ axutil_array_list_t *arr;
+ axiom_xpath_result_node_t *res_node;
+ int i;
+
+ /* Filter operation */
+ if (op->op1 == AXIOM_XPATH_PARSE_END)
+ {
+ return 0;
+ }
+
+ filter_res_n = axiom_xpath_evaluate_operation(context, op->op1);
+
+ /* Relative location path */
+ if (op->op2 == AXIOM_XPATH_PARSE_END)
+ {
+ return filter_res_n;
+ }
+
+ rel_loc_op = AXIOM_XPATH_OPR_GET(op->op2);
+ rel_loc_func = axiom_xpath_get_operator(rel_loc_op);
+
+ /* Array list to add all results from the filter expression */
+ arr = axutil_array_list_create(context->env, 0);
+
+ for (i = 0; i < filter_res_n; i++)
+ {
+ axutil_array_list_add(
+ arr,
+ context->env,
+ axutil_stack_pop(context->stack, context->env));
+ }
+
+ /* Evaluate relative location path for all results from the
+ filter expression */
+ for (i = 0; i < axutil_array_list_size(arr, context->env); i++)
+ {
+ res_node =
+ (axiom_xpath_result_node_t *)axutil_array_list_get(
+ arr, context->env, i);
+
+ if (res_node->type != AXIOM_XPATH_TYPE_NODE)
+ {
+ continue;
+ }
+
+ context->node = (axiom_node_t *)res_node->value;
+ context->position = i + 1;
+ context->size = filter_res_n;
+
+ n_nodes += rel_loc_func(context, rel_loc_op);
+ }
+
+ return n_nodes;
+}
+
+/* Equal Expression */
+int axiom_xpath_equalexpr_operator(
+ axiom_xpath_context_t *context,
+ axiom_xpath_operation_t * op)
+{
+ axiom_xpath_result_node_t *node;
+ int n_nodes[2];
+ int i, j;
+ int op12[2];
+ axutil_array_list_t *arr[2];
+
+ op12[0] = op->op1;
+ op12[1] = op->op2;
+
+ /* Evaluate both operands and get number of results */
+ for (i = 0; i < 2; i++)
+ {
+ if (op12[i] == AXIOM_XPATH_PARSE_END)
+ {
+ continue;
+ }
+
+ n_nodes[i] = axiom_xpath_evaluate_operation(context, op12[i]);
+ }
+
+
+ for (i = 1; i >= 0; i--)
+ {
+ arr[i] = axutil_array_list_create(context->env, 0);
+
+ for (j = 0; j < n_nodes[i]; j++)
+ {
+ axutil_array_list_add(
+ arr[i],
+ context->env,
+ axutil_stack_pop(context->stack, context->env));
+ }
+ }
+
+ node = AXIS2_MALLOC(context->env->allocator,
+ sizeof(axiom_xpath_result_node_t));
+
+ node->type = AXIOM_XPATH_TYPE_BOOLEAN;
+ node->value = NULL;
+
+ /* Checking equality
+ - If any node from the first set is equal to any node from the second set
+ the result is true */
+ for (i = 0; i < n_nodes[0]; i++)
+ {
+ for (j = 0; j < n_nodes[1]; j++)
+ {
+ if (axiom_xpath_compare_equal(
+ axutil_array_list_get(arr[0], context->env, i),
+ axutil_array_list_get(arr[1], context->env, j),
+ context))
+ {
+ AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, AXIS2_TRUE);
+
+ axutil_stack_push(context->stack, context->env, node);
+
+ return 1;
+ }
+ }
+ }
+
+ AXIOM_XPATH_CAST_SET_VALUE(axis2_bool_t, AXIS2_FALSE);
+
+ axutil_stack_push(context->stack, context->env, node);
+
+ return 1;
+}
+
+/* Union */
+int axiom_xpath_union_operator(
+ axiom_xpath_context_t *context,
+ axiom_xpath_operation_t * op)
+{
+ int n_nodes = 0;
+ int i;
+ int op12[2];
+
+ op12[0] = op->op1;
+ op12[1] = op->op2;
+
+ for (i = 0; i < 2; i++)
+ {
+ if (op12[i] == AXIOM_XPATH_PARSE_END)
+ {
+ continue;
+ }
+
+ n_nodes += axiom_xpath_evaluate_operation(context, op12[i]);
+ }
+
+ return n_nodes;
+}
+
+/* Set context node depending on whether relative or absolute location path */
+int axiom_xpath_start_node_operator(
+ axiom_xpath_context_t *context,
+ axiom_xpath_operation_t * op)
+{
+ int n_nodes = 0;
+
+ if (op->op1 == AXIOM_XPATH_PARSE_END)
+ {
+ return 0;
+ }
+
+ if (op->opr == AXIOM_XPATH_OPERATION_ROOT_NODE)
+ {
+ context->node = context->root_node;
+ n_nodes += axiom_xpath_evaluate_operation(context, op->op1);
+ }
+ else if (op->opr == AXIOM_XPATH_OPERATION_CONTEXT_NODE)
+ {
+ n_nodes += axiom_xpath_evaluate_operation(context, op->op1);
+ }
+
+ return n_nodes;
+}
+
+/* Step */
+int axiom_xpath_step_operator(
+ axiom_xpath_context_t *context,
+ axiom_xpath_operation_t * op)
+{
+ axiom_xpath_operation_t * node_test_op;
+ axiom_xpath_iterator_t iter;
+ axiom_xpath_axis_t axis;
+
+ if (op->op1 == AXIOM_XPATH_PARSE_END)
+ {
+#ifdef AXIOM_XPATH_DEBUG
+ printf("Node test operator empty\n");
+#endif
+
+ return AXIOM_XPATH_EVALUATION_ERROR;
+ }
+
+ if (op->op2 == AXIOM_XPATH_PARSE_END)
+ {
+ return 0;
+ }
+
+ /* Get the name */
+ node_test_op = AXIOM_XPATH_OPR_GET(op->op1);
+
+ /* Get the axis */
+ if (!node_test_op->par2)
+ {
+#ifdef AXIOM_XPATH_DEBUG
+ printf("axis is NULL in the step operator\n");
+#endif
+ return AXIOM_XPATH_EVALUATION_ERROR;
+ }
+ axis = *((axiom_xpath_axis_t *)node_test_op->par2);
+
+
+ /* Get the iteration for the axis */
+ iter = axiom_xpath_get_iterator(axis);
+
+ return iter(context,
+ op->op1 /* node test */,
+ op->op2 /* next step */,
+ node_test_op->op1 /* predicate */);
+}
+
+/* Predicates */
+axis2_bool_t axiom_xpath_evaluate_predicate_condition(
+ axiom_xpath_context_t *context,
+ int n_nodes)
+{
+ axiom_xpath_result_node_t *res;
+ int i;
+
+ if (n_nodes <= 0)
+ {
+ return AXIS2_FALSE;
+ }
+ else if (n_nodes > 1)
+ {
+ for (i = 0; i < n_nodes; i++)
+ {
+ axutil_stack_pop(context->stack, context->env);
+ }
+
+ return AXIS2_TRUE;
+ }
+ else
+ {
+ res = (axiom_xpath_result_node_t *)axutil_stack_pop(
+ context->stack, context->env);
+
+ if (res->type == AXIOM_XPATH_TYPE_NUMBER)
+ {
+ if (*(double *)(res->value) == context->position)
+ {
+ return AXIS2_TRUE;
+ }
+ else
+ {
+ return AXIS2_FAILURE;
+ }
+ }
+ else if (res->type == AXIOM_XPATH_TYPE_BOOLEAN)
+ {
+ return *(axis2_bool_t *)(res->value);
+ }
+ else
+ {
+ return AXIS2_TRUE;
+ }
+ }
+}
+
+/* Predicate */
+int axiom_xpath_evaluate_predicate(
+ axiom_xpath_context_t *context,
+ int op_next,
+ int op_predicate)
+{
+ int n_res;
+ axis2_bool_t res;
+
+ axiom_xpath_operation_t * pred_op;
+ axiom_node_t *context_node = context->node;
+
+ if (op_predicate == AXIOM_XPATH_PARSE_END)
+ {
+ return axiom_xpath_evaluate_operation(context, op_next);
+ }
+ else
+ {
+ pred_op = AXIOM_XPATH_OPR_GET(op_predicate);
+
+ pred_op->pos++;
+
+ /* Evaluate the predicate */
+ if (pred_op->op1 != AXIOM_XPATH_PARSE_END)
+ {
+ n_res = axiom_xpath_evaluate_operation(context, pred_op->op1);
+ context->position = pred_op->pos;
+
+ res = axiom_xpath_evaluate_predicate_condition(context, n_res);
+ }
+ else
+ {
+ res = AXIS2_TRUE;
+ }
+ /* A PredicateExpr is evaluated by evaluating the Expr and
+ converting the result to a boolean. If the result is a number,
+ the result will be converted to true if the number is equal to the
+ context position and will be converted to false otherwise; if the
+ result is not a number, then the result will be converted as if
+ by a call to the boolean function. */
+
+ /* Transform the result to number or boolean ? */
+
+ if (res)
+ {
+ context->node = context_node;
+
+ return axiom_xpath_evaluate_predicate(
+ context, op_next, pred_op->op2);
+ }
+ }
+
+ return 0;
+}
+
+/* Node test match */
+axis2_bool_t axiom_xpath_node_test_match(
+ axiom_xpath_context_t *context,
+ axiom_xpath_node_test_t *node_test)
+{
+ axiom_types_t type;
+ axiom_element_t *element = NULL;
+ axis2_char_t *name = NULL;
+ axiom_namespace_t *ns = NULL, *xpath_ns = NULL;
+
+ if (!context->node && !context->attribute && !context->ns)
+ {
+#ifdef AXIOM_XPATH_DEBUG
+ printf("Both context node and attribute are NULL.");
+ printf(" May be a literal or a number.\n");
+#endif
+ return AXIS2_FALSE;
+ }
+ else if (context->node)
+ {
+ /* Test if the node matches */
+ type = axiom_node_get_node_type(context->node, context->env);
+
+ if (type == AXIOM_ELEMENT)
+ {
+ element = axiom_node_get_data_element(
+ context->node, context->env);
+
+ name = axiom_element_get_localname(
+ element, context->env);
+
+ ns = axiom_element_get_namespace(
+ element, context->env, context->node);
+ }
+
+ if (node_test->type == AXIOM_XPATH_NODE_TEST_NONE)
+ {
+ return AXIS2_FALSE;
+ }
+ else
+ {
+ if (node_test->type == AXIOM_XPATH_NODE_TEST_ALL
+ || node_test->type == AXIOM_XPATH_NODE_TEST_STANDARD)
+ {
+ if (type != AXIOM_ELEMENT)
+ {
+ return AXIS2_FALSE;
+ }
+
+ /* Check namespace */
+ if (node_test->type == AXIOM_XPATH_NODE_TEST_ALL)
+ {
+ if (!ns && node_test->prefix)
+ {
+ return AXIS2_FALSE;
+ }
+ }
+ else
+ {
+ if ((ns && !node_test->prefix)
+ || (!ns && node_test->prefix))
+ {
+ return AXIS2_FALSE;
+ }
+ }
+
+ if (ns && node_test->prefix)
+ {
+ xpath_ns =
+ axiom_xpath_get_namespace(context, node_test->prefix);
+
+ if (!xpath_ns)
+ {
+ return AXIS2_FALSE;
+ }
+
+ if (axutil_strcmp(
+ axiom_namespace_get_uri(ns, context->env),
+ axiom_namespace_get_uri(xpath_ns, context->env)))
+ {
+ return AXIS2_FALSE;
+ }
+ }
+
+ /* Check local name */
+ if (node_test->type == AXIOM_XPATH_NODE_TEST_ALL)
+ {
+ return AXIS2_TRUE;
+ }
+ else if (node_test->type == AXIOM_XPATH_NODE_TEST_STANDARD)
+ {
+ if (name && axutil_strcmp(node_test->name, name) == 0)
+ {
+ return AXIS2_TRUE;
+ }
+ else
+ {
+ return AXIS2_FALSE;
+ }
+ }
+ }
+ else if (node_test->type == AXIOM_XPATH_NODE_TYPE_COMMENT)
+ {
+ if (type == AXIOM_COMMENT)
+ {
+ return AXIS2_TRUE;
+ }
+ else
+ {
+ return AXIS2_FALSE;
+ }
+ }
+ else if (node_test->type == AXIOM_XPATH_NODE_TYPE_PI)
+ {
+ if (type == AXIOM_PROCESSING_INSTRUCTION)
+ {
+ return AXIS2_TRUE;
+ }
+ else
+ {
+ return AXIS2_FALSE;
+ }
+ }
+ else if (node_test->type == AXIOM_XPATH_NODE_TYPE_NODE)
+ {
+ if (type == AXIOM_ELEMENT)
+ {
+ return AXIS2_TRUE;
+ }
+ else
+ {
+ return AXIS2_FALSE;
+ }
+ }
+ else if (node_test->type == AXIOM_XPATH_NODE_TYPE_TEXT)
+ {
+ if (type == AXIOM_TEXT)
+ {
+ return AXIS2_TRUE;
+ }
+ else
+ {
+ return AXIS2_FALSE;
+ }
+ }
+ }
+ }
+ /* Attributes */
+ else if (context->attribute)
+ {
+ name = axiom_attribute_get_localname(context->attribute, context->env);
+ ns = axiom_attribute_get_namespace(context->attribute, context->env);
+
+ if (node_test->type == AXIOM_XPATH_NODE_TEST_NONE)
+ {
+ return AXIS2_FALSE;
+ }
+ else
+ {
+ /* Check namespace */
+ if (node_test->type == AXIOM_XPATH_NODE_TEST_ALL)
+ {
+ if (!ns && node_test->prefix)
+ {
+ return AXIS2_FALSE;
+ }
+ }
+ else
+ {
+ if ((ns && !node_test->prefix) || (!ns && node_test->prefix))
+ {
+ return AXIS2_FALSE;
+ }
+ }
+
+ if (ns && node_test->prefix)
+ {
+ xpath_ns =
+ axiom_xpath_get_namespace(context, node_test->prefix);
+
+ if (!xpath_ns)
+ {
+ return AXIS2_FALSE;
+ }
+
+ if (axutil_strcmp(axiom_namespace_get_uri(ns, context->env),
+ axiom_namespace_get_uri(xpath_ns, context->env)))
+ {
+ return AXIS2_FALSE;
+ }
+ }
+
+ /* Check local name */
+ if (node_test->type == AXIOM_XPATH_NODE_TEST_ALL)
+ {
+ return AXIS2_TRUE;
+ }
+ else if (node_test->type == AXIOM_XPATH_NODE_TEST_STANDARD)
+ {
+ if (name && axutil_strcmp(node_test->name, name) == 0)
+ {
+ return AXIS2_TRUE;
+ }
+ else
+ {
+ return AXIS2_FALSE;
+ }
+ }
+ }
+ }
+
+ /* Namespace */
+ else if (context->ns)
+ {
+ /* Prefix is checked ??? If changed to uri the cast
+ method in xpath.c needs to be changed as well */
+ name = axiom_namespace_get_prefix(context->ns, context->env);
+ ns = NULL;
+
+ if (node_test->type == AXIOM_XPATH_NODE_TEST_NONE)
+ {
+ return AXIS2_FALSE;
+ }
+ else
+ {
+ /* Check namespace */
+ if (node_test->type == AXIOM_XPATH_NODE_TEST_ALL)
+ {
+ if (!ns && node_test->prefix)
+ {
+ return AXIS2_FALSE;
+ }
+ }
+ else
+ {
+ if ((ns && !node_test->prefix) || (!ns && node_test->prefix))
+ {
+ return AXIS2_FALSE;
+ }
+ }
+
+ if (ns && node_test->prefix)
+ {
+ xpath_ns =
+ axiom_xpath_get_namespace(context, node_test->prefix);
+
+ if (!xpath_ns)
+ {
+ return AXIS2_FALSE;
+ }
+
+ if (axutil_strcmp(axiom_namespace_get_uri(ns, context->env),
+ axiom_namespace_get_uri(xpath_ns, context->env)))
+ {
+ return AXIS2_FALSE;
+ }
+ }
+
+ /* Check local name */
+ if (node_test->type == AXIOM_XPATH_NODE_TEST_ALL)
+ {
+ return AXIS2_TRUE;
+ }
+ else if (node_test->type == AXIOM_XPATH_NODE_TEST_STANDARD)
+ {
+ if (name && axutil_strcmp(node_test->name, name) == 0)
+ {
+ return AXIS2_TRUE;
+ }
+ else
+ {
+ return AXIS2_FALSE;
+ }
+ }
+ }
+ }
+
+ return AXIS2_FALSE;
+}
+
+int axiom_xpath_function_call_operator(
+ axiom_xpath_context_t *context,
+ axiom_xpath_operation_t * op)
+{
+ axiom_xpath_function_t func = axiom_xpath_get_function(context, op->par1);
+ int n_args = 0;
+
+ if (!func)
+ {
+#ifdef AXIOM_XPATH_DEBUG
+ printf("Function %s not found\n", (char *)op->par1);
+#endif
+
+ return AXIOM_XPATH_EVALUATION_ERROR;
+ }
+
+ if (op->op1 != AXIOM_XPATH_PARSE_END)
+ {
+ n_args = axiom_xpath_evaluate_operation(context, op->op1);
+ }
+
+ return func(context, n_args);
+}
+
+int axiom_xpath_argument_operator(
+ axiom_xpath_context_t *context,
+ axiom_xpath_operation_t * op)
+{
+ int n_args = 0;
+
+ if (op->op1 != AXIOM_XPATH_PARSE_END)
+ {
+ n_args += axiom_xpath_evaluate_operation(context, op->op1);
+ }
+
+ if (op->op2 != AXIOM_XPATH_PARSE_END)
+ {
+ n_args += axiom_xpath_evaluate_operation(context, op->op1);
+ }
+
+ return n_args;
+}
+
+/* Collect the current node to the results list */
+int axiom_xpath_collect_operator(
+ axiom_xpath_context_t *context,
+ axiom_xpath_operation_t * op)
+{
+ axiom_xpath_result_node_t *node;
+
+ node = AXIS2_MALLOC(context->env->allocator,
+ sizeof(axiom_xpath_result_node_t));
+
+ if (context->node)
+ {
+ if (context->streaming)
+ {
+ node->value = axiom_node_detach(context->node, context->env);
+ }
+ else
+ {
+ node->value = context->node;
+ }
+ node->type = AXIOM_XPATH_TYPE_NODE;
+ }
+ else if (context->attribute)
+ {
+ if (context->streaming)
+ {
+ node->value =
+ axiom_attribute_clone(context->attribute, context->env);
+ }
+ else
+ {
+ node->value = context->attribute;
+ }
+ node->type = AXIOM_XPATH_TYPE_ATTRIBUTE;
+ }
+ else if (context->ns)
+ {
+ if (context->streaming)
+ {
+ node->value = axiom_namespace_clone(context->ns, context->env);
+ }
+ else
+ {
+ node->value = context->ns;
+ }
+ node->type = AXIOM_XPATH_TYPE_NAMESPACE;
+ }
+
+ axutil_stack_push(context->stack, context->env, node);
+
+ return 1;
+}
+
+/* Returns a pointer to the respective processing function */
+axiom_xpath_operator_t axiom_xpath_get_operator(axiom_xpath_operation_t * op)
+{
+ switch (op->opr)
+ {
+ case AXIOM_XPATH_OPERATION_STEP:
+ return axiom_xpath_step_operator;
+
+ case AXIOM_XPATH_OPERATION_ROOT_NODE:
+ case AXIOM_XPATH_OPERATION_CONTEXT_NODE:
+ return axiom_xpath_start_node_operator;
+
+ case AXIOM_XPATH_OPERATION_RESULT:
+ return axiom_xpath_collect_operator;
+
+ case AXIOM_XPATH_OPERATION_UNION:
+ return axiom_xpath_union_operator;
+
+ case AXIOM_XPATH_OPERATION_EQUAL_EXPR:
+ return axiom_xpath_equalexpr_operator;
+
+ case AXIOM_XPATH_OPERATION_LITERAL:
+ return axiom_xpath_literal_operator;
+
+ case AXIOM_XPATH_OPERATION_NUMBER:
+ return axiom_xpath_number_operator;
+
+ case AXIOM_XPATH_OPERATION_PATH_EXPRESSION:
+ return axiom_xpath_path_expression_operator;
+
+ case AXIOM_XPATH_OPERATION_FUNCTION_CALL:
+ return axiom_xpath_function_call_operator;
+
+ case AXIOM_XPATH_OPERATION_ARGUMENT:
+ return axiom_xpath_argument_operator;
+
+ default:
+#ifdef AXIOM_XPATH_DEBUG
+ printf("Unidentified operation.\n");
+#endif
+
+ return NULL;
+ }
+}
+
+/* Returns a pointer to the respective processing function */
+axiom_xpath_iterator_t axiom_xpath_get_iterator(axiom_xpath_axis_t axis)
+{
+ switch (axis)
+ {
+ case AXIOM_XPATH_AXIS_CHILD:
+ return axiom_xpath_child_iterator;
+
+ case AXIOM_XPATH_AXIS_DESCENDANT:
+ return axiom_xpath_descendant_iterator;
+
+ case AXIOM_XPATH_AXIS_PARENT:
+ return axiom_xpath_parent_iterator;
+
+ case AXIOM_XPATH_AXIS_ANCESTOR:
+ return axiom_xpath_ancestor_iterator;
+
+ case AXIOM_XPATH_AXIS_FOLLOWING_SIBLING:
+ return axiom_xpath_following_sibling_iterator;
+
+ case AXIOM_XPATH_AXIS_PRECEDING_SIBLING:
+ return axiom_xpath_preceding_sibling_iterator;
+
+ case AXIOM_XPATH_AXIS_FOLLOWING:
+ return axiom_xpath_following_iterator;
+
+ case AXIOM_XPATH_AXIS_PRECEDING:
+ return axiom_xpath_preceding_iterator;
+
+ case AXIOM_XPATH_AXIS_ATTRIBUTE:
+ return axiom_xpath_attribute_iterator;
+
+ case AXIOM_XPATH_AXIS_NAMESPACE:
+ return axiom_xpath_namespace_iterator;
+
+ case AXIOM_XPATH_AXIS_SELF:
+ return axiom_xpath_self_iterator;
+
+ case AXIOM_XPATH_AXIS_DESCENDANT_OR_SELF:
+ return axiom_xpath_descendant_self_iterator;
+
+ case AXIOM_XPATH_AXIS_ANCESTOR_OR_SELF:
+ return axiom_xpath_ancestor_self_iterator;
+
+ default:
+#ifdef AXIOM_XPATH_DEBUG
+ printf("Unidentified axis.\n");
+#endif
+
+ return NULL;
+ }
+}
+
+int axiom_xpath_evaluate_operation(axiom_xpath_context_t *context, int op)
+{
+ axiom_xpath_operation_t * operation;
+ axiom_xpath_operator_t function;
+
+ /* Get a pointer to the operation */
+ operation = AXIOM_XPATH_OPR_GET(op);
+
+ /* Get the funciton which processes the operations */
+ function = axiom_xpath_get_operator(operation);
+
+ return function(context, operation);
+}
Modified: webservices/axis2/trunk/c/axiom/src/xpath/xpath_internals_engine.h
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/c/axiom/src/xpath/xpath_internals_engine.h?rev=719381&r1=719380&r2=719381&view=diff
==============================================================================
--- webservices/axis2/trunk/c/axiom/src/xpath/xpath_internals_engine.h (original)
+++ webservices/axis2/trunk/c/axiom/src/xpath/xpath_internals_engine.h Thu Nov 20 13:26:08 2008
@@ -1,234 +1,234 @@
-
-/*
- * 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.
- */
-
-#ifndef XPATH_INTERNALS_ENGINE_H
-#define XPATH_INTERNALS_ENGINE_H
-
-#include "xpath_internals.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
- /**
- * @defgroup axiom_xpath_engine engine
- * @ingroup axiom_xpath
- * @{
- */
-
-
- /* Macros */
-
- /** Set node->value to _value */
-#define AXIOM_XPATH_CAST_SET_VALUE(type, _value) { \
- type * _var; \
- if(node->value) { AXIS2_FREE(context->env->allocator, node->value); } \
- _var = AXIS2_MALLOC(context->env->allocator, sizeof(type)); \
- *_var = _value; \
- node->value = (void *) _var; \
-}
-
- /* Functions */
-
- /**
- * Evaluate an XPath context, which containes a parsed expression
- *
- * @param context XPath context
- * @return Result set
- */
- axiom_xpath_result_t* axiom_xpath_run(axiom_xpath_context_t *context);
-
- /**
- * Finds the operator function for a given operation
- *
- * @param op Operation
- * @return Pointer to the function which process the given operation
- */
- axiom_xpath_operator_t axiom_xpath_get_operator(axiom_xpath_operation_t * op);
-
- /**
- * Get the iterotor for give axis
- *
- * @param axis XPath axis
- * @return Pointer to the function which iterater through the given axis
- */
- axiom_xpath_iterator_t axiom_xpath_get_iterator(axiom_xpath_axis_t axis);
-
- /* Operators */
-
- /**
- * Select the start node depending on whether it is an absolute or relative location path
- *
- * @param context XPath context
- * @param op XPath operation
- * @return Number of nodes added to the stack
- */
- int axiom_xpath_start_node_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op);
-
- /**
- * Add the context node or attribute to the results stack
- *
- * @param context XPath context
- * @param op XPath operation
- * @return Number of nodes added to the stack
- */
- int axiom_xpath_collect_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op);
-
- /**
- * Process union operator
- *
- * @param context XPath context
- * @param op XPath operation
- * @return Number of nodes added to the stack
- */
- int axiom_xpath_union_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op);
-
- /**
- * Perform equality test operation
- *
- * @param context XPath context
- * @param op XPath operation
- * @return Number of nodes added to the stack; which is one
- */
- int axiom_xpath_equalexpr_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op);
-
- /**
- * Evaluate function call operation
- *
- * @param context XPath context
- * @param op XPath operation
- * @return Number of nodes added to the stack; which is one
- */
- int axiom_xpath_function_call_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op);
-
- /**
- * Evaluate argument operation
- *
- * @param context XPath context
- * @param op XPath operation
- * @return Number of nodes added to the stack; which is one
- */
- int axiom_xpath_argument_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op);
-
- /**
- * Process a path expression
- *
- * @param context XPath context
- * @param op XPath operation
- * @return Number of nodes added to the stack
- */
- int axiom_xpath_path_expression_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op);
-
- /**
- * Process a number; push the value to the stack
- *
- * @param context XPath context
- * @param op XPath operation
- * @return Number of nodes added to the stack; which is one
- */
- int axiom_xpath_number_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op);
-
- /**
- * Process a literal; push the string to the stack
- *
- * @param context XPath context
- * @param op XPath operation
- * @return Number of nodes added to the stack; which is one
- */
- int axiom_xpath_literal_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op);
-
-
- /**
- * Converts an XPath result to a boolean result
- *
- * @param node Result
- * @param context XPath context
- */
- void axiom_xpath_cast_boolean(axiom_xpath_result_node_t *node, axiom_xpath_context_t *context);
-
- /**
- * Converts an XPath result to a number
- *
- * @param node Result
- * @param context XPath context
- */
- void axiom_xpath_cast_number(axiom_xpath_result_node_t *node, axiom_xpath_context_t *context);
-
- /**
- * Converts an XPath result to a string
- *
- * @param node Result
- * @param context XPath context
- */
- void axiom_xpath_cast_string(axiom_xpath_result_node_t *node, axiom_xpath_context_t *context);
-
- /**
- * Test if two result nodes are equal
- *
- * @param node1 First node
- * @param node2 Second node
- * @param context XPath context
- * @return AXIS2_TRUE if equal; AXIS2_FALSE otherwise
- */
- axis2_bool_t axiom_xpath_compare_equal(axiom_xpath_result_node_t *node1, axiom_xpath_result_node_t *node2, axiom_xpath_context_t *context);
-
- /**
- * Test if the axiom node matches node test
- *
- * @param context XPath context
- * @param node_test Node test
- * @return AXIS2_TRUE if matches; AXIS2_FALSE otherwise
- */
- axis2_bool_t axiom_xpath_node_test_match(axiom_xpath_context_t *context, axiom_xpath_node_test_t *node_test);
-
- /**
- * Evaluate if the predicate is true
- *
- * @param context XPath context
- * @param n_nodes Number of results after evaluating the expression in the predicate
- * @return AXIS2_TRUE if matches; AXIS2_FALSE otherwise
- */
- axis2_bool_t axiom_xpath_evaluate_predicate_condition(axiom_xpath_context_t *context, int n_nodes);
-
- /**
- * Evaluate if the predicate(s) is true using axiom_xpath_evaluate_predicate_condition and executes the operation op_next
- *
- * @param context XPath context
- * @param op_next The operation to be executed if all predicates are true
- * @param op_predicate Reference to predicate
- * @return Number of nodes added to the stack
- */
- int axiom_xpath_evaluate_predicate(axiom_xpath_context_t *context, int op_next, int op_predicate);
-
- /**
- * Evaluate operation pointed by op
- *
- * @param context XPath context
- * @param op The index of the operation in the operations list
- * @return Number of nodes added to the stack
- */
- int axiom_xpath_evaluate_operation(axiom_xpath_context_t *context, int op);
-
- /** @} */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+
+/*
+ * 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.
+ */
+
+#ifndef XPATH_INTERNALS_ENGINE_H
+#define XPATH_INTERNALS_ENGINE_H
+
+#include "xpath_internals.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ /**
+ * @defgroup axiom_xpath_engine engine
+ * @ingroup axiom_xpath
+ * @{
+ */
+
+
+ /* Macros */
+
+ /** Set node->value to _value */
+#define AXIOM_XPATH_CAST_SET_VALUE(type, _value) { \
+ type * _var; \
+ if(node->value) { AXIS2_FREE(context->env->allocator, node->value); } \
+ _var = AXIS2_MALLOC(context->env->allocator, sizeof(type)); \
+ *_var = _value; \
+ node->value = (void *) _var; \
+}
+
+ /* Functions */
+
+ /**
+ * Evaluate an XPath context, which containes a parsed expression
+ *
+ * @param context XPath context
+ * @return Result set
+ */
+ axiom_xpath_result_t* axiom_xpath_run(axiom_xpath_context_t *context);
+
+ /**
+ * Finds the operator function for a given operation
+ *
+ * @param op Operation
+ * @return Pointer to the function which process the given operation
+ */
+ axiom_xpath_operator_t axiom_xpath_get_operator(axiom_xpath_operation_t * op);
+
+ /**
+ * Get the iterotor for give axis
+ *
+ * @param axis XPath axis
+ * @return Pointer to the function which iterater through the given axis
+ */
+ axiom_xpath_iterator_t axiom_xpath_get_iterator(axiom_xpath_axis_t axis);
+
+ /* Operators */
+
+ /**
+ * Select the start node depending on whether it is an absolute or relative location path
+ *
+ * @param context XPath context
+ * @param op XPath operation
+ * @return Number of nodes added to the stack
+ */
+ int axiom_xpath_start_node_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op);
+
+ /**
+ * Add the context node or attribute to the results stack
+ *
+ * @param context XPath context
+ * @param op XPath operation
+ * @return Number of nodes added to the stack
+ */
+ int axiom_xpath_collect_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op);
+
+ /**
+ * Process union operator
+ *
+ * @param context XPath context
+ * @param op XPath operation
+ * @return Number of nodes added to the stack
+ */
+ int axiom_xpath_union_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op);
+
+ /**
+ * Perform equality test operation
+ *
+ * @param context XPath context
+ * @param op XPath operation
+ * @return Number of nodes added to the stack; which is one
+ */
+ int axiom_xpath_equalexpr_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op);
+
+ /**
+ * Evaluate function call operation
+ *
+ * @param context XPath context
+ * @param op XPath operation
+ * @return Number of nodes added to the stack; which is one
+ */
+ int axiom_xpath_function_call_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op);
+
+ /**
+ * Evaluate argument operation
+ *
+ * @param context XPath context
+ * @param op XPath operation
+ * @return Number of nodes added to the stack; which is one
+ */
+ int axiom_xpath_argument_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op);
+
+ /**
+ * Process a path expression
+ *
+ * @param context XPath context
+ * @param op XPath operation
+ * @return Number of nodes added to the stack
+ */
+ int axiom_xpath_path_expression_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op);
+
+ /**
+ * Process a number; push the value to the stack
+ *
+ * @param context XPath context
+ * @param op XPath operation
+ * @return Number of nodes added to the stack; which is one
+ */
+ int axiom_xpath_number_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op);
+
+ /**
+ * Process a literal; push the string to the stack
+ *
+ * @param context XPath context
+ * @param op XPath operation
+ * @return Number of nodes added to the stack; which is one
+ */
+ int axiom_xpath_literal_operator(axiom_xpath_context_t *context, axiom_xpath_operation_t * op);
+
+
+ /**
+ * Converts an XPath result to a boolean result
+ *
+ * @param node Result
+ * @param context XPath context
+ */
+ void axiom_xpath_cast_boolean(axiom_xpath_result_node_t *node, axiom_xpath_context_t *context);
+
+ /**
+ * Converts an XPath result to a number
+ *
+ * @param node Result
+ * @param context XPath context
+ */
+ void axiom_xpath_cast_number(axiom_xpath_result_node_t *node, axiom_xpath_context_t *context);
+
+ /**
+ * Converts an XPath result to a string
+ *
+ * @param node Result
+ * @param context XPath context
+ */
+ void axiom_xpath_cast_string(axiom_xpath_result_node_t *node, axiom_xpath_context_t *context);
+
+ /**
+ * Test if two result nodes are equal
+ *
+ * @param node1 First node
+ * @param node2 Second node
+ * @param context XPath context
+ * @return AXIS2_TRUE if equal; AXIS2_FALSE otherwise
+ */
+ axis2_bool_t axiom_xpath_compare_equal(axiom_xpath_result_node_t *node1, axiom_xpath_result_node_t *node2, axiom_xpath_context_t *context);
+
+ /**
+ * Test if the axiom node matches node test
+ *
+ * @param context XPath context
+ * @param node_test Node test
+ * @return AXIS2_TRUE if matches; AXIS2_FALSE otherwise
+ */
+ axis2_bool_t axiom_xpath_node_test_match(axiom_xpath_context_t *context, axiom_xpath_node_test_t *node_test);
+
+ /**
+ * Evaluate if the predicate is true
+ *
+ * @param context XPath context
+ * @param n_nodes Number of results after evaluating the expression in the predicate
+ * @return AXIS2_TRUE if matches; AXIS2_FALSE otherwise
+ */
+ axis2_bool_t axiom_xpath_evaluate_predicate_condition(axiom_xpath_context_t *context, int n_nodes);
+
+ /**
+ * Evaluate if the predicate(s) is true using axiom_xpath_evaluate_predicate_condition and executes the operation op_next
+ *
+ * @param context XPath context
+ * @param op_next The operation to be executed if all predicates are true
+ * @param op_predicate Reference to predicate
+ * @return Number of nodes added to the stack
+ */
+ int axiom_xpath_evaluate_predicate(axiom_xpath_context_t *context, int op_next, int op_predicate);
+
+ /**
+ * Evaluate operation pointed by op
+ *
+ * @param context XPath context
+ * @param op The index of the operation in the operations list
+ * @return Number of nodes added to the stack
+ */
+ int axiom_xpath_evaluate_operation(axiom_xpath_context_t *context, int op);
+
+ /** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif