varint.cpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. #include "varint.h"
  2. #include "zigzag.h"
  3. #include <util/generic/yexception.h>
  4. #include <util/generic/ylimits.h>
  5. namespace NYson {
  6. ////////////////////////////////////////////////////////////////////////////////
  7. int WriteVarUInt64(IOutputStream* output, ui64 value) {
  8. bool stop = false;
  9. int bytesWritten = 0;
  10. while (!stop) {
  11. ++bytesWritten;
  12. ui8 byte = static_cast<ui8>(value | 0x80);
  13. value >>= 7;
  14. if (value == 0) {
  15. stop = true;
  16. byte &= 0x7F;
  17. }
  18. output->Write(byte);
  19. }
  20. return bytesWritten;
  21. }
  22. int WriteVarInt32(IOutputStream* output, i32 value) {
  23. return WriteVarUInt64(output, static_cast<ui64>(ZigZagEncode32(value)));
  24. }
  25. int WriteVarInt64(IOutputStream* output, i64 value) {
  26. return WriteVarUInt64(output, static_cast<ui64>(ZigZagEncode64(value)));
  27. }
  28. int ReadVarUInt64(IInputStream* input, ui64* value) {
  29. size_t count = 0;
  30. ui64 result = 0;
  31. ui8 byte = 0;
  32. do {
  33. if (7 * count > 8 * sizeof(ui64)) {
  34. ythrow yexception() << "The data is too long to read ui64";
  35. }
  36. if (input->Read(&byte, 1) != 1) {
  37. ythrow yexception() << "The data is too short to read ui64";
  38. }
  39. result |= (static_cast<ui64>(byte & 0x7F)) << (7 * count);
  40. ++count;
  41. } while (byte & 0x80);
  42. *value = result;
  43. return count;
  44. }
  45. int ReadVarInt32(IInputStream* input, i32* value) {
  46. ui64 varInt;
  47. int bytesRead = ReadVarUInt64(input, &varInt);
  48. if (varInt > Max<ui32>()) {
  49. ythrow yexception() << "The data is too long to read i32";
  50. }
  51. *value = ZigZagDecode32(static_cast<ui32>(varInt));
  52. return bytesRead;
  53. }
  54. int ReadVarInt64(IInputStream* input, i64* value) {
  55. ui64 varInt;
  56. int bytesRead = ReadVarUInt64(input, &varInt);
  57. *value = ZigZagDecode64(varInt);
  58. return bytesRead;
  59. }
  60. } // namespace NYson