Fix for x86_64 build fail
[platform/upstream/connectedhomeip.git] / third_party / pigweed / repo / pw_varint / varint.cc
1 // Copyright 2020 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 #include "pw_varint/varint.h"
16
17 #include <algorithm>
18
19 namespace pw {
20 namespace varint {
21
22 extern "C" size_t pw_VarintEncode(uint64_t integer,
23                                   void* output,
24                                   size_t output_size) {
25   size_t written = 0;
26   std::byte* buffer = static_cast<std::byte*>(output);
27
28   do {
29     if (written >= output_size) {
30       return 0;
31     }
32
33     // Grab 7 bits; the eighth bit is set to 1 to indicate more data coming.
34     buffer[written++] = static_cast<std::byte>(integer) | std::byte(0x80);
35     integer >>= 7;
36   } while (integer != 0u);
37
38   buffer[written - 1] &= std::byte(0x7f);  // clear the top bit of the last byte
39   return written;
40 }
41
42 extern "C" size_t pw_VarintZigZagEncode(int64_t integer,
43                                         void* output,
44                                         size_t output_size) {
45   return pw_VarintEncode(ZigZagEncode(integer), output, output_size);
46 }
47
48 extern "C" size_t pw_VarintDecode(const void* input,
49                                   size_t input_size,
50                                   uint64_t* output) {
51   uint64_t decoded_value = 0;
52   uint_fast8_t count = 0;
53   const std::byte* buffer = static_cast<const std::byte*>(input);
54
55   // The largest 64-bit ints require 10 B.
56   const size_t max_count = std::min(kMaxVarint64SizeBytes, input_size);
57
58   while (true) {
59     if (count >= max_count) {
60       return 0;
61     }
62
63     // Add the bottom seven bits of the next byte to the result.
64     decoded_value |= static_cast<uint64_t>(buffer[count] & std::byte(0x7f))
65                      << (7 * count);
66
67     // Stop decoding if the top bit is not set.
68     if ((buffer[count++] & std::byte(0x80)) == std::byte(0)) {
69       break;
70     }
71   }
72
73   *output = decoded_value;
74   return count;
75 }
76
77 extern "C" size_t pw_VarintZigZagDecode(const void* input,
78                                         size_t input_size,
79                                         int64_t* output) {
80   uint64_t value = 0;
81   size_t bytes = pw_VarintDecode(input, input_size, &value);
82   *output = ZigZagDecode(value);
83   return bytes;
84 }
85
86 extern "C" size_t pw_VarintEncodedSize(uint64_t integer) {
87   return EncodedSize(integer);
88 }
89
90 extern "C" size_t pw_VarintZigZagEncodedSize(int64_t integer) {
91   return ZigZagEncodedSize(integer);
92 }
93
94 }  // namespace varint
95 }  // namespace pw