Fix a few remaining bugs related to CHAR_BIT!=8 platforms.
authorPetteri Aimonen <jpa@git.mail.kapsi.fi>
Wed, 27 Jan 2016 16:59:54 +0000 (18:59 +0200)
committerPetteri Aimonen <jpa@git.mail.kapsi.fi>
Wed, 27 Jan 2016 18:34:46 +0000 (20:34 +0200)
generator/nanopb_generator.py
pb_decode.c
pb_encode.c

index 0748e63..d16fd82 100755 (executable)
@@ -809,7 +809,7 @@ class Message:
         if not self.ordered_fields:
             # Empty structs are not allowed in C standard.
             # Therefore add a dummy field if an empty message occurs.
-            result += '    uint8_t dummy_field;'
+            result += '    char dummy_field;'
 
         result += '\n'.join([str(f) for f in self.ordered_fields])
         result += '\n}'
index b7a0093..1699091 100644 (file)
@@ -1155,19 +1155,22 @@ static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *fi
      * not break decoding of such messages, we cast <=32 bit fields to
      * int32_t first to get the sign correct.
      */
-    if (field->data_size == 8)
+    if (field->data_size == sizeof(int64_t))
         svalue = (int64_t)value;
     else
         svalue = (int32_t)value;
 
-    switch (field->data_size)
-    {
-        case 1: clamped = *(int8_t*)dest = (int8_t)svalue; break;
-        case 2: clamped = *(int16_t*)dest = (int16_t)svalue; break;
-        case 4: clamped = *(int32_t*)dest = (int32_t)svalue; break;
-        case 8: clamped = *(int64_t*)dest = svalue; break;
-        default: PB_RETURN_ERROR(stream, "invalid data_size");
-    }
+    /* Cast to the proper field size, while checking for overflows */
+    if (field->data_size == sizeof(int64_t))
+        clamped = *(int64_t*)dest = svalue;
+    else if (field->data_size == sizeof(int32_t))
+        clamped = *(int32_t*)dest = (int32_t)svalue;
+    else if (field->data_size == sizeof(int_least16_t))
+        clamped = *(int_least16_t*)dest = (int_least16_t)svalue;
+    else if (field->data_size == sizeof(int_least8_t))
+        clamped = *(int_least8_t*)dest = (int_least8_t)svalue;
+    else
+        PB_RETURN_ERROR(stream, "invalid data_size");
 
     if (clamped != svalue)
         PB_RETURN_ERROR(stream, "integer too large");
@@ -1181,14 +1184,17 @@ static bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *f
     if (!pb_decode_varint(stream, &value))
         return false;
     
-    switch (field->data_size)
-    {
-        case 1: clamped = *(uint_least8_t*)dest = (uint_least8_t)value; break;
-        case 2: clamped = *(uint_least16_t*)dest = (uint_least16_t)value; break;
-        case 4: clamped = *(uint32_t*)dest = (uint32_t)value; break;
-        case 8: clamped = *(uint64_t*)dest = value; break;
-        default: PB_RETURN_ERROR(stream, "invalid data_size");
-    }
+    /* Cast to the proper field size, while checking for overflows */
+    if (field->data_size == sizeof(uint64_t))
+        clamped = *(uint64_t*)dest = value;
+    else if (field->data_size == sizeof(uint32_t))
+        clamped = *(uint32_t*)dest = (uint32_t)value;
+    else if (field->data_size == sizeof(uint_least16_t))
+        clamped = *(uint_least16_t*)dest = (uint_least16_t)value;
+    else if (field->data_size == sizeof(uint_least8_t))
+        clamped = *(uint_least8_t*)dest = (uint_least8_t)value;
+    else
+        PB_RETURN_ERROR(stream, "invalid data_size");
     
     if (clamped != value)
         PB_RETURN_ERROR(stream, "integer too large");
