diff options
Diffstat (limited to 'pw_varint/varint_c.c')
-rw-r--r-- | pw_varint/varint_c.c | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/pw_varint/varint_c.c b/pw_varint/varint_c.c new file mode 100644 index 000000000..9194b4e34 --- /dev/null +++ b/pw_varint/varint_c.c @@ -0,0 +1,77 @@ +// Copyright 2023 The Pigweed Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +#include "pw_varint/varint.h" + +#define VARINT_ENCODE_FUNCTION_BODY(bits) \ + size_t written = 0; \ + uint8_t* buffer = (uint8_t*)output; \ + \ + do { \ + if (written >= output_size_bytes) { \ + return 0u; \ + } \ + buffer[written++] = pw_varint_EncodeOneByte##bits(&integer); \ + } while (integer != 0u); \ + \ + buffer[written - 1] &= 0x7f; \ + return written + +size_t pw_varint_Encode32(uint32_t integer, + void* output, + size_t output_size_bytes) { + VARINT_ENCODE_FUNCTION_BODY(32); +} + +size_t pw_varint_Encode64(uint64_t integer, + void* output, + size_t output_size_bytes) { + VARINT_ENCODE_FUNCTION_BODY(64); +} + +#define VARINT_DECODE_FUNCTION_BODY(bits) \ + uint##bits##_t value = 0; \ + size_t count = 0; \ + const uint8_t* buffer = (const uint8_t*)(input); \ + \ + /* Only read to the end of the buffer or largest possible encoded size. */ \ + const size_t max_count = \ + input_size_bytes < PW_VARINT_MAX_INT##bits##_SIZE_BYTES \ + ? input_size_bytes \ + : PW_VARINT_MAX_INT##bits##_SIZE_BYTES; \ + \ + bool keep_going; \ + do { \ + if (count >= max_count) { \ + return 0; \ + } \ + \ + keep_going = pw_varint_DecodeOneByte##bits(buffer[count], count, &value); \ + count += 1; \ + } while (keep_going); \ + \ + *output = value; \ + return count + +size_t pw_varint_Decode32(const void* input, + size_t input_size_bytes, + uint32_t* output) { + VARINT_DECODE_FUNCTION_BODY(32); +} + +size_t pw_varint_Decode64(const void* input, + size_t input_size_bytes, + uint64_t* output) { + VARINT_DECODE_FUNCTION_BODY(64); +} |