Esempio n. 1
0
void decode_decimal(pTHX_ unsigned char *input, STRLEN len, struct cc_type *type, SV *output)
{
    union {
        unsigned char bytes[4];
        int32_t scale;
    } bytes_or_scale;

    if (UNLIKELY(len < 5))
        croak("decode_decimal: len < 5");

    memcpy(bytes_or_scale.bytes, input, 4);
    bswap4(bytes_or_scale.bytes);
    bytes_or_scale.scale *= -1;

    decode_varint(aTHX_ input+4, len-4, type, output);
    if (bytes_or_scale.scale != 0) {
        char *sign;
        if (bytes_or_scale.scale > 0) {
            sign = "+";
        } else {
            sign = "";
        }
        sv_catpvf(output, "e%s%d", sign, bytes_or_scale.scale);
    }
}
Esempio n. 2
0
File: pb.c Progetto: boateam/boa
void decode_protobuf(char *buf, char *buf_end, yield_t yield)
{
    while(buf < buf_end)
    {
        uint64_t key = decode_varint(buf, &buf);
        struct key_value_pair pair = {
            .field_number = key >> 3,
            .wire_type = key & 0x07
        };
        switch(pair.wire_type)
        {
            case WT_VARINT:  /* varint */
                pair.value.varint = decode_varint(buf, &buf);
                break;

            case WT_64BIT:  /* 64 bit */
                pair.value._64_bit = get_32_le(buf, &buf);
                buf += 4;
                pair.value._64_bit |= (uint64_t)get_32_le(buf, &buf) << 32;
                buf += 4;
                break;

            case WT_STRING:  /* string */
                pair.value.string.len = decode_varint(buf, &buf);
                pair.value.string.start = buf;
                buf += pair.value.string.len;
                break;

            case WT_32BIT:  /* 32 bit */
                pair.value._32_bit = get_32_le(buf, &buf);
                buf += 4;
                break;
        }

        yield(&pair);
    }
}

void yield_cb(struct key_value_pair *pair)
{
    printf("Field number: %d, Wire type: %d\n", pair->field_number,
                                                pair->wire_type);
}
Esempio n. 3
0
  /**
   * Convert a <code>CassDecimal<code/> object into a numerical string value
   *
   * @param byte_array Byte array to convert
   * @return String representation of numerical value
   */
  static std::string to_string(CassDecimal decimal) {
    std::string byte_array = std::string(reinterpret_cast<const char *>(decimal.varint), decimal.varint_size);
    std::string integer_value = decode_varint(byte_array.c_str());

    //Ensure the decimal has scale
    if (decimal.scale > 0) {
      unsigned int period_position = integer_value.size() - decimal.scale;
      return integer_value.substr(0, period_position) + "." + integer_value.substr(period_position);
    }
    return integer_value;
  }
