diff options
Diffstat (limited to 'src/expat_erl.c')
-rw-r--r-- | src/expat_erl.c | 287 |
1 files changed, 0 insertions, 287 deletions
diff --git a/src/expat_erl.c b/src/expat_erl.c deleted file mode 100644 index 02d41ed33..000000000 --- a/src/expat_erl.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * ejabberd, Copyright (C) 2002-2013 ProcessOne - * - * 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; either version 2 of the - * License, or (at your option) any later version. - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - * - */ - - -#include <stdio.h> -#include <string.h> -#include <erl_driver.h> -#include <ei.h> -#include <expat.h> - - -#define XML_START 0 -#define XML_END 1 -#define XML_CDATA 2 -#define XML_ERROR 3 - -#define PARSE_COMMAND 0 -#define PARSE_FINAL_COMMAND 1 - -/* - * R15B changed several driver callbacks to use ErlDrvSizeT and - * ErlDrvSSizeT typedefs instead of int. - * This provides missing typedefs on older OTP versions. - */ -#if ERL_DRV_EXTENDED_MAJOR_VERSION < 2 -typedef int ErlDrvSizeT; -typedef int ErlDrvSSizeT; -#endif - -ei_x_buff event_buf; -ei_x_buff xmlns_buf; - -typedef struct { - ErlDrvPort port; - XML_Parser parser; -} expat_data; - -static XML_Memory_Handling_Suite ms; - -void encode_name(const XML_Char *name) -{ - char *name_start; - char *prefix_start; - char *buf; - int name_len, prefix_len, buf_len; - - if ((name_start = strchr(name, '\n'))) { - if ((prefix_start = strchr(name_start+1, '\n'))) { - name_len = prefix_start - name_start; - prefix_len = strlen(prefix_start+1); - buf_len = prefix_len + name_len; - buf = driver_alloc(buf_len); - memcpy(buf, prefix_start+1, prefix_len); - memcpy(buf+prefix_len, name_start, name_len); - buf[prefix_len] = ':'; - ei_x_encode_binary(&event_buf, buf, buf_len); - driver_free(buf); - } else { - ei_x_encode_binary(&event_buf, name_start+1, strlen(name_start+1)); - }; - } else { - ei_x_encode_binary(&event_buf, name, strlen(name)); - } -} - -void *erlXML_StartElementHandler(expat_data *d, - const XML_Char *name, - const XML_Char **atts) -{ - int i; - - ei_x_encode_list_header(&event_buf, 1); - ei_x_encode_tuple_header(&event_buf, 2); - ei_x_encode_long(&event_buf, XML_START); - ei_x_encode_tuple_header(&event_buf, 2); - encode_name(name); - ei_x_append(&event_buf, &xmlns_buf); - ei_x_free(&xmlns_buf); - ei_x_new(&xmlns_buf); - - for (i = 0; atts[i]; i += 2) {} - - if (i > 0) - { - ei_x_encode_list_header(&event_buf, i/2); - - for (i = 0; atts[i]; i += 2) - { - ei_x_encode_tuple_header(&event_buf, 2); - encode_name(atts[i]); - ei_x_encode_binary(&event_buf, atts[i+1], strlen(atts[i+1])); - } - } - - ei_x_encode_empty_list(&event_buf); - - return NULL; -} - -void *erlXML_EndElementHandler(expat_data *d, - const XML_Char *name) -{ - ei_x_encode_list_header(&event_buf, 1); - ei_x_encode_tuple_header(&event_buf, 2); - ei_x_encode_long(&event_buf, XML_END); - encode_name(name); - return NULL; -} - -void *erlXML_CharacterDataHandler(expat_data *d, - const XML_Char *s, - int len) -{ - ei_x_encode_list_header(&event_buf, 1); - ei_x_encode_tuple_header(&event_buf, 2); - ei_x_encode_long(&event_buf, XML_CDATA); - ei_x_encode_binary(&event_buf, s, len); - return NULL; -} - -void *erlXML_StartNamespaceDeclHandler(expat_data *d, - const XML_Char *prefix, - const XML_Char *uri) -{ - int prefix_len; - char *buf; - - /* From the expat documentation: - "For a default namespace declaration (xmlns='...'), - the prefix will be null ... - ... The URI will be null for the case where - the default namespace is being unset." - - FIXME: I'm not quite sure what all that means */ - if (uri == NULL) - return NULL; - - ei_x_encode_list_header(&xmlns_buf, 1); - ei_x_encode_tuple_header(&xmlns_buf, 2); - if (prefix) { - prefix_len = strlen(prefix); - buf = driver_alloc(7 + prefix_len); - strcpy(buf, "xmlns:"); - strcpy(buf+6, prefix); - ei_x_encode_binary(&xmlns_buf, buf, strlen(buf)); - driver_free(buf); - } else { - ei_x_encode_binary(&xmlns_buf, "xmlns", strlen("xmlns")); - }; - ei_x_encode_binary(&xmlns_buf, uri, strlen(uri)); - - return NULL; -} - -static ErlDrvData expat_erl_start(ErlDrvPort port, char *buff) -{ - expat_data* d = (expat_data*)driver_alloc(sizeof(expat_data)); - d->port = port; - d->parser = XML_ParserCreate_MM("UTF-8", &ms, "\n"); - XML_SetUserData(d->parser, d); - - set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY); - - XML_SetStartElementHandler( - d->parser, (XML_StartElementHandler)erlXML_StartElementHandler); - XML_SetEndElementHandler( - d->parser, (XML_EndElementHandler)erlXML_EndElementHandler); - XML_SetCharacterDataHandler( - d->parser, (XML_CharacterDataHandler)erlXML_CharacterDataHandler); - - XML_SetStartNamespaceDeclHandler( - d->parser, (XML_StartNamespaceDeclHandler) erlXML_StartNamespaceDeclHandler); - XML_SetReturnNSTriplet(d->parser, 1); - - XML_SetDefaultHandler(d->parser, NULL); - - return (ErlDrvData)d; -} - -static void expat_erl_stop(ErlDrvData handle) -{ - XML_ParserFree(((expat_data *)handle)->parser); - driver_free((char*)handle); -} - -static ErlDrvSSizeT expat_erl_control(ErlDrvData drv_data, - unsigned int command, - char *buf, ErlDrvSizeT len, - char **rbuf, ErlDrvSizeT rlen) -{ - expat_data* d = (expat_data*)drv_data; - int res, errcode; - char *errstring; - ErlDrvBinary *b; - size_t size; - - switch (command) - { - case PARSE_COMMAND: - case PARSE_FINAL_COMMAND: - ei_x_new_with_version(&event_buf); - ei_x_new(&xmlns_buf); - res = XML_Parse(d->parser, buf, len, command == PARSE_FINAL_COMMAND); - - if(!res) - { - errcode = XML_GetErrorCode(d->parser); - errstring = (char *)XML_ErrorString(errcode); - - ei_x_encode_list_header(&event_buf, 1); - ei_x_encode_tuple_header(&event_buf, 2); - ei_x_encode_long(&event_buf, XML_ERROR); - ei_x_encode_tuple_header(&event_buf, 2); - ei_x_encode_long(&event_buf, errcode); - ei_x_encode_binary(&event_buf, errstring, strlen(errstring)); - } - - ei_x_encode_empty_list(&event_buf); - - size = event_buf.index; - - b = driver_alloc_binary(size); - memcpy(b->orig_bytes, event_buf.buff, size); - - ei_x_free(&event_buf); - ei_x_free(&xmlns_buf); - - *rbuf = (char *)b; - return size; - default: - return 0; - } -} - -ErlDrvEntry expat_driver_entry = { - NULL, /* F_PTR init, N/A */ - expat_erl_start, /* L_PTR start, called when port is opened */ - expat_erl_stop, /* F_PTR stop, called when port is closed */ - NULL, /* F_PTR output, called when erlang has sent */ - NULL, /* F_PTR ready_input, called when input descriptor ready */ - NULL, /* F_PTR ready_output, called when output descriptor ready */ - "expat_erl", /* char *driver_name, the argument to open_port */ - NULL, /* F_PTR finish, called when unloaded */ - NULL, /* handle */ - expat_erl_control, /* F_PTR control, port_command callback */ - NULL, /* F_PTR timeout, reserved */ - NULL, /* F_PTR outputv, reserved */ - /* Added in Erlang/OTP R15B: */ - NULL, /* ready_async */ - NULL, /* flush */ - NULL, /* call */ - NULL, /* event */ - ERL_DRV_EXTENDED_MARKER, /* extended_marker */ - ERL_DRV_EXTENDED_MAJOR_VERSION, /* major_version */ - ERL_DRV_EXTENDED_MINOR_VERSION, /* minor_version */ - 0, /* driver_flags */ - NULL, /* handle2 */ - NULL, /* process_exit */ - NULL /* stop_select */ -}; - -DRIVER_INIT(expat_erl) /* must match name in driver_entry */ -{ - ms.malloc_fcn = driver_alloc; - ms.realloc_fcn = driver_realloc; - ms.free_fcn = driver_free; - return &expat_driver_entry; -} - - |