static int recur_flush_response(xmlrpc_env * env, struct mi_node *tree, str *buf) { struct mi_node *kid, *tmp; int ret; for(kid = tree->kids ; kid ; ) { /* write the current kid */ if (!(kid->flags & MI_WRITTEN)) { if (xr_write_node( buf, kid)!=0) { reply_buffer = (char*) pkg_realloc ( reply_buffer, 2*reply_buffer_len); if ( !reply_buffer ) { LM_ERR("pkg_realloc cannot reallocate any more memory!\n"); return -1; } buf->s = reply_buffer +(reply_buffer_len - buf->len); buf->len += reply_buffer_len; reply_buffer_len *=2 ; if ( xr_write_node( buf, tree ) != 0 ) { LM_ERR("failed to get MI node data!\n"); return -1; } } /* we are sure that this node has been written * => avoid writing it again */ kid->flags |= MI_WRITTEN; } if ((ret = recur_flush_response_array(env, kid, buf))<0) return -1; else if (ret > 0) return ret; if (!(kid->flags & MI_NOT_COMPLETED)) { tmp = kid; kid = kid->next; tree->kids = kid; if(!tmp->kids) { /* this node does not have any kids */ free_mi_node(tmp); } } else { /* the node will have more kids => to keep the tree shape, do not * flush any other node for now */ return 1; } } return 0; }
static int recur_flush_tree(FILE *stream, struct mi_node *tree, str *buf, int level) { struct mi_node *kid, *tmp; int ret; for(kid = tree->kids ; kid ; ){ /* write the current kid */ if (!(kid->flags & MI_WRITTEN)){ if (mi_write_node( buf, kid, level)!=0) { /* buffer is full -> write it and reset buffer */ if (mi_fifo_reply( stream,"%.*s", buf->s-mi_write_buffer, mi_write_buffer)!=0) return -1; buf->s = mi_write_buffer; buf->len = mi_write_buffer_len; if (mi_write_node( buf, kid, level)!=0) { LM_ERR("failed to write - line too long!\n"); return -1; } } /* we are sure that this node has been written * => avoid writing it again */ kid->flags |= MI_WRITTEN; } /* write the current kid's children */ if ((ret = recur_flush_tree(stream, kid, buf, level+1))<0) return -1; else if (ret > 0) return ret; if (!(kid->flags & MI_NOT_COMPLETED)){ tmp = kid; kid = kid->next; tree->kids = kid; if(!tmp->kids){ /* this node does not have any kids */ free_mi_node(tmp); } } else{ /* the node will have more kids => to keep the tree shape, do not * flush any other node for now */ return 1; } } return 0; }
static int recur_flush_response_array(xmlrpc_env * env, struct mi_node *tree, str *buf) { struct mi_node *kid, *tmp; int ret; for(kid = tree->kids ; kid ; ) { /* write the current kid */ if (!(kid->flags & MI_WRITTEN)) { if (xr_write_node( buf, kid)!=0) { LM_ERR("failed to write - line too long!\n"); return -1; } /* we are sure that this node has been written * => avoid writing it again */ kid->flags |= MI_WRITTEN; } reply_buffer[reply_buffer_len-buf->len] = 0; reply_item = xmlrpc_build_value(env, "s", reply_buffer); xmlrpc_array_append_item(env, xr_response, reply_item); buf->s = reply_buffer; buf->len = reply_buffer_len; /* write the current kid's children */ if ((ret = recur_flush_response_array(env, kid, buf))<0) return -1; else if (ret > 0) return ret; if (!(kid->flags & MI_NOT_COMPLETED)) { tmp = kid; kid = kid->next; tree->kids = kid; if(!tmp->kids) { /* this node does not have any kids */ free_mi_node(tmp); } } else { /* the node will have more kids => to keep the tree shape, do not * flush any other node for now */ return 1; } } return 0; }