cexternal_functions.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zorba/zorbac.h>
#include <zorba/store_manager_c.h>
typedef struct
{
unsigned int i;
} my_ext_data;
void
my_ext_fct_init(void** user_data, void* function_user_data)
{
my_ext_data* data;
*user_data = malloc(sizeof(my_ext_data));
data = (my_ext_data*)(*user_data);
data->i = 0;
}
XQC_Error
my_ext_fct_next(XQC_Sequence** args, unsigned int argc,
Zorba_ItemSetter* setter, void* user_data, void* function_data)
{
my_ext_data* data = (my_ext_data*) user_data;
while (data->i < argc) {
XQC_Sequence* lSeq = args[data->i];
XQC_ItemType lItemType;
if ( (lSeq->next(lSeq)) == XQC_END_OF_SEQUENCE) {
data->i++;
continue;
}
lSeq->item_type(lSeq, &lItemType);
switch (lItemType) {
case XQC_DECIMAL_TYPE: {
int lValue;
lSeq->integer_value(lSeq, &lValue);
setter->set_integer(setter, lValue);
break;
}
case XQC_DOUBLE_TYPE: {
double lValue;
lSeq->double_value(lSeq, &lValue);
setter->set_double(setter, lValue);
break;
}
case XQC_STRING_TYPE: {
const char* lValue;
lSeq->string_value(lSeq, &lValue);
setter->set_string(setter, lValue);
break;
}
case XQC_ANY_URI_TYPE:
case XQC_DATE_TYPE:
case XQC_DATE_TIME_TYPE:
case XQC_DURATION_TYPE:
case XQC_FLOAT_TYPE:
case XQC_G_DAY_TYPE:
case XQC_G_MONTH_TYPE:
case XQC_G_MONTH_DAY_TYPE:
case XQC_G_YEAR_TYPE:
case XQC_G_YEAR_MONTH_TYPE:
case XQC_TIME_TYPE: {
const char* lValue;
lSeq->string_value(lSeq, &lValue);
setter->set_typed_value(setter, lItemType, lValue);
break;
}
default:
printf("Unsupported type %d\n", lItemType);
break;
}
return XQC_NO_ERROR;
}
return XQC_END_OF_SEQUENCE;
}
void
my_ext_fct_free(void* user_data, void* function_user_data)
{
my_ext_data* data = (my_ext_data*)(user_data);
free(data);
}
int
external_function_example_1(XQC_Implementation* impl)
{
XQC_Expression* lExpr;
XQC_StaticContext* lContext;
Zorba_StaticContext* lZContext;
XQC_Sequence* lSeq;
impl->create_context(impl, &lContext);
lZContext = (Zorba_StaticContext*)
lContext->get_interface(lContext, "Zorba_StaticContext");
lZContext->register_external_function(lZContext, "urn:foo", "bar",
my_ext_fct_init, my_ext_fct_next, my_ext_fct_free, impl);
impl->prepare(impl,
"declare namespace foo=\"urn:foo\";\n"
"declare function foo:bar($x, $y, $z) external;\n"
"( foo:bar((1, 2, 3), \"2.57\", xs:double(2.57)),\n"
" foo:bar(xs:date(\"2010-01-13\"), xs:gYear(\"1984\"), xs:float(2.57)) )",
lContext, &lExpr);
lExpr->execute(lExpr, NULL, &lSeq);
while ( lSeq->next(lSeq) == XQC_NO_ERROR ) {
XQC_ItemType lItemType;
lSeq->item_type(lSeq, &lItemType);
switch (lItemType) {
case XQC_DECIMAL_TYPE: {
int lValue;
lSeq->integer_value(lSeq, &lValue);
printf("[int] %d\n", lValue);
break;
}
case XQC_DOUBLE_TYPE: {
double lValue;
lSeq->double_value(lSeq, &lValue);
printf("[double] %f\n", lValue);
break;
}
case XQC_STRING_TYPE: {
const char* lValue;
lSeq->string_value(lSeq, &lValue);
printf("[string] %s\n", lValue);
break;
}
case XQC_ANY_URI_TYPE:
case XQC_DATE_TYPE:
case XQC_DATE_TIME_TYPE:
case XQC_DURATION_TYPE:
case XQC_FLOAT_TYPE:
case XQC_G_DAY_TYPE:
case XQC_G_MONTH_TYPE:
case XQC_G_MONTH_DAY_TYPE:
case XQC_G_YEAR_TYPE:
case XQC_G_YEAR_MONTH_TYPE:
case XQC_TIME_TYPE: {
const char* lValue;
const char* lTypename;
lSeq->type_name(lSeq, &lValue, &lTypename);
lSeq->string_value(lSeq, &lValue);
printf("[typed_value %s] %s\n", lTypename, lValue);
break;
}
default:
printf("Unsupported type %d\n", lItemType);
break;
}
}
printf("\n");
lSeq->free(lSeq);
lExpr->free(lExpr);
lContext->free(lContext);
return 1;
}
int
cexternal_functions(int argc, char** argv)
{
int res = 0;
XQC_Implementation* impl;
void* store = create_store();
if ( zorba_implementation(&impl, store) != XQC_NO_ERROR)
return 1;
printf("executing C example 1\n");
res = external_function_example_1(impl);
if (!res) { impl->free(impl); return 1; };
printf("\n");
impl->free(impl);
shutdown_store(store);
return 0;
}