00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <stdio.h>
00036 #include <string.h>
00037 #include <ctype.h>
00038
00039 #include "../../str.h"
00040 #include "../../dprint.h"
00041 #include "../../mi/mi.h"
00042 #include "../../mem/mem.h"
00043 #include "../../mem/shm_mem.h"
00044 #include "datagram_fnc.h"
00045 #include "mi_datagram.h"
00046 #include "mi_datagram_parser.h"
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 static inline int mi_datagram_parse_node(datagram_stream * data, str *name, str *value)
00066 {
00067 char *p, *pmax;
00068 char *start, *start1;
00069 char *mark_nsp;
00070 int newline_found = 0;
00071
00072 LM_DBG("the remaining datagram to be parsed is %s and %i in length \n",
00073 data->current,data->len);
00074
00075 p =data->current;
00076 start1 = start = p;
00077 if(data->len > DATAGRAM_SOCK_BUF_SIZE) {
00078 LM_ERR("overflow while parsing the received datagram\n");
00079 goto parse_err;
00080 }
00081 pmax = start + data->len ;
00082
00083
00084 for( ; start<pmax && isspace((int)*start) ; start++ );
00085
00086 if(start == pmax)
00087 return 1;
00088
00089
00090 name->s = value->s = 0;
00091 name->len = value->len = 0;
00092
00093 mark_nsp = 0;
00094
00095
00096 if (*start!='"') {
00097 LM_DBG("the string is not just a quoted string\n");
00098
00099
00100 p = mark_nsp = start;
00101 while ( p!=pmax && (( *p!=MI_ATTR_VAL_SEP1) || p+1==pmax ||*(p+1)!=MI_ATTR_VAL_SEP2) ) {
00102 if (!isspace((int)*p)) {
00103 if (*p=='"') {
00104 LM_DBG("found \" before attr_separator\n");
00105 goto parse_err;
00106 }
00107 mark_nsp = p;
00108 }
00109 if(*p=='\n' && p!=(pmax -1)) {
00110 LM_DBG("found newline before attr_separator--we have just the "
00111 "attribute's value\n");
00112 mark_nsp++;
00113 pmax = ++p;
00114 break;
00115 }else if (p == (pmax-1)){
00116 mark_nsp++;
00117 pmax = ++p;
00118 LM_DBG("just a value, no new line");
00119 break;
00120 }
00121 p++;
00122 }
00123
00124 if (p!=pmax) {
00125
00126 LM_DBG("we've found the attr_separator\n");
00127 if (p==start) {
00128
00129 LM_DBG("empty attr_name\n");
00130 } else {
00131 name->s = start;
00132 name->len = mark_nsp - start+1;
00133 LM_DBG("attr name <%.*s> found\n",name->len, name->s);
00134 }
00135
00136 p += 2;
00137
00138
00139 for( ; p!=pmax && isspace((int)*p) ; p++) {
00140 if(*p=='\n') {
00141 LM_DBG("empty value\n");
00142
00143 goto done;
00144 }
00145 }
00146
00147
00148 if(p==pmax && *p=='\n') {
00149 LM_DBG("empty value\n");
00150
00151 goto done;
00152 }
00153
00154
00155 if (*p!='"') {
00156 LM_DBG("not quoted value, p is %c \n", *p);
00157 for( start=p ; p!=pmax ; p++ ) {
00158 if (!isspace((int)*p)) {
00159 if (*p=='"') {
00160 goto parse_err;
00161 }
00162 mark_nsp = p;
00163 LM_DBG("nsp is %p ,p is %p, pmax is %p and *p is %c\n",
00164 mark_nsp, p, pmax,*p);
00165 }
00166 if(*p=='\n') {
00167 pmax = p;
00168 break;
00169 }
00170 }
00171
00172 value->s = start;
00173 value->len = mark_nsp - start+1;
00174 LM_DBG("*start is %c and start is %p\n",*start, start);
00175 LM_DBG("attr value <%s> found\n", value->s);
00176 goto done;
00177 }
00178
00179 } else {
00180
00181 value->s = start;
00182 value->len = mark_nsp - start;
00183 LM_DBG("empty name, attr not quoted value <%.*s> found\n",
00184 value->len, value->s);
00185 goto done;
00186 }
00187 } else {
00188 p = start;
00189 }
00190
00191 LM_DBG("we have a quoted value, %s\n", p);
00192 start = p+1;
00193 value->s = start;
00194
00195 p = start;
00196
00197 while (p<pmax) {
00198 if (*p=='"' && start!=p) {
00199
00200 LM_DBG("\" found p is %s\n",p);
00201
00202 if (start+1!=p && *(p-1)=='\\') {
00203 LM_DBG("skipping %c",*p);
00204
00205 memmove( p-1, p, pmax-p);
00206 pmax--;
00207 } else {
00208 LM_DBG("we have reached the end of attr value, p is %s\n", p);
00209
00210 value->len = p - value->s;
00211 LM_DBG("attr value <%.*s> found\n",value->len, value->s);
00212
00213
00214 p++;
00215 for(; p!=pmax && isspace((int)*p) ; p++)
00216 {
00217 if(*p=='\n') {
00218
00219 LM_DBG("line ended properly case1\n");
00220 pmax = p;
00221 break;
00222 }
00223 }
00224 if (p!=pmax )
00225 {
00226 LM_ERR("didn't find newline case1 \n");
00227 goto parse_err;
00228 }
00229 newline_found = 1;
00230
00231 goto done;
00232 }
00233 } else {
00234 p++;
00235 }
00236 }
00237
00238 if(p== pmax && !newline_found) {
00239 LM_ERR("didn't find newline case2\n");
00240 goto parse_err;
00241 }
00242
00243 done:
00244
00245 LM_DBG("1 data->len is %i\n",data->len);
00246 data->len -= p-start1;
00247 LM_DBG("2 data->len is %i\n",data->len);
00248 data->current = p;
00249 return 0;
00250 parse_err:
00251 LM_ERR("parse error around %c\n",*p);
00252 return -1;
00253 }
00254
00255
00256
00257
00258 struct mi_root * mi_datagram_parse_tree(datagram_stream * datagram) {
00259 struct mi_root *root;
00260 struct mi_node *node;
00261 str name;
00262 str value;
00263 int ret;
00264
00265 root = init_mi_tree(0,0,0);
00266 if (!root) {
00267 LM_ERR("the MI tree cannot be initialized!\n");
00268 goto error;
00269 }
00270 if(!datagram || datagram->current[0] == '\0')
00271 {
00272 LM_DBG("no data in the datagram\n");
00273 return root;
00274 }
00275
00276 node = &root->node;
00277
00278 name.s = value.s = 0;
00279 name.len = value.len = 0;
00280
00281
00282 while ((ret=mi_datagram_parse_node(datagram, &name, &value))>=0 ) {
00283
00284 if(ret == 1)
00285 return root;
00286 LM_DBG("adding node <%.*s> ; val <%.*s>\n",
00287 name.len,name.s, value.len,value.s);
00288
00289 if(!add_mi_node_child(node,0,name.s,name.len,value.s,value.len)){
00290 LM_ERR("cannot add the child node to the tree\n");
00291 goto error;
00292 }
00293 LM_DBG("the remaining datagram has %i bytes\n",datagram->len);
00294
00295 if(datagram->len == 0) {
00296 LM_DBG("found end of input\n");
00297 return root;
00298 }
00299 }
00300
00301 LM_ERR("parse error!\n");
00302 error:
00303 if (root)
00304 free_mi_tree(root);
00305 return 0;
00306 }
00307
00308