xr_parser.c

Go to the documentation of this file.
00001 /*
00002  * $Id: xr_parser.c 4585 2008-08-06 08:20:30Z klaus_darilion $
00003  *
00004  * Copyright (C) 2006 Voice Sistem SRL
00005  *
00006  * This file is part of Kamailio.
00007  *
00008  * Kamailio is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU General Public License
00010  * as published by the Free Software Foundation; either version 2
00011  * of the License, or (at your option) any later version.
00012  *
00013  * Kamailio is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00021  *
00022  * History:
00023  * ---------
00024  *  2006-11-30  first version (lavinia)
00025  *  2007-10-05  support for libxmlrpc-c3 version 1.x.x added (dragos)
00026  */
00027 
00028 
00029 #include <string.h>
00030 #include <stdlib.h>
00031 #include "../../dprint.h"
00032 #include "../../mem/mem.h"
00033 #include "xr_parser.h"
00034 #include "xr_parser_lib.h"
00035 #include "mi_xmlrpc.h"
00036 
00037 /*
00038  * Convert in argument string each LFLF to CRLF and return length of
00039  * the string not including the terminating `\0' character.
00040  * This is a hack that is needed as long as Abyss XML-RPC server "normalizes"
00041  * CRLF to LF in XML-RPC strings. 
00042  */
00043 int lflf_to_crlf_hack(char *s) {
00044 
00045     unsigned int len;
00046 
00047     len = 0;
00048 
00049     while (*s) {
00050    if (*(s + 1) && (*s == '\n') && *(s + 1) == '\n') {
00051        *s = '\r';
00052        s = s + 2;
00053        len = len + 2;
00054    } else {
00055        s++;
00056        len++;
00057    }
00058     }
00059 
00060     return len;
00061 }
00062 
00063 
00064 struct mi_root * xr_parse_tree( xmlrpc_env * env, xmlrpc_value * paramArray ) {
00065 
00066    struct mi_root * mi_root;
00067    
00068    int size, i;
00069    size_t length;
00070 
00071    xmlrpc_int32 intValue;
00072    xmlrpc_bool boolValue;
00073 
00074    #ifdef XMLRPC_OLD_VERSION
00075    double doubleValue;
00076    char * contents;
00077    #else
00078    xmlrpc_double doubleValue;
00079    #endif
00080 
00081    char * stringValue = 0;
00082    char * byteStringValue =0;
00083    xmlrpc_value * item;
00084    
00085    mi_root = init_mi_tree(0, 0, 0);
00086    
00087    if ( !mi_root ) {
00088       LM_ERR("the MI tree cannot be initialized!\n");
00089       goto error;
00090    }
00091 
00092    size = xmlrpc_array_size(env, paramArray);
00093    
00094    for (i=0 ; i< size ; i++) {
00095 
00096       item = xmlrpc_array_get_item(env, paramArray, i);
00097       if ( env->fault_occurred ) {
00098          LM_ERR("failed to get array item: %s\n", env->fault_string);
00099          goto error;
00100       }
00101       
00102       switch ( xmlrpc_value_type(item) ) {
00103       
00104       case (XMLRPC_TYPE_INT):
00105 
00106          #ifdef XMLRPC_OLD_VERSION
00107          intValue = item->_value.i;
00108          #else 
00109          xmlrpc_read_int(env,item,&intValue);
00110          #endif
00111 
00112          if (addf_mi_node_child(&mi_root->node,0,0,0,"%d",intValue)==NULL) {
00113             LM_ERR("failed to add node to the MI tree.\n");
00114             goto error;
00115          }
00116 
00117          break;
00118       case (XMLRPC_TYPE_BOOL):
00119 
00120          #ifdef XMLRPC_OLD_VERSION
00121          boolValue = item->_value.b;
00122          #else
00123          xmlrpc_read_bool(env,item,&boolValue);
00124          #endif
00125 
00126          if (addf_mi_node_child(&mi_root->node,0,0,0,"%u",boolValue)==NULL){
00127             LM_ERR("failed to add node to the MI tree.\n");
00128             goto error;
00129          }
00130 
00131          break;
00132 
00133       case (XMLRPC_TYPE_DOUBLE):
00134 
00135          #ifdef XMLRPC_OLD_VERSION
00136          doubleValue = item->_value.d;
00137          #else
00138          xmlrpc_read_double(env,item,&doubleValue);
00139          #endif
00140 
00141          if ( addf_mi_node_child(&mi_root->node, 0, 0, 0, "%lf",
00142          doubleValue) == NULL ) {
00143             LM_ERR("failed to add node to the MI tree.\n");
00144             goto error;
00145          }
00146 
00147          break;
00148 
00149       case (XMLRPC_TYPE_STRING):
00150 
00151          #if HAVE_UNICODE_WCHAR
00152          
00153          #ifdef  XMLRPC_OLD_VERSION
00154          xmlrpc_read_string_w(env, item, &stringValue);
00155          #else
00156          xmlrpc_read_string_w(env, item , (const char **)&stringValue);
00157          #endif
00158 
00159          #else
00160 
00161          #ifdef  XMLRPC_OLD_VERSION
00162          xmlrpc_read_string(env, item, &stringValue);
00163          #else
00164          xmlrpc_read_string(env, item, (const char **)&stringValue);
00165          #endif
00166 
00167          #endif
00168 
00169          if ( env->fault_occurred ) {
00170             LM_ERR("failed to read stringValue: %s!\n", env->fault_string);
00171             goto error;
00172          }
00173          if ( add_mi_node_child(&mi_root->node, 0, 0, 0,
00174                       stringValue,
00175                       lflf_to_crlf_hack(stringValue)) == NULL ) {
00176             LM_ERR("failed to add node to the MI tree.\n");
00177             goto error;
00178          }
00179          
00180          break;
00181 
00182       case (XMLRPC_TYPE_BASE64):
00183 
00184          #ifdef XMLRPC_OLD_VERSION
00185 
00186          length = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, &item->_block);
00187          contents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, &item->_block);
00188          byteStringValue = pkg_malloc(length);
00189 
00190          if ( !byteStringValue ){
00191             xmlrpc_env_set_fault_formatted(env, XMLRPC_INTERNAL_ERROR,
00192                "Unable to allocate %u bytes for byte string.", length);
00193             LM_ERR("pkg_malloc cannot allocate any more memory!\n");
00194             goto error;
00195          } else
00196             memcpy(byteStringValue, contents, length);
00197 
00198          if ( add_mi_node_child(&mi_root->node, 0, 0, 0, byteStringValue,
00199          length) == NULL ) {
00200             LM_ERR("failed to add node to the MI tree.\n");
00201             goto error;
00202          }
00203 
00204          #else
00205 
00206          xmlrpc_read_base64(env, item, &length,
00207             (const unsigned char **)(void*)&byteStringValue);
00208 
00209          if ( env->fault_occurred ) {
00210             LM_ERR("failed to read byteStringValue: %s!\n", 
00211                   env->fault_string);
00212             goto error;
00213          }
00214 
00215          if ( add_mi_node_child(&mi_root->node, MI_DUP_VALUE, 0, 0, 
00216          byteStringValue, length) == NULL ) {
00217             LM_ERR("failed to add node to the MI tree.\n");
00218             goto error;
00219          }
00220          free(byteStringValue);
00221 
00222          #endif
00223 
00224          break;
00225 
00226       default :
00227          LM_ERR("unsupported node type %d\n",  xmlrpc_value_type(item)  );
00228          xmlrpc_env_set_fault_formatted( env, XMLRPC_TYPE_ERROR, 
00229             "Unsupported value of type %d supplied",
00230             xmlrpc_value_type(item));
00231          goto error;
00232       }
00233    }
00234    
00235    return mi_root;
00236 
00237 error:
00238    if ( mi_root ) free_mi_tree(mi_root);
00239    if ( byteStringValue ) pkg_free(byteStringValue);
00240    return 0;
00241 }

Generated on Fri May 25 00:00:35 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6