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/monlib/encode/spack/varint.cpp | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/monlib/encode/spack/varint.cpp')
-rw-r--r-- | library/cpp/monlib/encode/spack/varint.cpp | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/library/cpp/monlib/encode/spack/varint.cpp b/library/cpp/monlib/encode/spack/varint.cpp new file mode 100644 index 0000000000..051cf17380 --- /dev/null +++ b/library/cpp/monlib/encode/spack/varint.cpp @@ -0,0 +1,79 @@ +#include "varint.h" + +#include <util/generic/yexception.h> +#include <util/stream/input.h> +#include <util/stream/output.h> + +namespace NMonitoring { + ui32 WriteVarUInt32(IOutputStream* output, ui32 value) { + bool stop = false; + ui32 written = 0; + while (!stop) { + ui8 byte = static_cast<ui8>(value | 0x80); + value >>= 7; + if (value == 0) { + stop = true; + byte &= 0x7F; + } + output->Write(byte); + written++; + } + return written; + } + + ui32 ReadVarUInt32(IInputStream* input) { + ui32 value = 0; + switch (TryReadVarUInt32(input, &value)) { + case EReadResult::OK: + return value; + case EReadResult::ERR_OVERFLOW: + ythrow yexception() << "the data is too long to read ui32"; + case EReadResult::ERR_UNEXPECTED_EOF: + ythrow yexception() << "the data unexpectedly ended"; + default: + ythrow yexception() << "unknown error while reading varint"; + } + } + + size_t ReadVarUInt32(const ui8* buf, size_t len, ui32* result) { + size_t count = 0; + ui32 value = 0; + + ui8 byte = 0; + do { + if (7 * count > 8 * sizeof(ui32)) { + ythrow yexception() << "the data is too long to read ui32"; + } + if (count == len) { + ythrow yexception() << "the data unexpectedly ended"; + } + byte = buf[count]; + value |= (static_cast<ui32>(byte & 0x7F)) << (7 * count); + ++count; + } while (byte & 0x80); + + *result = value; + return count; + } + +EReadResult TryReadVarUInt32(IInputStream* input, ui32* value) { + size_t count = 0; + ui32 result = 0; + + ui8 byte = 0; + do { + if (7 * count > 8 * sizeof(ui32)) { + return EReadResult::ERR_OVERFLOW; + } + if (input->Read(&byte, 1) != 1) { + return EReadResult::ERR_UNEXPECTED_EOF; + } + result |= (static_cast<ui32>(byte & 0x7F)) << (7 * count); + ++count; + } while (byte & 0x80); + + *value = result; + return EReadResult::OK; + } + +} |