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.
* All rights reserved.
......@@ -29,13 +27,31 @@
* 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
#define PROTOBUF_C_H
#include <assert.h>
#include <limits.h>
#include <stddef.h>
#include <stdint.h>
#include <limits.h>
#ifdef __cplusplus
# define PROTOBUF_C__BEGIN_DECLS extern "C" {
......@@ -45,13 +61,7 @@
# define PROTOBUF_C__END_DECLS
#endif
#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
PROTOBUF_C__BEGIN_DECLS
#if defined(_WIN32) && defined(PROTOBUF_C_USE_SHARED_LIB)
# ifdef PROTOBUF_C_EXPORT
......@@ -63,514 +73,818 @@
# define PROTOBUF_C__API
#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
/**
* 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 string containing the version number of protobuf-c.
*/
PROTOBUF_C__API
const char *
protobuf_c_version(void);
#ifndef PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE
#define PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(enum_name) \
, _##enum_name##_IS_INT_SIZE = INT_MAX
#endif
#define PROTOBUF_C__SERVICE_DESCRIPTOR_MAGIC 0x14159bc3
#define PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC 0x28aaeef9
#define PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC 0x114315af
/**
* 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.
* \defgroup api Public API
*
* \return A 32 bit unsigned integer containing the version number of
* protobuf-c, represented in base-10 as (MAJOR*1E6) + (MINOR*1E3) + PATCH.
* This is the public API for `libprotobuf-c`. These interfaces are stable and
* 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
* format as protobuf_c_version().
* Values for the `flags` word in `ProtobufCFieldDescriptor`.
*/
#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),
/**
* 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
/** Set if the field is marked with the `deprecated` option. */
PROTOBUF_C_FIELD_FLAG_DEPRECATED = (1 << 1),
} ProtobufCFieldFlag;
/**
* The minimum protoc-c version which works with the current version of the
* protobuf-c headers.
* Message field rules.
*
* \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 {
/** A well-formed message must have exactly one of this field. */
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_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;
/**
* 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 {
PROTOBUF_C_TYPE_INT32,
PROTOBUF_C_TYPE_SINT32,
PROTOBUF_C_TYPE_SFIXED32,
PROTOBUF_C_TYPE_INT64,
PROTOBUF_C_TYPE_SINT64,
PROTOBUF_C_TYPE_SFIXED64,
PROTOBUF_C_TYPE_UINT32,
PROTOBUF_C_TYPE_FIXED32,
PROTOBUF_C_TYPE_UINT64,
PROTOBUF_C_TYPE_FIXED64,
PROTOBUF_C_TYPE_FLOAT,
PROTOBUF_C_TYPE_DOUBLE,
PROTOBUF_C_TYPE_BOOL,
PROTOBUF_C_TYPE_ENUM,
PROTOBUF_C_TYPE_STRING,
PROTOBUF_C_TYPE_BYTES,
/* PROTOBUF_C_TYPE_GROUP, -- NOT SUPPORTED */
PROTOBUF_C_TYPE_MESSAGE,
PROTOBUF_C_TYPE_INT32, /**< int32 */
PROTOBUF_C_TYPE_SINT32, /**< signed int32 */
PROTOBUF_C_TYPE_SFIXED32, /**< signed int32 (4 bytes) */
PROTOBUF_C_TYPE_INT64, /**< int64 */
PROTOBUF_C_TYPE_SINT64, /**< signed int64 */
PROTOBUF_C_TYPE_SFIXED64, /**< signed int64 (8 bytes) */
PROTOBUF_C_TYPE_UINT32, /**< unsigned int32 */
PROTOBUF_C_TYPE_FIXED32, /**< unsigned int32 (4 bytes) */
PROTOBUF_C_TYPE_UINT64, /**< unsigned int64 */
PROTOBUF_C_TYPE_FIXED64, /**< unsigned int64 (8 bytes) */
PROTOBUF_C_TYPE_FLOAT, /**< float */
PROTOBUF_C_TYPE_DOUBLE, /**< double */
PROTOBUF_C_TYPE_BOOL, /**< boolean */
PROTOBUF_C_TYPE_ENUM, /**< enumerated type */
PROTOBUF_C_TYPE_STRING, /**< UTF-8 or ASCII string */
PROTOBUF_C_TYPE_BYTES, /**< arbitrary byte sequence */
PROTOBUF_C_TYPE_MESSAGE, /**< nested message */
} ProtobufCType;
typedef struct ProtobufCBinaryData ProtobufCBinaryData;
struct ProtobufCBinaryData {
size_t len;
uint8_t *data;
};
/**
* Field wire types.
*
* \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;
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);
/** Function to free memory. */
void (*free)(void *allocator_data, void *pointer);
/** Opaque pointer passed to `alloc` and `free` functions. */
void *allocator_data;
};
/*
* This is a configurable allocator.
* 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.
/**
* Structure for the protobuf `bytes` scalar type.
*
* 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 {
/** Append function. Consumes the `len` bytes stored at `data`. */
void (*append)(ProtobufCBuffer *buffer,
size_t len,
const uint8_t *data);
};
/* --- enums --- */
typedef struct ProtobufCEnumValue ProtobufCEnumValue;
typedef struct ProtobufCEnumValueIndex ProtobufCEnumValueIndex;
typedef struct ProtobufCEnumDescriptor ProtobufCEnumDescriptor;
/*
* 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.
/**
* Simple buffer "subclass" of `ProtobufCBuffer`.
*
* \see PROTOBUF_C_BUFFER_SIMPLE_INIT
* \see PROTOBUF_C_BUFFER_SIMPLE_CLEAR
*/
struct ProtobufCEnumValue {
const char *name;
const char *c_name;
int value;
struct ProtobufCBufferSimple {
/** "Base class". */
ProtobufCBuffer base;
/** 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.
*
* '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.
/**
* Describes an enumeration as a whole, with all of its values.
*/
struct ProtobufCEnumDescriptor {
/** Magic value checked to ensure that the API is used correctly. */
uint32_t magic;
/** The qualified name (e.g., "namespace.Type"). */
const char *name;
/** The unqualified name as given in the .proto file (e.g., "Type"). */
const char *short_name;
/** Identifier used in generated C code. */
const char *c_name;
/** The dot-separated namespace. */
const char *package_name;
/* sorted by value */
/** Number elements in `values`. */
unsigned n_values;
/** Array of distinct values, sorted by numeric value. */
const ProtobufCEnumValue *values;
/* sorted by name */
/** Number of elements in `values_by_name`. */
unsigned n_value_names;
/** Array of named values, including aliases, sorted by name. */
const ProtobufCEnumValueIndex *values_by_name;
/* value-ranges, for faster lookups by number */
/** Number of elements in `value_ranges`. */
unsigned n_value_ranges;
/** Value ranges, for faster lookups by numeric value. */
const ProtobufCIntRange *value_ranges;
/** Reserved for future use. */
void *reserved1;
/** Reserved for future use. */
void *reserved2;
/** Reserved for future use. */
void *reserved3;
/** Reserved for future use. */
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;
typedef struct ProtobufCFieldDescriptor ProtobufCFieldDescriptor;
typedef struct ProtobufCMessage ProtobufCMessage;
typedef void (*ProtobufCMessageInit)(ProtobufCMessage *);
/** The string identifying this value in generated C code. */
const char *c_name;
/*
* ProtobufCFieldDescriptor: description of a single field in a message.
*
* '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}
* 'type' is the type of field.
* 'quantifier_offset' is the offset in bytes into the message's C structure
* for this member's "has_MEMBER" field (for optional members) or
* "n_MEMBER" field (for repeated members).
* 'offset' is the offset in bytes into the message's C structure
* for the member itself.
* '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,
* where allowed.
* 'flags' is a flag word. Zero or more of the bits defined in the
* ProtobufCFieldFlag enum may be set.
/** The numeric value assigned in the .proto file. */
int value;
};
/**
* Used by `ProtobufCEnumDescriptor` to look up enum values.
*/
struct ProtobufCEnumValueIndex {
/** Name of the enum value. */
const char *name;
/** Index into values[] array. */
unsigned index;
};
/**
* Describes a single field in a message.
*/
struct ProtobufCFieldDescriptor {
/** Name of the field as given in the .proto file. */
const char *name;
/** Tag value of the field as given in the .proto file. */
uint32_t id;
/** Whether the field is `REQUIRED`, `OPTIONAL`, or `REPEATED`. */
ProtobufCLabel label;
/** The type of the field. */
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;
/**
* The offset in bytes into the message's C structure for the member
* itself.
*/
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 *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;
/** Reserved for future use. */
unsigned reserved_flags;
/** Reserved for future use. */
void *reserved2;
/** Reserved for future use. */
void *reserved3;
};
typedef enum {
/* Set if the field is repeated and marked with the 'packed' option. */
PROTOBUF_C_FIELD_FLAG_PACKED = (1 << 0),
/**
* 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 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),
} ProtobufCFieldFlag;
/**
* An instance of a message.
*
* `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.
*
* '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)
/**
* Describes a message.
*/
struct ProtobufCMessageDescriptor {
/** Magic value checked to ensure that the API is used correctly. */
uint32_t magic;
/** The qualified name (e.g., "namespace.Type"). */
const char *name;
/** The unqualified name as given in the .proto file (e.g., "Type"). */
const char *short_name;
/** Identifier used in generated C code. */
const char *c_name;
/** The dot-separated namespace. */
const char *package_name;
/**
* Size in bytes of the C structure representing an instance of this
* type of message.
*/
size_t sizeof_message;
/* sorted by field-id */
/** Number of elements in `fields`. */
unsigned n_fields;
/** Field descriptors, sorted by tag number. */
const ProtobufCFieldDescriptor *fields;
/** Used for looking up fields by name. */
const unsigned *fields_sorted_by_name;
/* ranges, optimization for looking up fields */
/** Number of elements in `field_ranges`. */
unsigned n_field_ranges;
/** Used for looking up fields by id. */
const ProtobufCIntRange *field_ranges;
/** Message initialisation function. */
ProtobufCMessageInit message_init;
/** Reserved for future use. */
void *reserved1;
/** Reserved for future use. */
void *reserved2;
/** Reserved for future use. */
void *reserved3;
};
/*
* ProtobufCMessage: an instance of a message.
*
* 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.
/**
* An unknown message field.
*/
typedef struct ProtobufCMessageUnknownField ProtobufCMessageUnknownField;
struct ProtobufCMessage {
const ProtobufCMessageDescriptor *descriptor;
unsigned n_unknown_fields;
ProtobufCMessageUnknownField *unknown_fields;
struct ProtobufCMessageUnknownField {
/** The tag number. */
uint32_t tag;
/** The wire type of the field. */
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 }
/*
* 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.
/**
* Method descriptor.
*/
PROTOBUF_C__API void
protobuf_c_message_init(const ProtobufCMessageDescriptor *, void *message);
/* --- services --- */
typedef struct ProtobufCMethodDescriptor ProtobufCMethodDescriptor;
struct ProtobufCMethodDescriptor {
/** Method name. */
const char *name;
/** Input message descriptor. */
const ProtobufCMessageDescriptor *input;
/** Output message descriptor. */
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 {
/** Magic value checked to ensure that the API is used correctly. */
uint32_t magic;
/** Service name. */
const char *name;
/** Short version of service name. */
const char *short_name;
/** C identifier for the service name. */
const char *c_name;
/** Package name. */
const char *package;
/** Number of elements in `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;
};
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 {
const ProtobufCServiceDescriptor *descriptor;
void (*invoke)(ProtobufCService *service,
unsigned method_index,
const ProtobufCMessage *input,
ProtobufCClosure closure,
void *closure_data);
void (*destroy)(ProtobufCService *service);
};
/**
* 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 string containing the version number of protobuf-c.
*/
PROTOBUF_C__API
const char *
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(
const ProtobufCEnumDescriptor *desc,
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(
const ProtobufCEnumDescriptor *desc,
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(
const ProtobufCMessageDescriptor *desc,
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(
const ProtobufCMessageDescriptor *desc,
unsigned value);
PROTOBUF_C__API const ProtobufCMethodDescriptor *
protobuf_c_service_descriptor_get_method_by_name(
const ProtobufCServiceDescriptor *desc,
const char *name);
/* --- wire format enums --- */
/**
* Determine the number of bytes required to store the serialised message.
*
* \param message
* The message object to serialise.
* \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,
PROTOBUF_C_WIRE_TYPE_64BIT,
PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED,
PROTOBUF_C_WIRE_TYPE_START_GROUP, /* unsupported */
PROTOBUF_C_WIRE_TYPE_END_GROUP, /* unsupported */
PROTOBUF_C_WIRE_TYPE_32BIT
} ProtobufCWireType;
/**
* Serialise a message from its in-memory representation.
*
* This function stores the serialised bytes of the message in a pre-allocated
* buffer.
*
* \param message
* 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;
ProtobufCWireType wire_type;
size_t len;
uint8_t *data;
};
/**
* Unpack a serialised message into an in-memory representation.
*
* \param descriptor
* 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 {
ProtobufCBuffer base;
size_t alloced;
size_t len;
uint8_t *data;
protobuf_c_boolean must_free_data;
};
/**
* Check the validity of a message object.
*
* Makes sure all required fields (`PROTOBUF_C_LABEL_REQUIRED`) are present.
* Recursively checks nested messages.
*
* \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) \
{ \
{ protobuf_c_buffer_simple_append }, \
sizeof(array_of_bytes), \
0, \
(array_of_bytes), \
0 \
}
/** Message initialiser. */
#define PROTOBUF_C_MESSAGE_INIT(descriptor) { descriptor, 0, NULL }
#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)
/**
* Initialise a message object from a message descriptor.
*
* \param descriptor
* Message descriptor.
* \param message
* Allocated block of memory of size `descriptor->sizeof_message`.
*/
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
#define PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC 0x114315af
/**
* Look up a `ProtobufCMethodDescriptor` by name.
*
* \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
* 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.
/**
* Initialise a `ProtobufCBufferSimple` object.
*/
#ifndef PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE
#define PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(enum_name) \
, _##enum_name##_IS_INT_SIZE = INT_MAX
#endif
#define PROTOBUF_C_BUFFER_SIMPLE_INIT(array_of_bytes) \
{ \
{ protobuf_c_buffer_simple_append }, \
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
protobuf_c_buffer_simple_append(
ProtobufCBuffer *buffer,
size_t len,
const unsigned char *data);
/* === stuff which needs to be declared for use in the generated code === */
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 *);
PROTOBUF_C__API
void
protobuf_c_service_generated_init(
ProtobufCService *service,
const ProtobufCServiceDescriptor *descriptor,
ProtobufCServiceDestroy destroy);
void
PROTOBUF_C__API
void
protobuf_c_service_invoke_internal(
ProtobufCService *service,
unsigned method_index,
......@@ -578,6 +892,8 @@ protobuf_c_service_invoke_internal(
ProtobufCClosure closure,
void *closure_data);
/**@}*/
PROTOBUF_C__END_DECLS
#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