mi_datagram_writer.c
Go to the documentation of this file.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
00038 #include "../../str.h"
00039 #include "../../ut.h"
00040 #include "../../dprint.h"
00041 #include "../../mi/mi.h"
00042 #include "../../mem/mem.h"
00043 #include "mi_datagram.h"
00044 #include "datagram_fnc.h"
00045 #include "mi_datagram_parser.h"
00046
00047
00048 static unsigned int mi_write_buffer_len = 0;
00049 static str mi_datagram_indent;
00050
00051
00052 int mi_datagram_writer_init( unsigned int size , char *indent)
00053 {
00054 mi_write_buffer_len = size;
00055
00056 if (indent==NULL || indent[0]==0 ) {
00057 mi_datagram_indent.s = 0;
00058 mi_datagram_indent.len = 0;
00059 } else {
00060 mi_datagram_indent.s = indent;
00061 mi_datagram_indent.len = strlen(indent);
00062 }
00063
00064 return 0;
00065 }
00066
00067
00068 static inline int mi_datagram_write_node(datagram_stream * dtgram,
00069 struct mi_node *node, int level)
00070 {
00071 struct mi_attr *attr;
00072 char *start, *end, *p;
00073
00074
00075 start = p = dtgram->current;
00076 end = dtgram->start + dtgram->len;
00077 LM_DBG("writing the name <%.*s> and value <%.*s> \n",
00078 node->name.len, node->name.s, node->value.len, node->value.s);
00079
00080 if (mi_datagram_indent.s) {
00081 if (p + level*mi_datagram_indent.len>end) {
00082 LM_DBG("a too long line\n");
00083 return -1;
00084 }
00085 for( ; level>0 ; level-- ) {
00086 memcpy( p, mi_datagram_indent.s, mi_datagram_indent.len);
00087 p += mi_datagram_indent.len;
00088 }
00089 }
00090
00091 if (node->name.s!=NULL) {
00092 if (p+node->name.len+3>end) {
00093 LM_DBG("too long name\n");
00094 return -1;
00095 }
00096 memcpy(p,node->name.s,node->name.len);
00097 p += node->name.len;
00098 *(p++) = MI_ATTR_VAL_SEP1;
00099 *(p++) = MI_ATTR_VAL_SEP2;
00100 *(p++) = ' ';
00101 }
00102
00103
00104
00105 if (node->value.s!=NULL) {
00106 if (p+node->value.len>end) {
00107 LM_DBG("too long value\n");
00108 return -1;
00109 }
00110 memcpy(p,node->value.s,node->value.len);
00111 p += node->value.len;
00112 }
00113
00114
00115
00116 for( attr=node->attributes ; attr!=NULL ; attr=attr->next ) {
00117 if (attr->name.s!=NULL) {
00118 if (p+attr->name.len+2>end) {
00119 LM_DBG("too long attr name\n");
00120 return -1;
00121 }
00122 *(p++) = ' ';
00123 memcpy(p,attr->name.s,attr->name.len);
00124 p += attr->name.len;
00125 *(p++) = '=';
00126 }
00127 if (attr->value.s!=NULL) {
00128 if (p+attr->value.len>end) {
00129 LM_DBG("too long attr value\n");
00130 return -1;
00131 }
00132 memcpy(p,attr->value.s,attr->value.len);
00133 p += attr->value.len;
00134 }
00135 }
00136
00137
00138 if (p+1>end) {
00139 LM_DBG("overflow before returning\n");
00140 return -1;
00141 }
00142 *(p++) = '\n';
00143
00144 dtgram->len -= p-start;
00145 dtgram->current = p;
00146
00147 return 0;
00148 }
00149
00150
00151
00152 static int datagram_recur_write_tree(datagram_stream *dtgram,
00153 struct mi_node *tree, int level)
00154 {
00155 for( ; tree ; tree=tree->next ) {
00156 if (mi_datagram_write_node( dtgram, tree, level)!=0) {
00157 LM_ERR("failed to write -line too long!!!\n");
00158 return -1;
00159 }
00160 if (tree->kids) {
00161 if (datagram_recur_write_tree(dtgram, tree->kids, level+1)<0)
00162 return -1;
00163 }
00164 }
00165 return 0;
00166 }
00167
00168
00169
00170 int mi_datagram_write_tree(datagram_stream * dtgram, struct mi_root *tree)
00171 {
00172 str code;
00173 dtgram->current = dtgram->start;
00174 dtgram->len = mi_write_buffer_len;
00175
00176
00177 code.s = int2str((unsigned long)tree->code, &code.len);
00178 if (code.len+tree->reason.len+1 > dtgram->len) {
00179 LM_ERR("failed to write - reason too long!!!\n");
00180 return -1;
00181 }
00182
00183 memcpy( dtgram->start, code.s, code.len);
00184 dtgram->current += code.len;
00185 *(dtgram->current) = ' ';
00186 dtgram->current++;
00187
00188 if (tree->reason.len) {
00189 memcpy(dtgram->current, tree->reason.s, tree->reason.len);
00190 dtgram->current += tree->reason.len;
00191 }
00192
00193 *(dtgram->current) = '\n';
00194 dtgram->current++;
00195 dtgram->len -= code.len + 1 + tree->reason.len+1;
00196
00197 if (datagram_recur_write_tree(dtgram, tree->node.kids, 0)!=0)
00198 return -1;
00199
00200 if (dtgram->len<=0) {
00201 LM_ERR("failed to write - EOC does not fit in!!!\n");
00202 return -1;
00203 }
00204
00205 *(dtgram->current) = '\n';
00206 dtgram->len--;
00207 *(dtgram->current) = '\0';
00208
00209 return 0;
00210 }
00211