Esempio n. 4
0
// Decodes a 32-bit varint from the current buffer position.
// Returns a status code as described in decoder.int.h.
FORCEINLINE int32_t decode_v32(upb_pbdecoder *d, uint32_t *u32) {
  uint64_t u64;
  int32_t ret = decode_varint(d, &u64);
  if (ret >= 0) return ret;
  if (u64 > UINT32_MAX) {
    seterr(d, "Unterminated 32-bit varint");
    // TODO(haberman) guarantee that this function return is >= 0 somehow,
    // so we know this path will always be treated as error by our caller.
    // Right now the size_t -> int32_t can overflow and produce negative values.
    *u32 = 0;
    return upb_pbdecoder_suspend(d);
  }
  *u32 = u64;
  return DECODE_OK;
}
Esempio n. 5
0
/* 32bit compat */
void decode_time(pTHX_ unsigned char *input, STRLEN len, struct cc_type *type, SV *output)
{
    int32_t nano, seconds, hours, minutes;
    char *txt;
    char workbuf[20];
    STRLEN txt_len;

    decode_varint(aTHX_ input, len, type, output);
    /* output now contains a string represending the ns since midnight */

    txt = SvPV(output, txt_len);
    if (txt_len > 14) {
        croak("decode_time: invalid value");
    }

    if (txt_len <= 9) {
        memset(workbuf, 0, 20);
        memcpy(workbuf, txt, txt_len);
        seconds = 0;
        nano = atoi(workbuf);
    } else {
        memset(workbuf, 0, 20);
        memcpy(workbuf, txt+txt_len-9, 9);
        nano = atoi(workbuf);
        memset(workbuf, 0, 20);
        memcpy(workbuf, txt, txt_len-9);
        seconds = atoi(workbuf);
    }

    hours   = seconds / 3600;
    minutes = (seconds % 3600) / 60;
    seconds = seconds % 60;

    sv_setpvf(output, "%d:%.2d:%.2d.%d", hours, minutes, seconds, nano);
    txt = SvPV(output, txt_len);
    while (txt[txt_len-1] == '0')
        txt_len--;
    if (txt[txt_len-1] == '.')
        txt_len--;
    SvCUR_set(output, txt_len);
}
Esempio n. 6
0
T pbf::get_svarint() {
    pbf_assert((has_wire_type(pbf_wire_type::varint) || has_wire_type(pbf_wire_type::length_delimited)) && "not a varint");
    return static_cast<T>(decode_zigzag64(decode_varint(&m_data, m_end)));
}
Esempio n. 7
0
T pbf::get_varint() {
    return static_cast<T>(decode_varint(&m_data, m_end));
}
Esempio n. 8
0
int32_t upb_pbdecoder_skipunknown(upb_pbdecoder *d, int32_t fieldnum,
                                  uint8_t wire_type) {
  if (fieldnum >= 0)
    goto have_tag;

  while (true) {
    uint32_t tag;
    CHECK_RETURN(decode_v32(d, &tag));
    wire_type = tag & 0x7;
    fieldnum = tag >> 3;

have_tag:
    if (fieldnum == 0) {
      seterr(d, "Saw invalid field number (0)");
      return upb_pbdecoder_suspend(d);
    }

    // TODO: deliver to unknown field callback.
    switch (wire_type) {
      case UPB_WIRE_TYPE_32BIT:
        CHECK_RETURN(skip(d, 4));
        break;
      case UPB_WIRE_TYPE_64BIT:
        CHECK_RETURN(skip(d, 8));
        break;
      case UPB_WIRE_TYPE_VARINT: {
        uint64_t u64;
        CHECK_RETURN(decode_varint(d, &u64));
        break;
      }
      case UPB_WIRE_TYPE_DELIMITED: {
        uint32_t len;
        CHECK_RETURN(decode_v32(d, &len));
        CHECK_RETURN(skip(d, len));
        break;
      }
      case UPB_WIRE_TYPE_START_GROUP:
        CHECK_SUSPEND(pushtagdelim(d, -fieldnum));
        break;
      case UPB_WIRE_TYPE_END_GROUP:
        if (fieldnum == -d->top->groupnum) {
          pop(d);
        } else if (fieldnum == d->top->groupnum) {
          return DECODE_ENDGROUP;
        } else {
          seterr(d, "Unmatched ENDGROUP tag.");
          return upb_pbdecoder_suspend(d);
        }
        break;
      default:
        seterr(d, "Invalid wire type");
        return upb_pbdecoder_suspend(d);
    }

    if (d->top->groupnum >= 0) {
      return DECODE_OK;
    }

    if (d->ptr == d->delim_end) {
      seterr(d, "Enclosing submessage ended in the middle of value or group");
      // Unlike most errors we notice during parsing, right now we have consumed
      // all of the user's input.
      //
      // There are three different options for how to handle this case:
      //
      //   1. decode() = short count, error = set
      //   2. decode() = full count, error = set
      //   3. decode() = full count, error NOT set, short count and error will
      //      be reported on next call to decode() (or end())
      //
      // (1) and (3) have the advantage that they preserve the invariant that an
      // error occurs iff decode() returns a short count.
      //
      // (2) and (3) have the advantage of reflecting the fact that all of the
      // bytes were in fact parsed (and possibly delivered to the unknown field
      // handler, in the future when that is supported).
      //
      // (3) requires extra state in the decode (a place to store the "permanent
      // error" that we should return for all subsequent attempts to decode).
      // But we likely want this anyway.
      //
      // Right now we do (1), thanks to the fact that we checkpoint *after* this
      // check.  (3) may be a better choice long term; unclear at the moment.
      return upb_pbdecoder_suspend(d);
    }

    checkpoint(d);
  }
}
Esempio n. 9
0
 /**
  * Convert a two's compliment byte array into a numerical string value
  *
  * @param byte_array Byte array to convert
  * @return String representation of numerical value
  */
 static std::string to_string(const char *byte_array) {
   return decode_varint(byte_array);
 }
Esempio n. 10
0
void decode_cell(pTHX_ unsigned char *input, STRLEN len, STRLEN *pos, struct cc_type *type, SV *output)
{
    unsigned char *bytes;
    STRLEN bytes_len;

    if (unpack_bytes(aTHX_ input, len, pos, &bytes, &bytes_len) != 0) {
        sv_setsv(output, &PL_sv_undef);
        return;
    }

    switch (type->type_id) {
        case CC_TYPE_ASCII:
        case CC_TYPE_CUSTOM:
        case CC_TYPE_BLOB:
            decode_blob(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_BOOLEAN:
            decode_boolean(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_VARCHAR:
        case CC_TYPE_TEXT:
            decode_utf8(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_INET:
            decode_inet(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_SET:
        case CC_TYPE_LIST:
            decode_list(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_UUID:
        case CC_TYPE_TIMEUUID:
            decode_uuid(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_FLOAT:
            decode_float(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_DOUBLE:
            decode_double(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_DECIMAL:
            decode_decimal(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_VARINT:
        case CC_TYPE_BIGINT:
        case CC_TYPE_COUNTER:
        case CC_TYPE_TIMESTAMP:
        case CC_TYPE_SMALLINT:
        case CC_TYPE_TINYINT:
        case CC_TYPE_INT:
            decode_varint(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_DATE:
            decode_date(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_TIME:
            decode_time(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_MAP:
            decode_map(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_UDT:
            decode_udt(aTHX_ bytes, bytes_len, type, output);
            break;

        case CC_TYPE_TUPLE:
            decode_tuple(aTHX_ bytes, bytes_len, type, output);
            break;

        default:
            sv_setsv(output, &PL_sv_undef);
            warn("Decoder doesn't yet understand type %d, returning undef instead", type->type_id);
            break;
    }
}