WPILibC++ 2027.0.0-alpha-3
Loading...
Searching...
No Matches
reader.h
Go to the documentation of this file.
1// Protocol Buffers - Google's data interchange format
2// Copyright 2023 Google LLC. All rights reserved.
3//
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file or at
6// https://developers.google.com/open-source/licenses/bsd
7
8#ifndef UPB_WIRE_READER_H_
9#define UPB_WIRE_READER_H_
10
11#include <stddef.h>
12#include <stdint.h>
13#include <string.h>
14
18#include "upb/wire/types.h" // IWYU pragma: export
19
20// Must be last.
21#include "upb/port/def.inc"
22
23// The upb_WireReader interface is suitable for general-purpose parsing of
24// protobuf binary wire format. It is designed to be used along with
25// upb_EpsCopyInputStream for buffering, and all parsing routines in this file
26// assume that at least kUpb_EpsCopyInputStream_SlopBytes worth of data is
27// available to read without any bounds checks.
28
29#ifdef __cplusplus
30extern "C" {
31#endif
32
33// Parses a tag into `tag`, and returns a pointer past the end of the tag, or
34// NULL if there was an error in the tag data.
35//
36// REQUIRES: there must be at least 10 bytes of data available at `ptr`.
37// Bounds checks must be performed before calling this function, preferably
38// by calling upb_EpsCopyInputStream_IsDone().
40 uint32_t* tag) {
41 uint64_t val;
42 ptr = UPB_PRIVATE(_upb_WireReader_ReadVarint)(ptr, &val, 5, UINT32_MAX);
43 if (!ptr) return NULL;
44 *tag = val;
45 return ptr;
46}
47
48// Given a tag, returns the field number.
50
51// Given a tag, returns the wire type.
52UPB_API_INLINE uint8_t upb_WireReader_GetWireType(uint32_t tag);
53
55 uint64_t* val) {
56 return UPB_PRIVATE(_upb_WireReader_ReadVarint)(ptr, val, 10, UINT64_MAX);
57}
58
59// Skips data for a varint, returning a pointer past the end of the varint, or
60// NULL if there was an error in the varint data.
61//
62// REQUIRES: there must be at least 10 bytes of data available at `ptr`.
63// Bounds checks must be performed before calling this function, preferably
64// by calling upb_EpsCopyInputStream_IsDone().
65UPB_INLINE const char* upb_WireReader_SkipVarint(const char* ptr) {
66 uint64_t val;
67 return upb_WireReader_ReadVarint(ptr, &val);
68}
69
70// Reads a varint indicating the size of a delimited field into `size`, or
71// NULL if there was an error in the varint data.
72//
73// REQUIRES: there must be at least 10 bytes of data available at `ptr`.
74// Bounds checks must be performed before calling this function, preferably
75// by calling upb_EpsCopyInputStream_IsDone().
76UPB_INLINE const char* upb_WireReader_ReadSize(const char* ptr, int* size) {
77 uint64_t size64;
79 if (!ptr || size64 >= INT32_MAX) return NULL;
80 *size = size64;
81 return ptr;
82}
83
84// Reads a fixed32 field, performing byte swapping if necessary.
85//
86// REQUIRES: there must be at least 4 bytes of data available at `ptr`.
87// Bounds checks must be performed before calling this function, preferably
88// by calling upb_EpsCopyInputStream_IsDone().
89UPB_INLINE const char* upb_WireReader_ReadFixed32(const char* ptr, void* val) {
90 uint32_t uval;
91 memcpy(&uval, ptr, 4);
92 uval = upb_BigEndian32(uval);
93 memcpy(val, &uval, 4);
94 return ptr + 4;
95}
96
97// Reads a fixed64 field, performing byte swapping if necessary.
98//
99// REQUIRES: there must be at least 4 bytes of data available at `ptr`.
100// Bounds checks must be performed before calling this function, preferably
101// by calling upb_EpsCopyInputStream_IsDone().
102UPB_INLINE const char* upb_WireReader_ReadFixed64(const char* ptr, void* val) {
103 uint64_t uval;
104 memcpy(&uval, ptr, 8);
105 uval = upb_BigEndian64(uval);
106 memcpy(val, &uval, 8);
107 return ptr + 8;
108}
109
111 const char* ptr, uint32_t tag, int depth_limit,
112 upb_EpsCopyInputStream* stream);
113
114// Skips data for a group, returning a pointer past the end of the group, or
115// NULL if there was an error parsing the group. The `tag` argument should be
116// the start group tag that begins the group. The `depth_limit` argument
117// indicates how many levels of recursion the group is allowed to have before
118// reporting a parse error (this limit exists to protect against stack
119// overflow).
120//
121// TODO: evaluate how the depth_limit should be specified. Do users need
122// control over this?
124 const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) {
125 return UPB_PRIVATE(_upb_WireReader_SkipGroup)(ptr, tag, 100, stream);
126}
127
129 const char* ptr, uint32_t tag, int depth_limit,
130 upb_EpsCopyInputStream* stream) {
131 switch (upb_WireReader_GetWireType(tag)) {
135 return ptr + 4;
137 return ptr + 8;
139 int size;
141 if (!ptr || !upb_EpsCopyInputStream_CheckSize(stream, ptr, size)) {
142 return NULL;
143 }
144 ptr += size;
145 return ptr;
146 }
148 return UPB_PRIVATE(_upb_WireReader_SkipGroup)(ptr, tag, depth_limit,
149 stream);
151 return NULL; // Should be handled before now.
152 default:
153 return NULL; // Unknown wire type.
154 }
155}
156
157// Skips data for a wire value of any type, returning a pointer past the end of
158// the data, or NULL if there was an error parsing the group. The `tag` argument
159// should be the tag that was just parsed. The `depth_limit` argument indicates
160// how many levels of recursion a group is allowed to have before reporting a
161// parse error (this limit exists to protect against stack overflow).
162//
163// REQUIRES: there must be at least 10 bytes of data available at `ptr`.
164// Bounds checks must be performed before calling this function, preferably
165// by calling upb_EpsCopyInputStream_IsDone().
166//
167// TODO: evaluate how the depth_limit should be specified. Do users need
168// control over this?
170 const char* ptr, uint32_t tag, upb_EpsCopyInputStream* stream) {
171 return _upb_WireReader_SkipValue(ptr, tag, 100, stream);
172}
173
174#ifdef __cplusplus
175} /* extern "C" */
176#endif
177
178#include "upb/port/undef.inc"
179
180#endif // UPB_WIRE_READER_H_
#define UPB_API_INLINE
Definition def.inc:163
#define UPB_PRIVATE(x)
Definition def.inc:393
#define UPB_FORCEINLINE
Definition def.inc:288
#define UPB_INLINE
Definition def.inc:144
UPB_INLINE bool upb_EpsCopyInputStream_CheckSize(const upb_EpsCopyInputStream *e, const char *ptr, int size)
Definition eps_copy_input_stream.h:162
auto ptr(T p) -> const void *
Converts p to const void* for pointer formatting.
Definition format.h:3963
UPB_FORCEINLINE const char *UPB_PRIVATE _upb_WireReader_ReadVarint(const char *ptr, uint64_t *val, int maxlen, uint64_t maxval)
Definition reader.h:29
UPB_API_INLINE uint32_t upb_WireReader_GetFieldNumber(uint32_t tag)
Definition reader.h:47
UPB_API_INLINE uint8_t upb_WireReader_GetWireType(uint32_t tag)
Definition reader.h:51
UPB_INLINE const char * upb_WireReader_SkipVarint(const char *ptr)
Definition reader.h:65
UPB_INLINE const char * upb_WireReader_SkipValue(const char *ptr, uint32_t tag, upb_EpsCopyInputStream *stream)
Definition reader.h:169
UPB_INLINE const char * upb_WireReader_ReadFixed64(const char *ptr, void *val)
Definition reader.h:102
UPB_INLINE const char * _upb_WireReader_SkipValue(const char *ptr, uint32_t tag, int depth_limit, upb_EpsCopyInputStream *stream)
Definition reader.h:128
UPB_INLINE const char * upb_WireReader_ReadVarint(const char *ptr, uint64_t *val)
Definition reader.h:54
UPB_FORCEINLINE const char * upb_WireReader_ReadTag(const char *ptr, uint32_t *tag)
Definition reader.h:39
UPB_INLINE const char * upb_WireReader_ReadSize(const char *ptr, int *size)
Definition reader.h:76
UPB_INLINE const char * upb_WireReader_ReadFixed32(const char *ptr, void *val)
Definition reader.h:89
UPB_INLINE const char * upb_WireReader_SkipGroup(const char *ptr, uint32_t tag, upb_EpsCopyInputStream *stream)
Definition reader.h:123
const char *UPB_PRIVATE _upb_WireReader_SkipGroup(const char *ptr, uint32_t tag, int depth_limit, upb_EpsCopyInputStream *stream)
Definition eps_copy_input_stream.h:31
UPB_INLINE uint32_t upb_BigEndian32(uint32_t val)
Definition endian.h:25
UPB_INLINE uint64_t upb_BigEndian64(uint64_t val)
Definition endian.h:32
@ kUpb_WireType_EndGroup
Definition types.h:17
@ kUpb_WireType_32Bit
Definition types.h:18
@ kUpb_WireType_Delimited
Definition types.h:15
@ kUpb_WireType_64Bit
Definition types.h:14
@ kUpb_WireType_StartGroup
Definition types.h:16
@ kUpb_WireType_Varint
Definition types.h:13