/** * Convenience routine: format tree to memory buffer. * * @param root tree to dump * @param buf buffer where formatting is done * @param len buffer length * @param options formatting options * * @return length of generated string, -1 on failure. */ size_t xfmt_tree_to_buffer(const xnode_t *root, void *buf, size_t len, uint32 options) { ostream_t *os; pdata_t *pd; pmsg_t *mb; bool ok; size_t written = (size_t) -1; g_assert(root != NULL); g_assert(buf != NULL); g_assert(size_is_non_negative(len)); pd = pdata_allocb_ext(buf, len, pdata_free_nop, NULL); mb = pmsg_alloc(PMSG_P_DATA, pd, 0, 0); os = ostream_open_pmsg(mb); ok = xfmt_tree(root, os, options); ok = ostream_close(os) && ok; if (ok) written = pmsg_size(mb); pmsg_free(mb); g_assert((size_t) -1 == written || written <= len); return written; }
/** * Get a new RX buffer from the pool. * * @return new RX buffer. */ pdata_t * rxbuf_new(void) { char *phys = palloc(rxpool); /* * We want to use page-aligned memory to benefit from possible zero-copy * on read() operations. Hence we must use pdata_allocb_ext() to avoid * embedding the pdata_t header at the beginning of the buffer. */ return pdata_allocb_ext(phys, rxbuf_pagesize, rxbuf_data_free, NULL); }
/** * Received data from outside the RX stack. */ void thex_download_write(struct thex_download *ctx, char *data, size_t len) { pdata_t *db; pmsg_t *mb; g_assert(ctx->rx != NULL); /* * Prepare data buffer to feed the RX stack. */ db = pdata_allocb_ext(data, len, pdata_free_nop, NULL); mb = pmsg_alloc(PMSG_P_DATA, db, 0, len); /* * The message is given to the RX stack, and it will be freed by * the last function consuming it. */ rx_recv(rx_bottom(ctx->rx), mb); }