rendered paste body/* Copyright (C) 2006 MySQL AB 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; version 2 of the License. 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */#include <drizzled/server_includes.h>#include <drizzled/session.h>#include <drizzled/function/str/strfunc.h>#include <drizzled/util/convert.h>#include <stdio.h>#include <stdlib.h>#include <libxml/tree.h>#include <libxml/parser.h>#include <libxml/xpath.h>#include <libxml/xpathInternals.h>#include <zlib.h>int count_xpath_expression(const char* contents, const xmlChar* xpathExpr, const xmlChar* nsList);int register_namespaces(xmlXPathContextPtr xpathCtx, const xmlChar* nsList);class Item_func_uncompress: public Item_str_func{ String buffer;public: Item_func_uncompress(): Item_str_func(){} void fix_length_and_dec(){ maybe_null= 1; max_length= MAX_BLOB_WIDTH; } const char *func_name() const{return "uncompress";} String *val_str(String *) ;};String *Item_func_uncompress::val_str(String *str){ assert(fixed == 1); String *res= args[0]->val_str(str); int resint = 0; const char* contents = (const char *) "<?xml version=\"1.0\"?><EXAMPLE prop1=\"gnome is great\" prop2=\"& linux too\"> <head> <title>Welcome to Gnome</title> </head> <chapter> <title>The Linux adventure</title> <p>bla bla bla ...</p> <image href=\"linus.gif\"/> <p>...</p> </chapter> <chapter> <title>The Linux adventure</title> <p>bla bla bla ...</p> <image href=\"linus.gif\"/> <p>...</p> </chapter></EXAMPLE>"; const xmlChar* expression = (const xmlChar*) "//p"; const xmlChar* list = NULL; char buffer [50]; /* Init libxml */ xmlInitParser(); LIBXML_TEST_VERSION /* Do the main job */ //printf("size %d\n", count_xpath_expression(contents, BAD_CAST expression, NULL)); resint= sprintf(buffer, "%s", (const char *) count_xpath_expression(contents, expression, list)); //char *retchar= to_string( resint ); res= to_string(resint); /* Shutdown libxml */ xmlCleanupParser(); /* * this is to debug memory for regression tests */ // xmlMemoryDump(); //free(contents); //free(expression); return res;}int count_xpath_expression(const char* contents, const xmlChar* xpathExpr, const xmlChar* nsList) { xmlDocPtr doc; xmlXPathContextPtr xpathCtx; xmlXPathObjectPtr xpathObj; int count = 0; assert(contents); assert(xpathExpr); /* Load XML document */ doc = xmlParseMemory(contents, strlen(contents)); if (doc == NULL) { fprintf(stderr, "Error: unable to parse contents: \"%s\"\n", contents); return(-1); } /* Create xpath evaluation context */ xpathCtx = xmlXPathNewContext(doc); if(xpathCtx == NULL) { fprintf(stderr,"Error: unable to create new XPath context\n"); xmlFreeDoc(doc); return(-1); } /* Register namespaces from list (if any) */ if((nsList != NULL) && (register_namespaces(xpathCtx, nsList) < 0)) { fprintf(stderr,"Error: failed to register namespaces list \"%s\"\n", nsList); xmlXPathFreeContext(xpathCtx); xmlFreeDoc(doc); return(NULL); } /* Evaluate xpath expression */ xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx); if(xpathObj == NULL) { fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", xpathExpr); xmlXPathFreeContext(xpathCtx); xmlFreeDoc(doc); return(-1); } /* Print results */ count = xpathObj->nodesetval->nodeNr; // print_xpath_nodes(xpathObj->nodesetval, stdout); /* Cleanup */ xmlXPathFreeObject(xpathObj); xmlXPathFreeContext(xpathCtx); xmlFreeDoc(doc); return(count);}int register_namespaces(xmlXPathContextPtr xpathCtx, const xmlChar* nsList) { xmlChar* nsListDup; xmlChar* prefix; xmlChar* href; xmlChar* next; assert(xpathCtx); assert(nsList); nsListDup = xmlStrdup(nsList); if(nsListDup == NULL) { fprintf(stderr, "Error: unable to strdup namespaces list\n"); return(-1); } next = nsListDup; while(next != NULL) { /* skip spaces */ while((*next) == ' ') next++; if((*next) == '\0') break; /* find prefix */ prefix = next; next = (xmlChar*)xmlStrchr(next, '='); if(next == NULL) { fprintf(stderr,"Error: invalid namespaces list format\n"); xmlFree(nsListDup); return(-1); } *(next++) = '\0'; /* find href */ href = next; next = (xmlChar*)xmlStrchr(next, ' '); if(next != NULL) { *(next++) = '\0'; } /* do register namespace */ if(xmlXPathRegisterNs(xpathCtx, prefix, href) != 0) { fprintf(stderr,"Error: unable to register NS with prefix=\"%s\" and href=\"%s\"\n", prefix, href); xmlFree(nsListDup); return(-1); } } xmlFree(nsListDup); return(0);}Item_func* create_uncompressudf_item(MEM_ROOT* m){ return new (m) Item_func_uncompress();}static struct udf_func uncompressudf = { { C_STRING_WITH_LEN("uncompress") }, create_uncompressudf_item};static int uncompressudf_plugin_init(void *p){ udf_func **f = (udf_func**) p; *f= &uncompressudf; return 0;}static int uncompressudf_plugin_deinit(void *p){ udf_func *udff = (udf_func *) p; (void)udff; return 0;}mysql_declare_plugin(uncompress){ DRIZZLE_UDF_PLUGIN, "uncompress", "1.0", "Stewart Smith", "UDF for compress()", PLUGIN_LICENSE_GPL, uncompressudf_plugin_init, /* Plugin Init */ uncompressudf_plugin_deinit, /* Plugin Deinit */ NULL, /* status variables */ NULL, /* system variables */ NULL /* config options */}mysql_declare_plugin_end;