summaryrefslogtreecommitdiffstats
path: root/pb_encode.c
diff options
context:
space:
mode:
authorPetteri Aimonen <jpa@git.mail.kapsi.fi>2013-12-21 12:16:03 +0200
committerPetteri Aimonen <jpa@git.mail.kapsi.fi>2013-12-21 12:16:03 +0200
commitee5b12c537115b113ce01708d4a86a4062cdb182 (patch)
tree53c617ada095685ae321e71fbda1b7d7d35ce2cd /pb_encode.c
parent9cc19a5e998d93fbe6d7a7c18fba1e37a36076d5 (diff)
Add PB_LTYPE_UVARINT to fix encoding of negative int32 values.
Apparently int32 values that are negative must be cast into int64 first before being encoded. Because uint32 still needs to be cast to uint64, the cases for int32 and uint32 had to be separated. Update issue 97 Status: FixedInGit
Diffstat (limited to 'pb_encode.c')
-rw-r--r--pb_encode.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/pb_encode.c b/pb_encode.c
index ebf20de5..f6e08a57 100644
--- a/pb_encode.c
+++ b/pb_encode.c
@@ -28,6 +28,7 @@ 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);
@@ -40,6 +41,7 @@ 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,
@@ -424,6 +426,7 @@ 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;
@@ -506,12 +509,28 @@ bool checkreturn pb_encode_submessage(pb_ostream_t *stream, const pb_field_t fie
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");