Built motion from commit 6a09e18b.|2.6.11
[motion2.git] / legacy-libs / grpc-cloned / deps / grpc / third_party / upb / upb / upb.h
1 /*
2 ** This file contains shared definitions that are widely used across upb.
3 **
4 ** This is a mixed C/C++ interface that offers a full API to both languages.
5 ** See the top-level README for more information.
6 */
7
8 #ifndef UPB_H_
9 #define UPB_H_
10
11 #include <assert.h>
12 #include <stdarg.h>
13 #include <stdbool.h>
14 #include <stddef.h>
15 #include <stdint.h>
16 #include <string.h>
17
18 #ifdef __cplusplus
19 #include <memory>
20 namespace upb {
21 class Arena;
22 class Status;
23 template <int N> class InlinedArena;
24 }
25 #endif
26
27 #include "upb/port_def.inc"
28
29 /* upb_status *****************************************************************/
30
31 /* upb_status represents a success or failure status and error message.
32  * It owns no resources and allocates no memory, so it should work
33  * even in OOM situations. */
34
35 /* The maximum length of an error message before it will get truncated. */
36 #define UPB_STATUS_MAX_MESSAGE 127
37
38 typedef struct {
39   bool ok;
40   char msg[UPB_STATUS_MAX_MESSAGE];  /* Error message; NULL-terminated. */
41 } upb_status;
42
43 #ifdef __cplusplus
44 extern "C" {
45 #endif
46
47 const char *upb_status_errmsg(const upb_status *status);
48 bool upb_ok(const upb_status *status);
49
50 /* Any of the functions that write to a status object allow status to be NULL,
51  * to support use cases where the function's caller does not care about the
52  * status message. */
53 void upb_status_clear(upb_status *status);
54 void upb_status_seterrmsg(upb_status *status, const char *msg);
55 void upb_status_seterrf(upb_status *status, const char *fmt, ...);
56 void upb_status_vseterrf(upb_status *status, const char *fmt, va_list args);
57
58 UPB_INLINE void upb_status_setoom(upb_status *status) {
59   upb_status_seterrmsg(status, "out of memory");
60 }
61
62 #ifdef __cplusplus
63 }  /* extern "C" */
64
65 class upb::Status {
66  public:
67   Status() { upb_status_clear(&status_); }
68
69   upb_status* ptr() { return &status_; }
70
71   /* Returns true if there is no error. */
72   bool ok() const { return upb_ok(&status_); }
73
74   /* Guaranteed to be NULL-terminated. */
75   const char *error_message() const { return upb_status_errmsg(&status_); }
76
77   /* The error message will be truncated if it is longer than
78    * UPB_STATUS_MAX_MESSAGE-4. */
79   void SetErrorMessage(const char *msg) { upb_status_seterrmsg(&status_, msg); }
80   void SetFormattedErrorMessage(const char *fmt, ...) {
81     va_list args;
82     va_start(args, fmt);
83     upb_status_vseterrf(&status_, fmt, args);
84     va_end(args);
85   }
86
87   /* Resets the status to a successful state with no message. */
88   void Clear() { upb_status_clear(&status_); }
89
90  private:
91   upb_status status_;
92 };
93
94 #endif  /* __cplusplus */
95
96 /** upb_strview ************************************************************/
97
98 typedef struct {
99   const char *data;
100   size_t size;
101 } upb_strview;
102
103 UPB_INLINE upb_strview upb_strview_make(const char *data, size_t size) {
104   upb_strview ret;
105   ret.data = data;
106   ret.size = size;
107   return ret;
108 }
109
110 UPB_INLINE upb_strview upb_strview_makez(const char *data) {
111   return upb_strview_make(data, strlen(data));
112 }
113
114 UPB_INLINE bool upb_strview_eql(upb_strview a, upb_strview b) {
115   return a.size == b.size && memcmp(a.data, b.data, a.size) == 0;
116 }
117
118 #define UPB_STRVIEW_INIT(ptr, len) {ptr, len}
119
120 #define UPB_STRVIEW_FORMAT "%.*s"
121 #define UPB_STRVIEW_ARGS(view) (int)(view).size, (view).data
122
123 /** upb_alloc *****************************************************************/
124
125 /* A upb_alloc is a possibly-stateful allocator object.
126  *
127  * It could either be an arena allocator (which doesn't require individual
128  * free() calls) or a regular malloc() (which does).  The client must therefore
129  * free memory unless it knows that the allocator is an arena allocator. */
130
131 struct upb_alloc;
132 typedef struct upb_alloc upb_alloc;
133
134 /* A malloc()/free() function.
135  * If "size" is 0 then the function acts like free(), otherwise it acts like
136  * realloc().  Only "oldsize" bytes from a previous allocation are preserved. */
137 typedef void *upb_alloc_func(upb_alloc *alloc, void *ptr, size_t oldsize,
138                              size_t size);
139
140 struct upb_alloc {
141   upb_alloc_func *func;
142 };
143
144 UPB_INLINE void *upb_malloc(upb_alloc *alloc, size_t size) {
145   UPB_ASSERT(alloc);
146   return alloc->func(alloc, NULL, 0, size);
147 }
148
149 UPB_INLINE void *upb_realloc(upb_alloc *alloc, void *ptr, size_t oldsize,
150                              size_t size) {
151   UPB_ASSERT(alloc);
152   return alloc->func(alloc, ptr, oldsize, size);
153 }
154
155 UPB_INLINE void upb_free(upb_alloc *alloc, void *ptr) {
156   assert(alloc);
157   alloc->func(alloc, ptr, 0, 0);
158 }
159
160 /* The global allocator used by upb.  Uses the standard malloc()/free(). */
161
162 #ifdef __cplusplus
163 extern "C" {
164 #endif
165
166 extern upb_alloc upb_alloc_global;
167
168 #ifdef __cplusplus
169 }  /* extern "C" */
170 #endif
171
172 /* Functions that hard-code the global malloc.
173  *
174  * We still get benefit because we can put custom logic into our global
175  * allocator, like injecting out-of-memory faults in debug/testing builds. */
176
177 UPB_INLINE void *upb_gmalloc(size_t size) {
178   return upb_malloc(&upb_alloc_global, size);
179 }
180
181 UPB_INLINE void *upb_grealloc(void *ptr, size_t oldsize, size_t size) {
182   return upb_realloc(&upb_alloc_global, ptr, oldsize, size);
183 }
184
185 UPB_INLINE void upb_gfree(void *ptr) {
186   upb_free(&upb_alloc_global, ptr);
187 }
188
189 /* upb_arena ******************************************************************/
190
191 /* upb_arena is a specific allocator implementation that uses arena allocation.
192  * The user provides an allocator that will be used to allocate the underlying
193  * arena blocks.  Arenas by nature do not require the individual allocations
194  * to be freed.  However the Arena does allow users to register cleanup
195  * functions that will run when the arena is destroyed.
196  *
197  * A upb_arena is *not* thread-safe.
198  *
199  * You could write a thread-safe arena allocator that satisfies the
200  * upb_alloc interface, but it would not be as efficient for the
201  * single-threaded case. */
202
203 typedef void upb_cleanup_func(void *ud);
204
205 struct upb_arena;
206 typedef struct upb_arena upb_arena;
207
208 #ifdef __cplusplus
209 extern "C" {
210 #endif
211
212 /* Creates an arena from the given initial block (if any -- n may be 0).
213  * Additional blocks will be allocated from |alloc|.  If |alloc| is NULL, this
214  * is a fixed-size arena and cannot grow. */
215 upb_arena *upb_arena_init(void *mem, size_t n, upb_alloc *alloc);
216 void upb_arena_free(upb_arena *a);
217 bool upb_arena_addcleanup(upb_arena *a, void *ud, upb_cleanup_func *func);
218 size_t upb_arena_bytesallocated(const upb_arena *a);
219
220 UPB_INLINE upb_alloc *upb_arena_alloc(upb_arena *a) { return (upb_alloc*)a; }
221
222 /* Convenience wrappers around upb_alloc functions. */
223
224 UPB_INLINE void *upb_arena_malloc(upb_arena *a, size_t size) {
225   return upb_malloc(upb_arena_alloc(a), size);
226 }
227
228 UPB_INLINE void *upb_arena_realloc(upb_arena *a, void *ptr, size_t oldsize,
229                                    size_t size) {
230   return upb_realloc(upb_arena_alloc(a), ptr, oldsize, size);
231 }
232
233 UPB_INLINE upb_arena *upb_arena_new(void) {
234   return upb_arena_init(NULL, 0, &upb_alloc_global);
235 }
236
237 #ifdef __cplusplus
238 }  /* extern "C" */
239
240 class upb::Arena {
241  public:
242   /* A simple arena with no initial memory block and the default allocator. */
243   Arena() : ptr_(upb_arena_new(), upb_arena_free) {}
244
245   upb_arena* ptr() { return ptr_.get(); }
246
247   /* Allows this arena to be used as a generic allocator.
248    *
249    * The arena does not need free() calls so when using Arena as an allocator
250    * it is safe to skip them.  However they are no-ops so there is no harm in
251    * calling free() either. */
252   upb_alloc *allocator() { return upb_arena_alloc(ptr_.get()); }
253
254   /* Add a cleanup function to run when the arena is destroyed.
255    * Returns false on out-of-memory. */
256   bool AddCleanup(void *ud, upb_cleanup_func* func) {
257     return upb_arena_addcleanup(ptr_.get(), ud, func);
258   }
259
260   /* Total number of bytes that have been allocated.  It is undefined what
261    * Realloc() does to &arena_ counter. */
262   size_t BytesAllocated() const { return upb_arena_bytesallocated(ptr_.get()); }
263
264  private:
265   std::unique_ptr<upb_arena, decltype(&upb_arena_free)> ptr_;
266 };
267
268 #endif
269
270 /* upb::InlinedArena **********************************************************/
271
272 /* upb::InlinedArena seeds the arenas with a predefined amount of memory.  No
273  * heap memory will be allocated until the initial block is exceeded.
274  *
275  * These types only exist in C++ */
276
277 #ifdef __cplusplus
278
279 template <int N> class upb::InlinedArena : public upb::Arena {
280  public:
281   InlinedArena() : ptr_(upb_arena_new(&initial_block_, N, &upb_alloc_global)) {}
282
283   upb_arena* ptr() { return ptr_.get(); }
284
285  private:
286   InlinedArena(const InlinedArena*) = delete;
287   InlinedArena& operator=(const InlinedArena*) = delete;
288
289   std::unique_ptr<upb_arena, decltype(&upb_arena_free)> ptr_;
290   char initial_block_[N];
291 };
292
293 #endif  /* __cplusplus */
294
295 /* Constants ******************************************************************/
296
297 /* Generic function type. */
298 typedef void upb_func(void);
299
300 /* A list of types as they are encoded on-the-wire. */
301 typedef enum {
302   UPB_WIRE_TYPE_VARINT      = 0,
303   UPB_WIRE_TYPE_64BIT       = 1,
304   UPB_WIRE_TYPE_DELIMITED   = 2,
305   UPB_WIRE_TYPE_START_GROUP = 3,
306   UPB_WIRE_TYPE_END_GROUP   = 4,
307   UPB_WIRE_TYPE_32BIT       = 5
308 } upb_wiretype_t;
309
310 /* The types a field can have.  Note that this list is not identical to the
311  * types defined in descriptor.proto, which gives INT32 and SINT32 separate
312  * types (we distinguish the two with the "integer encoding" enum below). */
313 typedef enum {
314   /* Types stored in 1 byte. */
315   UPB_TYPE_BOOL     = 1,
316   /* Types stored in 4 bytes. */
317   UPB_TYPE_FLOAT    = 2,
318   UPB_TYPE_INT32    = 3,
319   UPB_TYPE_UINT32   = 4,
320   UPB_TYPE_ENUM     = 5,  /* Enum values are int32. */
321   /* Types stored as pointers (probably 4 or 8 bytes). */
322   UPB_TYPE_STRING   = 6,
323   UPB_TYPE_BYTES    = 7,
324   UPB_TYPE_MESSAGE  = 8,
325   /* Types stored as 8 bytes. */
326   UPB_TYPE_DOUBLE   = 9,
327   UPB_TYPE_INT64    = 10,
328   UPB_TYPE_UINT64   = 11
329 } upb_fieldtype_t;
330
331 /* The repeated-ness of each field; this matches descriptor.proto. */
332 typedef enum {
333   UPB_LABEL_OPTIONAL = 1,
334   UPB_LABEL_REQUIRED = 2,
335   UPB_LABEL_REPEATED = 3
336 } upb_label_t;
337
338 /* Descriptor types, as defined in descriptor.proto. */
339 typedef enum {
340   UPB_DESCRIPTOR_TYPE_DOUBLE   = 1,
341   UPB_DESCRIPTOR_TYPE_FLOAT    = 2,
342   UPB_DESCRIPTOR_TYPE_INT64    = 3,
343   UPB_DESCRIPTOR_TYPE_UINT64   = 4,
344   UPB_DESCRIPTOR_TYPE_INT32    = 5,
345   UPB_DESCRIPTOR_TYPE_FIXED64  = 6,
346   UPB_DESCRIPTOR_TYPE_FIXED32  = 7,
347   UPB_DESCRIPTOR_TYPE_BOOL     = 8,
348   UPB_DESCRIPTOR_TYPE_STRING   = 9,
349   UPB_DESCRIPTOR_TYPE_GROUP    = 10,
350   UPB_DESCRIPTOR_TYPE_MESSAGE  = 11,
351   UPB_DESCRIPTOR_TYPE_BYTES    = 12,
352   UPB_DESCRIPTOR_TYPE_UINT32   = 13,
353   UPB_DESCRIPTOR_TYPE_ENUM     = 14,
354   UPB_DESCRIPTOR_TYPE_SFIXED32 = 15,
355   UPB_DESCRIPTOR_TYPE_SFIXED64 = 16,
356   UPB_DESCRIPTOR_TYPE_SINT32   = 17,
357   UPB_DESCRIPTOR_TYPE_SINT64   = 18
358 } upb_descriptortype_t;
359
360 extern const uint8_t upb_desctype_to_fieldtype[];
361
362 #include "upb/port_undef.inc"
363
364 #endif  /* UPB_H_ */