먼저 varints는 1
및 0
인 문자열이 아닌 실제 바이트로 전송됩니다.
부호없는 varint의 경우, 다음 코드는 data
이 가리키는 버퍼에 varint 데이터가 있다고 가정 할 때 다음 코드를 디코딩합니다. 이 예제 함수는 참조 인수 int decoded_bytes
에서 디코딩 된 바이트 수를 반환합니다.
uint64_t decode_unsigned_varint(const uint8_t *const data, int &decoded_bytes)
{
int i = 0;
uint64_t decoded_value = 0;
int shift_amount = 0;
do
{
decoded_value |= (uint64_t)(data[i] & 0x7F) << shift_amount;
shift_amount += 7;
} while ((data[i++] & 0x80) != 0);
decoded_bytes = i;
return decoded_value;
}
서명 된 varint를 해독하려면 첫 번째 호출이 제 기능을 사용할 수 있습니다
int64_t decode_signed_varint(const uint8_t *const data, int &decoded_bytes)
{
uint64_t unsigned_value = decode_unsigned_varint(data, decoded_bytes);
return (int64_t)(unsigned_value & 1 ? ~(unsigned_value >> 1)
: (unsigned_value >> 1));
}
을 나는이 기능을 모두 올바른 믿습니다. 아래의 코드를 사용하여 몇 가지 기본 테스트를 수행하여 Google 페이지에서 몇 가지 데이터 포인트를 확인했습니다. 출력이 정확합니다.
#include <stdint.h>
#include <iostream>
uint64_t decode_unsigned_varint(const uint8_t *const data, int &decoded_bytes)
{
int i = 0;
uint64_t decoded_value = 0;
int shift_amount = 0;
do
{
decoded_value |= (uint64_t)(data[i] & 0x7F) << shift_amount;
shift_amount += 7;
} while ((data[i++] & 0x80) != 0);
decoded_bytes = i;
return decoded_value;
}
int64_t decode_signed_varint(const uint8_t *const data, int &decoded_bytes)
{
uint64_t unsigned_value = decode_unsigned_varint(data, decoded_bytes);
return (int64_t)(unsigned_value & 1 ? ~(unsigned_value >> 1)
: (unsigned_value >> 1));
}
uint8_t ex_p300[] = { 0xAC, 0x02 };
uint8_t ex_n1 [] = { 0x01 };
using namespace std;
int main()
{
int decoded_bytes_p300;
uint64_t p300;
p300 = decode_unsigned_varint(ex_p300, decoded_bytes_p300);
int decoded_bytes_n1;
int64_t n1;
n1 = decode_signed_varint(ex_n1, decoded_bytes_n1);
cout << "p300 = " << p300
<< " decoded_bytes_p300 = " << decoded_bytes_p300 << endl;
cout << "n1 = " << n1
<< " decoded_bytes_n1 = " << decoded_bytes_n1 << endl;
return 0;
}
varint를 인코딩하려면 다음 기능을 사용할 수 있습니다. 버퍼 uint8_t *const data
에는 최대 10 바이트의 공간이 있어야하며 최대 varint는 10 바이트입니다.
은 #INCLUDE 내가 본 적이
// Encode an unsigned 64-bit varint. Returns number of encoded bytes.
// 'buffer' must have room for up to 10 bytes.
int encode_unsigned_varint(uint8_t *const buffer, uint64_t value)
{
int encoded = 0;
do
{
uint8_t next_byte = value & 0x7F;
value >>= 7;
if (value)
next_byte |= 0x80;
buffer[encoded++] = next_byte;
} while (value);
return encoded;
}
// Encode a signed 64-bit varint. Works by first zig-zag transforming
// signed value into an unsigned value, and then reusing the unsigned
// encoder. 'buffer' must have room for up to 10 bytes.
int encode_signed_varint(uint8_t *const buffer, int64_t value)
{
uint64_t uvalue;
uvalue = uint64_t(value < 0 ? ~(value << 1) : (value << 1));
return encode_unsigned_varint(buffer, uvalue);
}
전에 varints,하지만 난 "varint C 라이브러리"에 대한 구글을 시도하고 일부 안타를 얻었다. 그 거대한 대답에 감사합니다. –