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;
}
Example #2
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;
}