Compare commits
27 Commits
nanopb-0.2
...
dev_instal
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b2ec9e29b3 | ||
|
|
55bd3d706b | ||
|
|
a5006cc612 | ||
|
|
a0f91bbeeb | ||
|
|
7723a30bd6 | ||
|
|
98e01b2b33 | ||
|
|
985f1b4943 | ||
|
|
df3fd72337 | ||
|
|
5ef9d5b698 | ||
|
|
4ecf27c817 | ||
|
|
ccf63de0c6 | ||
|
|
ece793fbc9 | ||
|
|
6adf4e163c | ||
|
|
420ad05e06 | ||
|
|
5e82a426e6 | ||
|
|
8209a668cd | ||
|
|
be81effcf4 | ||
|
|
f1b2ba57d3 | ||
|
|
d2ba776094 | ||
|
|
97554a41c6 | ||
|
|
b4457a86d6 | ||
|
|
bee09c3a38 | ||
|
|
8daadc556e | ||
|
|
43cc9940ad | ||
|
|
85be7a634e | ||
|
|
b5ae8eb6a5 | ||
|
|
2f982d30ef |
@@ -1,10 +1,3 @@
|
||||
nanopb-0.2.5 (2014-01-01)
|
||||
Fix a bug with encoding negative values in int32 fields (issue 97)
|
||||
Create binary packages of the generator + dependencies (issue 47)
|
||||
Add support for pointer-type fields to the encoder (part of issue 80)
|
||||
Fixed path in FindNanopb.cmake (issue 94)
|
||||
Improved tests
|
||||
|
||||
nanopb-0.2.4 (2013-11-07)
|
||||
Remove the deprecated NANOPB_INTERNALS functions from public API.
|
||||
Document the security model.
|
||||
|
||||
@@ -28,9 +28,9 @@ compiler. This has the advantage that there is no need to reimplement the
|
||||
basic parsing of .proto files. However, it does mean that you need the
|
||||
Google's protobuf library in order to run the generator.
|
||||
|
||||
If you have downloaded a binary package for nanopb (either Windows, Linux or
|
||||
Mac OS X version), the 'protoc' binary is included in the 'generator-bin'
|
||||
folder. In this case, you are ready to go. Simply run this command:
|
||||
If you have downloaded a binary package for nanopb (either Windows or Linux
|
||||
version), the 'protoc' binary is included in the 'generator-bin' folder. In
|
||||
this case, you are ready to go. Simply run this command:
|
||||
|
||||
generator-bin/protoc --nanopb_out=. myprotocol.proto
|
||||
|
||||
|
||||
@@ -104,12 +104,11 @@ requires a few header files to be available:
|
||||
#) *stdbool.h*, for definition of *bool*
|
||||
|
||||
If these header files do not come with your compiler, you can use the
|
||||
file *extra/pb_syshdr.h* instead. It contains an example of how to provide
|
||||
file *compat/pb_syshdr.h* instead. It contains an example of how to provide
|
||||
the dependencies. You may have to edit it a bit to suit your custom platform.
|
||||
|
||||
To use the pb_syshdr.h, define *PB_SYSTEM_HEADER* as *"pb_syshdr.h"* (including the quotes).
|
||||
Similarly, you can provide a custom include file, which should provide all the dependencies
|
||||
listed above.
|
||||
To use the pb_syshdr.h, define *PB_SYSTEM_HEADER* to be the name of your custom
|
||||
header file. It should provide all the dependencies listed above.
|
||||
|
||||
Running the test cases
|
||||
======================
|
||||
|
||||
@@ -7,8 +7,6 @@ CFLAGS += -I$(NANOPB_DIR)
|
||||
|
||||
all: server client
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
clean:
|
||||
rm -f server client fileproto.pb.c fileproto.pb.h
|
||||
|
||||
|
||||
@@ -7,8 +7,6 @@ CFLAGS += -I$(NANOPB_DIR)
|
||||
|
||||
all: run_tests
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
clean:
|
||||
rm -f test_conversions encode_double decode_double doubleproto.pb.c doubleproto.pb.h
|
||||
|
||||
|
||||
@@ -10,8 +10,6 @@ all: encode decode
|
||||
./encode 2 | ./decode
|
||||
./encode 3 | ./decode
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
clean:
|
||||
rm -f encode unionproto.pb.h unionproto.pb.c
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
'''Generate header file for nanopb from a ProtoBuf FileDescriptorSet.'''
|
||||
nanopb_version = "nanopb-0.2.5"
|
||||
nanopb_version = "nanopb-0.2.5-dev"
|
||||
|
||||
import sys
|
||||
|
||||
@@ -52,7 +52,7 @@ datatypes = {
|
||||
FieldD.TYPE_FIXED32: ('uint32_t', 'FIXED32', 4),
|
||||
FieldD.TYPE_FIXED64: ('uint64_t', 'FIXED64', 8),
|
||||
FieldD.TYPE_FLOAT: ('float', 'FLOAT', 4),
|
||||
FieldD.TYPE_INT32: ('int32_t', 'INT32', 10),
|
||||
FieldD.TYPE_INT32: ('int32_t', 'INT32', 5),
|
||||
FieldD.TYPE_INT64: ('int64_t', 'INT64', 10),
|
||||
FieldD.TYPE_SFIXED32: ('int32_t', 'SFIXED32', 4),
|
||||
FieldD.TYPE_SFIXED64: ('int64_t', 'SFIXED64', 8),
|
||||
@@ -195,34 +195,6 @@ class Field:
|
||||
else:
|
||||
raise NotImplementedError(desc.label)
|
||||
|
||||
# Check if the field can be implemented with static allocation
|
||||
# i.e. whether the data size is known.
|
||||
if desc.type == FieldD.TYPE_STRING and self.max_size is None:
|
||||
can_be_static = False
|
||||
|
||||
if desc.type == FieldD.TYPE_BYTES and self.max_size is None:
|
||||
can_be_static = False
|
||||
|
||||
# Decide how the field data will be allocated
|
||||
if field_options.type == nanopb_pb2.FT_DEFAULT:
|
||||
if can_be_static:
|
||||
field_options.type = nanopb_pb2.FT_STATIC
|
||||
else:
|
||||
field_options.type = nanopb_pb2.FT_CALLBACK
|
||||
|
||||
if field_options.type == nanopb_pb2.FT_STATIC and not can_be_static:
|
||||
raise Exception("Field %s is defined as static, but max_size or "
|
||||
"max_count is not given." % self.name)
|
||||
|
||||
if field_options.type == nanopb_pb2.FT_STATIC:
|
||||
self.allocation = 'STATIC'
|
||||
elif field_options.type == nanopb_pb2.FT_POINTER:
|
||||
self.allocation = 'POINTER'
|
||||
elif field_options.type == nanopb_pb2.FT_CALLBACK:
|
||||
self.allocation = 'CALLBACK'
|
||||
else:
|
||||
raise NotImplementedError(field_options.type)
|
||||
|
||||
# Decide the C data type to use in the struct.
|
||||
if datatypes.has_key(desc.type):
|
||||
self.ctype, self.pbtype, self.enc_size = datatypes[desc.type]
|
||||
@@ -234,18 +206,19 @@ class Field:
|
||||
self.enc_size = 5 # protoc rejects enum values > 32 bits
|
||||
elif desc.type == FieldD.TYPE_STRING:
|
||||
self.pbtype = 'STRING'
|
||||
self.ctype = 'char'
|
||||
if self.allocation == 'STATIC':
|
||||
if self.max_size is None:
|
||||
can_be_static = False
|
||||
else:
|
||||
self.ctype = 'char'
|
||||
self.array_decl += '[%d]' % self.max_size
|
||||
self.enc_size = varint_max_size(self.max_size) + self.max_size
|
||||
elif desc.type == FieldD.TYPE_BYTES:
|
||||
self.pbtype = 'BYTES'
|
||||
if self.allocation == 'STATIC':
|
||||
if self.max_size is None:
|
||||
can_be_static = False
|
||||
else:
|
||||
self.ctype = self.struct_name + self.name + 't'
|
||||
self.enc_size = varint_max_size(self.max_size) + self.max_size
|
||||
elif self.allocation == 'POINTER':
|
||||
self.ctype = 'pb_bytes_ptr_t'
|
||||
elif desc.type == FieldD.TYPE_MESSAGE:
|
||||
self.pbtype = 'MESSAGE'
|
||||
self.ctype = self.submsgname = names_from_type_name(desc.type_name)
|
||||
@@ -253,31 +226,35 @@ class Field:
|
||||
else:
|
||||
raise NotImplementedError(desc.type)
|
||||
|
||||
if field_options.type == nanopb_pb2.FT_DEFAULT:
|
||||
if can_be_static:
|
||||
field_options.type = nanopb_pb2.FT_STATIC
|
||||
else:
|
||||
field_options.type = nanopb_pb2.FT_CALLBACK
|
||||
|
||||
if field_options.type == nanopb_pb2.FT_STATIC and not can_be_static:
|
||||
raise Exception("Field %s is defined as static, but max_size or max_count is not given." % self.name)
|
||||
|
||||
if field_options.type == nanopb_pb2.FT_STATIC:
|
||||
self.allocation = 'STATIC'
|
||||
elif field_options.type == nanopb_pb2.FT_CALLBACK:
|
||||
self.allocation = 'CALLBACK'
|
||||
self.ctype = 'pb_callback_t'
|
||||
self.array_decl = ''
|
||||
else:
|
||||
raise NotImplementedError(field_options.type)
|
||||
|
||||
def __cmp__(self, other):
|
||||
return cmp(self.tag, other.tag)
|
||||
|
||||
def __str__(self):
|
||||
result = ''
|
||||
if self.allocation == 'POINTER':
|
||||
if self.rules == 'REPEATED':
|
||||
result += ' size_t ' + self.name + '_count;\n'
|
||||
|
||||
if self.pbtype == 'MESSAGE':
|
||||
# Use struct definition, so recursive submessages are possible
|
||||
result += ' struct _%s *%s;' % (self.ctype, self.name)
|
||||
elif self.rules == 'REPEATED' and self.pbtype == 'STRING':
|
||||
# String arrays need to be defined as pointers to pointers
|
||||
result += ' %s **%s;' % (self.ctype, self.name)
|
||||
else:
|
||||
result += ' %s *%s;' % (self.ctype, self.name)
|
||||
elif self.allocation == 'CALLBACK':
|
||||
result += ' pb_callback_t %s;' % self.name
|
||||
if self.rules == 'OPTIONAL' and self.allocation == 'STATIC':
|
||||
result = ' bool has_' + self.name + ';\n'
|
||||
elif self.rules == 'REPEATED' and self.allocation == 'STATIC':
|
||||
result = ' size_t ' + self.name + '_count;\n'
|
||||
else:
|
||||
if self.rules == 'OPTIONAL' and self.allocation == 'STATIC':
|
||||
result += ' bool has_' + self.name + ';\n'
|
||||
elif self.rules == 'REPEATED' and self.allocation == 'STATIC':
|
||||
result += ' size_t ' + self.name + '_count;\n'
|
||||
result += ' %s %s%s;' % (self.ctype, self.name, self.array_decl)
|
||||
result = ''
|
||||
result += ' %s %s%s;' % (self.ctype, self.name, self.array_decl)
|
||||
return result
|
||||
|
||||
def types(self):
|
||||
@@ -332,7 +309,7 @@ class Field:
|
||||
result = ' PB_FIELD2(%3d, ' % self.tag
|
||||
result += '%-8s, ' % self.pbtype
|
||||
result += '%s, ' % self.rules
|
||||
result += '%-8s, ' % self.allocation
|
||||
result += '%s, ' % self.allocation
|
||||
result += '%s, ' % ("FIRST" if not prev_field_name else "OTHER")
|
||||
result += '%s, ' % self.struct_name
|
||||
result += '%s, ' % self.name
|
||||
|
||||
@@ -12,7 +12,6 @@ option java_package = "fi.kapsi.koti.jpa.nanopb";
|
||||
enum FieldType {
|
||||
FT_DEFAULT = 0; // Automatically decide field type, generate static field if possible.
|
||||
FT_CALLBACK = 1; // Always generate a callback field.
|
||||
FT_POINTER = 4; // Always generate a dynamically allocated field.
|
||||
FT_STATIC = 2; // Generate a static field or raise an exception if not possible.
|
||||
FT_IGNORE = 3; // Ignore the field completely.
|
||||
}
|
||||
|
||||
@@ -9,5 +9,4 @@
|
||||
# path is already set up properly and there is no need to give
|
||||
# --plugin= on the command line.
|
||||
|
||||
MYPATH=$(dirname "$0")
|
||||
exec python "$MYPATH/nanopb_generator.py" --protoc-plugin
|
||||
exec python $(dirname $0)/nanopb_generator.py --protoc-plugin
|
||||
|
||||
@@ -9,4 +9,4 @@
|
||||
:: --plugin= on the command line.
|
||||
|
||||
set mydir=%~dp0
|
||||
python "%mydir%\nanopb_generator.py" --protoc-plugin
|
||||
python %mydir%\nanopb_generator.py --protoc-plugin
|
||||
|
||||
59
pb.h
59
pb.h
@@ -43,7 +43,7 @@
|
||||
|
||||
/* Version of the nanopb library. Just in case you want to check it in
|
||||
* your own program. */
|
||||
#define NANOPB_VERSION nanopb-0.2.5
|
||||
#define NANOPB_VERSION nanopb-0.2.5-dev
|
||||
|
||||
/* Include all the system headers needed by nanopb. You will need the
|
||||
* definitions of the following:
|
||||
@@ -116,6 +116,11 @@
|
||||
/* List of possible field types. These are used in the autogenerated code.
|
||||
* Least-significant 4 bits tell the scalar type
|
||||
* Most-significant 4 bits specify repeated/required/packed etc.
|
||||
*
|
||||
* INT32 and UINT32 are treated the same, as are (U)INT64 and (S)FIXED*
|
||||
* These types are simply casted to correct field type when they are
|
||||
* assigned to the memory pointer.
|
||||
* SINT* is different, though, because it is zig-zag coded.
|
||||
*/
|
||||
|
||||
typedef uint8_t pb_type_t;
|
||||
@@ -123,33 +128,32 @@ typedef uint8_t pb_type_t;
|
||||
/**** Field data types ****/
|
||||
|
||||
/* Numeric types */
|
||||
#define PB_LTYPE_VARINT 0x00 /* int32, int64, enum, bool */
|
||||
#define PB_LTYPE_UVARINT 0x01 /* uint32, uint64 */
|
||||
#define PB_LTYPE_SVARINT 0x02 /* sint32, sint64 */
|
||||
#define PB_LTYPE_FIXED32 0x03 /* fixed32, sfixed32, float */
|
||||
#define PB_LTYPE_FIXED64 0x04 /* fixed64, sfixed64, double */
|
||||
#define PB_LTYPE_VARINT 0x00 /* int32, uint32, int64, uint64, bool, enum */
|
||||
#define PB_LTYPE_SVARINT 0x01 /* sint32, sint64 */
|
||||
#define PB_LTYPE_FIXED32 0x02 /* fixed32, sfixed32, float */
|
||||
#define PB_LTYPE_FIXED64 0x03 /* fixed64, sfixed64, double */
|
||||
|
||||
/* Marker for last packable field type. */
|
||||
#define PB_LTYPE_LAST_PACKABLE 0x04
|
||||
#define PB_LTYPE_LAST_PACKABLE 0x03
|
||||
|
||||
/* Byte array with pre-allocated buffer.
|
||||
* data_size is the length of the allocated PB_BYTES_ARRAY structure. */
|
||||
#define PB_LTYPE_BYTES 0x05
|
||||
#define PB_LTYPE_BYTES 0x04
|
||||
|
||||
/* String with pre-allocated buffer.
|
||||
* data_size is the maximum length. */
|
||||
#define PB_LTYPE_STRING 0x06
|
||||
#define PB_LTYPE_STRING 0x05
|
||||
|
||||
/* Submessage
|
||||
* submsg_fields is pointer to field descriptions */
|
||||
#define PB_LTYPE_SUBMESSAGE 0x07
|
||||
#define PB_LTYPE_SUBMESSAGE 0x06
|
||||
|
||||
/* Extension pseudo-field
|
||||
* The field contains a pointer to pb_extension_t */
|
||||
#define PB_LTYPE_EXTENSION 0x08
|
||||
#define PB_LTYPE_EXTENSION 0x07
|
||||
|
||||
/* Number of declared LTYPES */
|
||||
#define PB_LTYPES_COUNT 9
|
||||
#define PB_LTYPES_COUNT 8
|
||||
#define PB_LTYPE_MASK 0x0F
|
||||
|
||||
/**** Field repetition rules ****/
|
||||
@@ -162,7 +166,6 @@ typedef uint8_t pb_type_t;
|
||||
/**** Field allocation types ****/
|
||||
|
||||
#define PB_ATYPE_STATIC 0x00
|
||||
#define PB_ATYPE_POINTER 0x80
|
||||
#define PB_ATYPE_CALLBACK 0x40
|
||||
#define PB_ATYPE_MASK 0xC0
|
||||
|
||||
@@ -228,16 +231,8 @@ struct _pb_bytes_array_t {
|
||||
size_t size;
|
||||
uint8_t bytes[1];
|
||||
};
|
||||
typedef struct _pb_bytes_array_t pb_bytes_array_t;
|
||||
|
||||
/* Same, except for pointer-type fields. There is no need to variable struct
|
||||
* length in this case.
|
||||
*/
|
||||
struct _pb_bytes_ptr_t {
|
||||
size_t size;
|
||||
uint8_t *bytes;
|
||||
};
|
||||
typedef struct _pb_bytes_ptr_t pb_bytes_ptr_t;
|
||||
typedef struct _pb_bytes_array_t pb_bytes_array_t;
|
||||
|
||||
/* This structure is used for giving the callback function.
|
||||
* It is stored in the message structure and filled in by the method that
|
||||
@@ -375,22 +370,6 @@ struct _pb_extension_t {
|
||||
pb_membersize(st, m[0]), \
|
||||
pb_arraysize(st, m), ptr}
|
||||
|
||||
/* Allocated fields carry the size of the actual data, not the pointer */
|
||||
#define PB_REQUIRED_POINTER(tag, st, m, fd, ltype, ptr) \
|
||||
{tag, PB_ATYPE_POINTER | PB_HTYPE_REQUIRED | ltype, \
|
||||
fd, 0, pb_membersize(st, m[0]), 0, ptr}
|
||||
|
||||
/* Optional fields don't need a has_ variable, as information would be redundant */
|
||||
#define PB_OPTIONAL_POINTER(tag, st, m, fd, ltype, ptr) \
|
||||
{tag, PB_ATYPE_POINTER | PB_HTYPE_OPTIONAL | ltype, \
|
||||
fd, 0, pb_membersize(st, m[0]), 0, ptr}
|
||||
|
||||
/* Repeated fields have a _count field and a pointer to array of pointers */
|
||||
#define PB_REPEATED_POINTER(tag, st, m, fd, ltype, ptr) \
|
||||
{tag, PB_ATYPE_POINTER | PB_HTYPE_REPEATED | ltype, \
|
||||
fd, pb_delta(st, m ## _count, m), \
|
||||
pb_membersize(st, m[0]), 0, ptr}
|
||||
|
||||
/* Callbacks are much like required fields except with special datatype. */
|
||||
#define PB_REQUIRED_CALLBACK(tag, st, m, fd, ltype, ptr) \
|
||||
{tag, PB_ATYPE_CALLBACK | PB_HTYPE_REQUIRED | ltype, \
|
||||
@@ -431,8 +410,8 @@ struct _pb_extension_t {
|
||||
#define PB_LTYPE_MAP_SINT32 PB_LTYPE_SVARINT
|
||||
#define PB_LTYPE_MAP_SINT64 PB_LTYPE_SVARINT
|
||||
#define PB_LTYPE_MAP_STRING PB_LTYPE_STRING
|
||||
#define PB_LTYPE_MAP_UINT32 PB_LTYPE_UVARINT
|
||||
#define PB_LTYPE_MAP_UINT64 PB_LTYPE_UVARINT
|
||||
#define PB_LTYPE_MAP_UINT32 PB_LTYPE_VARINT
|
||||
#define PB_LTYPE_MAP_UINT64 PB_LTYPE_VARINT
|
||||
#define PB_LTYPE_MAP_EXTENSION PB_LTYPE_EXTENSION
|
||||
|
||||
/* This is the actual macro used in field descriptions.
|
||||
|
||||
24
pb_decode.c
24
pb_decode.c
@@ -47,8 +47,7 @@ static bool checkreturn default_extension_decoder(pb_istream_t *stream, pb_exten
|
||||
static bool checkreturn decode_extension(pb_istream_t *stream, uint32_t tag, pb_wire_type_t wire_type, pb_field_iterator_t *iter);
|
||||
static bool checkreturn find_extension_field(pb_field_iterator_t *iter);
|
||||
static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct);
|
||||
static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest);
|
||||
static bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *field, void *dest);
|
||||
static bool pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest);
|
||||
static bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *field, void *dest);
|
||||
static bool checkreturn pb_dec_fixed32(pb_istream_t *stream, const pb_field_t *field, void *dest);
|
||||
static bool checkreturn pb_dec_fixed64(pb_istream_t *stream, const pb_field_t *field, void *dest);
|
||||
@@ -63,7 +62,6 @@ static bool checkreturn pb_skip_string(pb_istream_t *stream);
|
||||
*/
|
||||
static const pb_decoder_t PB_DECODERS[PB_LTYPES_COUNT] = {
|
||||
&pb_dec_varint,
|
||||
&pb_dec_uvarint,
|
||||
&pb_dec_svarint,
|
||||
&pb_dec_fixed32,
|
||||
&pb_dec_fixed64,
|
||||
@@ -825,24 +823,8 @@ bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, vo
|
||||
|
||||
switch (field->data_size)
|
||||
{
|
||||
case 1: *(int8_t*)dest = (int8_t)value; break;
|
||||
case 2: *(int16_t*)dest = (int16_t)value; break;
|
||||
case 4: *(int32_t*)dest = (int32_t)value; break;
|
||||
case 8: *(int64_t*)dest = (int64_t)value; break;
|
||||
default: PB_RETURN_ERROR(stream, "invalid data_size");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *field, void *dest)
|
||||
{
|
||||
uint64_t value;
|
||||
if (!pb_decode_varint(stream, &value))
|
||||
return false;
|
||||
|
||||
switch (field->data_size)
|
||||
{
|
||||
case 1: *(uint8_t*)dest = (uint8_t)value; break;
|
||||
case 2: *(uint16_t*)dest = (uint16_t)value; break;
|
||||
case 4: *(uint32_t*)dest = (uint32_t)value; break;
|
||||
case 8: *(uint64_t*)dest = value; break;
|
||||
default: PB_RETURN_ERROR(stream, "invalid data_size");
|
||||
|
||||
109
pb_encode.c
109
pb_encode.c
@@ -28,7 +28,6 @@ static bool checkreturn encode_field(pb_ostream_t *stream, const pb_field_t *fie
|
||||
static bool checkreturn default_extension_encoder(pb_ostream_t *stream, const pb_extension_t *extension);
|
||||
static bool checkreturn encode_extension_field(pb_ostream_t *stream, const pb_field_t *field, const void *pData);
|
||||
static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src);
|
||||
static bool checkreturn pb_enc_uvarint(pb_ostream_t *stream, const pb_field_t *field, const void *src);
|
||||
static bool checkreturn pb_enc_svarint(pb_ostream_t *stream, const pb_field_t *field, const void *src);
|
||||
static bool checkreturn pb_enc_fixed32(pb_ostream_t *stream, const pb_field_t *field, const void *src);
|
||||
static bool checkreturn pb_enc_fixed64(pb_ostream_t *stream, const pb_field_t *field, const void *src);
|
||||
@@ -41,7 +40,6 @@ static bool checkreturn pb_enc_submessage(pb_ostream_t *stream, const pb_field_t
|
||||
*/
|
||||
static const pb_encoder_t PB_ENCODERS[PB_LTYPES_COUNT] = {
|
||||
&pb_enc_varint,
|
||||
&pb_enc_uvarint,
|
||||
&pb_enc_svarint,
|
||||
&pb_enc_fixed32,
|
||||
&pb_enc_fixed64,
|
||||
@@ -118,8 +116,8 @@ static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *fie
|
||||
|
||||
if (count == 0)
|
||||
return true;
|
||||
|
||||
if (PB_ATYPE(field->type) != PB_ATYPE_POINTER && count > field->array_size)
|
||||
|
||||
if (count > field->array_size)
|
||||
PB_RETURN_ERROR(stream, "array max size exceeded");
|
||||
|
||||
/* We always pack arrays if the datatype allows it. */
|
||||
@@ -172,22 +170,8 @@ static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *fie
|
||||
{
|
||||
if (!pb_encode_tag_for_field(stream, field))
|
||||
return false;
|
||||
|
||||
/* Normally the data is stored directly in the array entries, but
|
||||
* for pointer-type string fields, the array entries are actually
|
||||
* string pointers. So we have to dereference once more to get to
|
||||
* the character data. */
|
||||
if (PB_ATYPE(field->type) == PB_ATYPE_POINTER &&
|
||||
PB_LTYPE(field->type) == PB_LTYPE_STRING)
|
||||
{
|
||||
if (!func(stream, field, *(const void* const*)p))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!func(stream, field, p))
|
||||
return false;
|
||||
}
|
||||
if (!func(stream, field, p))
|
||||
return false;
|
||||
p = (const char*)p + field->data_size;
|
||||
}
|
||||
}
|
||||
@@ -195,38 +179,25 @@ static bool checkreturn encode_array(pb_ostream_t *stream, const pb_field_t *fie
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Encode a field with static or pointer allocation, i.e. one whose data
|
||||
* is available to the encoder directly. */
|
||||
static bool checkreturn encode_basic_field(pb_ostream_t *stream,
|
||||
/* Encode a field with static allocation, i.e. one whose data is stored
|
||||
* in the structure itself. */
|
||||
static bool checkreturn encode_static_field(pb_ostream_t *stream,
|
||||
const pb_field_t *field, const void *pData)
|
||||
{
|
||||
pb_encoder_t func;
|
||||
const void *pSize;
|
||||
bool implicit_has = true;
|
||||
bool dummy = true;
|
||||
|
||||
func = PB_ENCODERS[PB_LTYPE(field->type)];
|
||||
|
||||
if (field->size_offset)
|
||||
pSize = (const char*)pData + field->size_offset;
|
||||
else
|
||||
pSize = &implicit_has;
|
||||
|
||||
if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
|
||||
{
|
||||
/* pData is a pointer to the field, which contains pointer to
|
||||
* the data. If the 2nd pointer is NULL, it is interpreted as if
|
||||
* the has_field was false.
|
||||
*/
|
||||
|
||||
pData = *(const void* const*)pData;
|
||||
implicit_has = (pData != NULL);
|
||||
}
|
||||
|
||||
pSize = &dummy;
|
||||
|
||||
switch (PB_HTYPE(field->type))
|
||||
{
|
||||
case PB_HTYPE_REQUIRED:
|
||||
if (!pData)
|
||||
PB_RETURN_ERROR(stream, "missing required field");
|
||||
if (!pb_encode_tag_for_field(stream, field))
|
||||
return false;
|
||||
if (!func(stream, field, pData))
|
||||
@@ -284,8 +255,7 @@ static bool checkreturn encode_field(pb_ostream_t *stream,
|
||||
switch (PB_ATYPE(field->type))
|
||||
{
|
||||
case PB_ATYPE_STATIC:
|
||||
case PB_ATYPE_POINTER:
|
||||
return encode_basic_field(stream, field, pData);
|
||||
return encode_static_field(stream, field, pData);
|
||||
|
||||
case PB_ATYPE_CALLBACK:
|
||||
return encode_callback_field(stream, field, pData);
|
||||
@@ -342,10 +312,7 @@ bool checkreturn pb_encode(pb_ostream_t *stream, const pb_field_t fields[], cons
|
||||
while (field->tag != 0)
|
||||
{
|
||||
pData = (const char*)pData + prev_size + field->data_offset;
|
||||
if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
|
||||
prev_size = sizeof(const void*);
|
||||
else
|
||||
prev_size = field->data_size;
|
||||
prev_size = field->data_size;
|
||||
|
||||
/* Special case for static arrays */
|
||||
if (PB_ATYPE(field->type) == PB_ATYPE_STATIC &&
|
||||
@@ -457,7 +424,6 @@ bool checkreturn pb_encode_tag_for_field(pb_ostream_t *stream, const pb_field_t
|
||||
switch (PB_LTYPE(field->type))
|
||||
{
|
||||
case PB_LTYPE_VARINT:
|
||||
case PB_LTYPE_UVARINT:
|
||||
case PB_LTYPE_SVARINT:
|
||||
wiretype = PB_WT_VARINT;
|
||||
break;
|
||||
@@ -499,12 +465,7 @@ bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fie
|
||||
bool status;
|
||||
|
||||
if (!pb_encode(&substream, fields, src_struct))
|
||||
{
|
||||
#ifndef PB_NO_ERRMSG
|
||||
stream->errmsg = substream.errmsg;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
size = substream.bytes_written;
|
||||
|
||||
@@ -544,29 +505,13 @@ bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fie
|
||||
/* Field encoders */
|
||||
|
||||
bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *field, const void *src)
|
||||
{
|
||||
int64_t value = 0;
|
||||
|
||||
/* Cases 1 and 2 are for compilers that have smaller types for bool
|
||||
* or enums. */
|
||||
switch (field->data_size)
|
||||
{
|
||||
case 1: value = *(const int8_t*)src; break;
|
||||
case 2: value = *(const int16_t*)src; break;
|
||||
case 4: value = *(const int32_t*)src; break;
|
||||
case 8: value = *(const int64_t*)src; break;
|
||||
default: PB_RETURN_ERROR(stream, "invalid data_size");
|
||||
}
|
||||
|
||||
return pb_encode_varint(stream, (uint64_t)value);
|
||||
}
|
||||
|
||||
bool checkreturn pb_enc_uvarint(pb_ostream_t *stream, const pb_field_t *field, const void *src)
|
||||
{
|
||||
uint64_t value = 0;
|
||||
|
||||
switch (field->data_size)
|
||||
{
|
||||
case 1: value = *(const uint8_t*)src; break;
|
||||
case 2: value = *(const uint16_t*)src; break;
|
||||
case 4: value = *(const uint32_t*)src; break;
|
||||
case 8: value = *(const uint64_t*)src; break;
|
||||
default: PB_RETURN_ERROR(stream, "invalid data_size");
|
||||
@@ -603,32 +548,20 @@ bool checkreturn pb_enc_fixed32(pb_ostream_t *stream, const pb_field_t *field, c
|
||||
|
||||
bool checkreturn pb_enc_bytes(pb_ostream_t *stream, const pb_field_t *field, const void *src)
|
||||
{
|
||||
if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
|
||||
{
|
||||
const pb_bytes_ptr_t *bytes = (const pb_bytes_ptr_t*)src;
|
||||
return pb_encode_string(stream, bytes->bytes, bytes->size);
|
||||
}
|
||||
else
|
||||
{
|
||||
const pb_bytes_array_t *bytes = (const pb_bytes_array_t*)src;
|
||||
if (bytes->size + offsetof(pb_bytes_array_t, bytes) > field->data_size)
|
||||
PB_RETURN_ERROR(stream, "bytes size exceeded");
|
||||
const pb_bytes_array_t *bytes = (const pb_bytes_array_t*)src;
|
||||
|
||||
return pb_encode_string(stream, bytes->bytes, bytes->size);
|
||||
}
|
||||
if (bytes->size + offsetof(pb_bytes_array_t, bytes) > field->data_size)
|
||||
PB_RETURN_ERROR(stream, "bytes size exceeded");
|
||||
|
||||
return pb_encode_string(stream, bytes->bytes, bytes->size);
|
||||
}
|
||||
|
||||
bool checkreturn pb_enc_string(pb_ostream_t *stream, const pb_field_t *field, const void *src)
|
||||
{
|
||||
/* strnlen() is not always available, so just use a loop */
|
||||
/* strnlen() is not always available, so just use a for-loop */
|
||||
size_t size = 0;
|
||||
size_t max_size = field->data_size;
|
||||
const char *p = (const char*)src;
|
||||
|
||||
if (PB_ATYPE(field->type) == PB_ATYPE_POINTER)
|
||||
max_size = (size_t)-1;
|
||||
|
||||
while (size < max_size && *p != '\0')
|
||||
while (size < field->data_size && *p != '\0')
|
||||
{
|
||||
size++;
|
||||
p++;
|
||||
|
||||
@@ -52,7 +52,7 @@ if not env.GetOption('clean'):
|
||||
string = conf.CheckCHeader('string.h')
|
||||
if not stdbool or not stdint or not stddef or not string:
|
||||
conf.env.Append(CPPDEFINES = {'PB_SYSTEM_HEADER': '\\"pb_syshdr.h\\"'})
|
||||
conf.env.Append(CPPPATH = "#../extra")
|
||||
conf.env.Append(CPPPATH = "#../compat")
|
||||
|
||||
if stdbool: conf.env.Append(CPPDEFINES = {'HAVE_STDBOOL_H': 1})
|
||||
if stdint: conf.env.Append(CPPDEFINES = {'HAVE_STDINT_H': 1})
|
||||
|
||||
@@ -7,29 +7,6 @@ env.NanopbProto(["alltypes", "alltypes.options"])
|
||||
enc = env.Program(["encode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_encode.o"])
|
||||
dec = env.Program(["decode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_decode.o"])
|
||||
|
||||
# Test the round-trip from nanopb encoder to nanopb decoder
|
||||
env.RunTest(enc)
|
||||
env.RunTest([dec, "encode_alltypes.output"])
|
||||
|
||||
# Re-encode the data using protoc, and check that the results from nanopb
|
||||
# match byte-per-byte to the protoc output.
|
||||
env.Decode("encode_alltypes.output.decoded",
|
||||
["encode_alltypes.output", "alltypes.proto"],
|
||||
MESSAGE='AllTypes')
|
||||
env.Encode("encode_alltypes.output.recoded",
|
||||
["encode_alltypes.output.decoded", "alltypes.proto"],
|
||||
MESSAGE='AllTypes')
|
||||
env.Compare(["encode_alltypes.output", "encode_alltypes.output.recoded"])
|
||||
|
||||
# Do the same checks with the optional fields present.
|
||||
env.RunTest("optionals.output", enc, ARGS = ['1'])
|
||||
env.RunTest("optionals.decout", [dec, "optionals.output"], ARGS = ['1'])
|
||||
env.Decode("optionals.output.decoded",
|
||||
["optionals.output", "alltypes.proto"],
|
||||
MESSAGE='AllTypes')
|
||||
env.Encode("optionals.output.recoded",
|
||||
["optionals.output.decoded", "alltypes.proto"],
|
||||
MESSAGE='AllTypes')
|
||||
env.Compare(["optionals.output", "optionals.output.recoded"])
|
||||
|
||||
|
||||
|
||||
@@ -8,24 +8,6 @@ message EmptyMessage {
|
||||
|
||||
}
|
||||
|
||||
enum HugeEnum {
|
||||
Negative = -2147483647; /* protoc doesn't accept -2147483648 here */
|
||||
Positive = 2147483647;
|
||||
}
|
||||
|
||||
message Limits {
|
||||
required int32 int32_min = 1;
|
||||
required int32 int32_max = 2;
|
||||
required uint32 uint32_min = 3;
|
||||
required uint32 uint32_max = 4;
|
||||
required int64 int64_min = 5;
|
||||
required int64 int64_max = 6;
|
||||
required uint64 uint64_min = 7;
|
||||
required uint64 uint64_max = 8;
|
||||
required HugeEnum enum_min = 9;
|
||||
required HugeEnum enum_max = 10;
|
||||
}
|
||||
|
||||
enum MyEnum {
|
||||
Zero = 0;
|
||||
First = 1;
|
||||
@@ -57,26 +39,26 @@ message AllTypes {
|
||||
required EmptyMessage req_emptymsg = 18;
|
||||
|
||||
|
||||
repeated int32 rep_int32 = 21 [packed = true];
|
||||
repeated int64 rep_int64 = 22 [packed = true];
|
||||
repeated uint32 rep_uint32 = 23 [packed = true];
|
||||
repeated uint64 rep_uint64 = 24 [packed = true];
|
||||
repeated sint32 rep_sint32 = 25 [packed = true];
|
||||
repeated sint64 rep_sint64 = 26 [packed = true];
|
||||
repeated bool rep_bool = 27 [packed = true];
|
||||
repeated int32 rep_int32 = 21;
|
||||
repeated int64 rep_int64 = 22;
|
||||
repeated uint32 rep_uint32 = 23;
|
||||
repeated uint64 rep_uint64 = 24;
|
||||
repeated sint32 rep_sint32 = 25;
|
||||
repeated sint64 rep_sint64 = 26;
|
||||
repeated bool rep_bool = 27;
|
||||
|
||||
repeated fixed32 rep_fixed32 = 28 [packed = true];
|
||||
repeated sfixed32 rep_sfixed32= 29 [packed = true];
|
||||
repeated float rep_float = 30 [packed = true];
|
||||
repeated fixed32 rep_fixed32 = 28;
|
||||
repeated sfixed32 rep_sfixed32= 29;
|
||||
repeated float rep_float = 30;
|
||||
|
||||
repeated fixed64 rep_fixed64 = 31 [packed = true];
|
||||
repeated sfixed64 rep_sfixed64= 32 [packed = true];
|
||||
repeated double rep_double = 33 [packed = true];
|
||||
repeated fixed64 rep_fixed64 = 31;
|
||||
repeated sfixed64 rep_sfixed64= 32;
|
||||
repeated double rep_double = 33;
|
||||
|
||||
repeated string rep_string = 34;
|
||||
repeated bytes rep_bytes = 35;
|
||||
repeated SubMessage rep_submsg = 36;
|
||||
repeated MyEnum rep_enum = 37 [packed = true];
|
||||
repeated MyEnum rep_enum = 37;
|
||||
repeated EmptyMessage rep_emptymsg = 38;
|
||||
|
||||
optional int32 opt_int32 = 41 [default = 4041];
|
||||
@@ -101,9 +83,6 @@ message AllTypes {
|
||||
optional MyEnum opt_enum = 57 [default = Second];
|
||||
optional EmptyMessage opt_emptymsg = 58;
|
||||
|
||||
// Check that extreme integer values are handled correctly
|
||||
required Limits req_limits = 98;
|
||||
|
||||
// Just to make sure that the size of the fields has been calculated
|
||||
// properly, i.e. otherwise a bug in last field might not be detected.
|
||||
required int32 end = 99;
|
||||
|
||||
@@ -170,17 +170,6 @@ bool check_alltypes(pb_istream_t *stream, int mode)
|
||||
TEST(alltypes.has_opt_emptymsg == true);
|
||||
}
|
||||
|
||||
TEST(alltypes.req_limits.int32_min == INT32_MIN);
|
||||
TEST(alltypes.req_limits.int32_max == INT32_MAX);
|
||||
TEST(alltypes.req_limits.uint32_min == 0);
|
||||
TEST(alltypes.req_limits.uint32_max == UINT32_MAX);
|
||||
TEST(alltypes.req_limits.int64_min == INT64_MIN);
|
||||
TEST(alltypes.req_limits.int64_max == INT64_MAX);
|
||||
TEST(alltypes.req_limits.uint64_min == 0);
|
||||
TEST(alltypes.req_limits.uint64_max == UINT64_MAX);
|
||||
TEST(alltypes.req_limits.enum_min == HugeEnum_Negative);
|
||||
TEST(alltypes.req_limits.enum_max == HugeEnum_Positive);
|
||||
|
||||
TEST(alltypes.end == 1099);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -67,17 +67,6 @@ int main(int argc, char **argv)
|
||||
alltypes.rep_enum_count = 5; alltypes.rep_enum[4] = MyEnum_Truth;
|
||||
alltypes.rep_emptymsg_count = 5;
|
||||
|
||||
alltypes.req_limits.int32_min = INT32_MIN;
|
||||
alltypes.req_limits.int32_max = INT32_MAX;
|
||||
alltypes.req_limits.uint32_min = 0;
|
||||
alltypes.req_limits.uint32_max = UINT32_MAX;
|
||||
alltypes.req_limits.int64_min = INT64_MIN;
|
||||
alltypes.req_limits.int64_max = INT64_MAX;
|
||||
alltypes.req_limits.uint64_min = 0;
|
||||
alltypes.req_limits.uint64_max = UINT64_MAX;
|
||||
alltypes.req_limits.enum_min = HugeEnum_Negative;
|
||||
alltypes.req_limits.enum_max = HugeEnum_Positive;
|
||||
|
||||
if (mode != 0)
|
||||
{
|
||||
/* Fill in values for optional fields */
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
# Encode the AllTypes message using pointers for all fields, and verify the
|
||||
# output against the normal AllTypes test case.
|
||||
|
||||
Import("env")
|
||||
|
||||
c = Copy("$TARGET", "$SOURCE")
|
||||
env.Command("alltypes.proto", "#alltypes/alltypes.proto", c)
|
||||
|
||||
env.NanopbProto(["alltypes", "alltypes.options"])
|
||||
enc = env.Program(["encode_alltypes_pointer.c", "alltypes.pb.c", "$COMMON/pb_encode.o"])
|
||||
|
||||
refdec = "$BUILD/alltypes/decode_alltypes$PROGSUFFIX"
|
||||
|
||||
# Encode and compare results
|
||||
env.RunTest(enc)
|
||||
env.RunTest("decode_alltypes.output", [refdec, "encode_alltypes_pointer.output"])
|
||||
env.Compare(["encode_alltypes_pointer.output", "$BUILD/alltypes/encode_alltypes.output"])
|
||||
|
||||
# Do the same thing with the optional fields present
|
||||
env.RunTest("optionals.output", enc, ARGS = ['1'])
|
||||
env.RunTest("optionals.decout", [refdec, "optionals.output"], ARGS = ['1'])
|
||||
env.Compare(["optionals.output", "$BUILD/alltypes/optionals.output"])
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
# Generate all fields as pointers.
|
||||
* type:FT_POINTER
|
||||
|
||||
@@ -1,187 +0,0 @@
|
||||
/* Attempts to test all the datatypes supported by ProtoBuf.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pb_encode.h>
|
||||
#include "alltypes.pb.h"
|
||||
#include "test_helpers.h"
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int mode = (argc > 1) ? atoi(argv[1]) : 0;
|
||||
|
||||
/* Values for required fields */
|
||||
int32_t req_int32 = -1001;
|
||||
int64_t req_int64 = -1002;
|
||||
uint32_t req_uint32 = 1003;
|
||||
uint64_t req_uint64 = 1004;
|
||||
int32_t req_sint32 = -1005;
|
||||
int64_t req_sint64 = -1006;
|
||||
bool req_bool = true;
|
||||
uint32_t req_fixed32 = 1008;
|
||||
int32_t req_sfixed32 = -1009;
|
||||
float req_float = 1010.0f;
|
||||
uint64_t req_fixed64 = 1011;
|
||||
int64_t req_sfixed64 = -1012;
|
||||
double req_double = 1013.0;
|
||||
char* req_string = "1014";
|
||||
pb_bytes_ptr_t req_bytes = {4, (uint8_t*)"1015"};
|
||||
static int32_t req_substuff = 1016;
|
||||
SubMessage req_submsg = {"1016", &req_substuff};
|
||||
MyEnum req_enum = MyEnum_Truth;
|
||||
EmptyMessage req_emptymsg = {0};
|
||||
|
||||
int32_t end = 1099;
|
||||
|
||||
/* Values for repeated fields */
|
||||
int32_t rep_int32[5] = {0, 0, 0, 0, -2001};
|
||||
int64_t rep_int64[5] = {0, 0, 0, 0, -2002};
|
||||
uint32_t rep_uint32[5] = {0, 0, 0, 0, 2003};
|
||||
uint64_t rep_uint64[5] = {0, 0, 0, 0, 2004};
|
||||
int32_t rep_sint32[5] = {0, 0, 0, 0, -2005};
|
||||
int64_t rep_sint64[5] = {0, 0, 0, 0, -2006};
|
||||
bool rep_bool[5] = {false, false, false, false, true};
|
||||
uint32_t rep_fixed32[5] = {0, 0, 0, 0, 2008};
|
||||
int32_t rep_sfixed32[5] = {0, 0, 0, 0, -2009};
|
||||
float rep_float[5] = {0, 0, 0, 0, 2010.0f};
|
||||
uint64_t rep_fixed64[5] = {0, 0, 0, 0, 2011};
|
||||
int64_t rep_sfixed64[5] = {0, 0, 0, 0, -2012};
|
||||
double rep_double[5] = {0, 0, 0, 0, 2013.0f};
|
||||
char* rep_string[5] = {"", "", "", "", "2014"};
|
||||
pb_bytes_ptr_t rep_bytes[5] = {{0,0}, {0,0}, {0,0}, {0,0}, {4, (uint8_t*)"2015"}};
|
||||
static int32_t rep_sub2zero = 0;
|
||||
static int32_t rep_substuff2 = 2016;
|
||||
static uint32_t rep_substuff3 = 2016;
|
||||
SubMessage rep_submsg[5] = {{"", &rep_sub2zero},
|
||||
{"", &rep_sub2zero},
|
||||
{"", &rep_sub2zero},
|
||||
{"", &rep_sub2zero},
|
||||
{"2016", &rep_substuff2, &rep_substuff3}};
|
||||
MyEnum rep_enum[5] = {0, 0, 0, 0, MyEnum_Truth};
|
||||
EmptyMessage rep_emptymsg[5] = {{0}, {0}, {0}, {0}, {0}};
|
||||
|
||||
/* Values for optional fields */
|
||||
int32_t opt_int32 = 3041;
|
||||
int64_t opt_int64 = 3042;
|
||||
uint32_t opt_uint32 = 3043;
|
||||
uint64_t opt_uint64 = 3044;
|
||||
int32_t opt_sint32 = 3045;
|
||||
int64_t opt_sint64 = 3046;
|
||||
bool opt_bool = true;
|
||||
uint32_t opt_fixed32 = 3048;
|
||||
int32_t opt_sfixed32 = 3049;
|
||||
float opt_float = 3050.0f;
|
||||
uint64_t opt_fixed64 = 3051;
|
||||
int64_t opt_sfixed64 = 3052;
|
||||
double opt_double = 3053.0;
|
||||
char* opt_string = "3054";
|
||||
pb_bytes_ptr_t opt_bytes = {4, (uint8_t*)"3055"};
|
||||
static int32_t opt_substuff = 3056;
|
||||
SubMessage opt_submsg = {"3056", &opt_substuff};
|
||||
MyEnum opt_enum = MyEnum_Truth;
|
||||
EmptyMessage opt_emptymsg = {0};
|
||||
|
||||
/* Values for the Limits message. */
|
||||
static int32_t int32_min = INT32_MIN;
|
||||
static int32_t int32_max = INT32_MAX;
|
||||
static uint32_t uint32_min = 0;
|
||||
static uint32_t uint32_max = UINT32_MAX;
|
||||
static int64_t int64_min = INT64_MIN;
|
||||
static int64_t int64_max = INT64_MAX;
|
||||
static uint64_t uint64_min = 0;
|
||||
static uint64_t uint64_max = UINT64_MAX;
|
||||
static HugeEnum enum_min = HugeEnum_Negative;
|
||||
static HugeEnum enum_max = HugeEnum_Positive;
|
||||
Limits req_limits = {&int32_min, &int32_max,
|
||||
&uint32_min, &uint32_max,
|
||||
&int64_min, &int64_max,
|
||||
&uint64_min, &uint64_max,
|
||||
&enum_min, &enum_max};
|
||||
|
||||
/* Initialize the message struct with pointers to the fields. */
|
||||
AllTypes alltypes = {0};
|
||||
|
||||
alltypes.req_int32 = &req_int32;
|
||||
alltypes.req_int64 = &req_int64;
|
||||
alltypes.req_uint32 = &req_uint32;
|
||||
alltypes.req_uint64 = &req_uint64;
|
||||
alltypes.req_sint32 = &req_sint32;
|
||||
alltypes.req_sint64 = &req_sint64;
|
||||
alltypes.req_bool = &req_bool;
|
||||
alltypes.req_fixed32 = &req_fixed32;
|
||||
alltypes.req_sfixed32 = &req_sfixed32;
|
||||
alltypes.req_float = &req_float;
|
||||
alltypes.req_fixed64 = &req_fixed64;
|
||||
alltypes.req_sfixed64 = &req_sfixed64;
|
||||
alltypes.req_double = &req_double;
|
||||
alltypes.req_string = req_string;
|
||||
alltypes.req_bytes = &req_bytes;
|
||||
alltypes.req_submsg = &req_submsg;
|
||||
alltypes.req_enum = &req_enum;
|
||||
alltypes.req_emptymsg = &req_emptymsg;
|
||||
alltypes.req_limits = &req_limits;
|
||||
|
||||
alltypes.rep_int32_count = 5; alltypes.rep_int32 = rep_int32;
|
||||
alltypes.rep_int64_count = 5; alltypes.rep_int64 = rep_int64;
|
||||
alltypes.rep_uint32_count = 5; alltypes.rep_uint32 = rep_uint32;
|
||||
alltypes.rep_uint64_count = 5; alltypes.rep_uint64 = rep_uint64;
|
||||
alltypes.rep_sint32_count = 5; alltypes.rep_sint32 = rep_sint32;
|
||||
alltypes.rep_sint64_count = 5; alltypes.rep_sint64 = rep_sint64;
|
||||
alltypes.rep_bool_count = 5; alltypes.rep_bool = rep_bool;
|
||||
alltypes.rep_fixed32_count = 5; alltypes.rep_fixed32 = rep_fixed32;
|
||||
alltypes.rep_sfixed32_count = 5; alltypes.rep_sfixed32 = rep_sfixed32;
|
||||
alltypes.rep_float_count = 5; alltypes.rep_float = rep_float;
|
||||
alltypes.rep_fixed64_count = 5; alltypes.rep_fixed64 = rep_fixed64;
|
||||
alltypes.rep_sfixed64_count = 5; alltypes.rep_sfixed64 = rep_sfixed64;
|
||||
alltypes.rep_double_count = 5; alltypes.rep_double = rep_double;
|
||||
alltypes.rep_string_count = 5; alltypes.rep_string = rep_string;
|
||||
alltypes.rep_bytes_count = 5; alltypes.rep_bytes = rep_bytes;
|
||||
alltypes.rep_submsg_count = 5; alltypes.rep_submsg = rep_submsg;
|
||||
alltypes.rep_enum_count = 5; alltypes.rep_enum = rep_enum;
|
||||
alltypes.rep_emptymsg_count = 5; alltypes.rep_emptymsg = rep_emptymsg;
|
||||
|
||||
if (mode != 0)
|
||||
{
|
||||
/* Fill in values for optional fields */
|
||||
alltypes.opt_int32 = &opt_int32;
|
||||
alltypes.opt_int64 = &opt_int64;
|
||||
alltypes.opt_uint32 = &opt_uint32;
|
||||
alltypes.opt_uint64 = &opt_uint64;
|
||||
alltypes.opt_sint32 = &opt_sint32;
|
||||
alltypes.opt_sint64 = &opt_sint64;
|
||||
alltypes.opt_bool = &opt_bool;
|
||||
alltypes.opt_fixed32 = &opt_fixed32;
|
||||
alltypes.opt_sfixed32 = &opt_sfixed32;
|
||||
alltypes.opt_float = &opt_float;
|
||||
alltypes.opt_fixed64 = &opt_fixed64;
|
||||
alltypes.opt_sfixed64 = &opt_sfixed64;
|
||||
alltypes.opt_double = &opt_double;
|
||||
alltypes.opt_string = opt_string;
|
||||
alltypes.opt_bytes = &opt_bytes;
|
||||
alltypes.opt_submsg = &opt_submsg;
|
||||
alltypes.opt_enum = &opt_enum;
|
||||
alltypes.opt_emptymsg = &opt_emptymsg;
|
||||
}
|
||||
|
||||
alltypes.end = &end;
|
||||
|
||||
{
|
||||
uint8_t buffer[4096];
|
||||
pb_ostream_t stream = pb_ostream_from_buffer(buffer, sizeof(buffer));
|
||||
|
||||
/* Now encode it and check if we succeeded. */
|
||||
if (pb_encode(&stream, AllTypes_fields, &alltypes))
|
||||
{
|
||||
SET_BINARY_MODE(stdout);
|
||||
fwrite(buffer, 1, stream.bytes_written, stdout);
|
||||
return 0; /* Success */
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Encoding failed: %s\n", PB_GET_ERROR(&stream));
|
||||
return 1; /* Failure */
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <pb_decode.h>
|
||||
#include "alltypes_legacy.h"
|
||||
#include "test_helpers.h"
|
||||
|
||||
#define TEST(x) if (!(x)) { \
|
||||
printf("Test " #x " failed.\n"); \
|
||||
@@ -177,19 +176,15 @@ bool check_alltypes(pb_istream_t *stream, int mode)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
uint8_t buffer[1024];
|
||||
size_t count;
|
||||
pb_istream_t stream;
|
||||
|
||||
/* Whether to expect the optional values or the default values. */
|
||||
int mode = (argc > 1) ? atoi(argv[1]) : 0;
|
||||
|
||||
/* Read the data into buffer */
|
||||
SET_BINARY_MODE(stdin);
|
||||
count = fread(buffer, 1, sizeof(buffer), stdin);
|
||||
uint8_t buffer[1024];
|
||||
size_t count = fread(buffer, 1, sizeof(buffer), stdin);
|
||||
|
||||
/* Construct a pb_istream_t for reading from the buffer */
|
||||
stream = pb_istream_from_buffer(buffer, count);
|
||||
pb_istream_t stream = pb_istream_from_buffer(buffer, count);
|
||||
|
||||
/* Decode and print out the stuff */
|
||||
if (!check_alltypes(&stream, mode))
|
||||
|
||||
@@ -3,10 +3,6 @@
|
||||
|
||||
Import("env")
|
||||
|
||||
# This is needed to get INT32_MIN etc. macros defined
|
||||
env = env.Clone()
|
||||
env.Append(CPPDEFINES = ['__STDC_LIMIT_MACROS'])
|
||||
|
||||
# Copy the files to .cxx extension in order to force C++ build.
|
||||
c = Copy("$TARGET", "$SOURCE")
|
||||
env.Command("pb_encode.cxx", "#../pb_encode.c", c)
|
||||
|
||||
@@ -10,7 +10,5 @@ dec = env.GetBuildPath('$BUILD/basic_stream/${PROGPREFIX}decode_stream${PROGSUFF
|
||||
env.RunTest('person_with_extra_field_stream.output', [dec, "person_with_extra_field.pb"])
|
||||
env.Compare(["person_with_extra_field_stream.output", "person_with_extra_field.expected"])
|
||||
|
||||
# This uses the backwards compatibility alltypes test, so that
|
||||
# alltypes_with_extra_fields.pb doesn't have to be remade so often.
|
||||
dec2 = env.GetBuildPath('$BUILD/backwards_compatibility/${PROGPREFIX}decode_legacy${PROGSUFFIX}')
|
||||
dec2 = env.GetBuildPath('$BUILD/alltypes/${PROGPREFIX}decode_alltypes${PROGSUFFIX}')
|
||||
env.RunTest('alltypes_with_extra_fields.output', [dec2, 'alltypes_with_extra_fields.pb'])
|
||||
|
||||
@@ -8,24 +8,6 @@ message EmptyMessage {
|
||||
|
||||
}
|
||||
|
||||
enum HugeEnum {
|
||||
Negative = -2147483647; /* protoc doesn't accept -2147483648 here */
|
||||
Positive = 2147483647;
|
||||
}
|
||||
|
||||
message Limits {
|
||||
required int32 int32_min = 1;
|
||||
required int32 int32_max = 2;
|
||||
required uint32 uint32_min = 3;
|
||||
required uint32 uint32_max = 4;
|
||||
required int64 int64_min = 5;
|
||||
required int64 int64_max = 6;
|
||||
required uint64 uint64_min = 7;
|
||||
required uint64 uint64_max = 8;
|
||||
required HugeEnum enum_min = 9;
|
||||
required HugeEnum enum_max = 10;
|
||||
}
|
||||
|
||||
enum MyEnum {
|
||||
Zero = 0;
|
||||
First = 1;
|
||||
@@ -101,9 +83,6 @@ message AllTypes {
|
||||
optional MyEnum opt_enum = 10057 [default = Second];
|
||||
optional EmptyMessage opt_emptymsg = 10058;
|
||||
|
||||
// Check that extreme integer values are handled correctly
|
||||
required Limits req_limits = 98;
|
||||
|
||||
// Just to make sure that the size of the fields has been calculated
|
||||
// properly, i.e. otherwise a bug in last field might not be detected.
|
||||
required int32 end = 10099;
|
||||
|
||||
@@ -8,24 +8,6 @@ message EmptyMessage {
|
||||
|
||||
}
|
||||
|
||||
enum HugeEnum {
|
||||
Negative = -2147483647; /* protoc doesn't accept -2147483648 here */
|
||||
Positive = 2147483647;
|
||||
}
|
||||
|
||||
message Limits {
|
||||
required int32 int32_min = 1;
|
||||
required int32 int32_max = 2;
|
||||
required uint32 uint32_min = 3;
|
||||
required uint32 uint32_max = 4;
|
||||
required int64 int64_min = 5;
|
||||
required int64 int64_max = 6;
|
||||
required uint64 uint64_min = 7;
|
||||
required uint64 uint64_max = 8;
|
||||
required HugeEnum enum_min = 9;
|
||||
required HugeEnum enum_max = 10;
|
||||
}
|
||||
|
||||
enum MyEnum {
|
||||
Zero = 0;
|
||||
First = 1;
|
||||
@@ -101,9 +83,6 @@ message AllTypes {
|
||||
optional MyEnum opt_enum = 10057 [default = Second];
|
||||
optional EmptyMessage opt_emptymsg = 10058;
|
||||
|
||||
// Check that extreme integer values are handled correctly
|
||||
required Limits req_limits = 98;
|
||||
|
||||
// Just to make sure that the size of the fields has been calculated
|
||||
// properly, i.e. otherwise a bug in last field might not be detected.
|
||||
required int32 end = 13432099;
|
||||
|
||||
@@ -19,11 +19,7 @@ def add_nanopb_builders(env):
|
||||
else:
|
||||
infile = None
|
||||
|
||||
args = [str(source[0])]
|
||||
if env.has_key('ARGS'):
|
||||
args.extend(env['ARGS'])
|
||||
|
||||
pipe = subprocess.Popen(args,
|
||||
pipe = subprocess.Popen(str(source[0]),
|
||||
stdin = infile,
|
||||
stdout = open(str(target[0]), 'w'),
|
||||
stderr = sys.stderr)
|
||||
@@ -49,17 +45,6 @@ def add_nanopb_builders(env):
|
||||
suffix = '.decoded')
|
||||
env.Append(BUILDERS = {'Decode': decode_builder})
|
||||
|
||||
# Build command that encodes a message using protoc
|
||||
def encode_actions(source, target, env, for_signature):
|
||||
esc = env['ESCAPE']
|
||||
dirs = ' '.join(['-I' + esc(env.GetBuildPath(d)) for d in env['PROTOCPATH']])
|
||||
return '$PROTOC $PROTOCFLAGS %s --encode=%s %s <%s >%s' % (
|
||||
dirs, env['MESSAGE'], esc(str(source[1])), esc(str(source[0])), esc(str(target[0])))
|
||||
|
||||
encode_builder = Builder(generator = encode_actions,
|
||||
suffix = '.encoded')
|
||||
env.Append(BUILDERS = {'Encode': encode_builder})
|
||||
|
||||
# Build command that asserts that two files be equal
|
||||
def compare_files(target, source, env):
|
||||
data1 = open(str(source[0]), 'rb').read()
|
||||
|
||||
@@ -57,16 +57,16 @@ def _detect_protoc(env):
|
||||
# Use protoc defined by user
|
||||
return env['PROTOC']
|
||||
|
||||
n = _detect_nanopb(env)
|
||||
p1 = os.path.join(n, 'generator-bin', 'protoc' + env['PROGSUFFIX'])
|
||||
p = _detect_nanopb(env)
|
||||
p1 = os.path.join(p, 'generator-bin', 'protoc')
|
||||
if os.path.exists(p1):
|
||||
# Use protoc bundled with binary package
|
||||
return env['ESCAPE'](p1)
|
||||
return p1
|
||||
|
||||
p = env.WhereIs('protoc')
|
||||
if p:
|
||||
# Use protoc from path
|
||||
return env['ESCAPE'](p)
|
||||
return p
|
||||
|
||||
raise SCons.Errors.StopError(NanopbWarning,
|
||||
"Could not find the protoc compiler")
|
||||
@@ -78,8 +78,7 @@ def _detect_protocflags(env):
|
||||
|
||||
p = _detect_protoc(env)
|
||||
n = _detect_nanopb(env)
|
||||
p1 = os.path.join(n, 'generator-bin', 'protoc' + env['PROGSUFFIX'])
|
||||
if p == env['ESCAPE'](p1):
|
||||
if p == os.path.join(n, 'generator-bin', 'protoc'):
|
||||
# Using the bundled protoc, no options needed
|
||||
return ''
|
||||
|
||||
|
||||
@@ -34,10 +34,10 @@ LIBPROTOC=$(ldd `which protoc` | grep -o '/.*libprotoc[^ ]*')
|
||||
cp $LIBPROTOC $DEST/generator-bin/
|
||||
cat > $DEST/generator-bin/protoc << EOF
|
||||
#!/bin/bash
|
||||
SCRIPTDIR=\$(dirname "\$0")
|
||||
SCRIPTDIR=\$(dirname \$(readlink -f \$0))
|
||||
export LD_LIBRARY_PATH=\$SCRIPTDIR
|
||||
export PATH=\$SCRIPTDIR:\$PATH
|
||||
exec "\$SCRIPTDIR/protoc.bin" "\$@"
|
||||
exec \$SCRIPTDIR/protoc.bin "\$@"
|
||||
EOF
|
||||
chmod +x $DEST/generator-bin/protoc
|
||||
|
||||
|
||||
@@ -37,13 +37,13 @@ LIBPROTOBUF=$(otool -L `which protoc` | grep -o '/.*libprotobuf[^ ]*')
|
||||
cp $LIBPROTOC $LIBPROTOBUF $DEST/generator-bin/
|
||||
cat > $DEST/generator-bin/protoc << EOF
|
||||
#!/bin/bash
|
||||
SCRIPTDIR=\$(dirname "\$0")
|
||||
SCRIPTDIR=\$(cd \$(dirname \$0); pwd)
|
||||
export DYLD_LIBRARY_PATH=\$SCRIPTDIR
|
||||
export PATH=\$SCRIPTDIR:\$PATH
|
||||
exec "\$SCRIPTDIR/protoc.bin" "\$@"
|
||||
exec \$SCRIPTDIR/protoc.bin "\$@"
|
||||
EOF
|
||||
chmod +x $DEST/generator-bin/protoc
|
||||
|
||||
# Tar it all up
|
||||
( cd dist; zip -r $VERSION.zip $VERSION )
|
||||
( cd dist; tar -czf $VERSION.tgz $VERSION )
|
||||
|
||||
|
||||
Reference in New Issue
Block a user