This is the next step in bootstrapping. upb_struct defines the in-memory layout that will be used by both compile-time and run-time defintions of protobufs. descriptor.h describes the proto format using this format. The next step is to create a descriptor.c that can parse descriptor protos into this format. Then real run-time reflection can begin.pull/13171/head
parent
d4f3e5a1af
commit
fdcefd68b1
3 changed files with 649 additions and 30 deletions
@ -1,46 +1,402 @@ |
||||
/* Auto-generated from descriptor.proto. Do not edit. */ |
||||
|
||||
enum pbstream_FieldDescriptorProtoType { |
||||
PBSTREAM_TYPE_INT32 = 5, |
||||
PBSTREAM_TYPE_STRING = 9, |
||||
PBSTREAM_TYPE_MESSAGE = 11, |
||||
PBSTREAM_TYPE_ENUM = 14, |
||||
}; |
||||
#include "upb_struct.h" |
||||
|
||||
/* Enums. */ |
||||
|
||||
typedef enum google_protobuf_FieldDescriptorProto_Type { |
||||
GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_DOUBLE = 1, |
||||
GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_FLOAT = 2, |
||||
GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_INT64 = 3, |
||||
GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_UINT64 = 4, |
||||
GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_INT32 = 5, |
||||
GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_FIXED64 = 6, |
||||
GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_FIXED32 = 7, |
||||
GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_BOOL = 8, |
||||
GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_STRING = 9, |
||||
GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_GROUP = 10, |
||||
GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_MESSAGE = 11, |
||||
GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_BYTES = 12, |
||||
GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_UINT32 = 13, |
||||
GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_ENUM = 14, |
||||
GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_SFIXED32 = 15, |
||||
GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_SFIXED64 = 16, |
||||
GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_SINT32 = 17, |
||||
GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_TYPE_SINT64 = 18, |
||||
} google_protobuf_FieldDescriptorProto_Type; |
||||
|
||||
typedef enum google_protobuf_FieldDescriptorProto_Label { |
||||
GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_LABEL_OPTIONAL = 1, |
||||
GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_LABEL_REQUIRED = 2, |
||||
GOOGLE_PROTOBUF_FIELDDESCRIPTORPROTO_LABEL_REPEATED = 3, |
||||
} google_protobuf_FieldDescriptorProto_Label; |
||||
|
||||
typedef enum google_protobuf_FileOptions_OptimizeMode { |
||||
GOOGLE_PROTOBUF_FILEOPTIONS_SPEED = 1, |
||||
GOOGLE_PROTOBUF_FILEOPTIONS_CODE_SIZE = 2, |
||||
} google_protobuf_FileOptions_OptimizeMode; |
||||
|
||||
typedef enum google_protobuf_FieldOptions_CType { |
||||
GOOGLE_PROTOBUF_FIELDOPTIONS_CORD = 1, |
||||
GOOGLE_PROTOBUF_FIELDOPTIONS_STRING_PIECE = 2, |
||||
} google_protobuf_FieldOptions_CType; |
||||
|
||||
/* Forward declarations of all message types.
|
||||
* So they can refer to each other in possibly-recursive ways. */ |
||||
|
||||
struct google_protobuf_FileDescriptorSet; |
||||
typedef struct google_protobuf_FileDescriptorSet |
||||
google_protobuf_FileDescriptorSet; |
||||
|
||||
struct google_protobuf_FileDescriptorProto; |
||||
typedef struct google_protobuf_FileDescriptorProto |
||||
google_protobuf_FileDescriptorProto; |
||||
|
||||
struct google_protobuf_DescriptorProto; |
||||
typedef struct google_protobuf_DescriptorProto |
||||
google_protobuf_DescriptorProto; |
||||
|
||||
struct google_protobuf_DescriptorProto_ExtensionRange; |
||||
typedef struct google_protobuf_DescriptorProto_ExtensionRange |
||||
google_protobuf_DescriptorProto_ExtensionRange; |
||||
|
||||
struct google_protobuf_FieldDescriptorProto; |
||||
typedef struct google_protobuf_FieldDescriptorProto |
||||
google_protobuf_FieldDescriptorProto; |
||||
|
||||
struct google_protobuf_EnumDescriptorProto; |
||||
typedef struct google_protobuf_EnumDescriptorProto |
||||
google_protobuf_EnumDescriptorProto; |
||||
|
||||
struct google_protobuf_EnumValueDescriptorProto; |
||||
typedef struct google_protobuf_EnumValueDescriptorProto |
||||
google_protobuf_EnumValueDescriptorProto; |
||||
|
||||
struct google_protobuf_ServiceDescriptorProto; |
||||
typedef struct google_protobuf_ServiceDescriptorProto |
||||
google_protobuf_ServiceDescriptorProto; |
||||
|
||||
struct google_protobuf_MethodDescriptorProto; |
||||
typedef struct google_protobuf_MethodDescriptorProto |
||||
google_protobuf_MethodDescriptorProto; |
||||
|
||||
struct google_protobuf_FileOptions; |
||||
typedef struct google_protobuf_FileOptions |
||||
google_protobuf_FileOptions; |
||||
|
||||
struct google_protobuf_MessageOptions; |
||||
typedef struct google_protobuf_MessageOptions |
||||
google_protobuf_MessageOptions; |
||||
|
||||
struct google_protobuf_FieldOptions; |
||||
typedef struct google_protobuf_FieldOptions |
||||
google_protobuf_FieldOptions; |
||||
|
||||
struct google_protobuf_EnumOptions; |
||||
typedef struct google_protobuf_EnumOptions |
||||
google_protobuf_EnumOptions; |
||||
|
||||
struct google_protobuf_EnumValueOptions; |
||||
typedef struct google_protobuf_EnumValueOptions |
||||
google_protobuf_EnumValueOptions; |
||||
|
||||
struct google_protobuf_ServiceOptions; |
||||
typedef struct google_protobuf_ServiceOptions |
||||
google_protobuf_ServiceOptions; |
||||
|
||||
struct google_protobuf_MethodOptions; |
||||
typedef struct google_protobuf_MethodOptions |
||||
google_protobuf_MethodOptions; |
||||
|
||||
struct google_protobuf_UninterpretedOption; |
||||
typedef struct google_protobuf_UninterpretedOption |
||||
google_protobuf_UninterpretedOption; |
||||
|
||||
struct pbstream_FileDescriptorSet { |
||||
int file_count; |
||||
struct pbstream_FileDescriptorProto *file; |
||||
struct google_protobuf_UninterpretedOption_NamePart; |
||||
typedef struct google_protobuf_UninterpretedOption_NamePart |
||||
google_protobuf_UninterpretedOption_NamePart; |
||||
|
||||
/* The message definitions themselves. */ |
||||
|
||||
struct google_protobuf_FileDescriptorSet { |
||||
union { |
||||
uint8_t bytes[1]; |
||||
struct { |
||||
bool file:1; /* = 1, repeated. */ |
||||
} has; |
||||
} set_flags; |
||||
UPB_STRUCT_ARRAY(google_protobuf_FileDescriptorProto)* file; |
||||
}; |
||||
UPB_DEFINE_STRUCT_ARRAY(google_protobuf_FileDescriptorSet) |
||||
|
||||
struct pbstream_FileDescriptorProto { |
||||
int message_type_count; |
||||
struct pbstream_FileDescriptorProto *message_type; |
||||
struct google_protobuf_FileDescriptorProto { |
||||
union { |
||||
uint8_t bytes[1]; |
||||
struct { |
||||
bool name:1; /* = 1, optional. */ |
||||
bool package:1; /* = 2, optional. */ |
||||
bool dependency:1; /* = 3, repeated. */ |
||||
bool message_type:1; /* = 4, repeated. */ |
||||
bool enum_type:1; /* = 5, repeated. */ |
||||
bool service:1; /* = 6, repeated. */ |
||||
bool extension:1; /* = 7, repeated. */ |
||||
bool options:1; /* = 8, optional. */ |
||||
} has; |
||||
} set_flags; |
||||
struct upb_string* name; |
||||
struct upb_string* package; |
||||
struct upb_string_array* dependency; |
||||
UPB_STRUCT_ARRAY(google_protobuf_DescriptorProto)* message_type; |
||||
UPB_STRUCT_ARRAY(google_protobuf_EnumDescriptorProto)* enum_type; |
||||
UPB_STRUCT_ARRAY(google_protobuf_ServiceDescriptorProto)* service; |
||||
UPB_STRUCT_ARRAY(google_protobuf_FieldDescriptorProto)* extension; |
||||
google_protobuf_FileOptions* options; |
||||
}; |
||||
UPB_DEFINE_STRUCT_ARRAY(google_protobuf_FileDescriptorProto) |
||||
|
||||
struct pbstream_DescriptorProto { |
||||
char *name; |
||||
int field_count; |
||||
struct pbstream_FieldDescriptorProto *field; |
||||
int nested_type_count; |
||||
struct pbstream_DescriptorProto *nested_type; |
||||
int enum_type_count; |
||||
struct pbstream_EnumDescriptorProto *enum_type; |
||||
struct google_protobuf_DescriptorProto_ExtensionRange { |
||||
union { |
||||
uint8_t bytes[1]; |
||||
struct { |
||||
bool start:1; /* = 1, optional. */ |
||||
bool end:1; /* = 2, optional. */ |
||||
} has; |
||||
} set_flags; |
||||
int32_t start; |
||||
int32_t end; |
||||
}; |
||||
UPB_DEFINE_STRUCT_ARRAY(google_protobuf_DescriptorProto_ExtensionRange) |
||||
struct google_protobuf_DescriptorProto { |
||||
union { |
||||
uint8_t bytes[1]; |
||||
struct { |
||||
bool name:1; /* = 1, optional. */ |
||||
bool field:1; /* = 2, repeated. */ |
||||
bool nested_type:1; /* = 3, repeated. */ |
||||
bool enum_type:1; /* = 4, repeated. */ |
||||
bool extension_range:1; /* = 5, repeated. */ |
||||
bool extension:1; /* = 6, repeated. */ |
||||
bool options:1; /* = 7, optional. */ |
||||
} has; |
||||
} set_flags; |
||||
struct upb_string* name; |
||||
UPB_STRUCT_ARRAY(google_protobuf_FieldDescriptorProto)* field; |
||||
UPB_STRUCT_ARRAY(google_protobuf_FieldDescriptorProto)* extension; |
||||
UPB_STRUCT_ARRAY(google_protobuf_DescriptorProto)* nested_type; |
||||
UPB_STRUCT_ARRAY(google_protobuf_EnumDescriptorProto)* enum_type; |
||||
UPB_STRUCT_ARRAY(google_protobuf_DescriptorProto_ExtensionRange)* extension_range; |
||||
google_protobuf_MessageOptions* options; |
||||
}; |
||||
UPB_DEFINE_STRUCT_ARRAY(google_protobuf_DescriptorProto) |
||||
|
||||
struct pbstream_FieldDescriptorProto { |
||||
char *name; |
||||
struct google_protobuf_FieldDescriptorProto { |
||||
union { |
||||
uint8_t bytes[1]; |
||||
struct { |
||||
bool name:1; /* = 1, optional. */ |
||||
bool extendee:1; /* = 2, optional. */ |
||||
bool number:1; /* = 3, optional. */ |
||||
bool label:1; /* = 4, optional. */ |
||||
bool type:1; /* = 5, optional. */ |
||||
bool type_name:1; /* = 6, optional. */ |
||||
bool default_value:1; /* = 7, optional. */ |
||||
bool options:1; /* = 8, optional. */ |
||||
} has; |
||||
} set_flags; |
||||
struct upb_string* name; |
||||
int32_t number; |
||||
enum pbstream_FieldDescriptorProtoType type; |
||||
char *type_name; |
||||
int32_t label; /* enum google.protobuf.FieldDescriptorProto.Label */ |
||||
int32_t type; /* enum google.protobuf.FieldDescriptorProto.Type */ |
||||
struct upb_string* type_name; |
||||
struct upb_string* extendee; |
||||
struct upb_string* default_value; |
||||
google_protobuf_FieldOptions* options; |
||||
}; |
||||
UPB_DEFINE_STRUCT_ARRAY(google_protobuf_FieldDescriptorProto) |
||||
|
||||
struct pbstream_EnumValueDescriptorProto { |
||||
char *name; |
||||
struct google_protobuf_EnumDescriptorProto { |
||||
union { |
||||
uint8_t bytes[1]; |
||||
struct { |
||||
bool name:1; /* = 1, optional. */ |
||||
bool value:1; /* = 2, repeated. */ |
||||
bool options:1; /* = 3, optional. */ |
||||
} has; |
||||
} set_flags; |
||||
struct upb_string* name; |
||||
UPB_STRUCT_ARRAY(google_protobuf_EnumValueDescriptorProto)* value; |
||||
google_protobuf_EnumOptions* options; |
||||
}; |
||||
UPB_DEFINE_STRUCT_ARRAY(google_protobuf_EnumDescriptorProto) |
||||
|
||||
struct google_protobuf_EnumValueDescriptorProto { |
||||
union { |
||||
uint8_t bytes[1]; |
||||
struct { |
||||
bool name:1; /* = 1, optional. */ |
||||
bool number:1; /* = 2, optional. */ |
||||
bool options:1; /* = 3, optional. */ |
||||
} has; |
||||
} set_flags; |
||||
struct upb_string* name; |
||||
int32_t number; |
||||
google_protobuf_EnumValueOptions* options; |
||||
}; |
||||
UPB_DEFINE_STRUCT_ARRAY(google_protobuf_EnumValueDescriptorProto) |
||||
|
||||
struct google_protobuf_ServiceDescriptorProto { |
||||
union { |
||||
uint8_t bytes[1]; |
||||
struct { |
||||
bool name:1; /* = 1, optional. */ |
||||
bool method:1; /* = 2, repeated. */ |
||||
bool options:1; /* = 3, optional. */ |
||||
} has; |
||||
} set_flags; |
||||
struct upb_string* name; |
||||
UPB_STRUCT_ARRAY(google_protobuf_MethodDescriptorProto)* method; |
||||
google_protobuf_ServiceOptions* options; |
||||
}; |
||||
UPB_DEFINE_STRUCT_ARRAY(google_protobuf_ServiceDescriptorProto) |
||||
|
||||
struct google_protobuf_MethodDescriptorProto { |
||||
union { |
||||
uint8_t bytes[1]; |
||||
struct { |
||||
bool name:1; /* = 1, optional. */ |
||||
bool input_type:1; /* = 2, optional. */ |
||||
bool output_type:1; /* = 3, optional. */ |
||||
bool options:1; /* = 4, optional. */ |
||||
} has; |
||||
} set_flags; |
||||
struct upb_string* name; |
||||
struct upb_string* input_type; |
||||
struct upb_string* output_type; |
||||
google_protobuf_MethodOptions* options; |
||||
}; |
||||
UPB_DEFINE_STRUCT_ARRAY(google_protobuf_MethodDescriptorProto) |
||||
|
||||
struct google_protobuf_FileOptions { |
||||
union { |
||||
uint8_t bytes[1]; |
||||
struct { |
||||
bool java_package:1; /* = 1, optional. */ |
||||
bool java_outer_classname:1; /* = 8, optional. */ |
||||
bool optimize_for:1; /* = 9, optional. */ |
||||
bool java_multiple_files:1; /* = 10, optional. */ |
||||
bool uninterpreted_option:1; /* = 999, repeated. */ |
||||
} has; |
||||
} set_flags; |
||||
struct upb_string* java_package; |
||||
struct upb_string* java_outer_classname; |
||||
bool java_multiple_files; |
||||
int32_t optimize_for; /* enum google.protobuf.FileOptions.OptimizeMode */ |
||||
UPB_STRUCT_ARRAY(google_protobuf_UninterpretedOption)* uninterpreted_option; |
||||
}; |
||||
UPB_DEFINE_STRUCT_ARRAY(google_protobuf_FileOptions) |
||||
|
||||
struct google_protobuf_MessageOptions { |
||||
union { |
||||
uint8_t bytes[1]; |
||||
struct { |
||||
bool message_set_wire_format:1; /* = 1, optional. */ |
||||
bool uninterpreted_option:1; /* = 999, repeated. */ |
||||
} has; |
||||
} set_flags; |
||||
bool message_set_wire_format; |
||||
UPB_STRUCT_ARRAY(google_protobuf_UninterpretedOption)* uninterpreted_option; |
||||
}; |
||||
UPB_DEFINE_STRUCT_ARRAY(google_protobuf_MessageOptions) |
||||
|
||||
struct google_protobuf_FieldOptions { |
||||
union { |
||||
uint8_t bytes[1]; |
||||
struct { |
||||
bool ctype:1; /* = 1, optional. */ |
||||
bool experimental_map_key:1; /* = 9, optional. */ |
||||
bool uninterpreted_option:1; /* = 999, repeated. */ |
||||
} has; |
||||
} set_flags; |
||||
int32_t ctype; /* enum google.protobuf.FieldOptions.CType */ |
||||
struct upb_string* experimental_map_key; |
||||
UPB_STRUCT_ARRAY(google_protobuf_UninterpretedOption)* uninterpreted_option; |
||||
}; |
||||
UPB_DEFINE_STRUCT_ARRAY(google_protobuf_FieldOptions) |
||||
|
||||
struct google_protobuf_EnumOptions { |
||||
union { |
||||
uint8_t bytes[1]; |
||||
struct { |
||||
bool uninterpreted_option:1; /* = 999, repeated. */ |
||||
} has; |
||||
} set_flags; |
||||
UPB_STRUCT_ARRAY(google_protobuf_UninterpretedOption)* uninterpreted_option; |
||||
}; |
||||
UPB_DEFINE_STRUCT_ARRAY(google_protobuf_EnumOptions) |
||||
|
||||
struct google_protobuf_EnumValueOptions { |
||||
union { |
||||
uint8_t bytes[1]; |
||||
struct { |
||||
bool uninterpreted_option:1; /* = 999, repeated. */ |
||||
} has; |
||||
} set_flags; |
||||
UPB_STRUCT_ARRAY(google_protobuf_UninterpretedOption)* uninterpreted_option; |
||||
}; |
||||
UPB_DEFINE_STRUCT_ARRAY(google_protobuf_EnumValueOptions) |
||||
|
||||
struct google_protobuf_ServiceOptions { |
||||
union { |
||||
uint8_t bytes[1]; |
||||
struct { |
||||
bool uninterpreted_option:1; /* = 999, repeated. */ |
||||
} has; |
||||
} set_flags; |
||||
UPB_STRUCT_ARRAY(google_protobuf_UninterpretedOption)* uninterpreted_option; |
||||
}; |
||||
UPB_DEFINE_STRUCT_ARRAY(google_protobuf_ServiceOptions) |
||||
|
||||
struct pbstream_EnumDescriptorProto { |
||||
char *name; |
||||
int value_count; |
||||
struct pbstream_EnumValueDescriptorProto *value; |
||||
struct google_protobuf_MethodOptions { |
||||
union { |
||||
uint8_t bytes[1]; |
||||
struct { |
||||
bool uninterpreted_option:1; /* = 999, repeated. */ |
||||
} has; |
||||
} set_flags; |
||||
UPB_STRUCT_ARRAY(google_protobuf_UninterpretedOption)* uninterpreted_option; |
||||
}; |
||||
UPB_DEFINE_STRUCT_ARRAY(google_protobuf_MethodOptions) |
||||
|
||||
struct google_protobuf_UninterpretedOption_NamePart { |
||||
union { |
||||
uint8_t bytes[1]; |
||||
struct { |
||||
bool name_part:1; /* = 1, required. */ |
||||
bool is_extension:1; /* = 2, required. */ |
||||
} has; |
||||
} set_flags; |
||||
struct upb_string* name_part; |
||||
bool is_extension; |
||||
}; |
||||
UPB_DEFINE_STRUCT_ARRAY(google_protobuf_UninterpretedOption_NamePart) |
||||
struct google_protobuf_UninterpretedOption { |
||||
union { |
||||
uint8_t bytes[1]; |
||||
struct { |
||||
bool name:1; /* = 2, repeated. */ |
||||
bool identifier_value:1; /* = 3, optional. */ |
||||
bool positive_int_value:1; /* = 4, optional. */ |
||||
bool negative_int_value:1; /* = 5, optional. */ |
||||
bool double_value:1; /* = 6, optional. */ |
||||
bool string_value:1; /* = 7, optional. */ |
||||
} has; |
||||
} set_flags; |
||||
UPB_STRUCT_ARRAY(google_protobuf_UninterpretedOption_NamePart)* name; |
||||
struct upb_string* identifier_value; |
||||
uint64_t positive_int_value; |
||||
int64_t negative_int_value; |
||||
double double_value; |
||||
struct upb_string* string_value; |
||||
}; |
||||
UPB_DEFINE_STRUCT_ARRAY(google_protobuf_UninterpretedOption) |
||||
|
||||
|
@ -0,0 +1,44 @@ |
||||
/*
|
||||
* upb - a minimalist implementation of protocol buffers. |
||||
* |
||||
* Definitions that will emit code for inline functions, per C99 inlining |
||||
* rules (see http://www.greenend.org.uk/rjk/2003/03/inline.html).
|
||||
*/ |
||||
|
||||
#include "upb_struct.h" |
||||
|
||||
#define UPB_DECLARE_ACCESSORS(ctype, name) \ |
||||
extern ctype *upb_struct_get_ ## name ## _ptr( \
|
||||
uint8_t *s, struct upb_struct_field *f); \
|
||||
extern ctype upb_struct_get_ ## name( \
|
||||
uint8_t *s, struct upb_struct_field *f); \
|
||||
extern void upb_struct_set_ ## name( \
|
||||
uint8_t *s, struct upb_struct_field *f, ctype val); |
||||
|
||||
#define UPB_DECLARE_ARRAY_ACCESSORS(ctype, name) \ |
||||
extern ctype *upb_array_get_ ## name ## _ptr(struct upb_array *a, int n); \
|
||||
extern ctype upb_array_get_ ## name(struct upb_array *a, int n); \
|
||||
extern void upb_array_set_ ## name(struct upb_array *a, int n, ctype val); |
||||
|
||||
#define UPB_DECLARE_ALL_ACCESSORS(ctype, name) \ |
||||
UPB_DECLARE_ACCESSORS(ctype, name) \
|
||||
UPB_DECLARE_ARRAY_ACCESSORS(ctype, name) |
||||
|
||||
UPB_DECLARE_ALL_ACCESSORS(double, double) |
||||
UPB_DECLARE_ALL_ACCESSORS(float, float) |
||||
UPB_DECLARE_ALL_ACCESSORS(int32_t, int32) |
||||
UPB_DECLARE_ALL_ACCESSORS(int64_t, int64) |
||||
UPB_DECLARE_ALL_ACCESSORS(uint32_t, uint32) |
||||
UPB_DECLARE_ALL_ACCESSORS(uint64_t, uint64) |
||||
UPB_DECLARE_ALL_ACCESSORS(bool, bool) |
||||
UPB_DECLARE_ALL_ACCESSORS(struct upb_struct_delimited*, bytes) |
||||
UPB_DECLARE_ALL_ACCESSORS(struct upb_struct_delimited*, string) |
||||
UPB_DECLARE_ALL_ACCESSORS(uint8_t*, substruct) |
||||
UPB_DECLARE_ACCESSORS(struct upb_array*, array) |
||||
|
||||
extern void upb_struct_set(uint8_t *s, struct upb_struct_field *f); |
||||
extern void upb_struct_unset(uint8_t *s, struct upb_struct_field *f); |
||||
extern bool upb_struct_is_set(uint8_t *s, struct upb_struct_field *f); |
||||
extern bool upb_struct_all_required_fields_set( |
||||
uint8_t *s, struct upb_struct_definition *d); |
||||
extern void upb_struct_clear(uint8_t *s, struct upb_struct_definition *d); |
@ -0,0 +1,219 @@ |
||||
/*
|
||||
* upb - a minimalist implementation of protocol buffers. |
||||
* |
||||
* Copyright (c) 2009 Joshua Haberman. See LICENSE for details. |
||||
* |
||||
* upb_struct defines an in-memory byte-level format for storing protobufs. It |
||||
* is very much like a C struct that you can define at run-time, but also |
||||
* supports reflection. Like C structs it supports offset-based access, as |
||||
* opposed to the much slower name-based lookup. The format represents both |
||||
* the values themselves and bits describing whether each field is set or not. |
||||
* |
||||
* The upb compiler emits C structs that mimic this definition exactly, so that |
||||
* you can access the same hunk of memory using either this run-time |
||||
* reflection-supporting interface or a C struct that was generated by the upb |
||||
* compiler. |
||||
* |
||||
* Like C structs the format depends on the endianness of the host machine, so |
||||
* it is not suitable for exchanging across machines of differing endianness. |
||||
* But there is no reason to do that -- the protobuf serialization format is |
||||
* designed already for serialization/deserialization, and is more compact than |
||||
* this format. This format is designed to allow the fastest possible random |
||||
* access of individual fields. |
||||
* |
||||
* Note that no memory management is defined, which should make it easier to |
||||
* integrate this format with existing memory-management schemes. Any memory |
||||
* management semantics can be used with the format as defined here. |
||||
*/ |
||||
|
||||
#ifndef PBSTRUCT_H_ |
||||
#define PBSTRUCT_H_ |
||||
|
||||
#include <stdbool.h> |
||||
#include <stddef.h> |
||||
#include <stdint.h> |
||||
#include <string.h> |
||||
|
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
/* Structure definition. ******************************************************/ |
||||
|
||||
/* One single field of the struct. */ |
||||
struct upb_struct_field { |
||||
ptrdiff_t byte_offset; /* Where to find the data. */ |
||||
ptrdiff_t isset_byte_offset; /* The byte where the "set" bit lives. */ |
||||
uint8_t isset_byte_mask; |
||||
}; |
||||
|
||||
/* Definition of a complete struct. */ |
||||
struct upb_struct_definition { |
||||
size_t size; |
||||
int num_fields; |
||||
int set_flags_bytes; |
||||
int num_required_fields; /* Required fields have the lowest set bytemasks. */ |
||||
struct upb_struct_field fields[]; |
||||
}; |
||||
|
||||
/* While these are written to be as fast as possible, it will still be faster
|
||||
* cache the results of this lookup if possible. These return NULL if no such |
||||
* field is found. */ |
||||
struct upb_struct_field *upb_struct_find_field_by_name( |
||||
struct upb_struct_definition *d, char *name); |
||||
struct upb_struct_field *upb_struct_find_field_by_number( |
||||
struct upb_struct_definition *d, uint32_t number); |
||||
|
||||
/* Variable-length data (strings and arrays).**********************************/ |
||||
|
||||
/* Represents a string or bytes. */ |
||||
struct upb_string { |
||||
size_t byte_len; |
||||
uint8_t *data; |
||||
}; |
||||
|
||||
/* Represents an array (a repeated field) of any type. The interpretation of
|
||||
* the data in the array depends on the type. */ |
||||
struct upb_array { |
||||
size_t len; /* Measured in elements. */ |
||||
uint8_t *data; /* Size of individual elements is based on type. */ |
||||
}; |
||||
|
||||
/* A generic array of structs, using void* instead of specific types. */ |
||||
struct upb_struct_array { |
||||
size_t len; |
||||
void **elements; |
||||
}; |
||||
|
||||
/* An array of strings. */ |
||||
struct upb_string_array { |
||||
size_t len; |
||||
struct upb_string **elements; |
||||
}; |
||||
|
||||
/* Specific arrays of all the primitive types. */ |
||||
#define UPB_DEFINE_PRIMITIVE_ARRAY(type, name) \ |
||||
struct upb_ ## name ## _array { \
|
||||
size_t len; \
|
||||
type *elements; \
|
||||
}; |
||||
|
||||
UPB_DEFINE_PRIMITIVE_ARRAY(double, double) |
||||
UPB_DEFINE_PRIMITIVE_ARRAY(float, float) |
||||
UPB_DEFINE_PRIMITIVE_ARRAY(int32_t, int32) |
||||
UPB_DEFINE_PRIMITIVE_ARRAY(int64_t, int64) |
||||
UPB_DEFINE_PRIMITIVE_ARRAY(uint32_t, uint32) |
||||
UPB_DEFINE_PRIMITIVE_ARRAY(uint64_t, uint64) |
||||
UPB_DEFINE_PRIMITIVE_ARRAY(bool, bool) |
||||
#undef UPB_DEFINE_PRMITIVE_ARRAY |
||||
|
||||
#define UPB_STRUCT_ARRAY(struct_type) struct struct_type ## _array |
||||
|
||||
#define UPB_DEFINE_STRUCT_ARRAY(struct_type) \ |
||||
UPB_STRUCT_ARRAY(struct_type) { \
|
||||
size_t len; \
|
||||
struct_type **elements; \
|
||||
}; |
||||
|
||||
/* Accessors for primitive types. ********************************************/ |
||||
|
||||
/* For each primitive type we define a set of six functions:
|
||||
* |
||||
* // For fetching out of a struct (s points to the raw struct data).
|
||||
* int32_t *upb_struct_get_int32_ptr(uint8_t *s, struct upb_struct_field *f); |
||||
* int32_t upb_struct_get_int32(uint8_t *s, struct upb_struct_field *f); |
||||
* void upb_struct_set_int32(uint8_t *s, struct upb_struct_field *f, int32_t val); |
||||
* |
||||
* // For fetching out of an array.
|
||||
* int32_t *upb_array_get_int32_ptr(struct upb_array *a, int n); |
||||
* int32_t upb_array_get_int32(struct upb_array *a, int n); |
||||
* void upb_array_set_int32(struct upb_array *a, int n, ctype val); |
||||
* |
||||
* For arrays we provide only the first three because protobufs do not support |
||||
* arrays of arrays. |
||||
* |
||||
* These do no existence checks, bounds checks, or type checks. */ |
||||
|
||||
#define UPB_DEFINE_ACCESSORS(ctype, name) \ |
||||
inline ctype *upb_struct_get_ ## name ## _ptr( \
|
||||
uint8_t *s, struct upb_struct_field *f) { \
|
||||
return (ctype*)(s + f->byte_offset); \
|
||||
} \
|
||||
inline ctype upb_struct_get_ ## name( \
|
||||
uint8_t *s, struct upb_struct_field *f) { \
|
||||
return *upb_struct_get_ ## name ## _ptr(s, f); \
|
||||
} \
|
||||
inline void upb_struct_set_ ## name( \
|
||||
uint8_t *s, struct upb_struct_field *f, ctype val) { \
|
||||
*upb_struct_get_ ## name ## _ptr(s, f) = val; \
|
||||
} |
||||
|
||||
#define UPB_DEFINE_ARRAY_ACCESSORS(ctype, name) \ |
||||
inline ctype *upb_array_get_ ## name ## _ptr(struct upb_array *a, int n) { \
|
||||
return ((ctype*)a->data) + n; \
|
||||
} \
|
||||
inline ctype upb_array_get_ ## name(struct upb_array *a, int n) { \
|
||||
return *upb_array_get_ ## name ## _ptr(a, n); \
|
||||
} \
|
||||
inline void upb_array_set_ ## name(struct upb_array *a, int n, ctype val) { \
|
||||
*upb_array_get_ ## name ## _ptr(a, n) = val; \
|
||||
} |
||||
|
||||
#define UPB_DEFINE_ALL_ACCESSORS(ctype, name) \ |
||||
UPB_DEFINE_ACCESSORS(ctype, name) \
|
||||
UPB_DEFINE_ARRAY_ACCESSORS(ctype, name) |
||||
|
||||
UPB_DEFINE_ALL_ACCESSORS(double, double) |
||||
UPB_DEFINE_ALL_ACCESSORS(float, float) |
||||
UPB_DEFINE_ALL_ACCESSORS(int32_t, int32) |
||||
UPB_DEFINE_ALL_ACCESSORS(int64_t, int64) |
||||
UPB_DEFINE_ALL_ACCESSORS(uint32_t, uint32) |
||||
UPB_DEFINE_ALL_ACCESSORS(uint64_t, uint64) |
||||
UPB_DEFINE_ALL_ACCESSORS(bool, bool) |
||||
UPB_DEFINE_ALL_ACCESSORS(struct upb_struct_delimited*, bytes) |
||||
UPB_DEFINE_ALL_ACCESSORS(struct upb_struct_delimited*, string) |
||||
UPB_DEFINE_ALL_ACCESSORS(uint8_t*, substruct) |
||||
UPB_DEFINE_ACCESSORS(struct upb_array*, array) |
||||
|
||||
/* Functions for reading and writing the "set" flags in the pbstruct. Note
|
||||
* that these do not perform any memory management associated with any dynamic |
||||
* memory these fields may be referencing; that is the client's responsibility. |
||||
* These *only* set and test the flags. */ |
||||
inline void upb_struct_set(uint8_t *s, struct upb_struct_field *f) |
||||
{ |
||||
s[f->isset_byte_offset] |= f->isset_byte_mask; |
||||
} |
||||
|
||||
inline void upb_struct_unset(uint8_t *s, struct upb_struct_field *f) |
||||
{ |
||||
s[f->isset_byte_offset] &= ~f->isset_byte_mask; |
||||
} |
||||
|
||||
inline bool upb_struct_is_set(uint8_t *s, struct upb_struct_field *f) |
||||
{ |
||||
return s[f->isset_byte_offset] & f->isset_byte_mask; |
||||
} |
||||
|
||||
inline bool upb_struct_all_required_fields_set( |
||||
uint8_t *s, struct upb_struct_definition *d) |
||||
{ |
||||
int num_fields = d->num_required_fields; |
||||
int i = 0; |
||||
while(num_fields > 8) { |
||||
if(s[i++] != 0xFF) return false; |
||||
num_fields -= 8; |
||||
} |
||||
if(s[i] != (1 << num_fields) - 1) return false; |
||||
return true; |
||||
} |
||||
|
||||
inline void upb_struct_clear(uint8_t *s, struct upb_struct_definition *d) |
||||
{ |
||||
memset(s, 0, d->set_flags_bytes); |
||||
} |
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#endif /* PBSTRUCT_H_ */ |
Loading…
Reference in new issue