int serialize_table_as_pb(lua_sandbox* lsb, int index)
{
  output_data* d = &lsb->output;
  d->pos = 0;
  size_t needed = 18;
  if (needed > d->size) {
    if (realloc_output(d, needed)) return 1;
  }

  // create a type 4 uuid
  d->data[d->pos++] = 2 | (1 << 3);
  d->data[d->pos++] = 16;
  for (int x = 0; x < 16; ++x) {
    d->data[d->pos++] = rand() % 255;
  }
  d->data[8] = (d->data[8] & 0x0F) | 0x40;
  d->data[10] = (d->data[10] & 0x0F) | 0xA0;

  // use existing or create a timestamp
  lua_getfield(lsb->lua, index, "Timestamp");
  long long ts;
  if (lua_isnumber(lsb->lua, -1)) {
    ts = (long long)lua_tonumber(lsb->lua, -1);
  } else {
    ts = (long long)(time(NULL) * 1e9);
  }
  lua_pop(lsb->lua, 1);
  if (pb_write_tag(d, 2, 0)) return 1;
  if (pb_write_varint(d, ts)) return 1;

  if (encode_string(lsb, d, 3, "Type", index)) return 1;
  if (encode_string(lsb, d, 4, "Logger", index)) return 1;
  if (encode_int(lsb, d, 5, "Severity", index)) return 1;
  if (encode_string(lsb, d, 6, "Payload", index)) return 1;
  if (encode_string(lsb, d, 7, "EnvVersion", index)) return 1;
  if (encode_int(lsb, d, 8, "Pid", index)) return 1;
  if (encode_string(lsb, d, 9, "Hostname", index)) return 1;
  if (encode_fields(lsb, d, 10, "Fields", index)) return 1;
  // if we go above 15 pb_write_tag will need to start varint encoding
  needed = 1;
  if (needed > d->size - d->pos) {
    if (realloc_output(d, needed)) return 1;
  }
  d->data[d->pos] = 0; // NULL terminate incase someone tries to treat this
                       // as a string

  return 0;
}
예제 #2
0
int appendc(output_data* output, char ch)
{
  size_t needed = 2;
  if (output->size - output->pos < needed) {
    if (realloc_output(output, needed)) return 1;
  }
  output->data[output->pos++] = ch;
  output->data[output->pos] = 0;
  return 0;
}
예제 #3
0
int appends(output_data* output, const char* str)
{
  size_t needed = strlen(str) + 1;
  if (output->size - output->pos < needed) {
    if (realloc_output(output, needed)) return 1;
  }
  memcpy(output->data + output->pos, str, needed);
  output->pos += needed - 1;
  return 0;
}
int pb_write_tag(output_data* d, char id, char wire_type)
{
  size_t needed = 1;
  if (needed > d->size - d->pos) {
    if (realloc_output(d, needed)) return 1;
  }

  d->data[d->pos++] = wire_type | (id << 3);
  return 0;
}
int pb_write_double(output_data* d, double i)
{
  size_t needed = sizeof(double);
  if (needed > d->size - d->pos) {
    if (realloc_output(d, needed)) return 1;
  }

  memcpy(&d->data[d->pos], &i, needed);
  d->pos += needed;
  return 0;
}
int pb_write_bool(output_data* d, int i)
{
  size_t needed = 1;
  if (needed > d->size - d->pos) {
    if (realloc_output(d, needed)) return 1;
  }

  if (i) {
    d->data[d->pos++] = 1;
  } else {
    d->data[d->pos++] = 0;
  }
  return 0;
}
예제 #7
0
int pb_write_string(output_data* d, char id, const char* s, size_t len)
{

    if (pb_write_tag(d, id, 2)) return 1;
    if (pb_write_varint(d, len)) return 1;

    size_t needed = len;
    if (needed > d->m_size - d->m_pos) {
        if (realloc_output(d, needed)) return 1;
    }
    memcpy(&d->m_data[d->m_pos], s, len);
    d->m_pos += len;
    return 0;
}
int pb_write_varint(output_data* d, long long i)
{
  size_t needed = 10;
  if (needed > d->size - d->pos) {
    if (realloc_output(d, needed)) return 1;
  }

  if (i == 0) {
    d->data[d->pos++] = 0;
    return 0;
  }

  while (i) {
    d->data[d->pos++] = (i & 0x7F) | 0x80;
    i >>= 7;
  }
  d->data[d->pos - 1] &= 0x7F; // end the varint
  return 0;
}
int update_field_length(output_data* d, size_t len_pos)
{
  size_t len = d->pos - len_pos - 1;
  if (len < 128) {
    d->data[len_pos] = (char)len;
    return 0;
  }
  size_t l = len, cnt = 0;
  while (l) {
    l >>= 7;
    ++cnt;  // compute the number of bytes needed for the varint length
  }
  size_t needed = cnt - 1;
  if (needed > d->size - d->pos) {
    if (realloc_output(d, needed)) return 1;
  }
  size_t end_pos = d->pos + needed;
  memmove(&d->data[len_pos + cnt], &d->data[len_pos + 1], len);
  d->pos = len_pos;
  if (pb_write_varint(d, len)) return 1;
  d->pos = end_pos;
  return 0;
}
예제 #10
0
int serialize_data_as_json(lua_sandbox* lsb, int index, output_data* output)
{
  const char* s;
  size_t len = 0;
  size_t start_pos = output->pos;
  size_t escaped_len = 0;
  switch (lua_type(lsb->lua, index)) {
  case LUA_TNUMBER:
    if (serialize_double(output, lua_tonumber(lsb->lua, index))) {
      return 1;
    }
    break;
  case LUA_TSTRING:
    s = lua_tolstring(lsb->lua, index, &len);
    escaped_len = len + 3; // account for the quotes and terminator
    if (output->pos + escaped_len > output->size) {
      if (realloc_output(output, escaped_len)) return 1;
    }
    output->data[output->pos++] = '"';

    for (size_t i = 0; i < len; ++i) {
      // buffer needs at least enough room for an escaped character, an end
      // quote and a null terminator
      if (output->pos + 4 > output->size) {
        size_t needed = escaped_len - (output->pos - start_pos);
        if (realloc_output(output, needed)) return 1;
      }
      switch (s[i]) {
      case '"':
        output->data[output->pos++] = '\\';
        output->data[output->pos++] = '"';
        ++escaped_len;
        break;
      case '\\':
        output->data[output->pos++] = '\\';
        output->data[output->pos++] = '\\';
        ++escaped_len;
        break;
      case '/':
        output->data[output->pos++] = '\\';
        output->data[output->pos++] = '/';
        ++escaped_len;
        break;
      case '\b':
        output->data[output->pos++] = '\\';
        output->data[output->pos++] = 'b';
        ++escaped_len;
        break;
      case '\f':
        output->data[output->pos++] = '\\';
        output->data[output->pos++] = 'f';
        ++escaped_len;
        break;
      case '\n':
        output->data[output->pos++] = '\\';
        output->data[output->pos++] = 'n';
        ++escaped_len;
        break;
      case '\r':
        output->data[output->pos++] = '\\';
        output->data[output->pos++] = 'r';
        ++escaped_len;
        break;
      case '\t':
        output->data[output->pos++] = '\\';
        output->data[output->pos++] = 't';
        ++escaped_len;
        break;
      default:
        output->data[output->pos++] = s[i];
      }
    }
    output->data[output->pos++] = '"';
    output->data[output->pos] = 0;
    break;
  case LUA_TBOOLEAN:
    if (appendf(output, "%s", lua_toboolean(lsb->lua, index)
                ? "true" : "false")) {
      return 1;
    }
  case LUA_TNIL:
    break;
  default:
    snprintf(lsb->error_message, LSB_ERROR_SIZE,
             "serialize_data_as_json cannot preserve type '%s'",
             lua_typename(lsb->lua, lua_type(lsb->lua, index)));
    return 1;
  }
  return 0;
}