aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetteri Aimonen <jpa@git.mail.kapsi.fi>2016-01-26 22:10:09 +0200
committerPetteri Aimonen <jpa@git.mail.kapsi.fi>2016-01-26 22:12:09 +0200
commitd79b15d8aa377116735c87e4d694fc2d20a5fef5 (patch)
tree125387275bde67b1bcab9325c706fba0ff10d8df
parentcad502a1d690ad129af9d4942185cfdbf1fa1504 (diff)
Get rid of type punning in pb_encode_fixedXX().
This was never very clean code, but it was fast. Hopefully compilers are smart enough to optimize it away, or the speed difference is not very large. This should be checked. However working code is always more important than fast code, and the previous way couldn't really work for platforms that do not have byte-sized memory access. Related to PR #191.
-rw-r--r--pb_decode.c47
-rw-r--r--pb_encode.c44
2 files changed, 37 insertions, 54 deletions
diff --git a/pb_decode.c b/pb_decode.c
index 0bf8befd..e7689806 100644
--- a/pb_decode.c
+++ b/pb_decode.c
@@ -1106,44 +1106,35 @@ bool pb_decode_svarint(pb_istream_t *stream, int64_t *dest)
bool pb_decode_fixed32(pb_istream_t *stream, void *dest)
{
- #ifdef __BIG_ENDIAN__
- uint8_t *bytes = (uint8_t*)dest;
- uint8_t lebytes[4];
-
- if (!pb_read(stream, lebytes, 4))
+ uint8_t bytes[4];
+
+ if (!pb_read(stream, bytes, 4))
return false;
- bytes[0] = lebytes[3];
- bytes[1] = lebytes[2];
- bytes[2] = lebytes[1];
- bytes[3] = lebytes[0];
+ *(uint32_t*)dest = ((uint32_t)bytes[0] << 0) |
+ ((uint32_t)bytes[1] << 8) |
+ ((uint32_t)bytes[2] << 16) |
+ ((uint32_t)bytes[3] << 24);
return true;
- #else
- return pb_read(stream, (uint8_t*)dest, 4);
- #endif
}
bool pb_decode_fixed64(pb_istream_t *stream, void *dest)
{
- #ifdef __BIG_ENDIAN__
- uint8_t *bytes = (uint8_t*)dest;
- uint8_t lebytes[8];
-
- if (!pb_read(stream, lebytes, 8))
+ uint8_t bytes[8];
+
+ if (!pb_read(stream, bytes, 8))
return false;
- bytes[0] = lebytes[7];
- bytes[1] = lebytes[6];
- bytes[2] = lebytes[5];
- bytes[3] = lebytes[4];
- bytes[4] = lebytes[3];
- bytes[5] = lebytes[2];
- bytes[6] = lebytes[1];
- bytes[7] = lebytes[0];
+ *(uint64_t*)dest = ((uint64_t)bytes[0] << 0) |
+ ((uint64_t)bytes[1] << 8) |
+ ((uint64_t)bytes[2] << 16) |
+ ((uint64_t)bytes[3] << 24) |
+ ((uint64_t)bytes[4] << 32) |
+ ((uint64_t)bytes[5] << 40) |
+ ((uint64_t)bytes[6] << 48) |
+ ((uint64_t)bytes[7] << 56);
+
return true;
- #else
- return pb_read(stream, (uint8_t*)dest, 8);
- #endif
}
static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest)
diff --git a/pb_encode.c b/pb_encode.c
index cc372b8f..14e657e9 100644
--- a/pb_encode.c
+++ b/pb_encode.c
@@ -443,36 +443,28 @@ bool checkreturn pb_encode_svarint(pb_ostream_t *stream, int64_t value)
bool checkreturn pb_encode_fixed32(pb_ostream_t *stream, const void *value)
{
- #ifdef __BIG_ENDIAN__
- const uint8_t *bytes = value;
- uint8_t lebytes[4];
- lebytes[0] = bytes[3];
- lebytes[1] = bytes[2];
- lebytes[2] = bytes[1];
- lebytes[3] = bytes[0];
- return pb_write(stream, lebytes, 4);
- #else
- return pb_write(stream, (const uint8_t*)value, 4);
- #endif
+ uint32_t val = *(const uint32_t*)value;
+ uint8_t bytes[4];
+ bytes[0] = (uint8_t)(val & 0xFF);
+ bytes[1] = (uint8_t)((val >> 8) & 0xFF);
+ bytes[2] = (uint8_t)((val >> 16) & 0xFF);
+ bytes[3] = (uint8_t)((val >> 24) & 0xFF);
+ return pb_write(stream, bytes, 4);
}
bool checkreturn pb_encode_fixed64(pb_ostream_t *stream, const void *value)
{
- #ifdef __BIG_ENDIAN__
- const uint8_t *bytes = value;
- uint8_t lebytes[8];
- lebytes[0] = bytes[7];
- lebytes[1] = bytes[6];
- lebytes[2] = bytes[5];
- lebytes[3] = bytes[4];
- lebytes[4] = bytes[3];
- lebytes[5] = bytes[2];
- lebytes[6] = bytes[1];
- lebytes[7] = bytes[0];
- return pb_write(stream, lebytes, 8);
- #else
- return pb_write(stream, (const uint8_t*)value, 8);
- #endif
+ uint64_t val = *(const uint64_t*)value;
+ uint8_t bytes[8];
+ bytes[0] = (uint8_t)(val & 0xFF);
+ bytes[1] = (uint8_t)((val >> 8) & 0xFF);
+ bytes[2] = (uint8_t)((val >> 16) & 0xFF);
+ bytes[3] = (uint8_t)((val >> 24) & 0xFF);
+ bytes[4] = (uint8_t)((val >> 32) & 0xFF);
+ bytes[5] = (uint8_t)((val >> 40) & 0xFF);
+ bytes[6] = (uint8_t)((val >> 48) & 0xFF);
+ bytes[7] = (uint8_t)((val >> 56) & 0xFF);
+ return pb_write(stream, bytes, 8);
}
bool checkreturn pb_encode_tag(pb_ostream_t *stream, pb_wire_type_t wiretype, uint32_t field_number)