diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/yt/coding/varint-inl.h | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/yt/coding/varint-inl.h')
-rw-r--r-- | library/cpp/yt/coding/varint-inl.h | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/library/cpp/yt/coding/varint-inl.h b/library/cpp/yt/coding/varint-inl.h new file mode 100644 index 0000000000..f0a09e9d30 --- /dev/null +++ b/library/cpp/yt/coding/varint-inl.h @@ -0,0 +1,240 @@ +#ifndef VARINT_INL_H_ +#error "Direct inclusion of this file is not allowed, include varint.h" +// For the sake of sane code completion. +#include "varint.h" +#endif + +#include "zig_zag.h" + +namespace NYT { + +//////////////////////////////////////////////////////////////////////////////// + +template <class TWriteCallback> +Y_FORCE_INLINE int WriteVarUint64Impl(TWriteCallback doWrite, ui64 value) +{ + bool stop = false; + int bytesWritten = 0; + while (!stop) { + ++bytesWritten; + ui8 byte = static_cast<ui8>(value | 0x80); + value >>= 7; + if (value == 0) { + stop = true; + byte &= 0x7F; + } + doWrite(byte); + } + return bytesWritten; +} + +// These are optimized versions of these Read/Write functions in protobuf/io/coded_stream.cc. +Y_FORCE_INLINE int WriteVarUint64(IOutputStream* output, ui64 value) +{ + return WriteVarUint64Impl([&] (ui8 byte) { + output->Write(byte); + }, value); +} + +Y_FORCE_INLINE int WriteVarUint64(char* output, ui64 value) +{ + return WriteVarUint64Impl([&] (ui8 byte) { + *output++ = byte; + }, value); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <class TOutput> +Y_FORCE_INLINE int WriteVarUint32Impl(TOutput output, ui32 value) +{ + return WriteVarUint64(output, static_cast<ui64>(value)); +} + +Y_FORCE_INLINE int WriteVarUint32(IOutputStream* output, ui32 value) +{ + return WriteVarUint32Impl(output, value); +} + +Y_FORCE_INLINE int WriteVarUint32(char* output, ui32 value) +{ + return WriteVarUint32Impl(output, value); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <class TOutput> +Y_FORCE_INLINE int WriteVarInt32Impl(TOutput output, i32 value) +{ + return WriteVarUint64(output, static_cast<ui64>(ZigZagEncode32(value))); +} + +Y_FORCE_INLINE int WriteVarInt32(IOutputStream* output, i32 value) +{ + return WriteVarInt32Impl(output, value); +} + +Y_FORCE_INLINE int WriteVarInt32(char* output, i32 value) +{ + return WriteVarInt32Impl(output, value); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <class TOutput> +Y_FORCE_INLINE int WriteVarInt64Impl(TOutput output, i64 value) +{ + return WriteVarUint64(output, static_cast<ui64>(ZigZagEncode64(value))); +} + +Y_FORCE_INLINE int WriteVarInt64(IOutputStream* output, i64 value) +{ + return WriteVarInt64Impl(output, value); +} + +Y_FORCE_INLINE int WriteVarInt64(char* output, i64 value) +{ + return WriteVarInt64Impl(output, value); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <class TReadCallback> +Y_FORCE_INLINE int ReadVarUint64Impl(TReadCallback doRead, ui64* value) +{ + size_t count = 0; + ui64 result = 0; + + ui8 byte; + do { + if (7 * count > 8 * sizeof(ui64) ) { + throw TSimpleException("Value is too big for varuint64"); + } + byte = doRead(); + result |= (static_cast<ui64> (byte & 0x7F)) << (7 * count); + ++count; + } while (byte & 0x80); + + *value = result; + return count; +} + +Y_FORCE_INLINE int ReadVarUint64(IInputStream* input, ui64* value) +{ + return ReadVarUint64Impl([&] () { + char byte; + if (input->Read(&byte, 1) != 1) { + throw TSimpleException("Premature end of stream while reading varuint64"); + } + return byte; + }, value); +} + +Y_FORCE_INLINE int ReadVarUint64(const char* input, ui64* value) +{ + return ReadVarUint64Impl([&] () { + char byte = *input; + ++input; + return byte; + }, value); +} + +Y_FORCE_INLINE int ReadVarUint64(const char* input, const char* end, ui64* value) +{ + return ReadVarUint64Impl([&] () { + if (input == end) { + throw TSimpleException("Premature end of data while reading varuint64"); + } + char byte = *input; + ++input; + return byte; + }, value); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <class... Args> +Y_FORCE_INLINE int ReadVarUint32Impl(ui32* value, Args... args) +{ + ui64 varInt; + int bytesRead = ReadVarUint64(args..., &varInt); + if (varInt > std::numeric_limits<ui32>::max()) { + throw TSimpleException("Value is too big for varuint32"); + } + *value = static_cast<ui32>(varInt); + return bytesRead; +} + +Y_FORCE_INLINE int ReadVarUint32(IInputStream* input, ui32* value) +{ + return ReadVarUint32Impl(value, input); +} + +Y_FORCE_INLINE int ReadVarUint32(const char* input, ui32* value) +{ + return ReadVarUint32Impl(value, input); +} + +Y_FORCE_INLINE int ReadVarUint32(const char* input, const char* end, ui32* value) +{ + return ReadVarUint32Impl(value, input, end); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <class... Args> +Y_FORCE_INLINE int ReadVarInt32Impl(i32* value, Args... args) +{ + ui64 varInt; + int bytesRead = ReadVarUint64(args..., &varInt); + if (varInt > std::numeric_limits<ui32>::max()) { + throw TSimpleException("Value is too big for varint32"); + } + *value = ZigZagDecode32(static_cast<ui32>(varInt)); + return bytesRead; +} + +Y_FORCE_INLINE int ReadVarInt32(IInputStream* input, i32* value) +{ + return ReadVarInt32Impl(value, input); +} + +Y_FORCE_INLINE int ReadVarInt32(const char* input, i32* value) +{ + return ReadVarInt32Impl(value, input); +} + +Y_FORCE_INLINE int ReadVarInt32(const char* input, const char* end, i32* value) +{ + return ReadVarInt32Impl(value, input, end); +} + +//////////////////////////////////////////////////////////////////////////////// + +template <class... Args> +Y_FORCE_INLINE int ReadVarInt64Impl(i64* value, Args... args) +{ + ui64 varInt; + int bytesRead = ReadVarUint64(args..., &varInt); + *value = ZigZagDecode64(varInt); + return bytesRead; +} + +Y_FORCE_INLINE int ReadVarInt64(IInputStream* input, i64* value) +{ + return ReadVarInt64Impl(value, input); +} + +Y_FORCE_INLINE int ReadVarInt64(const char* input, i64* value) +{ + return ReadVarInt64Impl(value, input); +} + +Y_FORCE_INLINE int ReadVarInt64(const char* input, const char* end, i64* value) +{ + return ReadVarInt64Impl(value, input, end); +} + +//////////////////////////////////////////////////////////////////////////////// + +} // namespace NYT |