|
||||
File indexing completed on 2025-01-30 10:25:25
0001 // Protocol Buffers - Google's data interchange format 0002 // Copyright 2023 Google LLC. All rights reserved. 0003 // 0004 // Use of this source code is governed by a BSD-style 0005 // license that can be found in the LICENSE file or at 0006 // https://developers.google.com/open-source/licenses/bsd 0007 0008 #ifndef UPB_WIRE_READER_H_ 0009 #define UPB_WIRE_READER_H_ 0010 0011 #include "upb/base/internal/endian.h" 0012 #include "upb/wire/eps_copy_input_stream.h" 0013 #include "upb/wire/internal/reader.h" 0014 #include "upb/wire/types.h" // IWYU pragma: export 0015 0016 // Must be last. 0017 #include "upb/port/def.inc" 0018 0019 // The upb_WireReader interface is suitable for general-purpose parsing of 0020 // protobuf binary wire format. It is designed to be used along with 0021 // upb_EpsCopyInputStream for buffering, and all parsing routines in this file 0022 // assume that at least kUpb_EpsCopyInputStream_SlopBytes worth of data is 0023 // available to read without any bounds checks. 0024 0025 #ifdef __cplusplus 0026 extern "C" { 0027 #endif 0028 0029 // Parses a tag into `tag`, and returns a pointer past the end of the tag, or 0030 // NULL if there was an error in the tag data. 0031 // 0032 // REQUIRES: there must be at least 10 bytes of data available at `ptr`. 0033 // Bounds checks must be performed before calling this function, preferably 0034 // by calling upb_EpsCopyInputStream_IsDone(). 0035 UPB_FORCEINLINE const char* upb_WireReader_ReadTag(const char* ptr, 0036 uint32_t* tag) { 0037 uint64_t val; 0038 ptr = UPB_PRIVATE(_upb_WireReader_ReadVarint)(ptr, &val, 5, UINT32_MAX); 0039 if (!ptr) return NULL; 0040 *tag = val; 0041 return ptr; 0042 } 0043 0044 // Given a tag, returns the field number. 0045 UPB_API_INLINE uint32_t upb_WireReader_GetFieldNumber(uint32_t tag); 0046 0047 // Given a tag, returns the wire type. 0048 UPB_API_INLINE uint8_t upb_WireReader_GetWireType(uint32_t tag); 0049 0050 UPB_INLINE const char* upb_WireReader_ReadVarint(const char* ptr, 0051 uint64_t* val) { 0052 return UPB_PRIVATE(_upb_WireReader_ReadVarint)(ptr, val, 10, UINT64_MAX); 0053 } 0054 0055 // Skips data for a varint, returning a pointer past the end of the varint, or 0056 // NULL if there was an error in the varint data. 0057 // 0058 // REQUIRES: there must be at least 10 bytes of data available at `ptr`. 0059 // Bounds checks must be performed before calling this function, preferably 0060 // by calling upb_EpsCopyInputStream_IsDone(). 0061 UPB_INLINE const char* upb_WireReader_SkipVarint(const char* ptr) { 0062 uint64_t val; 0063 return upb_WireReader_ReadVarint(ptr, &val); 0064 } 0065 0066 // Reads a varint indicating the size of a delimited field into `size`, or 0067 // NULL if there was an error in the varint data. 0068 // 0069 // REQUIRES: there must be at least 10 bytes of data available at `ptr`. 0070 // Bounds checks must be performed before calling this function, preferably 0071 // by calling upb_EpsCopyInputStream_IsDone(). 0072 UPB_INLINE const char* upb_WireReader_ReadSize(const char* ptr, int* size) { 0073 uint64_t size64; 0074 ptr = upb_WireReader_ReadVarint(ptr, &size64); 0075 if (!ptr || size64 >= INT32_MAX) return NULL; 0076 *size = size64; 0077 return ptr; 0078 } 0079 0080 // Reads a fixed32 field, performing byte swapping if necessary. 0081 // 0082 // REQUIRES: there must be at least 4 bytes of data available at `ptr`. 0083 // Bounds checks must be performed before calling this function, preferably 0084 // by calling upb_EpsCopyInputStream_IsDone(). 0085 UPB_INLINE const char* upb_WireReader_ReadFixed32(const char* ptr, void* val) { 0086 uint32_t uval; 0087 memcpy(&uval, ptr, 4); 0088 uval = upb_BigEndian32(uval); 0089 memcpy(val, &uval, 4); 0090 return ptr + 4; 0091 } 0092 0093 // Reads a fixed64 field, performing byte swapping if necessary. 0094 // 0095 // REQUIRES: there must be at least 4 bytes of data available at `ptr`. 0096 // Bounds checks must be performed before calling this function, preferably 0097 // by calling upb_EpsCopyInputStream_IsDone(). 0098 UPB_INLINE const char* upb_WireReader_ReadFixed64(const char* ptr, void* val) { 0099 uint64_t uval; 0100 memcpy(&uval, ptr, 8); 0101 uval = upb_BigEndian64(uval); 0102 memcpy(val, &uval, 8); 0103 return ptr + 8; 0104 } 0105 0106 const char* UPB_PRIVATE(_upb_WireReader_SkipGroup)( 0107 const char* ptr, uint32_t tag, int depth_limit, 0108 upb_EpsCopyInputStream* stream); 0109 0110 // Skips data for a group, returning a pointer past the end of the group, or 0111 // NULL if there was an error parsing the group. The `tag` argument should be 0112 // the start group tag that begins the group. The `depth_limit` argument 0113 // indicates how many levels of recursion the group is allowed to have before 0114 // reporting a parse error (this limit exists to protect against stack 0115 // overflow). 0116 // 0117 // TODO: evaluate how the depth_limit should be specified. Do users need 0118 // control over this? 0119 UPB_INLINE const char* upb_WireReader_SkipGroup( 0120 const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) { 0121 return UPB_PRIVATE(_upb_WireReader_SkipGroup)(ptr, tag, 100, stream); 0122 } 0123 0124 UPB_INLINE const char* _upb_WireReader_SkipValue( 0125 const char* ptr, uint32_t tag, int depth_limit, 0126 upb_EpsCopyInputStream* stream) { 0127 switch (upb_WireReader_GetWireType(tag)) { 0128 case kUpb_WireType_Varint: 0129 return upb_WireReader_SkipVarint(ptr); 0130 case kUpb_WireType_32Bit: 0131 return ptr + 4; 0132 case kUpb_WireType_64Bit: 0133 return ptr + 8; 0134 case kUpb_WireType_Delimited: { 0135 int size; 0136 ptr = upb_WireReader_ReadSize(ptr, &size); 0137 if (!ptr) return NULL; 0138 ptr += size; 0139 return ptr; 0140 } 0141 case kUpb_WireType_StartGroup: 0142 return UPB_PRIVATE(_upb_WireReader_SkipGroup)(ptr, tag, depth_limit, 0143 stream); 0144 case kUpb_WireType_EndGroup: 0145 return NULL; // Should be handled before now. 0146 default: 0147 return NULL; // Unknown wire type. 0148 } 0149 } 0150 0151 // Skips data for a wire value of any type, returning a pointer past the end of 0152 // the data, or NULL if there was an error parsing the group. The `tag` argument 0153 // should be the tag that was just parsed. The `depth_limit` argument indicates 0154 // how many levels of recursion a group is allowed to have before reporting a 0155 // parse error (this limit exists to protect against stack overflow). 0156 // 0157 // REQUIRES: there must be at least 10 bytes of data available at `ptr`. 0158 // Bounds checks must be performed before calling this function, preferably 0159 // by calling upb_EpsCopyInputStream_IsDone(). 0160 // 0161 // TODO: evaluate how the depth_limit should be specified. Do users need 0162 // control over this? 0163 UPB_INLINE const char* upb_WireReader_SkipValue( 0164 const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) { 0165 return _upb_WireReader_SkipValue(ptr, tag, 100, stream); 0166 } 0167 0168 #ifdef __cplusplus 0169 } /* extern "C" */ 0170 #endif 0171 0172 #include "upb/port/undef.inc" 0173 0174 #endif // UPB_WIRE_READER_H_
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |