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 "rtc_base/bitstream_reader.h" 14 #include "rtc_base/checks.h" 15 16 // TODO(eladalon): Add unit tests. 17 18 namespace webrtc { 19 20 const size_t kMaxVarIntLengthBytes = 10; // ceil(64 / 7.0) is 10. 21 EncodeVarInt(uint64_t input)22std::string EncodeVarInt(uint64_t input) { 23 std::string output; 24 output.reserve(kMaxVarIntLengthBytes); 25 26 do { 27 uint8_t byte = static_cast<uint8_t>(input & 0x7f); 28 input >>= 7; 29 if (input > 0) { 30 byte |= 0x80; 31 } 32 output += byte; 33 } while (input > 0); 34 35 RTC_DCHECK_GE(output.size(), 1u); 36 RTC_DCHECK_LE(output.size(), kMaxVarIntLengthBytes); 37 38 return output; 39 } 40 41 // There is some code duplication between the flavors of this function. 42 // For performance's sake, it's best to just keep it. DecodeVarInt(absl::string_view input,uint64_t * output)43std::pair<bool, absl::string_view> DecodeVarInt(absl::string_view input, 44 uint64_t* output) { 45 RTC_DCHECK(output); 46 47 uint64_t decoded = 0; 48 for (size_t i = 0; i < input.length() && i < kMaxVarIntLengthBytes; ++i) { 49 decoded += (static_cast<uint64_t>(input[i] & 0x7f) 50 << static_cast<uint64_t>(7 * i)); 51 if (!(input[i] & 0x80)) { 52 *output = decoded; 53 return {true, input.substr(i + 1)}; 54 } 55 } 56 57 return {false, input}; 58 } 59 60 // There is some code duplication between the flavors of this function. 61 // For performance's sake, it's best to just keep it. DecodeVarInt(BitstreamReader & input)62uint64_t DecodeVarInt(BitstreamReader& input) { 63 uint64_t decoded = 0; 64 for (size_t i = 0; i < kMaxVarIntLengthBytes; ++i) { 65 uint8_t byte = input.Read<uint8_t>(); 66 decoded += 67 (static_cast<uint64_t>(byte & 0x7f) << static_cast<uint64_t>(7 * i)); 68 if (!(byte & 0x80)) { 69 return decoded; 70 } 71 } 72 73 input.Invalidate(); 74 return 0; 75 } 76 77 } // namespace webrtc 78