예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
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;
}