@@ -1202,14 +1208,17 @@ static bool checkreturn pb_dec_svarint(pb_istream_t *stream, const pb_field_t *f
     if (!pb_decode_svarint(stream, &value))
         return false;
     
-    switch (field->data_size)
-    {
-        case 1: clamped = *(int_least8_t*)dest = (int_least8_t)value; break;
-        case 2: clamped = *(int_least16_t*)dest = (int_least16_t)value; break;
-        case 4: clamped = *(int32_t*)dest = (int32_t)value; break;
-        case 8: clamped = *(int64_t*)dest = value; break;
-        default: PB_RETURN_ERROR(stream, "invalid data_size");
-    }
+    /* Cast to the proper field size, while checking for overflows */
+    if (field->data_size == sizeof(int64_t))
+        clamped = *(int64_t*)dest = value;
+    else if (field->data_size == sizeof(int32_t))
+        clamped = *(int32_t*)dest = (int32_t)value;
+    else if (field->data_size == sizeof(int_least16_t))
+        clamped = *(int_least16_t*)dest = (int_least16_t)value;
+    else if (field->data_size == sizeof(int_least8_t))
+        clamped = *(int_least8_t*)dest = (int_least8_t)value;
+    else
+        PB_RETURN_ERROR(stream, "invalid data_size");
 
     if (clamped != value)
         PB_RETURN_ERROR(stream, "integer too large");
index 9568375..9f91c9d 100644 (file)
@@ -572,16 +572,16 @@ static bool checkreturn pb_enc_varint(pb_ostream_t *stream, const pb_field_t *fi
 {
     int64_t value = 0;
     
-    /* Cases 1 and 2 are for compilers that have smaller types for bool
-     * or enums, and for int_size option. */
-    switch (field->data_size)
-    {
-        case 1: value = *(const int_least8_t*)src; break;
-        case 2: value = *(const int_least16_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");
-    }
+    if (field->data_size == sizeof(int_least8_t))
+        value = *(const int_least8_t*)src;
+    else if (field->data_size == sizeof(int_least16_t))
+        value = *(const int_least16_t*)src;
+    else if (field->data_size == sizeof(int32_t))
+        value = *(const int32_t*)src;
+    else if (field->data_size == sizeof(int64_t))
+        value = *(const int64_t*)src;
+    else
+        PB_RETURN_ERROR(stream, "invalid data_size");
     
     return pb_encode_varint(stream, (uint64_t)value);
 }
@@ -590,14 +590,16 @@ static bool checkreturn pb_enc_uvarint(pb_ostream_t *stream, const pb_field_t *f
 {
     uint64_t value = 0;
     
-    switch (field->data_size)
-    {
-        case 1: value = *(const uint_least8_t*)src; break;
-        case 2: value = *(const uint_least16_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");
-    }
+    if (field->data_size == sizeof(uint_least8_t))
+        value = *(const uint_least8_t*)src;
+    else if (field->data_size == sizeof(uint_least16_t))
+        value = *(const uint_least16_t*)src;
+    else if (field->data_size == sizeof(uint32_t))
+        value = *(const uint32_t*)src;
+    else if (field->data_size == sizeof(uint64_t))
+        value = *(const uint64_t*)src;
+    else
+        PB_RETURN_ERROR(stream, "invalid data_size");
     
     return pb_encode_varint(stream, value);
 }
@@ -606,14 +608,16 @@ static bool checkreturn pb_enc_svarint(pb_ostream_t *stream, const pb_field_t *f
 {
     int64_t value = 0;
     
-    switch (field->data_size)
-    {
-        case 1: value = *(const int_least8_t*)src; break;
-        case 2: value = *(const int_least16_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");
-    }
+    if (field->data_size == sizeof(int_least8_t))
+        value = *(const int_least8_t*)src;
+    else if (field->data_size == sizeof(int_least16_t))
+        value = *(const int_least16_t*)src;
+    else if (field->data_size == sizeof(int32_t))
+        value = *(const int32_t*)src;
+    else if (field->data_size == sizeof(int64_t))
+        value = *(const int64_t*)src;
+    else
+        PB_RETURN_ERROR(stream, "invalid data_size");
     
     return pb_encode_svarint(stream, value);
 }