Commit d14bb42d authored by Robert Edmonds's avatar Robert Edmonds

add doxygen documentation for the public header file

this also significantly reorganizes the header file.

based heavily on kevin lyda's work in PR #140.
parent 8655ca07
/* --- protobuf-c.h: protobuf c runtime api --- */
/* /*
* Copyright (c) 2008-2014, Dave Benson and the protobuf-c authors. * Copyright (c) 2008-2014, Dave Benson and the protobuf-c authors.
* All rights reserved. * All rights reserved.
...@@ -29,13 +27,31 @@ ...@@ -29,13 +27,31 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
/*! \file
* \mainpage Introduction
*
* This is [protobuf-c], a C implementation of [Protocol Buffers].
*
* This file defines the public API for the `libprotobuf-c` support library.
* This API includes interfaces that can be used directly by client code as well
* as the interfaces used by the code generated by the `protoc-c` compiler.
*
* \authors Dave Benson and the `protobuf-c` authors.
*
* \copyright 2008-2014. Licensed under the terms of the [BSD-2-Clause] license.
*
* [protobuf-c]: https://github.com/protobuf-c/protobuf-c
* [Protocol Buffers]: https://developers.google.com/protocol-buffers/
* [BSD-2-Clause]: http://opensource.org/licenses/BSD-2-Clause
*/
#ifndef PROTOBUF_C_H #ifndef PROTOBUF_C_H
#define PROTOBUF_C_H #define PROTOBUF_C_H
#include <assert.h> #include <assert.h>
#include <limits.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <limits.h>
#ifdef __cplusplus #ifdef __cplusplus
# define PROTOBUF_C__BEGIN_DECLS extern "C" { # define PROTOBUF_C__BEGIN_DECLS extern "C" {
...@@ -45,13 +61,7 @@ ...@@ -45,13 +61,7 @@
# define PROTOBUF_C__END_DECLS # define PROTOBUF_C__END_DECLS
#endif #endif
#if !defined(PROTOBUF_C__NO_DEPRECATED) PROTOBUF_C__BEGIN_DECLS
# if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
# define PROTOBUF_C__DEPRECATED __attribute__((__deprecated__))
# endif
#else
# define PROTOBUF_C__DEPRECATED
#endif
#if defined(_WIN32) && defined(PROTOBUF_C_USE_SHARED_LIB) #if defined(_WIN32) && defined(PROTOBUF_C_USE_SHARED_LIB)
# ifdef PROTOBUF_C_EXPORT # ifdef PROTOBUF_C_EXPORT
...@@ -63,514 +73,818 @@ ...@@ -63,514 +73,818 @@
# define PROTOBUF_C__API # define PROTOBUF_C__API
#endif #endif
PROTOBUF_C__BEGIN_DECLS #if !defined(PROTOBUF_C__NO_DEPRECATED)
# if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
# define PROTOBUF_C__DEPRECATED __attribute__((__deprecated__))
# endif
#else
# define PROTOBUF_C__DEPRECATED
#endif
/** #ifndef PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE
* Get the version of the protobuf-c library. Note that this is the version of #define PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(enum_name) \
* the library linked against, not the version of the headers compiled against. , _##enum_name##_IS_INT_SIZE = INT_MAX
* #endif
* \return A string containing the version number of protobuf-c.
*/ #define PROTOBUF_C__SERVICE_DESCRIPTOR_MAGIC 0x14159bc3
PROTOBUF_C__API #define PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC 0x28aaeef9
const char * #define PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC 0x114315af
protobuf_c_version(void);
/** /**
* Get the version of the protobuf-c library. Note that this is the version of * \defgroup api Public API
* the library linked against, not the version of the headers compiled against.
* *
* \return A 32 bit unsigned integer containing the version number of * This is the public API for `libprotobuf-c`. These interfaces are stable and
* protobuf-c, represented in base-10 as (MAJOR*1E6) + (MINOR*1E3) + PATCH. * subject to Semantic Versioning guarantees.
*
* @{
*/ */
PROTOBUF_C__API
uint32_t
protobuf_c_version_number(void);
/** /**
* The version of the protobuf-c headers, represented as a string using the same * Values for the `flags` word in `ProtobufCFieldDescriptor`.
* format as protobuf_c_version().
*/ */
#define PROTOBUF_C_VERSION "1.0.0-rc1" typedef enum {
/** Set if the field is repeated and marked with the `packed` option. */
PROTOBUF_C_FIELD_FLAG_PACKED = (1 << 0),
/** /** Set if the field is marked with the `deprecated` option. */
* The version of the protobuf-c headers, represented as an integer using the PROTOBUF_C_FIELD_FLAG_DEPRECATED = (1 << 1),
* same format as protobuf_c_version_number(). } ProtobufCFieldFlag;
*/
#define PROTOBUF_C_VERSION_NUMBER 1000000
/** /**
* The minimum protoc-c version which works with the current version of the * Message field rules.
* protobuf-c headers. *
* \see [Defining A Message Type] in the Protocol Buffers documentation.
*
* [Defining A Message Type]:
* https://developers.google.com/protocol-buffers/docs/proto#simple
*/ */
#define PROTOBUF_C_MIN_COMPILER_VERSION 1000000
typedef int protobuf_c_boolean;
typedef enum { typedef enum {
/** A well-formed message must have exactly one of this field. */
PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_LABEL_REQUIRED,
/**
* A well-formed message can have zero or one of this field (but not
* more than one).
*/
PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_LABEL_OPTIONAL,
PROTOBUF_C_LABEL_REPEATED
/**
* This field can be repeated any number of times (including zero) in a
* well-formed message. The order of the repeated values will be
* preserved.
*/
PROTOBUF_C_LABEL_REPEATED,
} ProtobufCLabel; } ProtobufCLabel;
/**
* Field value types.
*
* \see [Scalar Value Types] in the Protocol Buffers documentation.
*
* [Scalar Value Types]:
* https://developers.google.com/protocol-buffers/docs/proto#scalar
*/
typedef enum { typedef enum {
PROTOBUF_C_TYPE_INT32, PROTOBUF_C_TYPE_INT32, /**< int32 */
PROTOBUF_C_TYPE_SINT32, PROTOBUF_C_TYPE_SINT32, /**< signed int32 */
PROTOBUF_C_TYPE_SFIXED32, PROTOBUF_C_TYPE_SFIXED32, /**< signed int32 (4 bytes) */
PROTOBUF_C_TYPE_INT64, PROTOBUF_C_TYPE_INT64, /**< int64 */
PROTOBUF_C_TYPE_SINT64, PROTOBUF_C_TYPE_SINT64, /**< signed int64 */
PROTOBUF_C_TYPE_SFIXED64, PROTOBUF_C_TYPE_SFIXED64, /**< signed int64 (8 bytes) */
PROTOBUF_C_TYPE_UINT32, PROTOBUF_C_TYPE_UINT32, /**< unsigned int32 */
PROTOBUF_C_TYPE_FIXED32, PROTOBUF_C_TYPE_FIXED32, /**< unsigned int32 (4 bytes) */
PROTOBUF_C_TYPE_UINT64, PROTOBUF_C_TYPE_UINT64, /**< unsigned int64 */
PROTOBUF_C_TYPE_FIXED64, PROTOBUF_C_TYPE_FIXED64, /**< unsigned int64 (8 bytes) */
PROTOBUF_C_TYPE_FLOAT, PROTOBUF_C_TYPE_FLOAT, /**< float */
PROTOBUF_C_TYPE_DOUBLE, PROTOBUF_C_TYPE_DOUBLE, /**< double */
PROTOBUF_C_TYPE_BOOL, PROTOBUF_C_TYPE_BOOL, /**< boolean */
PROTOBUF_C_TYPE_ENUM, PROTOBUF_C_TYPE_ENUM, /**< enumerated type */
PROTOBUF_C_TYPE_STRING, PROTOBUF_C_TYPE_STRING, /**< UTF-8 or ASCII string */
PROTOBUF_C_TYPE_BYTES, PROTOBUF_C_TYPE_BYTES, /**< arbitrary byte sequence */
/* PROTOBUF_C_TYPE_GROUP, -- NOT SUPPORTED */ PROTOBUF_C_TYPE_MESSAGE, /**< nested message */
PROTOBUF_C_TYPE_MESSAGE,
} ProtobufCType; } ProtobufCType;
typedef struct ProtobufCBinaryData ProtobufCBinaryData; /**
struct ProtobufCBinaryData { * Field wire types.
size_t len; *
uint8_t *data; * \see [Message Structure] in the Protocol Buffers documentation.
}; *
* [Message Structure]:
* https://developers.google.com/protocol-buffers/docs/encoding#structure
*/
typedef enum {
PROTOBUF_C_WIRE_TYPE_VARINT = 0,
PROTOBUF_C_WIRE_TYPE_64BIT = 1,
PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED = 2,
/* "Start group" and "end group" wire types are unsupported. */
PROTOBUF_C_WIRE_TYPE_32BIT = 5,
} ProtobufCWireType;
typedef struct ProtobufCIntRange ProtobufCIntRange; /* private */ struct ProtobufCAllocator;
struct ProtobufCBinaryData;
struct ProtobufCBuffer;
struct ProtobufCBufferSimple;
struct ProtobufCEnumDescriptor;
struct ProtobufCEnumValue;
struct ProtobufCEnumValueIndex;
struct ProtobufCFieldDescriptor;
struct ProtobufCIntRange;
struct ProtobufCMessage;
struct ProtobufCMessageDescriptor;
struct ProtobufCMessageUnknownField;
struct ProtobufCMethodDescriptor;
struct ProtobufCService;
struct ProtobufCServiceDescriptor;
/* --- memory management --- */
typedef struct ProtobufCAllocator ProtobufCAllocator; typedef struct ProtobufCAllocator ProtobufCAllocator;
struct ProtobufCAllocator typedef struct ProtobufCBinaryData ProtobufCBinaryData;
{ typedef struct ProtobufCBuffer ProtobufCBuffer;
typedef struct ProtobufCBufferSimple ProtobufCBufferSimple;
typedef struct ProtobufCEnumDescriptor ProtobufCEnumDescriptor;
typedef struct ProtobufCEnumValue ProtobufCEnumValue;
typedef struct ProtobufCEnumValueIndex ProtobufCEnumValueIndex;
typedef struct ProtobufCFieldDescriptor ProtobufCFieldDescriptor;
typedef struct ProtobufCIntRange ProtobufCIntRange;
typedef struct ProtobufCMessage ProtobufCMessage;
typedef struct ProtobufCMessageDescriptor ProtobufCMessageDescriptor;
typedef struct ProtobufCMessageUnknownField ProtobufCMessageUnknownField;
typedef struct ProtobufCMethodDescriptor ProtobufCMethodDescriptor;
typedef struct ProtobufCService ProtobufCService;
typedef struct ProtobufCServiceDescriptor ProtobufCServiceDescriptor;
/** Boolean type. */
typedef int protobuf_c_boolean;
typedef void (*ProtobufCClosure)(const ProtobufCMessage *, void *closure_data);
typedef void (*ProtobufCMessageInit)(ProtobufCMessage *);
typedef void (*ProtobufCServiceDestroy)(ProtobufCService *);
/**
* Structure for defining a custom memory allocator.
*/
struct ProtobufCAllocator {
/** Function to allocate memory. */
void *(*alloc)(void *allocator_data, size_t size); void *(*alloc)(void *allocator_data, size_t size);
/** Function to free memory. */
void (*free)(void *allocator_data, void *pointer); void (*free)(void *allocator_data, void *pointer);
/** Opaque pointer passed to `alloc` and `free` functions. */
void *allocator_data; void *allocator_data;
}; };
/* /**
* This is a configurable allocator. * Structure for the protobuf `bytes` scalar type.
* By default, it uses the system allocator (meaning malloc() and free()).
* This is typically changed to adapt to frameworks that provide
* some nonstandard allocation functions.
* *
* NOTE: you may modify this allocator. * The data contained in a `ProtobufCBinaryData` is an arbitrary sequence of
* bytes. It may contain embedded `NUL` characters and is not required to be
* `NUL`-terminated.
*/ */
extern PROTOBUF_C__API ProtobufCAllocator protobuf_c_default_allocator; /* settable */ struct ProtobufCBinaryData {
size_t len; /**< Number of bytes in the `data` field. */
uint8_t *data; /**< Data bytes. */
};
/* --- append-only data buffer --- */ /**
typedef struct ProtobufCBuffer ProtobufCBuffer; * Structure for defining a virtual append-only buffer. Used by
* protobuf_c_message_pack_to_buffer().
*/
struct ProtobufCBuffer { struct ProtobufCBuffer {
/** Append function. Consumes the `len` bytes stored at `data`. */
void (*append)(ProtobufCBuffer *buffer, void (*append)(ProtobufCBuffer *buffer,
size_t len, size_t len,
const uint8_t *data); const uint8_t *data);
}; };
/* --- enums --- */ /**
* Simple buffer "subclass" of `ProtobufCBuffer`.
typedef struct ProtobufCEnumValue ProtobufCEnumValue; *
typedef struct ProtobufCEnumValueIndex ProtobufCEnumValueIndex; * \see PROTOBUF_C_BUFFER_SIMPLE_INIT
typedef struct ProtobufCEnumDescriptor ProtobufCEnumDescriptor; * \see PROTOBUF_C_BUFFER_SIMPLE_CLEAR
/*
* ProtobufCEnumValue: this represents a single value of an enumeration.
* 'name' is the string identifying this value, as given in the .proto file.
* 'c_name' is the full name of the C enumeration value.
* 'value' is the number assigned to this value, as given in the .proto file.
*/ */
struct ProtobufCEnumValue { struct ProtobufCBufferSimple {
const char *name; /** "Base class". */
const char *c_name; ProtobufCBuffer base;
int value; /** Number of bytes allocated in `data`. */
size_t alloced;
/** Number of bytes currently stored in `data`. */
size_t len;
/** Data bytes. */
uint8_t *data;
/** Whether `data` must be freed. */
protobuf_c_boolean must_free_data;
}; };
/* /**
* ProtobufCEnumDescriptor: represents the enum as a whole, with all its values. * Describes an enumeration as a whole, with all of its values.
*
* 'magic' is a code we check to ensure that the api is used correctly.
* 'name' is the qualified name (e.g. "namespace.Type").
* 'short_name' is the unqualified name ("Type"), as given in the .proto file.
* 'package_name' is the '.'-separated namespace
* 'n_values' is the number of distinct values.
* 'values' is the array of distinct values.
* 'n_value_names' number of named values (including aliases).
* 'value_names' are the named values (including aliases).
*
* The rest of the values are private essentially.
*
* See also: Use protobuf_c_enum_descriptor_get_value_by_name()
* and protobuf_c_enum_descriptor_get_value() to efficiently
* lookup values in the descriptor.
*/ */
struct ProtobufCEnumDescriptor { struct ProtobufCEnumDescriptor {
/** Magic value checked to ensure that the API is used correctly. */
uint32_t magic; uint32_t magic;
/** The qualified name (e.g., "namespace.Type"). */
const char *name; const char *name;
/** The unqualified name as given in the .proto file (e.g., "Type"). */
const char *short_name; const char *short_name;
/** Identifier used in generated C code. */
const char *c_name; const char *c_name;
/** The dot-separated namespace. */
const char *package_name; const char *package_name;
/* sorted by value */ /** Number elements in `values`. */
unsigned n_values; unsigned n_values;
/** Array of distinct values, sorted by numeric value. */
const ProtobufCEnumValue *values; const ProtobufCEnumValue *values;
/* sorted by name */ /** Number of elements in `values_by_name`. */
unsigned n_value_names; unsigned n_value_names;
/** Array of named values, including aliases, sorted by name. */
const ProtobufCEnumValueIndex *values_by_name; const ProtobufCEnumValueIndex *values_by_name;
/* value-ranges, for faster lookups by number */ /** Number of elements in `value_ranges`. */
unsigned n_value_ranges; unsigned n_value_ranges;
/** Value ranges, for faster lookups by numeric value. */
const ProtobufCIntRange *value_ranges; const ProtobufCIntRange *value_ranges;
/** Reserved for future use. */
void *reserved1; void *reserved1;
/** Reserved for future use. */
void *reserved2; void *reserved2;
/** Reserved for future use. */
void *reserved3; void *reserved3;
/** Reserved for future use. */
void *reserved4; void *reserved4;
}; };
/* --- messages --- */ /**
* Represents a single value of an enumeration.
*/
struct ProtobufCEnumValue {
/** The string identifying this value in the .proto file. */
const char *name;
typedef struct ProtobufCMessageDescriptor ProtobufCMessageDescriptor; /** The string identifying this value in generated C code. */
typedef struct ProtobufCFieldDescriptor ProtobufCFieldDescriptor; const char *c_name;
typedef struct ProtobufCMessage ProtobufCMessage;
typedef void (*ProtobufCMessageInit)(ProtobufCMessage *);
/* /** The numeric value assigned in the .proto file. */
* ProtobufCFieldDescriptor: description of a single field in a message. int value;
* };
* 'name' is the name of the field, as given in the .proto file.
* 'id' is the code representing the field, as given in the .proto file. /**
* 'label' is one of PROTOBUF_C_LABEL_{REQUIRED,OPTIONAL,REPEATED} * Used by `ProtobufCEnumDescriptor` to look up enum values.
* 'type' is the type of field. */
* 'quantifier_offset' is the offset in bytes into the message's C structure struct ProtobufCEnumValueIndex {
* for this member's "has_MEMBER" field (for optional members) or /** Name of the enum value. */
* "n_MEMBER" field (for repeated members). const char *name;
* 'offset' is the offset in bytes into the message's C structure /** Index into values[] array. */
* for the member itself. unsigned index;
* 'descriptor' is a pointer to a ProtobufC{Enum,Message}Descriptor };
* if type is PROTOBUF_C_TYPE_{ENUM,MESSAGE} respectively,
* otherwise NULL. /**
* 'default_value' is a pointer to a default value for this field, * Describes a single field in a message.
* where allowed.
* 'flags' is a flag word. Zero or more of the bits defined in the
* ProtobufCFieldFlag enum may be set.
*/ */
struct ProtobufCFieldDescriptor { struct ProtobufCFieldDescriptor {
/** Name of the field as given in the .proto file. */
const char *name; const char *name;
/** Tag value of the field as given in the .proto file. */
uint32_t id; uint32_t id;
/** Whether the field is `REQUIRED`, `OPTIONAL`, or `REPEATED`. */
ProtobufCLabel label; ProtobufCLabel label;
/** The type of the field. */
ProtobufCType type; ProtobufCType type;
/**
* The offset in bytes of the message's C structure's quantifier field
* (the `has_MEMBER` field for optional members or the `n_MEMBER` field
* for repeated members.
*/
unsigned quantifier_offset; unsigned quantifier_offset;
/**
* The offset in bytes into the message's C structure for the member
* itself.
*/
unsigned offset; unsigned offset;
/**
* A type-specific descriptor.
*
* If `type` is `PROTOBUF_C_TYPE_ENUM`, then `descriptor` points to the
* corresponding `ProtobufCEnumDescriptor`.
*
* If `type` is `PROTOBUF_C_TYPE_MESSAGE`, then `descriptor` points to
* the corresponding `ProtobufCMessageDescriptor`.
*
* Otherwise this field is NULL.
*/
const void *descriptor; /* for MESSAGE and ENUM types */ const void *descriptor; /* for MESSAGE and ENUM types */
const void *default_value; /* can be NULL */
/** The default value for this field, if defined. May be NULL. */
const void *default_value;
/**
* A flag word. Zero or more of the bits defined in the
* `ProtobufCFieldFlag` enum may be set.
*/
uint32_t flags; uint32_t flags;
/** Reserved for future use. */
unsigned reserved_flags; unsigned reserved_flags;
/** Reserved for future use. */
void *reserved2; void *reserved2;
/** Reserved for future use. */
void *reserved3; void *reserved3;
}; };
typedef enum { /**
/* Set if the field is repeated and marked with the 'packed' option. */ * Helper structure for optimizing int => index lookups in the case
PROTOBUF_C_FIELD_FLAG_PACKED = (1 << 0), * where the keys are mostly consecutive values, as they presumably are for
* enums and fields.
*
* The data structures requires that the values in the original array are
* sorted.
*/
struct ProtobufCIntRange {
int start_value;
unsigned orig_index;
/*
* NOTE: the number of values in the range can be inferred by looking
* at the next element's orig_index. A dummy element is added to make
* this simple.
*/
};
/* Set if the field is marked with the 'deprecated' option. */ /**
PROTOBUF_C_FIELD_FLAG_DEPRECATED = (1 << 1), * An instance of a message.
} ProtobufCFieldFlag; *
* `ProtobufCMessage` is a light-weight "base class" for all messages.
*
* In particular, `ProtobufCMessage` doesn't have any allocation policy
* associated with it. That's because it's common to create `ProtobufCMessage`
* objects on the stack. In fact, that's what we recommend for sending messages.
* If the object is allocated from the stack, you can't really have a memory
* leak.
*
* This means that calls to functions like protobuf_c_message_unpack() which
* return a `ProtobufCMessage` must be paired with a call to a free function,
* like protobuf_c_message_free_unpacked().
*/
struct ProtobufCMessage {
/** The descriptor for this message type. */
const ProtobufCMessageDescriptor *descriptor;
/** The number of elements in `unknown_fields`. */
unsigned n_unknown_fields;
/** The fields that weren't recognized by the parser. */
ProtobufCMessageUnknownField *unknown_fields;
};
/* /**
* ProtobufCMessageDescriptor: description of a message. * Describes a message.
*
* 'magic' is a code we check to ensure that the api is used correctly.
* 'name' is the qualified name (e.g. "namespace.Type").
* 'short_name' is the unqualified name ("Type"), as given in the .proto file.
* 'c_name' is the c-formatted name of the structure
* 'package_name' is the '.'-separated namespace
* 'sizeof_message' is the size in bytes of the C structure
* representing an instance of this type of message.
* 'n_fields' is the number of known fields in this message.
* 'fields' is the fields sorted by id number.
* 'fields_sorted_by_name', 'n_field_ranges' and 'field_ranges'
* are used for looking up fields by name and id. (private)
*/ */
struct ProtobufCMessageDescriptor { struct ProtobufCMessageDescriptor {
/** Magic value checked to ensure that the API is used correctly. */
uint32_t magic; uint32_t magic;
/** The qualified name (e.g., "namespace.Type"). */
const char *name; const char *name;
/** The unqualified name as given in the .proto file (e.g., "Type"). */
const char *short_name; const char *short_name;
/** Identifier used in generated C code. */
const char *c_name; const char *c_name;
/** The dot-separated namespace. */
const char *package_name; const char *package_name;
/**
* Size in bytes of the C structure representing an instance of this
* type of message.
*/
size_t sizeof_message; size_t sizeof_message;
/* sorted by field-id */ /** Number of elements in `fields`. */
unsigned n_fields; unsigned n_fields;
/** Field descriptors, sorted by tag number. */
const ProtobufCFieldDescriptor *fields; const ProtobufCFieldDescriptor *fields;
/** Used for looking up fields by name. */
const unsigned *fields_sorted_by_name; const unsigned *fields_sorted_by_name;
/* ranges, optimization for looking up fields */ /** Number of elements in `field_ranges`. */
unsigned n_field_ranges; unsigned n_field_ranges;
/** Used for looking up fields by id. */
const ProtobufCIntRange *field_ranges; const ProtobufCIntRange *field_ranges;
/** Message initialisation function. */
ProtobufCMessageInit message_init; ProtobufCMessageInit message_init;
/** Reserved for future use. */
void *reserved1; void *reserved1;
/** Reserved for future use. */
void *reserved2; void *reserved2;
/** Reserved for future use. */
void *reserved3; void *reserved3;
}; };
/* /**
* ProtobufCMessage: an instance of a message. * An unknown message field.
*
* ProtobufCMessage is sort of a light-weight base class for all messages.
*
* In particular, ProtobufCMessage doesn't have any allocation policy
* associated with it. That's because it's common to create ProtobufCMessage's
* on the stack. In fact, that's what we recommend for sending messages
* (because if you just allocate from the stack, then you can't really have a
* memory leak).
*
* This means that functions like protobuf_c_message_unpack() which return a
* ProtobufCMessage must be paired with a free function, like
* protobuf_c_message_free_unpacked().
*
* 'descriptor' gives the locations and types of the members of message.
* 'n_unknown_fields' is the number of fields we didn't recognize.
* 'unknown_fields' are fields we didn't recognize.
*/ */
typedef struct ProtobufCMessageUnknownField ProtobufCMessageUnknownField; struct ProtobufCMessageUnknownField {
struct ProtobufCMessage { /** The tag number. */
const ProtobufCMessageDescriptor *descriptor; uint32_t tag;
unsigned n_unknown_fields; /** The wire type of the field. */
ProtobufCMessageUnknownField *unknown_fields; ProtobufCWireType wire_type;
/** Number of bytes in `data`. */
size_t len;
/** Field data. */
uint8_t *data;
}; };
#define PROTOBUF_C_MESSAGE_INIT(descriptor) { descriptor, 0, NULL } /**
* Method descriptor.
/*
* To pack a message: you have two options:
* (1) you can compute the size of the message using
* protobuf_c_message_get_packed_size() then pass
* protobuf_c_message_pack() a buffer of that length.
*
* (2) Provide a virtual buffer (a ProtobufCBuffer) to
* accept data as we scan through it.
*/
PROTOBUF_C__API size_t
protobuf_c_message_get_packed_size(const ProtobufCMessage *);
PROTOBUF_C__API size_t
protobuf_c_message_pack(const ProtobufCMessage *, uint8_t *out);
PROTOBUF_C__API size_t
protobuf_c_message_pack_to_buffer(const ProtobufCMessage *, ProtobufCBuffer *);
PROTOBUF_C__API ProtobufCMessage *
protobuf_c_message_unpack(
const ProtobufCMessageDescriptor *,
ProtobufCAllocator *,
size_t len,
const uint8_t *data);
PROTOBUF_C__API void
protobuf_c_message_free_unpacked(ProtobufCMessage *, ProtobufCAllocator *);
PROTOBUF_C__API protobuf_c_boolean
protobuf_c_message_check(const ProtobufCMessage *);
/*
* WARNING: 'message' must be a block of memory of size
* descriptor->sizeof_message.
*/ */
PROTOBUF_C__API void
protobuf_c_message_init(const ProtobufCMessageDescriptor *, void *message);
/* --- services --- */
typedef struct ProtobufCMethodDescriptor ProtobufCMethodDescriptor;
struct ProtobufCMethodDescriptor { struct ProtobufCMethodDescriptor {
/** Method name. */
const char *name; const char *name;
/** Input message descriptor. */
const ProtobufCMessageDescriptor *input; const ProtobufCMessageDescriptor *input;
/** Output message descriptor. */
const ProtobufCMessageDescriptor *output; const ProtobufCMessageDescriptor *output;
}; };
typedef struct ProtobufCServiceDescriptor ProtobufCServiceDescriptor; /**
* Service.
*/
struct ProtobufCService {
/** Service descriptor. */
const ProtobufCServiceDescriptor *descriptor;
/** Function to invoke the service. */
void (*invoke)(ProtobufCService *service,
unsigned method_index,
const ProtobufCMessage *input,
ProtobufCClosure closure,
void *closure_data);
/** Function to destroy the service. */
void (*destroy)(ProtobufCService *service);
};
/**
* Service descriptor.
*/
struct ProtobufCServiceDescriptor { struct ProtobufCServiceDescriptor {
/** Magic value checked to ensure that the API is used correctly. */
uint32_t magic; uint32_t magic;
/** Service name. */
const char *name; const char *name;
/** Short version of service name. */
const char *short_name; const char *short_name;
/** C identifier for the service name. */
const char *c_name; const char *c_name;
/** Package name. */
const char *package; const char *package;
/** Number of elements in `methods`. */
unsigned n_methods; unsigned n_methods;
const ProtobufCMethodDescriptor *methods; /* in order from .proto file */ /** Method descriptors, in the order defined in the .proto file. */
const ProtobufCMethodDescriptor *methods;
/** Sort index of methods. */
const unsigned *method_indices_by_name; const unsigned *method_indices_by_name;
}; };
typedef void (*ProtobufCClosure)(const ProtobufCMessage *, void *closure_data); /**
* The default memory allocator.
*
* By default, it uses the system allocator (meaning malloc() and free()).
* This is typically changed to adapt to frameworks that provide
* some non-standard allocation functions.
*
* NOTE: you may modify this allocator.
*/
extern PROTOBUF_C__API ProtobufCAllocator protobuf_c_default_allocator;
typedef struct ProtobufCService ProtobufCService; /**
struct ProtobufCService { * Get the version of the protobuf-c library. Note that this is the version of
const ProtobufCServiceDescriptor *descriptor; * the library linked against, not the version of the headers compiled against.
void (*invoke)(ProtobufCService *service, *
unsigned method_index, * \return A string containing the version number of protobuf-c.
const ProtobufCMessage *input, */
ProtobufCClosure closure, PROTOBUF_C__API
void *closure_data); const char *
void (*destroy)(ProtobufCService *service); protobuf_c_version(void);
};
/**
* Get the version of the protobuf-c library. Note that this is the version of
* the library linked against, not the version of the headers compiled against.
*
* \return A 32 bit unsigned integer containing the version number of
* protobuf-c, represented in base-10 as (MAJOR*1E6) + (MINOR*1E3) + PATCH.
*/
PROTOBUF_C__API
uint32_t
protobuf_c_version_number(void);
PROTOBUF_C__API void /**
protobuf_c_service_destroy(ProtobufCService *); * The version of the protobuf-c headers, represented as a string using the same
* format as protobuf_c_version().
*/
#define PROTOBUF_C_VERSION "1.0.0-rc1"
/* --- querying the descriptors --- */ /**
* The version of the protobuf-c headers, represented as an integer using the
* same format as protobuf_c_version_number().
*/
#define PROTOBUF_C_VERSION_NUMBER 1000000
PROTOBUF_C__API const ProtobufCEnumValue * /**
* The minimum protoc-c version which works with the current version of the
* protobuf-c headers.
*/
#define PROTOBUF_C_MIN_COMPILER_VERSION 1000000
/**
* Look up a `ProtobufCEnumValue` from a `ProtobufCEnumDescriptor` by name.
*
* \param desc
* The `ProtobufCEnumDescriptor` object.
* \param name
* The `name` field from the corresponding `ProtobufCEnumValue` object to
* match.
* \return
* A `ProtobufCEnumValue` object.
* \retval NULL
* If not found.
*/
PROTOBUF_C__API
const ProtobufCEnumValue *
protobuf_c_enum_descriptor_get_value_by_name( protobuf_c_enum_descriptor_get_value_by_name(
const ProtobufCEnumDescriptor *desc, const ProtobufCEnumDescriptor *desc,
const char *name); const char *name);
PROTOBUF_C__API const ProtobufCEnumValue * /**
* Look up a `ProtobufCEnumValue` from a `ProtobufCEnumDescriptor` by numeric
* value.
*
* \param desc
* The `ProtobufCEnumDescriptor` object.
* \param value
* The `value` field from the corresponding `ProtobufCEnumValue` object to
* match.
*
* \return
* A `ProtobufCEnumValue` object.
* \retval NULL
* If not found.
*/
PROTOBUF_C__API
const ProtobufCEnumValue *
protobuf_c_enum_descriptor_get_value( protobuf_c_enum_descriptor_get_value(
const ProtobufCEnumDescriptor *desc, const ProtobufCEnumDescriptor *desc,
int value); int value);
PROTOBUF_C__API const ProtobufCFieldDescriptor * /**
* Look up a `ProtobufCFieldDescriptor` from a `ProtobufCMessageDescriptor` by
* the name of the field.
*
* \param desc
* The `ProtobufCMessageDescriptor` object.
* \param name
* The name of the field.
* \return
* A `ProtobufCFieldDescriptor` object.
* \retval NULL
* If not found.
*/
PROTOBUF_C__API
const ProtobufCFieldDescriptor *
protobuf_c_message_descriptor_get_field_by_name( protobuf_c_message_descriptor_get_field_by_name(
const ProtobufCMessageDescriptor *desc, const ProtobufCMessageDescriptor *desc,
const char *name); const char *name);
PROTOBUF_C__API const ProtobufCFieldDescriptor * /**
* Look up a `ProtobufCFieldDescriptor` from a `ProtobufCMessageDescriptor` by
* the tag value of the field.
*
* \param desc
* The `ProtobufCMessageDescriptor` object.
* \param value
* The tag value of the field.
* \return
* A `ProtobufCFieldDescriptor` object.
* \retval NULL
* If not found.
*/
PROTOBUF_C__API
const ProtobufCFieldDescriptor *
protobuf_c_message_descriptor_get_field( protobuf_c_message_descriptor_get_field(
const ProtobufCMessageDescriptor *desc, const ProtobufCMessageDescriptor *desc,
unsigned value); unsigned value);
PROTOBUF_C__API const ProtobufCMethodDescriptor * /**
protobuf_c_service_descriptor_get_method_by_name( * Determine the number of bytes required to store the serialised message.
const ProtobufCServiceDescriptor *desc, *
const char *name); * \param message
* The message object to serialise.
/* --- wire format enums --- */ * \return
* Number of bytes.
*/
PROTOBUF_C__API
size_t
protobuf_c_message_get_packed_size(const ProtobufCMessage *message);
typedef enum { /**
PROTOBUF_C_WIRE_TYPE_VARINT, * Serialise a message from its in-memory representation.
PROTOBUF_C_WIRE_TYPE_64BIT, *
PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED, * This function stores the serialised bytes of the message in a pre-allocated
PROTOBUF_C_WIRE_TYPE_START_GROUP, /* unsupported */ * buffer.
PROTOBUF_C_WIRE_TYPE_END_GROUP, /* unsupported */ *
PROTOBUF_C_WIRE_TYPE_32BIT * \param message
} ProtobufCWireType; * The message object to serialise.
* \param[out] out
* Buffer to store the bytes of the serialised message. This buffer must
* have enough space to store the packed message. Use
* protobuf_c_message_get_packed_size() to determine the number of bytes
* required.
* \return
* Number of bytes stored in `out`.
*/
PROTOBUF_C__API
size_t
protobuf_c_message_pack(const ProtobufCMessage *message, uint8_t *out);
/* --- unknown message fields --- */ /**
* Serialise a message from its in-memory representation to a virtual buffer.
*
* This function calls the `append` method of a `ProtobufCBuffer` object to
* consume the bytes generated by the serialiser.
*
* \param message
* The message object to serialise.
* \param buffer
* The virtual buffer object.
* \return
* Number of bytes passed to the virtual buffer.
*/
PROTOBUF_C__API
size_t
protobuf_c_message_pack_to_buffer(
const ProtobufCMessage *message,
ProtobufCBuffer *buffer);
struct ProtobufCMessageUnknownField { /**
uint32_t tag; * Unpack a serialised message into an in-memory representation.
ProtobufCWireType wire_type; *
size_t len; * \param descriptor
uint8_t *data; * The message descriptor.
}; * \param allocator
* `ProtobufCAllocator` to use for memory allocation. May be NULL to
* specify the default allocator.
* \param len
* Length in bytes of the serialised message.
* \param data
* Pointer to the serialised message.
* \return
* An unpacked message object.
* \retval NULL
* If an error occurred during unpacking.
*/
PROTOBUF_C__API
ProtobufCMessage *
protobuf_c_message_unpack(
const ProtobufCMessageDescriptor *descriptor,
ProtobufCAllocator *allocator,
size_t len,
const uint8_t *data);
/* --- extra (superfluous) api: trivial buffer --- */ /**
* Free an unpacked message object.
*
* This function should be used to deallocate the memory used by a call to
* protobuf_c_message_unpack().
*
* \param message
* The message object to free.
* \param allocator
* `ProtobufCAllocator` to use for memory deallocation. May be NULL to
* specify the default allocator.
*/
PROTOBUF_C__API
void
protobuf_c_message_free_unpacked(
ProtobufCMessage *message,
ProtobufCAllocator *allocator);
typedef struct ProtobufCBufferSimple ProtobufCBufferSimple; /**
struct ProtobufCBufferSimple { * Check the validity of a message object.
ProtobufCBuffer base; *
size_t alloced; * Makes sure all required fields (`PROTOBUF_C_LABEL_REQUIRED`) are present.
size_t len; * Recursively checks nested messages.
uint8_t *data; *
protobuf_c_boolean must_free_data; * \retval TRUE
}; * Message is valid.
* \retval FALSE
* Message is invalid.
*/
PROTOBUF_C__API
protobuf_c_boolean
protobuf_c_message_check(const ProtobufCMessage *);
#define PROTOBUF_C_BUFFER_SIMPLE_INIT(array_of_bytes) \ /** Message initialiser. */
{ \ #define PROTOBUF_C_MESSAGE_INIT(descriptor) { descriptor, 0, NULL }
{ protobuf_c_buffer_simple_append }, \
sizeof(array_of_bytes), \
0, \
(array_of_bytes), \
0 \
}
#define PROTOBUF_C_BUFFER_SIMPLE_CLEAR(simp_buf) \ /**
do { \ * Initialise a message object from a message descriptor.
if ((simp_buf)->must_free_data) { \ *
protobuf_c_default_allocator.free( \ * \param descriptor
&protobuf_c_default_allocator, \ * Message descriptor.
(simp_buf)->data); \ * \param message
} \ * Allocated block of memory of size `descriptor->sizeof_message`.
} while (0) */
PROTOBUF_C__API
void
protobuf_c_message_init(
const ProtobufCMessageDescriptor *descriptor,
void *message);
/* ====== private ====== */ /**
* Free a service.
*
* \param service
* The service object to free.
*/
PROTOBUF_C__API
void
protobuf_c_service_destroy(ProtobufCService *service);
#define PROTOBUF_C__SERVICE_DESCRIPTOR_MAGIC 0x14159bc3 /**
#define PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC 0x28aaeef9 * Look up a `ProtobufCMethodDescriptor` by name.
#define PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC 0x114315af *
* \param desc
* Service descriptor.
* \param name
* Name of the method.
*
* \return
* A `ProtobufCMethodDescriptor` object.
* \retval NULL
* If not found.
*/
PROTOBUF_C__API
const ProtobufCMethodDescriptor *
protobuf_c_service_descriptor_get_method_by_name(
const ProtobufCServiceDescriptor *desc,
const char *name);
/* /**
* A little enum helper macro: this will ensure that your enum's size is * Initialise a `ProtobufCBufferSimple` object.
* sizeof(int). In protobuf, it need not be larger than 32-bits. This is
* written assuming it is appended to a list w/o a tail comma.
*/ */
#ifndef PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE #define PROTOBUF_C_BUFFER_SIMPLE_INIT(array_of_bytes) \
#define PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(enum_name) \ { \
, _##enum_name##_IS_INT_SIZE = INT_MAX { protobuf_c_buffer_simple_append }, \
#endif sizeof(array_of_bytes), \
0, \
(array_of_bytes), \
0 \
}
/* === needs to be declared for the PROTOBUF_C_BUFFER_SIMPLE_INIT macro === */ /**
* Clear a `ProtobufCBufferSimple` object, freeing any allocated memory.
*/
#define PROTOBUF_C_BUFFER_SIMPLE_CLEAR(simp_buf) \
do { \
if ((simp_buf)->must_free_data) { \
protobuf_c_default_allocator.free( \
&protobuf_c_default_allocator, \
(simp_buf)->data); \
} \
} while (0)
/**
* The `append` method for `ProtobufCBufferSimple`.
*
* \param buffer
* The buffer object to append to. Must actually be a
* `ProtobufCBufferSimple` object.
* \param len
* Number of bytes in `data`.
* \param data
* Data to append.
*/
PROTOBUF_C__API
void void
protobuf_c_buffer_simple_append( protobuf_c_buffer_simple_append(
ProtobufCBuffer *buffer, ProtobufCBuffer *buffer,
size_t len, size_t len,
const unsigned char *data); const unsigned char *data);
/* === stuff which needs to be declared for use in the generated code === */ PROTOBUF_C__API
struct ProtobufCEnumValueIndex {
const char *name;
unsigned index; /* into values[] array */
};
/*
* IntRange: helper structure for optimizing int => index lookups in the case
* where the keys are mostly consecutive values, as they presumably are for
* enums and fields.
*
* The data structures assumes that the values in the original array are
* sorted.
*/
struct ProtobufCIntRange {
int start_value;
unsigned orig_index;
/*
* NOTE: the number of values in the range can be inferred by looking
* at the next element's orig_index. A dummy element is added to make
* this simple.
*/
};
/* === declared for exposition on ProtobufCIntRange === */
/*
* Note: ranges must have an extra sentinel IntRange at the end whose
* orig_index is set to the number of actual values in the original array.
* Returns -1 if no orig_index found.
*/
int
protobuf_c_int_ranges_lookup(unsigned n_ranges, ProtobufCIntRange *ranges);
/* === behind the scenes on the generated service's __init functions */
typedef void (*ProtobufCServiceDestroy)(ProtobufCService *);
void void
protobuf_c_service_generated_init( protobuf_c_service_generated_init(
ProtobufCService *service, ProtobufCService *service,
const ProtobufCServiceDescriptor *descriptor, const ProtobufCServiceDescriptor *descriptor,
ProtobufCServiceDestroy destroy); ProtobufCServiceDestroy destroy);
void PROTOBUF_C__API
void
protobuf_c_service_invoke_internal( protobuf_c_service_invoke_internal(
ProtobufCService *service, ProtobufCService *service,
unsigned method_index, unsigned method_index,
...@@ -578,6 +892,8 @@ protobuf_c_service_invoke_internal( ...@@ -578,6 +892,8 @@ protobuf_c_service_invoke_internal(
ProtobufCClosure closure, ProtobufCClosure closure,
void *closure_data); void *closure_data);
/**@}*/
PROTOBUF_C__END_DECLS PROTOBUF_C__END_DECLS
#endif /* PROTOBUF_C_H */ #endif /* PROTOBUF_C_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment