/*! \brief Resize an area within an msgb * * This resizes a sub area of the msgb data and adjusts the pointers (incl * l1h-l4h) accordingly. The cb part is not updated. If the area is extended, * the contents of the extension is undefined. The complete sub area must be a * part of [data,tail]. * * \param[inout] msg The msgb object * \param[in] area A pointer to the sub-area * \param[in] old_size The old size of the sub-area * \param[in] new_size The new size of the sub-area * \returns 0 on success, -1 if there is not enough space to extend the area */ int msgb_resize_area(struct msgb *msg, uint8_t *area, int old_size, int new_size) { int rc; uint8_t *post_start = area + old_size; int pre_len = area - msg->data; int post_len = msg->len - old_size - pre_len; int delta_size = new_size - old_size; if (old_size < 0 || new_size < 0) MSGB_ABORT(msg, "Negative sizes are not allowed\n"); if (area < msg->data || post_start > msg->tail) MSGB_ABORT(msg, "Sub area is not fully contained in the msg data\n"); if (delta_size == 0) return 0; if (delta_size > 0) { rc = msgb_trim(msg, msg->len + delta_size); if (rc < 0) return rc; } memmove(area + new_size, area + old_size, post_len); if (msg->l1h >= post_start) msg->l1h += delta_size; if (msg->l2h >= post_start) msg->l2h += delta_size; if (msg->l3h >= post_start) msg->l3h += delta_size; if (msg->l4h >= post_start) msg->l4h += delta_size; if (delta_size < 0) msgb_trim(msg, msg->len + delta_size); return 0; }
static int osmo_stats_reporter_statsd_send(struct osmo_stats_reporter *srep, const char *name1, unsigned int index1, const char *name2, int64_t value, const char *unit) { char *buf; int buf_size; int nchars, rc = 0; char *fmt = NULL; char *prefix = srep->name_prefix; int old_len = msgb_length(srep->buffer); if (prefix) { if (name1) { if (index1 != 0) fmt = "%1$s.%2$s.%6$u.%3$s:%4$d|%5$s"; else fmt = "%1$s.%2$s.%3$s:%4$d|%5$s"; } else { fmt = "%1$s.%2$0.0s%3$s:%4$d|%5$s"; } } else { prefix = ""; if (name1) { if (index1 != 0) fmt = "%1$s%2$s.%6$u.%3$s:%4$d|%5$s"; else fmt = "%1$s%2$s.%3$s:%4$d|%5$s"; } else { fmt = "%1$s%2$0.0s%3$s:%4$d|%5$s"; } } if (srep->agg_enabled) { if (msgb_length(srep->buffer) > 0 && msgb_tailroom(srep->buffer) > 0) { msgb_put_u8(srep->buffer, '\n'); } } buf = (char *)msgb_put(srep->buffer, 0); buf_size = msgb_tailroom(srep->buffer); nchars = snprintf(buf, buf_size, fmt, prefix, name1, name2, value, unit, index1); if (nchars >= buf_size) { /* Truncated */ /* Restore original buffer (without trailing LF) */ msgb_trim(srep->buffer, old_len); /* Send it */ rc = osmo_stats_reporter_send_buffer(srep); /* Try again */ buf = (char *)msgb_put(srep->buffer, 0); buf_size = msgb_tailroom(srep->buffer); nchars = snprintf(buf, buf_size, fmt, prefix, name1, name2, value, unit, index1); if (nchars >= buf_size) return -EMSGSIZE; } if (nchars > 0) msgb_trim(srep->buffer, msgb_length(srep->buffer) + nchars); if (!srep->agg_enabled) rc = osmo_stats_reporter_send_buffer(srep); return rc; }