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