Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sudo-project
GitHub Repository: sudo-project/sudo
Path: blob/main/include/protobuf-c/protobuf-c.h
1532 views
1
/*
2
* Copyright (c) 2008-2025, Dave Benson and the protobuf-c authors.
3
* All rights reserved.
4
*
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions are
7
* met:
8
*
9
* * Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
*
12
* * Redistributions in binary form must reproduce the above
13
* copyright notice, this list of conditions and the following disclaimer
14
* in the documentation and/or other materials provided with the
15
* distribution.
16
*
17
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
*/
29
30
/*! \file
31
* \mainpage Introduction
32
*
33
* This is [protobuf-c], a C implementation of [Protocol Buffers].
34
*
35
* This file defines the public API for the `libprotobuf-c` support library.
36
* This API includes interfaces that can be used directly by client code as well
37
* as the interfaces used by the code generated by the `protoc-gen-c` compiler
38
* plugin.
39
*
40
* The `libprotobuf-c` support library performs the actual serialization and
41
* deserialization of Protocol Buffers messages. It interacts with structures,
42
* definitions, and metadata generated by the `protoc-gen-c` compiler plugin
43
* from .proto files.
44
*
45
* \authors Dave Benson and the `protobuf-c` authors.
46
*
47
* \copyright 2008-2025. Licensed under the terms of the [BSD-2-Clause] license.
48
*
49
* [protobuf-c]: https://github.com/protobuf-c/protobuf-c
50
* [Protocol Buffers]: https://developers.google.com/protocol-buffers/
51
* [BSD-2-Clause]: http://opensource.org/licenses/BSD-2-Clause
52
*
53
* \page gencode Generated Code
54
*
55
* For each enum, we generate a C enum. For each message, we generate a C
56
* structure which can be cast to a `ProtobufCMessage`.
57
*
58
* For each enum and message, we generate a descriptor object that allows us to
59
* implement a kind of reflection on the structures.
60
*
61
* First, some naming conventions:
62
*
63
* - The name of the type for enums and messages and services is camel case
64
* (meaning WordsAreCrammedTogether) except that double underscores are used
65
* to delimit scopes. For example, the following `.proto` file:
66
*
67
~~~{.proto}
68
package foo.bar;
69
message BazBah {
70
optional int32 val = 1;
71
}
72
~~~
73
*
74
* would generate a C type `Foo__Bar__BazBah`.
75
*
76
* - Identifiers for functions and globals are all lowercase, with camel case
77
* words separated by single underscores. For example, one of the function
78
* prototypes generated by `protoc-gen-c` for the above example:
79
*
80
~~~{.c}
81
Foo__Bar__BazBah *
82
foo__bar__baz_bah__unpack
83
(ProtobufCAllocator *allocator,
84
size_t len,
85
const uint8_t *data);
86
~~~
87
*
88
* - Identifiers for enum values contain an uppercase prefix which embeds the
89
* package name and the enum type name.
90
*
91
* - A double underscore is used to separate further components of identifier
92
* names.
93
*
94
* For example, in the name of the unpack function above, the package name
95
* `foo.bar` has become `foo__bar`, the message name BazBah has become
96
* `baz_bah`, and the method name is `unpack`. These are all joined with double
97
* underscores to form the C identifier `foo__bar__baz_bah__unpack`.
98
*
99
* We also generate descriptor objects for messages and enums. These are
100
* declared in the `.pb-c.h` files:
101
*
102
~~~{.c}
103
extern const ProtobufCMessageDescriptor foo__bar__baz_bah__descriptor;
104
~~~
105
*
106
* The message structures all begin with `ProtobufCMessageDescriptor *` which is
107
* sufficient to allow them to be cast to `ProtobufCMessage`.
108
*
109
* For each message defined in a `.proto` file, we generate a number of
110
* functions and macros. Each function name contains a prefix based on the
111
* package name and message name in order to make it a unique C identifier.
112
*
113
* - `INIT`. Statically initializes a message object, initializing its
114
* descriptor and setting its fields to default values. Uninitialized
115
* messages cannot be processed by the protobuf-c library.
116
*
117
~~~{.c}
118
#define FOO__BAR__BAZ_BAH__INIT \
119
{ PROTOBUF_C_MESSAGE_INIT (&foo__bar__baz_bah__descriptor), 0 }
120
~~~
121
* - `init()`. Initializes a message object, initializing its descriptor and
122
* setting its fields to default values. Uninitialized messages cannot be
123
* processed by the protobuf-c library.
124
*
125
~~~{.c}
126
void foo__bar__baz_bah__init
127
(Foo__Bar__BazBah *message);
128
~~~
129
* - `unpack()`. Unpacks data for a particular message format. Note that the
130
* `allocator` parameter is usually `NULL` to indicate that the system's
131
* `malloc()` and `free()` functions should be used for dynamically allocating
132
* memory.
133
*
134
~~~{.c}
135
Foo__Bar__BazBah *
136
foo__bar__baz_bah__unpack
137
(ProtobufCAllocator *allocator,
138
size_t len,
139
const uint8_t *data);
140
~~~
141
*
142
* - `free_unpacked()`. Frees a message object obtained with the `unpack()`
143
* method. Freeing `NULL` is allowed (the same as with `free()`).
144
*
145
~~~{.c}
146
void foo__bar__baz_bah__free_unpacked
147
(Foo__Bar__BazBah *message,
148
ProtobufCAllocator *allocator);
149
~~~
150
*
151
* - `get_packed_size()`. Calculates the length in bytes of the serialized
152
* representation of the message object.
153
*
154
~~~{.c}
155
size_t foo__bar__baz_bah__get_packed_size
156
(const Foo__Bar__BazBah *message);
157
~~~
158
*
159
* - `pack()`. Pack a message object into a preallocated buffer. Assumes that
160
* the buffer is large enough. (Use `get_packed_size()` first.)
161
*
162
~~~{.c}
163
size_t foo__bar__baz_bah__pack
164
(const Foo__Bar__BazBah *message,
165
uint8_t *out);
166
~~~
167
*
168
* - `pack_to_buffer()`. Packs a message into a "virtual buffer". This is an
169
* object which defines an "append bytes" callback to consume data as it is
170
* serialized.
171
*
172
~~~{.c}
173
size_t foo__bar__baz_bah__pack_to_buffer
174
(const Foo__Bar__BazBah *message,
175
ProtobufCBuffer *buffer);
176
~~~
177
*
178
* \page pack Packing and unpacking messages
179
*
180
* To pack a message, first compute the packed size of the message with
181
* protobuf_c_message_get_packed_size(), then allocate a buffer of at least
182
* that size, then call protobuf_c_message_pack().
183
*
184
* Alternatively, a message can be serialized without calculating the final size
185
* first. Use the protobuf_c_message_pack_to_buffer() function and provide a
186
* ProtobufCBuffer object which implements an "append" method that consumes
187
* data.
188
*
189
* To unpack a message, call the protobuf_c_message_unpack() function. The
190
* result can be cast to an object of the type that matches the descriptor for
191
* the message.
192
*
193
* The result of unpacking a message should be freed with
194
* protobuf_c_message_free_unpacked().
195
*/
196
197
#ifndef PROTOBUF_C_H
198
#define PROTOBUF_C_H
199
200
#include <assert.h>
201
#include <limits.h>
202
#include <stddef.h>
203
#include <inttypes.h> /* stdint.h not present on older systems */
204
205
#ifdef __cplusplus
206
# define PROTOBUF_C__BEGIN_DECLS extern "C" {
207
# define PROTOBUF_C__END_DECLS }
208
#else
209
# define PROTOBUF_C__BEGIN_DECLS
210
# define PROTOBUF_C__END_DECLS
211
#endif
212
213
PROTOBUF_C__BEGIN_DECLS
214
215
#if defined(_WIN32) && defined(PROTOBUF_C_USE_SHARED_LIB)
216
# ifdef PROTOBUF_C_EXPORT
217
# define PROTOBUF_C__API __declspec(dllexport)
218
# else
219
# define PROTOBUF_C__API __declspec(dllimport)
220
# endif
221
#else
222
# define PROTOBUF_C__API
223
#endif
224
225
#if !defined(PROTOBUF_C__NO_DEPRECATED) && \
226
((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
227
# define PROTOBUF_C__DEPRECATED __attribute__((__deprecated__))
228
#else
229
# define PROTOBUF_C__DEPRECATED
230
#endif
231
232
#ifndef PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE
233
#define PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(enum_name) \
234
, _##enum_name##_IS_INT_SIZE = INT_MAX
235
#endif
236
237
#define PROTOBUF_C__SERVICE_DESCRIPTOR_MAGIC 0x14159bc3
238
#define PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC 0x28aaeef9
239
#define PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC 0x114315af
240
241
/* Empty string used for initializers */
242
#if defined(_WIN32) && defined(PROTOBUF_C_USE_SHARED_LIB)
243
static const char protobuf_c_empty_string[] = "";
244
#else
245
extern const char protobuf_c_empty_string[];
246
#endif
247
248
/**
249
* \defgroup api Public API
250
*
251
* This is the public API for `libprotobuf-c`. These interfaces are stable and
252
* subject to Semantic Versioning guarantees.
253
*
254
* @{
255
*/
256
257
/**
258
* Values for the `flags` word in `ProtobufCFieldDescriptor`.
259
*/
260
typedef enum {
261
/** Set if the field is repeated and marked with the `packed` option. */
262
PROTOBUF_C_FIELD_FLAG_PACKED = (1 << 0),
263
264
/** Set if the field is marked with the `deprecated` option. */
265
PROTOBUF_C_FIELD_FLAG_DEPRECATED = (1 << 1),
266
267
/** Set if the field is a member of a oneof (union). */
268
PROTOBUF_C_FIELD_FLAG_ONEOF = (1 << 2),
269
} ProtobufCFieldFlag;
270
271
/**
272
* Message field rules.
273
*
274
* \see [Defining A Message Type] in the Protocol Buffers documentation.
275
*
276
* [Defining A Message Type]:
277
* https://developers.google.com/protocol-buffers/docs/proto#simple
278
*/
279
typedef enum {
280
/** A well-formed message must have exactly one of this field. */
281
PROTOBUF_C_LABEL_REQUIRED,
282
283
/**
284
* A well-formed message can have zero or one of this field (but not
285
* more than one).
286
*/
287
PROTOBUF_C_LABEL_OPTIONAL,
288
289
/**
290
* This field can be repeated any number of times (including zero) in a
291
* well-formed message. The order of the repeated values will be
292
* preserved.
293
*/
294
PROTOBUF_C_LABEL_REPEATED,
295
296
/**
297
* This field has no label. This is valid only in proto3 and is
298
* equivalent to OPTIONAL but no "has" quantifier will be consulted.
299
*/
300
PROTOBUF_C_LABEL_NONE,
301
} ProtobufCLabel;
302
303
/**
304
* Field value types.
305
*
306
* \see [Scalar Value Types] in the Protocol Buffers documentation.
307
*
308
* [Scalar Value Types]:
309
* https://developers.google.com/protocol-buffers/docs/proto#scalar
310
*/
311
typedef enum {
312
PROTOBUF_C_TYPE_INT32, /**< int32 */
313
PROTOBUF_C_TYPE_SINT32, /**< signed int32 */
314
PROTOBUF_C_TYPE_SFIXED32, /**< signed int32 (4 bytes) */
315
PROTOBUF_C_TYPE_INT64, /**< int64 */
316
PROTOBUF_C_TYPE_SINT64, /**< signed int64 */
317
PROTOBUF_C_TYPE_SFIXED64, /**< signed int64 (8 bytes) */
318
PROTOBUF_C_TYPE_UINT32, /**< unsigned int32 */
319
PROTOBUF_C_TYPE_FIXED32, /**< unsigned int32 (4 bytes) */
320
PROTOBUF_C_TYPE_UINT64, /**< unsigned int64 */
321
PROTOBUF_C_TYPE_FIXED64, /**< unsigned int64 (8 bytes) */
322
PROTOBUF_C_TYPE_FLOAT, /**< float */
323
PROTOBUF_C_TYPE_DOUBLE, /**< double */
324
PROTOBUF_C_TYPE_BOOL, /**< boolean */
325
PROTOBUF_C_TYPE_ENUM, /**< enumerated type */
326
PROTOBUF_C_TYPE_STRING, /**< UTF-8 or ASCII string */
327
PROTOBUF_C_TYPE_BYTES, /**< arbitrary byte sequence */
328
PROTOBUF_C_TYPE_MESSAGE, /**< nested message */
329
} ProtobufCType;
330
331
/**
332
* Field wire types.
333
*
334
* \see [Message Structure] in the Protocol Buffers documentation.
335
*
336
* [Message Structure]:
337
* https://developers.google.com/protocol-buffers/docs/encoding#structure
338
*/
339
typedef enum {
340
PROTOBUF_C_WIRE_TYPE_VARINT = 0,
341
PROTOBUF_C_WIRE_TYPE_64BIT = 1,
342
PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED = 2,
343
/* "Start group" and "end group" wire types are unsupported. */
344
PROTOBUF_C_WIRE_TYPE_32BIT = 5,
345
} ProtobufCWireType;
346
347
struct ProtobufCAllocator;
348
struct ProtobufCBinaryData;
349
struct ProtobufCBuffer;
350
struct ProtobufCBufferSimple;
351
struct ProtobufCEnumDescriptor;
352
struct ProtobufCEnumValue;
353
struct ProtobufCEnumValueIndex;
354
struct ProtobufCFieldDescriptor;
355
struct ProtobufCIntRange;
356
struct ProtobufCMessage;
357
struct ProtobufCMessageDescriptor;
358
struct ProtobufCMessageUnknownField;
359
struct ProtobufCMethodDescriptor;
360
struct ProtobufCService;
361
struct ProtobufCServiceDescriptor;
362
363
typedef struct ProtobufCAllocator ProtobufCAllocator;
364
typedef struct ProtobufCBinaryData ProtobufCBinaryData;
365
typedef struct ProtobufCBuffer ProtobufCBuffer;
366
typedef struct ProtobufCBufferSimple ProtobufCBufferSimple;
367
typedef struct ProtobufCEnumDescriptor ProtobufCEnumDescriptor;
368
typedef struct ProtobufCEnumValue ProtobufCEnumValue;
369
typedef struct ProtobufCEnumValueIndex ProtobufCEnumValueIndex;
370
typedef struct ProtobufCFieldDescriptor ProtobufCFieldDescriptor;
371
typedef struct ProtobufCIntRange ProtobufCIntRange;
372
typedef struct ProtobufCMessage ProtobufCMessage;
373
typedef struct ProtobufCMessageDescriptor ProtobufCMessageDescriptor;
374
typedef struct ProtobufCMessageUnknownField ProtobufCMessageUnknownField;
375
typedef struct ProtobufCMethodDescriptor ProtobufCMethodDescriptor;
376
typedef struct ProtobufCService ProtobufCService;
377
typedef struct ProtobufCServiceDescriptor ProtobufCServiceDescriptor;
378
379
/** Boolean type. */
380
typedef int protobuf_c_boolean;
381
382
typedef void (*ProtobufCClosure)(const ProtobufCMessage *, void *closure_data);
383
typedef void (*ProtobufCMessageInit)(ProtobufCMessage *);
384
typedef void (*ProtobufCServiceDestroy)(ProtobufCService *);
385
386
/**
387
* Structure for defining a custom memory allocator.
388
*/
389
struct ProtobufCAllocator {
390
/** Function to allocate memory. */
391
void *(*alloc)(void *allocator_data, size_t size);
392
393
/** Function to free memory. */
394
void (*free)(void *allocator_data, void *pointer);
395
396
/** Opaque pointer passed to `alloc` and `free` functions. */
397
void *allocator_data;
398
};
399
400
/**
401
* Structure for the protobuf `bytes` scalar type.
402
*
403
* The data contained in a `ProtobufCBinaryData` is an arbitrary sequence of
404
* bytes. It may contain embedded `NUL` characters and is not required to be
405
* `NUL`-terminated.
406
*/
407
struct ProtobufCBinaryData {
408
size_t len; /**< Number of bytes in the `data` field. */
409
uint8_t *data; /**< Data bytes. */
410
};
411
412
/**
413
* Structure for defining a virtual append-only buffer. Used by
414
* protobuf_c_message_pack_to_buffer() to abstract the consumption of serialized
415
* bytes.
416
*
417
* `ProtobufCBuffer` "subclasses" may be defined on the stack. For example, to
418
* write to a `FILE` object:
419
*
420
~~~{.c}
421
typedef struct {
422
ProtobufCBuffer base;
423
FILE *fp;
424
} BufferAppendToFile;
425
426
static void
427
my_buffer_file_append(ProtobufCBuffer *buffer,
428
size_t len,
429
const uint8_t *data)
430
{
431
BufferAppendToFile *file_buf = (BufferAppendToFile *) buffer;
432
fwrite(data, len, 1, file_buf->fp); // XXX: No error handling!
433
}
434
~~~
435
*
436
* To use this new type of ProtobufCBuffer, it could be called as follows:
437
*
438
~~~{.c}
439
...
440
BufferAppendToFile tmp = {0};
441
tmp.base.append = my_buffer_file_append;
442
tmp.fp = fp;
443
protobuf_c_message_pack_to_buffer(&message, &tmp);
444
...
445
~~~
446
*/
447
struct ProtobufCBuffer {
448
/** Append function. Consumes the `len` bytes stored at `data`. */
449
void (*append)(ProtobufCBuffer *buffer,
450
size_t len,
451
const uint8_t *data);
452
};
453
454
/**
455
* Simple buffer "subclass" of `ProtobufCBuffer`.
456
*
457
* A `ProtobufCBufferSimple` object is declared on the stack and uses a
458
* scratch buffer provided by the user for the initial allocation. It performs
459
* exponential resizing, using dynamically allocated memory. A
460
* `ProtobufCBufferSimple` object can be created and used as follows:
461
*
462
~~~{.c}
463
uint8_t pad[128];
464
ProtobufCBufferSimple simple = PROTOBUF_C_BUFFER_SIMPLE_INIT(pad);
465
ProtobufCBuffer *buffer = (ProtobufCBuffer *) &simple;
466
~~~
467
*
468
* `buffer` can now be used with `protobuf_c_message_pack_to_buffer()`. Once a
469
* message has been serialized to a `ProtobufCBufferSimple` object, the
470
* serialized data bytes can be accessed from the `.data` field.
471
*
472
* To free the memory allocated by a `ProtobufCBufferSimple` object, if any,
473
* call PROTOBUF_C_BUFFER_SIMPLE_CLEAR() on the object, for example:
474
*
475
~~~{.c}
476
PROTOBUF_C_BUFFER_SIMPLE_CLEAR(&simple);
477
~~~
478
*
479
* \see PROTOBUF_C_BUFFER_SIMPLE_INIT
480
* \see PROTOBUF_C_BUFFER_SIMPLE_CLEAR
481
*/
482
struct ProtobufCBufferSimple {
483
/** "Base class". */
484
ProtobufCBuffer base;
485
/** Number of bytes allocated in `data`. */
486
size_t alloced;
487
/** Number of bytes currently stored in `data`. */
488
size_t len;
489
/** Data bytes. */
490
uint8_t *data;
491
/** Whether `data` must be freed. */
492
protobuf_c_boolean must_free_data;
493
/** Allocator to use. May be NULL to indicate the system allocator. */
494
ProtobufCAllocator *allocator;
495
};
496
497
/**
498
* Describes an enumeration as a whole, with all of its values.
499
*/
500
struct ProtobufCEnumDescriptor {
501
/** Magic value checked to ensure that the API is used correctly. */
502
uint32_t magic;
503
504
/** The qualified name (e.g., "namespace.Type"). */
505
const char *name;
506
/** The unqualified name as given in the .proto file (e.g., "Type"). */
507
const char *short_name;
508
/** Identifier used in generated C code. */
509
const char *c_name;
510
/** The dot-separated namespace. */
511
const char *package_name;
512
513
/** Number elements in `values`. */
514
unsigned n_values;
515
/** Array of distinct values, sorted by numeric value. */
516
const ProtobufCEnumValue *values;
517
518
/** Number of elements in `values_by_name`. */
519
unsigned n_value_names;
520
/** Array of named values, including aliases, sorted by name. */
521
const ProtobufCEnumValueIndex *values_by_name;
522
523
/** Number of elements in `value_ranges`. */
524
unsigned n_value_ranges;
525
/** Value ranges, for faster lookups by numeric value. */
526
const ProtobufCIntRange *value_ranges;
527
528
/** Reserved for future use. */
529
void *reserved1;
530
/** Reserved for future use. */
531
void *reserved2;
532
/** Reserved for future use. */
533
void *reserved3;
534
/** Reserved for future use. */
535
void *reserved4;
536
};
537
538
/**
539
* Represents a single value of an enumeration.
540
*/
541
struct ProtobufCEnumValue {
542
/** The string identifying this value in the .proto file. */
543
const char *name;
544
545
/** The string identifying this value in generated C code. */
546
const char *c_name;
547
548
/** The numeric value assigned in the .proto file. */
549
int value;
550
};
551
552
/**
553
* Used by `ProtobufCEnumDescriptor` to look up enum values.
554
*/
555
struct ProtobufCEnumValueIndex {
556
/** Name of the enum value. */
557
const char *name;
558
/** Index into values[] array. */
559
unsigned index;
560
};
561
562
/**
563
* Describes a single field in a message.
564
*/
565
struct ProtobufCFieldDescriptor {
566
/** Name of the field as given in the .proto file. */
567
const char *name;
568
569
/** Tag value of the field as given in the .proto file. */
570
uint32_t id;
571
572
/** Whether the field is `REQUIRED`, `OPTIONAL`, or `REPEATED`. */
573
ProtobufCLabel label;
574
575
/** The type of the field. */
576
ProtobufCType type;
577
578
/**
579
* The offset in bytes of the message's C structure's quantifier field
580
* (the `has_MEMBER` field for optional members or the `n_MEMBER` field
581
* for repeated members or the case enum for oneofs).
582
*/
583
unsigned quantifier_offset;
584
585
/**
586
* The offset in bytes into the message's C structure for the member
587
* itself.
588
*/
589
unsigned offset;
590
591
/**
592
* A type-specific descriptor.
593
*
594
* If `type` is `PROTOBUF_C_TYPE_ENUM`, then `descriptor` points to the
595
* corresponding `ProtobufCEnumDescriptor`.
596
*
597
* If `type` is `PROTOBUF_C_TYPE_MESSAGE`, then `descriptor` points to
598
* the corresponding `ProtobufCMessageDescriptor`.
599
*
600
* Otherwise this field is NULL.
601
*/
602
const void *descriptor; /* for MESSAGE and ENUM types */
603
604
/** The default value for this field, if defined. May be NULL. */
605
const void *default_value;
606
607
/**
608
* A flag word. Zero or more of the bits defined in the
609
* `ProtobufCFieldFlag` enum may be set.
610
*/
611
uint32_t flags;
612
613
/** Reserved for future use. */
614
unsigned reserved_flags;
615
/** Reserved for future use. */
616
void *reserved2;
617
/** Reserved for future use. */
618
void *reserved3;
619
};
620
621
/**
622
* Helper structure for optimizing int => index lookups in the case
623
* where the keys are mostly consecutive values, as they presumably are for
624
* enums and fields.
625
*
626
* The data structures requires that the values in the original array are
627
* sorted.
628
*/
629
struct ProtobufCIntRange {
630
int start_value;
631
unsigned orig_index;
632
/*
633
* NOTE: the number of values in the range can be inferred by looking
634
* at the next element's orig_index. A dummy element is added to make
635
* this simple.
636
*/
637
};
638
639
/**
640
* An instance of a message.
641
*
642
* `ProtobufCMessage` is a light-weight "base class" for all messages.
643
*
644
* In particular, `ProtobufCMessage` doesn't have any allocation policy
645
* associated with it. That's because it's common to create `ProtobufCMessage`
646
* objects on the stack. In fact, that's what we recommend for sending messages.
647
* If the object is allocated from the stack, you can't really have a memory
648
* leak.
649
*
650
* This means that calls to functions like protobuf_c_message_unpack() which
651
* return a `ProtobufCMessage` must be paired with a call to a free function,
652
* like protobuf_c_message_free_unpacked().
653
*/
654
struct ProtobufCMessage {
655
/** The descriptor for this message type. */
656
const ProtobufCMessageDescriptor *descriptor;
657
/** The number of elements in `unknown_fields`. */
658
unsigned n_unknown_fields;
659
/** The fields that weren't recognized by the parser. */
660
ProtobufCMessageUnknownField *unknown_fields;
661
};
662
663
/**
664
* Describes a message.
665
*/
666
struct ProtobufCMessageDescriptor {
667
/** Magic value checked to ensure that the API is used correctly. */
668
uint32_t magic;
669
670
/** The qualified name (e.g., "namespace.Type"). */
671
const char *name;
672
/** The unqualified name as given in the .proto file (e.g., "Type"). */
673
const char *short_name;
674
/** Identifier used in generated C code. */
675
const char *c_name;
676
/** The dot-separated namespace. */
677
const char *package_name;
678
679
/**
680
* Size in bytes of the C structure representing an instance of this
681
* type of message.
682
*/
683
size_t sizeof_message;
684
685
/** Number of elements in `fields`. */
686
unsigned n_fields;
687
/** Field descriptors, sorted by tag number. */
688
const ProtobufCFieldDescriptor *fields;
689
/** Used for looking up fields by name. */
690
const unsigned *fields_sorted_by_name;
691
692
/** Number of elements in `field_ranges`. */
693
unsigned n_field_ranges;
694
/** Used for looking up fields by id. */
695
const ProtobufCIntRange *field_ranges;
696
697
/** Message initialisation function. */
698
ProtobufCMessageInit message_init;
699
700
/** Reserved for future use. */
701
void *reserved1;
702
/** Reserved for future use. */
703
void *reserved2;
704
/** Reserved for future use. */
705
void *reserved3;
706
};
707
708
/**
709
* An unknown message field.
710
*/
711
struct ProtobufCMessageUnknownField {
712
/** The tag number. */
713
uint32_t tag;
714
/** The wire type of the field. */
715
ProtobufCWireType wire_type;
716
/** Number of bytes in `data`. */
717
size_t len;
718
/** Field data. */
719
uint8_t *data;
720
};
721
722
/**
723
* Method descriptor.
724
*/
725
struct ProtobufCMethodDescriptor {
726
/** Method name. */
727
const char *name;
728
/** Input message descriptor. */
729
const ProtobufCMessageDescriptor *input;
730
/** Output message descriptor. */
731
const ProtobufCMessageDescriptor *output;
732
};
733
734
/**
735
* Service.
736
*/
737
struct ProtobufCService {
738
/** Service descriptor. */
739
const ProtobufCServiceDescriptor *descriptor;
740
/** Function to invoke the service. */
741
void (*invoke)(ProtobufCService *service,
742
unsigned method_index,
743
const ProtobufCMessage *input,
744
ProtobufCClosure closure,
745
void *closure_data);
746
/** Function to destroy the service. */
747
void (*destroy)(ProtobufCService *service);
748
};
749
750
/**
751
* Service descriptor.
752
*/
753
struct ProtobufCServiceDescriptor {
754
/** Magic value checked to ensure that the API is used correctly. */
755
uint32_t magic;
756
757
/** Service name. */
758
const char *name;
759
/** Short version of service name. */
760
const char *short_name;
761
/** C identifier for the service name. */
762
const char *c_name;
763
/** Package name. */
764
const char *package;
765
/** Number of elements in `methods`. */
766
unsigned n_methods;
767
/** Method descriptors, in the order defined in the .proto file. */
768
const ProtobufCMethodDescriptor *methods;
769
/** Sort index of methods. */
770
const unsigned *method_indices_by_name;
771
};
772
773
/**
774
* Get the version of the protobuf-c library. Note that this is the version of
775
* the library linked against, not the version of the headers compiled against.
776
*
777
* \return A string containing the version number of protobuf-c.
778
*/
779
PROTOBUF_C__API
780
const char *
781
protobuf_c_version(void);
782
783
/**
784
* Get the version of the protobuf-c library. Note that this is the version of
785
* the library linked against, not the version of the headers compiled against.
786
*
787
* \return A 32 bit unsigned integer containing the version number of
788
* protobuf-c, represented in base-10 as (MAJOR*1E6) + (MINOR*1E3) + PATCH.
789
*/
790
PROTOBUF_C__API
791
uint32_t
792
protobuf_c_version_number(void);
793
794
/**
795
* The version of the protobuf-c headers, represented as a string using the same
796
* format as protobuf_c_version().
797
*/
798
#define PROTOBUF_C_VERSION "1.5.2"
799
800
/**
801
* The version of the protobuf-c headers, represented as an integer using the
802
* same format as protobuf_c_version_number().
803
*/
804
#define PROTOBUF_C_VERSION_NUMBER 1005002
805
806
/**
807
* The minimum protoc-gen-c version which works with the current version of the
808
* protobuf-c headers.
809
*/
810
#define PROTOBUF_C_MIN_COMPILER_VERSION 1000000
811
812
/**
813
* Look up a `ProtobufCEnumValue` from a `ProtobufCEnumDescriptor` by name.
814
*
815
* \param desc
816
* The `ProtobufCEnumDescriptor` object.
817
* \param name
818
* The `name` field from the corresponding `ProtobufCEnumValue` object to
819
* match.
820
* \return
821
* A `ProtobufCEnumValue` object.
822
* \retval NULL
823
* If not found or if the optimize_for = CODE_SIZE option was set.
824
*/
825
PROTOBUF_C__API
826
const ProtobufCEnumValue *
827
protobuf_c_enum_descriptor_get_value_by_name(
828
const ProtobufCEnumDescriptor *desc,
829
const char *name);
830
831
/**
832
* Look up a `ProtobufCEnumValue` from a `ProtobufCEnumDescriptor` by numeric
833
* value.
834
*
835
* \param desc
836
* The `ProtobufCEnumDescriptor` object.
837
* \param value
838
* The `value` field from the corresponding `ProtobufCEnumValue` object to
839
* match.
840
*
841
* \return
842
* A `ProtobufCEnumValue` object.
843
* \retval NULL
844
* If not found.
845
*/
846
PROTOBUF_C__API
847
const ProtobufCEnumValue *
848
protobuf_c_enum_descriptor_get_value(
849
const ProtobufCEnumDescriptor *desc,
850
int value);
851
852
/**
853
* Look up a `ProtobufCFieldDescriptor` from a `ProtobufCMessageDescriptor` by
854
* the name of the field.
855
*
856
* \param desc
857
* The `ProtobufCMessageDescriptor` object.
858
* \param name
859
* The name of the field.
860
* \return
861
* A `ProtobufCFieldDescriptor` object.
862
* \retval NULL
863
* If not found or if the optimize_for = CODE_SIZE option was set.
864
*/
865
PROTOBUF_C__API
866
const ProtobufCFieldDescriptor *
867
protobuf_c_message_descriptor_get_field_by_name(
868
const ProtobufCMessageDescriptor *desc,
869
const char *name);
870
871
/**
872
* Look up a `ProtobufCFieldDescriptor` from a `ProtobufCMessageDescriptor` by
873
* the tag value of the field.
874
*
875
* \param desc
876
* The `ProtobufCMessageDescriptor` object.
877
* \param value
878
* The tag value of the field.
879
* \return
880
* A `ProtobufCFieldDescriptor` object.
881
* \retval NULL
882
* If not found.
883
*/
884
PROTOBUF_C__API
885
const ProtobufCFieldDescriptor *
886
protobuf_c_message_descriptor_get_field(
887
const ProtobufCMessageDescriptor *desc,
888
unsigned value);
889
890
/**
891
* Determine the number of bytes required to store the serialised message.
892
*
893
* \param message
894
* The message object to serialise.
895
* \return
896
* Number of bytes.
897
*/
898
PROTOBUF_C__API
899
size_t
900
protobuf_c_message_get_packed_size(const ProtobufCMessage *message);
901
902
/**
903
* Serialise a message from its in-memory representation.
904
*
905
* This function stores the serialised bytes of the message in a pre-allocated
906
* buffer.
907
*
908
* \param message
909
* The message object to serialise.
910
* \param[out] out
911
* Buffer to store the bytes of the serialised message. This buffer must
912
* have enough space to store the packed message. Use
913
* protobuf_c_message_get_packed_size() to determine the number of bytes
914
* required.
915
* \return
916
* Number of bytes stored in `out`.
917
*/
918
PROTOBUF_C__API
919
size_t
920
protobuf_c_message_pack(const ProtobufCMessage *message, uint8_t *out);
921
922
/**
923
* Serialise a message from its in-memory representation to a virtual buffer.
924
*
925
* This function calls the `append` method of a `ProtobufCBuffer` object to
926
* consume the bytes generated by the serialiser.
927
*
928
* \param message
929
* The message object to serialise.
930
* \param buffer
931
* The virtual buffer object.
932
* \return
933
* Number of bytes passed to the virtual buffer.
934
*/
935
PROTOBUF_C__API
936
size_t
937
protobuf_c_message_pack_to_buffer(
938
const ProtobufCMessage *message,
939
ProtobufCBuffer *buffer);
940
941
/**
942
* Unpack a serialised message into an in-memory representation.
943
*
944
* \param descriptor
945
* The message descriptor.
946
* \param allocator
947
* `ProtobufCAllocator` to use for memory allocation. May be NULL to
948
* specify the default allocator.
949
* \param len
950
* Length in bytes of the serialised message.
951
* \param data
952
* Pointer to the serialised message.
953
* \return
954
* An unpacked message object.
955
* \retval NULL
956
* If an error occurred during unpacking.
957
*/
958
PROTOBUF_C__API
959
ProtobufCMessage *
960
protobuf_c_message_unpack(
961
const ProtobufCMessageDescriptor *descriptor,
962
ProtobufCAllocator *allocator,
963
size_t len,
964
const uint8_t *data);
965
966
/**
967
* Free an unpacked message object.
968
*
969
* This function should be used to deallocate the memory used by a call to
970
* protobuf_c_message_unpack().
971
*
972
* \param message
973
* The message object to free. May be NULL.
974
* \param allocator
975
* `ProtobufCAllocator` to use for memory deallocation. May be NULL to
976
* specify the default allocator.
977
*/
978
PROTOBUF_C__API
979
void
980
protobuf_c_message_free_unpacked(
981
ProtobufCMessage *message,
982
ProtobufCAllocator *allocator);
983
984
/**
985
* Check the validity of a message object.
986
*
987
* Makes sure all required fields (`PROTOBUF_C_LABEL_REQUIRED`) are present.
988
* Recursively checks nested messages.
989
*
990
* \retval TRUE
991
* Message is valid.
992
* \retval FALSE
993
* Message is invalid.
994
*/
995
PROTOBUF_C__API
996
protobuf_c_boolean
997
protobuf_c_message_check(const ProtobufCMessage *);
998
999
/** Message initialiser. */
1000
#define PROTOBUF_C_MESSAGE_INIT(descriptor) { descriptor, 0, NULL }
1001
1002
/**
1003
* Initialise a message object from a message descriptor.
1004
*
1005
* \param descriptor
1006
* Message descriptor.
1007
* \param message
1008
* Allocated block of memory of size `descriptor->sizeof_message`.
1009
*/
1010
PROTOBUF_C__API
1011
void
1012
protobuf_c_message_init(
1013
const ProtobufCMessageDescriptor *descriptor,
1014
void *message);
1015
1016
/**
1017
* Free a service.
1018
*
1019
* \param service
1020
* The service object to free.
1021
*/
1022
PROTOBUF_C__API
1023
void
1024
protobuf_c_service_destroy(ProtobufCService *service);
1025
1026
/**
1027
* Look up a `ProtobufCMethodDescriptor` by name.
1028
*
1029
* \param desc
1030
* Service descriptor.
1031
* \param name
1032
* Name of the method.
1033
*
1034
* \return
1035
* A `ProtobufCMethodDescriptor` object.
1036
* \retval NULL
1037
* If not found or if the optimize_for = CODE_SIZE option was set.
1038
*/
1039
PROTOBUF_C__API
1040
const ProtobufCMethodDescriptor *
1041
protobuf_c_service_descriptor_get_method_by_name(
1042
const ProtobufCServiceDescriptor *desc,
1043
const char *name);
1044
1045
/**
1046
* Initialise a `ProtobufCBufferSimple` object.
1047
*/
1048
#define PROTOBUF_C_BUFFER_SIMPLE_INIT(array_of_bytes) \
1049
{ \
1050
{ protobuf_c_buffer_simple_append }, \
1051
sizeof(array_of_bytes), \
1052
0, \
1053
(array_of_bytes), \
1054
0, \
1055
NULL \
1056
}
1057
1058
/**
1059
* Clear a `ProtobufCBufferSimple` object, freeing any allocated memory.
1060
*/
1061
#define PROTOBUF_C_BUFFER_SIMPLE_CLEAR(simp_buf) \
1062
do { \
1063
if ((simp_buf)->must_free_data) { \
1064
if ((simp_buf)->allocator != NULL) \
1065
(simp_buf)->allocator->free( \
1066
(simp_buf)->allocator, \
1067
(simp_buf)->data); \
1068
else \
1069
free((simp_buf)->data); \
1070
} \
1071
} while (0)
1072
1073
/**
1074
* The `append` method for `ProtobufCBufferSimple`.
1075
*
1076
* \param buffer
1077
* The buffer object to append to. Must actually be a
1078
* `ProtobufCBufferSimple` object.
1079
* \param len
1080
* Number of bytes in `data`.
1081
* \param data
1082
* Data to append.
1083
*/
1084
PROTOBUF_C__API
1085
void
1086
protobuf_c_buffer_simple_append(
1087
ProtobufCBuffer *buffer,
1088
size_t len,
1089
const unsigned char *data);
1090
1091
PROTOBUF_C__API
1092
void
1093
protobuf_c_service_generated_init(
1094
ProtobufCService *service,
1095
const ProtobufCServiceDescriptor *descriptor,
1096
ProtobufCServiceDestroy destroy);
1097
1098
PROTOBUF_C__API
1099
void
1100
protobuf_c_service_invoke_internal(
1101
ProtobufCService *service,
1102
unsigned method_index,
1103
const ProtobufCMessage *input,
1104
ProtobufCClosure closure,
1105
void *closure_data);
1106
1107
/**@}*/
1108
1109
PROTOBUF_C__END_DECLS
1110
1111
#endif /* PROTOBUF_C_H */
1112
1113