var_int.cc (2301B)
1 /* 2 * Copyright (c) 2018 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "logging/rtc_event_log/encoder/var_int.h" 12 13 #include <cstddef> 14 #include <cstdint> 15 #include <string> 16 #include <utility> 17 18 #include "absl/strings/string_view.h" 19 #include "rtc_base/bitstream_reader.h" 20 #include "rtc_base/checks.h" 21 22 // TODO(eladalon): Add unit tests. 23 24 namespace webrtc { 25 26 const size_t kMaxVarIntLengthBytes = 10; // ceil(64 / 7.0) is 10. 27 28 std::string EncodeVarInt(uint64_t input) { 29 std::string output; 30 output.reserve(kMaxVarIntLengthBytes); 31 32 do { 33 uint8_t byte = static_cast<uint8_t>(input & 0x7f); 34 input >>= 7; 35 if (input > 0) { 36 byte |= 0x80; 37 } 38 output += byte; 39 } while (input > 0); 40 41 RTC_DCHECK_GE(output.size(), 1u); 42 RTC_DCHECK_LE(output.size(), kMaxVarIntLengthBytes); 43 44 return output; 45 } 46 47 // There is some code duplication between the flavors of this function. 48 // For performance's sake, it's best to just keep it. 49 std::pair<bool, absl::string_view> DecodeVarInt(absl::string_view input, 50 uint64_t* output) { 51 RTC_DCHECK(output); 52 53 uint64_t decoded = 0; 54 for (size_t i = 0; i < input.length() && i < kMaxVarIntLengthBytes; ++i) { 55 decoded += (static_cast<uint64_t>(input[i] & 0x7f) 56 << static_cast<uint64_t>(7 * i)); 57 if (!(input[i] & 0x80)) { 58 *output = decoded; 59 return {true, input.substr(i + 1)}; 60 } 61 } 62 63 return {false, input}; 64 } 65 66 // There is some code duplication between the flavors of this function. 67 // For performance's sake, it's best to just keep it. 68 uint64_t DecodeVarInt(BitstreamReader& input) { 69 uint64_t decoded = 0; 70 for (size_t i = 0; i < kMaxVarIntLengthBytes; ++i) { 71 uint8_t byte = input.Read<uint8_t>(); 72 decoded += 73 (static_cast<uint64_t>(byte & 0x7f) << static_cast<uint64_t>(7 * i)); 74 if (!(byte & 0x80)) { 75 return decoded; 76 } 77 } 78 79 input.Invalidate(); 80 return 0; 81 } 82 83 } // namespace webrtc