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.
 
 
 
 
 
 

96 lines
2.7 KiB

/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2010-2011 Joshua Haberman. See LICENSE for details.
*
* Data structure for storing a message of protobuf data. Unlike Google's
* protobuf, upb_msg and upb_array are reference counted instead of having
* exclusive ownership of their fields. This is a better match for dynamic
* languages where statements like a.b = other_b are normal.
*
* upb's parsers and serializers could also be used to populate and serialize
* other kinds of message objects (even one generated by Google's protobuf).
*/
#ifndef UPB_MSG_H
#define UPB_MSG_H
#include "upb.h"
#include "upb_def.h"
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
/* upb_array ******************************************************************/
typedef uint32_t upb_arraylen_t;
struct _upb_array {
upb_atomic_refcount_t refcount;
upb_arraylen_t len;
upb_arraylen_t size;
upb_valueptr elements;
};
void _upb_array_free(upb_array *a, upb_fielddef *f);
INLINE upb_valueptr _upb_array_getptr(upb_array *a, upb_fielddef *f,
uint32_t elem) {
upb_valueptr p;
p._void = &a->elements.uint8[elem * upb_types[f->type].size];
return p;
}
upb_array *upb_array_new(void);
INLINE void upb_array_unref(upb_array *a, upb_fielddef *f) {
if (upb_atomic_unref(&a->refcount)) _upb_array_free(a, f);
}
INLINE uint32_t upb_array_len(upb_array *a) {
return a->len;
}
/* upb_msg ********************************************************************/
struct _upb_msg {
upb_atomic_refcount_t refcount;
uint8_t data[4]; // We allocate the appropriate amount per message.
};
void _upb_msg_free(upb_msg *msg, upb_msgdef *md);
INLINE upb_valueptr _upb_msg_getptr(upb_msg *msg, upb_fielddef *f) {
upb_valueptr p;
p._void = &msg->data[f->byte_offset];
return p;
}
// Creates a new msg of the given type.
upb_msg *upb_msg_new(upb_msgdef *md);
// Unrefs the given message.
INLINE void upb_msg_unref(upb_msg *msg, upb_msgdef *md) {
if (msg && upb_atomic_unref(&msg->refcount)) _upb_msg_free(msg, md);
}
// Tests whether the given field is explicitly set, or whether it will return a
// default.
INLINE bool upb_msg_has(upb_msg *msg, upb_fielddef *f) {
return (msg->data[f->field_index/8] & (1 << (f->field_index % 8))) != 0;
}
// Unsets all field values back to their defaults.
INLINE void upb_msg_clear(upb_msg *msg, upb_msgdef *md) {
memset(msg->data, 0, md->set_flags_bytes);
}
// Registers a set of handlers that will populate this msgdef.
void upb_msg_register_handlers(upb_msg *msg, upb_msgdef *md,
upb_handlers *handlers);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif