lsb_err_value lsb_write_heka_uuid(lsb_output_buffer *ob, const char *uuid, size_t len) { if (!ob) { return LSB_ERR_UTIL_NULL; } static const size_t needed = 18; ob->pos = 0; // writing a uuid will always clear the buffer as it is the // start of a new message lsb_err_value ret = lsb_expand_output_buffer(ob, needed); if (ret) return ret; ob->buf[ob->pos++] = 2 | (LSB_PB_UUID << 3); // write key ob->buf[ob->pos++] = LSB_UUID_SIZE; // write length if (uuid && len == LSB_UUID_SIZE) { memcpy(ob->buf + ob->pos, uuid, LSB_UUID_SIZE); ob->pos += LSB_UUID_SIZE; } else if (uuid && len == LSB_UUID_STR_SIZE) { int cnt = sscanf(uuid, "%02hhx%02hhx%02hhx%02hhx" "-%02hhx%02hhx" "-%02hhx%02hhx" "-%02hhx%02hhx" "-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", (unsigned char *)ob->buf + ob->pos, (unsigned char *)ob->buf + ob->pos + 1, (unsigned char *)ob->buf + ob->pos + 2, (unsigned char *)ob->buf + ob->pos + 3, (unsigned char *)ob->buf + ob->pos + 4, (unsigned char *)ob->buf + ob->pos + 5, (unsigned char *)ob->buf + ob->pos + 6, (unsigned char *)ob->buf + ob->pos + 7, (unsigned char *)ob->buf + ob->pos + 8, (unsigned char *)ob->buf + ob->pos + 9, (unsigned char *)ob->buf + ob->pos + 10, (unsigned char *)ob->buf + ob->pos + 11, (unsigned char *)ob->buf + ob->pos + 12, (unsigned char *)ob->buf + ob->pos + 13, (unsigned char *)ob->buf + ob->pos + 14, (unsigned char *)ob->buf + ob->pos + 15); if (cnt == LSB_UUID_SIZE) { ob->pos += cnt; } } if (ob->pos == 2) { // only the header has been written for (int x = 0; x < LSB_UUID_SIZE; ++x) { ob->buf[ob->pos++] = rand() % 256; } ob->buf[8] = (ob->buf[8] & 0x0F) | 0x40; ob->buf[10] = (ob->buf[10] & 0x0F) | 0xA0; } return NULL; }
lsb_err_value lsb_outputc(lsb_output_buffer *b, char ch) { if (!b) { return LSB_ERR_UTIL_NULL; } lsb_err_value ret = lsb_expand_output_buffer(b, 2); if (ret) return ret; b->buf[b->pos++] = ch; b->buf[b->pos] = 0; return NULL; }
lsb_err_value lsb_outputs(lsb_output_buffer *b, const char *str, size_t len) { if (!b) { return LSB_ERR_UTIL_NULL; } lsb_err_value ret = lsb_expand_output_buffer(b, len + 1); if (ret) return ret; memcpy(b->buf + b->pos, str, len); b->pos += len; b->buf[b->pos] = 0; return ret; }
lsb_err_value heka_encode_message_table(lsb_lua_sandbox *lsb, int idx) { lsb_err_value ret = NULL; lsb_output_buffer *ob = &lsb->output; ob->pos = 0; // use existing or create a type 4 uuid lua_getfield(lsb->lua, idx, LSB_UUID); size_t len; const char *uuid = lua_tolstring(lsb->lua, -1, &len); ret = lsb_write_heka_uuid(ob, uuid, len); lua_pop(lsb->lua, 1); // remove uuid if (ret) return ret; // use existing or create a timestamp lua_getfield(lsb->lua, idx, LSB_TIMESTAMP); long long ts; if (lua_isnumber(lsb->lua, -1)) { ts = (long long)lua_tonumber(lsb->lua, -1); } else { ts = time(NULL) * 1000000000LL; } lua_pop(lsb->lua, 1); // remove timestamp ret = lsb_pb_write_key(ob, LSB_PB_TIMESTAMP, LSB_PB_WT_VARINT); if (!ret) ret = lsb_pb_write_varint(ob, ts); if (!ret) ret = encode_string(lsb, ob, LSB_PB_TYPE, LSB_TYPE, idx); if (!ret) ret = encode_string(lsb, ob, LSB_PB_LOGGER, LSB_LOGGER, idx); if (!ret) ret = encode_int(lsb, ob, LSB_PB_SEVERITY, LSB_SEVERITY, idx); if (!ret) ret = encode_string(lsb, ob, LSB_PB_PAYLOAD, LSB_PAYLOAD, idx); if (!ret) ret = encode_string(lsb, ob, LSB_PB_ENV_VERSION, LSB_ENV_VERSION, idx); if (!ret) ret = encode_int(lsb, ob, LSB_PB_PID, LSB_PID, idx); if (!ret) ret = encode_string(lsb, ob, LSB_PB_HOSTNAME, LSB_HOSTNAME, idx); if (!ret) ret = encode_fields(lsb, ob, LSB_PB_FIELDS, LSB_FIELDS, idx); if (!ret) ret = lsb_expand_output_buffer(ob, 1); ob->buf[ob->pos] = 0; // prevent possible overrun if treated as a string return ret; }
lsb_err_value lsb_outputfd(lsb_output_buffer *b, double d) { if (!b) return LSB_ERR_UTIL_NULL; if (d < INT_MIN || d > INT_MAX) { return lsb_outputf(b, "%0.17g", d); } const int precision = 8; const unsigned magnitude = 100000000; char buffer[20]; char *p = buffer; int negative = 0; if (d < 0) { negative = 1; d = -d; } int number = (int)d; double tmp = (d - number) * magnitude; unsigned fraction = (unsigned)tmp; double diff = tmp - fraction; if (diff > 0.5) { ++fraction; if (fraction >= magnitude) { fraction = 0; ++number; } } else if (diff == 0.5 && ((fraction == 0) || (fraction & 1))) { // bankers rounding ++fraction; } // decimal fraction if (fraction != 0) { int nodigits = 1; char c = 0; for (int x = 0; x < precision; ++x) { c = fraction % 10; if (!(c == 0 && nodigits)) { *p++ = c + '0'; nodigits = 0; } fraction /= 10; } *p++ = '.'; } // number do { *p++ = (number % 10) + '0'; number /= 10; } while (number > 0); lsb_err_value ret = lsb_expand_output_buffer(b, (p - buffer) + negative); if (!ret) { if (negative) { b->buf[b->pos++] = '-'; } do { --p; b->buf[b->pos++] = *p; } while (p != buffer); b->buf[b->pos] = 0; } return ret; }