1 // Copyright 2023 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 #define VARINT_ENCODE_FUNCTION_BODY(bits) \
18 size_t written = 0; \
19 uint8_t* buffer = (uint8_t*)output; \
20 \
21 do { \
22 if (written >= output_size_bytes) { \
23 return 0u; \
24 } \
25 buffer[written++] = pw_varint_EncodeOneByte##bits(&integer); \
26 } while (integer != 0u); \
27 \
28 buffer[written - 1] &= 0x7f; \
29 return written
30
pw_varint_Encode32(uint32_t integer,void * output,size_t output_size_bytes)31 size_t pw_varint_Encode32(uint32_t integer,
32 void* output,
33 size_t output_size_bytes) {
34 VARINT_ENCODE_FUNCTION_BODY(32);
35 }
36
pw_varint_Encode64(uint64_t integer,void * output,size_t output_size_bytes)37 size_t pw_varint_Encode64(uint64_t integer,
38 void* output,
39 size_t output_size_bytes) {
40 VARINT_ENCODE_FUNCTION_BODY(64);
41 }
42
43 #define VARINT_DECODE_FUNCTION_BODY(bits) \
44 uint##bits##_t value = 0; \
45 size_t count = 0; \
46 const uint8_t* buffer = (const uint8_t*)(input); \
47 \
48 /* Only read to the end of the buffer or largest possible encoded size. */ \
49 const size_t max_count = \
50 input_size_bytes < PW_VARINT_MAX_INT##bits##_SIZE_BYTES \
51 ? input_size_bytes \
52 : PW_VARINT_MAX_INT##bits##_SIZE_BYTES; \
53 \
54 bool keep_going; \
55 do { \
56 if (count >= max_count) { \
57 return 0; \
58 } \
59 \
60 keep_going = pw_varint_DecodeOneByte##bits(buffer[count], count, &value); \
61 count += 1; \
62 } while (keep_going); \
63 \
64 *output = value; \
65 return count
66
pw_varint_Decode32(const void * input,size_t input_size_bytes,uint32_t * output)67 size_t pw_varint_Decode32(const void* input,
68 size_t input_size_bytes,
69 uint32_t* output) {
70 VARINT_DECODE_FUNCTION_BODY(32);
71 }
72
pw_varint_Decode64(const void * input,size_t input_size_bytes,uint64_t * output)73 size_t pw_varint_Decode64(const void* input,
74 size_t input_size_bytes,
75 uint64_t* output) {
76 VARINT_DECODE_FUNCTION_BODY(64);
77 }
78