#include "coding.h"
#include <cstddef>
#include <string_view>
namespace eloqstore
{
void PutFixed16(std::string *dst, uint16_t value)
{
char buf[sizeof(uint16_t)];
EncodeFixed16(buf, value);
dst->append(buf, sizeof(uint16_t));
}
void PutFixed32(std::string *dst, uint32_t value)
{
char buf[sizeof(value)];
EncodeFixed32(buf, value);
dst->append(buf, sizeof(buf));
}
void PutFixed64(std::string *dst, uint64_t value)
{
char buf[sizeof(value)];
EncodeFixed64(buf, value);
dst->append(buf, sizeof(buf));
}
char *EncodeVarint32(char *dst, uint32_t v)
{
uint8_t *ptr = reinterpret_cast<uint8_t *>(dst);
static const int B = 128;
if (v < (1 << 7))
{
*(ptr++) = v;
}
else if (v < (1 << 14))
{
*(ptr++) = v | B;
*(ptr++) = v >> 7;
}
else if (v < (1 << 21))
{
*(ptr++) = v | B;
*(ptr++) = (v >> 7) | B;
*(ptr++) = v >> 14;
}
else if (v < (1 << 28))
{
*(ptr++) = v | B;
*(ptr++) = (v >> 7) | B;
*(ptr++) = (v >> 14) | B;
*(ptr++) = v >> 21;
}
else
{
*(ptr++) = v | B;
*(ptr++) = (v >> 7) | B;
*(ptr++) = (v >> 14) | B;
*(ptr++) = (v >> 21) | B;
*(ptr++) = v >> 28;
}
return reinterpret_cast<char *>(ptr);
}
size_t Varint32Size(uint32_t v)
{
if (v < (1 << 7))
{
return 1;
}
else if (v < (1 << 14))
{
return 2;
}
else if (v < (1 << 21))
{
return 3;
}
else if (v < (1 << 28))
{
return 4;
}
else
{
return 5;
}
}
void PutVarint32(std::string *dst, uint32_t v)
{
char buf[5];
char *ptr = EncodeVarint32(buf, v);
dst->append(buf, ptr - buf);
}
char *EncodeVarint64(char *dst, uint64_t v)
{
static const int B = 128;
uint8_t *ptr = reinterpret_cast<uint8_t *>(dst);
while (v >= B)
{
*(ptr++) = v | B;
v >>= 7;
}
*(ptr++) = static_cast<uint8_t>(v);
return reinterpret_cast<char *>(ptr);
}
size_t Varint64Size(uint64_t value)
{
static const int B = 128;
size_t bytes = 1;
while (value >= B)
{
value >>= 7;
++bytes;
}
return bytes;
}
void PutVarint64(std::string *dst, uint64_t v)
{
char buf[10];
char *ptr = EncodeVarint64(buf, v);
dst->append(buf, ptr - buf);
}
int VarintLength(uint64_t v)
{
int len = 1;
while (v >= 128)
{
v >>= 7;
len++;
}
return len;
}
const char *GetVarint32PtrFallback(const char *p,
const char *limit,
uint32_t *value)
{
uint32_t result = 0;
for (uint32_t shift = 0; shift <= 28 && p < limit; shift += 7)
{
uint32_t byte = *(reinterpret_cast<const uint8_t *>(p));
p++;
if (byte & 128)
{
result |= ((byte & 127) << shift);
}
else
{
result |= (byte << shift);
*value = result;
return reinterpret_cast<const char *>(p);
}
}
return nullptr;
}
bool GetVarint32(std::string_view *input, uint32_t *value)
{
const char *p = input->data();
const char *limit = p + input->size();
const char *q = GetVarint32Ptr(p, limit, value);
if (q == nullptr)
{
return false;
}
else
{
*input = {q, (size_t) (limit - q)};
return true;
}
}
const char *GetVarint64Ptr(const char *p, const char *limit, uint64_t *value)
{
uint64_t result = 0;
for (uint32_t shift = 0; shift <= 63 && p < limit; shift += 7)
{
uint64_t byte = *(reinterpret_cast<const uint8_t *>(p));
p++;
if (byte & 128)
{
result |= ((byte & 127) << shift);
}
else
{
result |= (byte << shift);
*value = result;
return reinterpret_cast<const char *>(p);
}
}
return nullptr;
}
bool GetVarint64(std::string_view *input, uint64_t *value)
{
const char *p = input->data();
const char *limit = p + input->size();
const char *q = GetVarint64Ptr(p, limit, value);
if (q == nullptr)
{
return false;
}
else
{
*input = {q, (size_t) (limit - q)};
return true;
}
}
}