| // Protocol Buffers - Google's data interchange format |
| // Copyright 2023 Google LLC. All rights reserved. |
| // |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file or at |
| // https://developers.google.com/open-source/licenses/bsd |
| |
| #ifndef UPB_WIRE_INTERNAL_READER_H_ |
| #define UPB_WIRE_INTERNAL_READER_H_ |
| |
| // Must be last. |
| #include "upb/port/def.inc" |
| |
| #define kUpb_WireReader_WireTypeBits 3 |
| #define kUpb_WireReader_WireTypeMask 7 |
| |
| typedef struct { |
| const char* ptr; |
| uint64_t val; |
| } UPB_PRIVATE(_upb_WireReader_LongVarint); |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| UPB_PRIVATE(_upb_WireReader_LongVarint) |
| UPB_PRIVATE(_upb_WireReader_ReadLongVarint)(const char* ptr, uint64_t val); |
| |
| UPB_FORCEINLINE const char* UPB_PRIVATE(_upb_WireReader_ReadVarint)( |
| const char* ptr, uint64_t* val, int maxlen, uint64_t maxval) { |
| uint64_t byte = (uint8_t)*ptr; |
| if (UPB_LIKELY((byte & 0x80) == 0)) { |
| *val = (uint32_t)byte; |
| return ptr + 1; |
| } |
| const char* start = ptr; |
| UPB_PRIVATE(_upb_WireReader_LongVarint) |
| res = UPB_PRIVATE(_upb_WireReader_ReadLongVarint)(ptr, byte); |
| if (!res.ptr || (maxlen < 10 && res.ptr - start > maxlen) || |
| res.val > maxval) { |
| return NULL; // Malformed. |
| } |
| *val = res.val; |
| return res.ptr; |
| } |
| |
| UPB_API_INLINE uint32_t upb_WireReader_GetFieldNumber(uint32_t tag) { |
| return tag >> kUpb_WireReader_WireTypeBits; |
| } |
| |
| UPB_API_INLINE uint8_t upb_WireReader_GetWireType(uint32_t tag) { |
| return tag & kUpb_WireReader_WireTypeMask; |
| } |
| |
| #ifdef __cplusplus |
| } /* extern "C" */ |
| #endif |
| |
| #include "upb/port/undef.inc" |
| |
| #endif // UPB_WIRE_INTERNAL_READER_H_ |