Protocol Buffers - Google's data interchange format (grpc依赖) https://developers.google.com/protocol-buffers/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

341 lines
9.6 KiB

/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2009 Joshua Haberman. See LICENSE for details.
*
* This file contains shared definitions that are widely used across upb.
*/
#ifndef UPB_H_
#define UPB_H_
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h> // only for size_t.
#include <assert.h>
#include "descriptor_const.h"
#include "upb_atomic.h"
#ifdef __cplusplus
extern "C" {
#endif
// inline if possible, emit standalone code if required.
#ifndef INLINE
#define INLINE static inline
#endif
#define UPB_MAX(x, y) ((x) > (y) ? (x) : (y))
#define UPB_MIN(x, y) ((x) < (y) ? (x) : (y))
#define UPB_INDEX(base, i, m) (void*)((char*)(base) + ((i)*(m)))
// The maximum that any submessages can be nested. Matches proto2's limit.
#define UPB_MAX_NESTING 64
// The maximum number of fields that any one .proto type can have. Note that
// this is very different than the max field number. It is hard to imagine a
// scenario where more than 32k fields makes sense.
#define UPB_MAX_FIELDS (1<<15)
typedef int16_t upb_field_count_t;
// Nested type names are separated by periods.
#define UPB_SYMBOL_SEPARATOR '.'
// This limit is for the longest fully-qualified symbol, eg. foo.bar.MsgType
#define UPB_SYMBOL_MAXLEN 128
// The longest chain that mutually-recursive types are allowed to form. For
// example, this is a type cycle of length 2:
// message A {
// B b = 1;
// }
// message B {
// A a = 1;
// }
#define UPB_MAX_TYPE_CYCLE_LEN 16
// The maximum depth that the type graph can have. Note that this setting does
// not automatically constrain UPB_MAX_NESTING, because type cycles allow for
// unlimited nesting if we do not limit it.
#define UPB_MAX_TYPE_DEPTH 64
// The biggest possible single value is a 10-byte varint.
#define UPB_MAX_ENCODED_SIZE 10
/* Fundamental types and type constants. **************************************/
// A list of types as they are encoded on-the-wire.
enum upb_wire_type {
UPB_WIRE_TYPE_VARINT = 0,
UPB_WIRE_TYPE_64BIT = 1,
UPB_WIRE_TYPE_DELIMITED = 2,
UPB_WIRE_TYPE_START_GROUP = 3,
UPB_WIRE_TYPE_END_GROUP = 4,
UPB_WIRE_TYPE_32BIT = 5,
// This isn't a real wire type, but we use this constant to describe varints
// that are expected to be a maximum of 32 bits.
UPB_WIRE_TYPE_32BIT_VARINT = 8
};
typedef uint8_t upb_wire_type_t;
// Type of a field as defined in a .proto file. eg. string, int32, etc. The
// integers that represent this are defined by descriptor.proto. Note that
// descriptor.proto reserves "0" for errors, and we use it to represent
// exceptional circumstances.
typedef uint8_t upb_fieldtype_t;
// For referencing the type constants tersely.
#define UPB_TYPE(type) GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_ ## type
#define UPB_LABEL(type) GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_LABEL_ ## type
// Info for a given field type.
typedef struct {
uint8_t align;
uint8_t size;
upb_wire_type_t native_wire_type;
uint8_t allowed_wire_types; // For packable fields, also allows delimited.
char *ctype;
} upb_type_info;
// A static array of info about all of the field types, indexed by type number.
extern const upb_type_info upb_types[];
// The number of a field, eg. "optional string foo = 3".
typedef int32_t upb_field_number_t;
// Label (optional, repeated, required) as defined in a .proto file. The
// values of this are defined by google.protobuf.FieldDescriptorProto.Label
// (from descriptor.proto).
typedef uint8_t upb_label_t;
// A scalar (non-string) wire value. Used only for parsing unknown fields.
typedef union {
uint64_t varint;
uint64_t _64bit;
uint32_t _32bit;
} upb_wire_value;
/* Polymorphic values of .proto types *****************************************/
struct _upb_string;
typedef struct _upb_string upb_string;
struct _upb_array;
typedef struct _upb_array upb_array;
struct _upb_msg;
typedef struct _upb_msg upb_msg;
struct _upb_bytesrc;
typedef struct _upb_bytesrc upb_bytesrc;
typedef int32_t upb_strlen_t;
#define UPB_STRLEN_MAX INT32_MAX
// The type of a upb_value. This is like a upb_fieldtype_t, but adds the
// constant UPB_VALUETYPE_ARRAY to represent an array.
typedef uint8_t upb_valuetype_t;
#define UPB_VALUETYPE_ARRAY 32
#define UPB_VALUETYPE_BYTESRC 32
#define UPB_VALUETYPE_RAW 33
// A single .proto value. The owner must have an out-of-band way of knowing
// the type, so that it knows which union member to use.
typedef struct {
union {
double _double;
float _float;
int32_t int32;
int64_t int64;
uint32_t uint32;
uint64_t uint64;
bool _bool;
upb_string *str;
upb_bytesrc *bytesrc;
upb_msg *msg;
upb_array *arr;
upb_atomic_refcount_t *refcount;
void *_void;
} val;
// In debug mode we carry the value type around also so we can check accesses
// to be sure the right member is being read.
#ifndef NDEBUG
upb_valuetype_t type;
#endif
} upb_value;
#ifdef NDEBUG
#define SET_TYPE(dest, val)
#else
#define SET_TYPE(dest, val) dest = val
#endif
#define UPB_VALUE_ACCESSORS(name, membername, ctype, proto_type) \
INLINE ctype upb_value_get ## name(upb_value val) { \
assert(val.type == proto_type || val.type == UPB_VALUETYPE_RAW); \
return val.val.membername; \
} \
INLINE void upb_value_set ## name(upb_value *val, ctype cval) { \
SET_TYPE(val->type, proto_type); \
val->val.membername = cval; \
}
UPB_VALUE_ACCESSORS(double, _double, double, UPB_TYPE(DOUBLE));
UPB_VALUE_ACCESSORS(float, _float, float, UPB_TYPE(FLOAT));
UPB_VALUE_ACCESSORS(int32, int32, int32_t, UPB_TYPE(INT32));
UPB_VALUE_ACCESSORS(int64, int64, int64_t, UPB_TYPE(INT64));
UPB_VALUE_ACCESSORS(uint32, uint32, uint32_t, UPB_TYPE(UINT32));
UPB_VALUE_ACCESSORS(uint64, uint64, uint64_t, UPB_TYPE(UINT64));
UPB_VALUE_ACCESSORS(bool, _bool, bool, UPB_TYPE(BOOL));
UPB_VALUE_ACCESSORS(str, str, upb_string*, UPB_TYPE(STRING));
UPB_VALUE_ACCESSORS(bytesrc, bytesrc, upb_bytesrc*, UPB_VALUETYPE_BYTESRC);
INLINE void upb_value_setraw(upb_value *val, uint64_t cval) {
SET_TYPE(val->type, UPB_VALUETYPE_RAW);
val->val.uint64 = cval;
}
// A pointer to a .proto value. The owner must have an out-of-band way of
// knowing the type, so it knows which union member to use.
typedef union {
double *_double;
float *_float;
int32_t *int32;
int64_t *int64;
uint8_t *uint8;
uint32_t *uint32;
uint64_t *uint64;
bool *_bool;
upb_string **str;
upb_msg **msg;
upb_array **arr;
void *_void;
} upb_valueptr;
INLINE upb_valueptr upb_value_addrof(upb_value *val) {
upb_valueptr ptr = {&val->val._double};
return ptr;
}
// Reads or writes a upb_value from an address represented by a upb_value_ptr.
// We need to know the value type to perform this operation, because we need to
// know how much memory to copy (and for big-endian machines, we need to know
// where in the upb_value the data goes).
//
// For little endian-machines where we didn't mind overreading, we could make
// upb_value_read simply use memcpy().
INLINE upb_value upb_value_read(upb_valueptr ptr, upb_fieldtype_t ft) {
upb_value val;
#define CASE(t, member_name) \
case UPB_TYPE(t): val.val.member_name = *ptr.member_name; break;
switch(ft) {
CASE(DOUBLE, _double)
CASE(FLOAT, _float)
CASE(INT32, int32)
CASE(INT64, int64)
CASE(UINT32, uint32)
CASE(UINT64, uint64)
CASE(SINT32, int32)
CASE(SINT64, int64)
CASE(FIXED32, uint32)
CASE(FIXED64, uint64)
CASE(SFIXED32, int32)
CASE(SFIXED64, int64)
CASE(BOOL, _bool)
CASE(ENUM, int32)
CASE(STRING, str)
CASE(BYTES, str)
CASE(MESSAGE, msg)
CASE(GROUP, msg)
default: break;
}
return val;
#undef CASE
}
INLINE void upb_value_write(upb_valueptr ptr, upb_value val,
upb_fieldtype_t ft) {
#define CASE(t, member_name) \
case UPB_TYPE(t): *ptr.member_name = val.val.member_name; break;
switch(ft) {
CASE(DOUBLE, _double)
CASE(FLOAT, _float)
CASE(INT32, int32)
CASE(INT64, int64)
CASE(UINT32, uint32)
CASE(UINT64, uint64)
CASE(SINT32, int32)
CASE(SINT64, int64)
CASE(FIXED32, uint32)
CASE(FIXED64, uint64)
CASE(SFIXED32, int32)
CASE(SFIXED64, int64)
CASE(BOOL, _bool)
CASE(ENUM, int32)
CASE(STRING, str)
CASE(BYTES, str)
CASE(MESSAGE, msg)
CASE(GROUP, msg)
default: break;
}
#undef CASE
}
// Status codes used as a return value. Codes >0 are not fatal and can be
// resumed.
enum upb_status_code {
// The operation completed successfully.
UPB_OK = 0,
// The bytesrc is at EOF and all data was read successfully.
UPB_EOF = 1,
// A read or write from a streaming src/sink could not be completed right now.
UPB_TRYAGAIN = 2,
// An unrecoverable error occurred.
UPB_ERROR = -1,
// A recoverable error occurred (for example, data of the wrong type was
// encountered which we can skip over).
// UPB_STATUS_RECOVERABLE_ERROR = -2
};
// TODO: consider adding error space and code, to let ie. errno be stored
// as a proper code, or application-specific error codes.
typedef struct {
char code;
upb_string *str;
} upb_status;
#define UPB_STATUS_INIT {UPB_OK, NULL}
#define UPB_ERRORMSG_MAXLEN 256
INLINE bool upb_ok(upb_status *status) {
return status->code == UPB_OK;
}
INLINE void upb_status_init(upb_status *status) {
status->code = UPB_OK;
status->str = NULL;
}
void upb_status_uninit(upb_status *status);
void upb_printerr(upb_status *status);
void upb_clearerr(upb_status *status);
void upb_seterr(upb_status *status, enum upb_status_code code, const char *msg,
...);
void upb_copyerr(upb_status *to, upb_status *from);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* UPB_H_ */