| // 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_ |