xref: /aosp_15_r20/external/webrtc/logging/rtc_event_log/encoder/var_int.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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)22 std::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)43 std::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)62 uint64_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