basic: add unaligned macros for little endian
Also add test code for that.
This commit is contained in:
@@ -21,8 +21,11 @@
|
||||
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <endian.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* BE */
|
||||
|
||||
static inline uint16_t unaligned_read_be16(const void *_u) {
|
||||
const uint8_t *u = _u;
|
||||
|
||||
@@ -64,3 +67,47 @@ static inline void unaligned_write_be64(void *_u, uint64_t a) {
|
||||
unaligned_write_be32(u, (uint32_t) (a >> 32));
|
||||
unaligned_write_be32(u + 4, (uint32_t) a);
|
||||
}
|
||||
|
||||
/* LE */
|
||||
|
||||
static inline uint16_t unaligned_read_le16(const void *_u) {
|
||||
const uint8_t *u = _u;
|
||||
|
||||
return (((uint16_t) u[1]) << 8) |
|
||||
((uint16_t) u[0]);
|
||||
}
|
||||
|
||||
static inline uint32_t unaligned_read_le32(const void *_u) {
|
||||
const uint8_t *u = _u;
|
||||
|
||||
return (((uint32_t) unaligned_read_le16(u + 2)) << 16) |
|
||||
((uint32_t) unaligned_read_le16(u));
|
||||
}
|
||||
|
||||
static inline uint64_t unaligned_read_le64(const void *_u) {
|
||||
const uint8_t *u = _u;
|
||||
|
||||
return (((uint64_t) unaligned_read_le32(u + 4)) << 32) |
|
||||
((uint64_t) unaligned_read_le32(u));
|
||||
}
|
||||
|
||||
static inline void unaligned_write_le16(void *_u, uint16_t a) {
|
||||
uint8_t *u = _u;
|
||||
|
||||
u[0] = (uint8_t) a;
|
||||
u[1] = (uint8_t) (a >> 8);
|
||||
}
|
||||
|
||||
static inline void unaligned_write_le32(void *_u, uint32_t a) {
|
||||
uint8_t *u = _u;
|
||||
|
||||
unaligned_write_le16(u, (uint16_t) a);
|
||||
unaligned_write_le16(u + 2, (uint16_t) (a >> 16));
|
||||
}
|
||||
|
||||
static inline void unaligned_write_le64(void *_u, uint64_t a) {
|
||||
uint8_t *u = _u;
|
||||
|
||||
unaligned_write_le32(u, (uint32_t) a);
|
||||
unaligned_write_le32(u + 4, (uint32_t) (a >> 32));
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ static uint8_t data[] = {
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
};
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
static void test_be(void) {
|
||||
uint8_t scratch[16];
|
||||
|
||||
assert_se(unaligned_read_be16(&data[0]) == 0x0001);
|
||||
@@ -91,3 +91,75 @@ int main(int argc, const char *argv[]) {
|
||||
unaligned_write_be64(&scratch[7], 0x0708090a0b0c0d0e);
|
||||
assert_se(memcmp(&scratch[7], &data[7], sizeof(uint64_t)) == 0);
|
||||
}
|
||||
|
||||
static void test_le(void) {
|
||||
uint8_t scratch[16];
|
||||
|
||||
assert_se(unaligned_read_le16(&data[0]) == 0x0100);
|
||||
assert_se(unaligned_read_le16(&data[1]) == 0x0201);
|
||||
|
||||
assert_se(unaligned_read_le32(&data[0]) == 0x03020100);
|
||||
assert_se(unaligned_read_le32(&data[1]) == 0x04030201);
|
||||
assert_se(unaligned_read_le32(&data[2]) == 0x05040302);
|
||||
assert_se(unaligned_read_le32(&data[3]) == 0x06050403);
|
||||
|
||||
assert_se(unaligned_read_le64(&data[0]) == 0x0706050403020100);
|
||||
assert_se(unaligned_read_le64(&data[1]) == 0x0807060504030201);
|
||||
assert_se(unaligned_read_le64(&data[2]) == 0x0908070605040302);
|
||||
assert_se(unaligned_read_le64(&data[3]) == 0x0a09080706050403);
|
||||
assert_se(unaligned_read_le64(&data[4]) == 0x0b0a090807060504);
|
||||
assert_se(unaligned_read_le64(&data[5]) == 0x0c0b0a0908070605);
|
||||
assert_se(unaligned_read_le64(&data[6]) == 0x0d0c0b0a09080706);
|
||||
assert_se(unaligned_read_le64(&data[7]) == 0x0e0d0c0b0a090807);
|
||||
|
||||
zero(scratch);
|
||||
unaligned_write_le16(&scratch[0], 0x0100);
|
||||
assert_se(memcmp(&scratch[0], &data[0], sizeof(uint16_t)) == 0);
|
||||
zero(scratch);
|
||||
unaligned_write_le16(&scratch[1], 0x0201);
|
||||
assert_se(memcmp(&scratch[1], &data[1], sizeof(uint16_t)) == 0);
|
||||
|
||||
zero(scratch);
|
||||
unaligned_write_le32(&scratch[0], 0x03020100);
|
||||
|
||||
assert_se(memcmp(&scratch[0], &data[0], sizeof(uint32_t)) == 0);
|
||||
zero(scratch);
|
||||
unaligned_write_le32(&scratch[1], 0x04030201);
|
||||
assert_se(memcmp(&scratch[1], &data[1], sizeof(uint32_t)) == 0);
|
||||
zero(scratch);
|
||||
unaligned_write_le32(&scratch[2], 0x05040302);
|
||||
assert_se(memcmp(&scratch[2], &data[2], sizeof(uint32_t)) == 0);
|
||||
zero(scratch);
|
||||
unaligned_write_le32(&scratch[3], 0x06050403);
|
||||
assert_se(memcmp(&scratch[3], &data[3], sizeof(uint32_t)) == 0);
|
||||
|
||||
zero(scratch);
|
||||
unaligned_write_le64(&scratch[0], 0x0706050403020100);
|
||||
assert_se(memcmp(&scratch[0], &data[0], sizeof(uint64_t)) == 0);
|
||||
zero(scratch);
|
||||
unaligned_write_le64(&scratch[1], 0x0807060504030201);
|
||||
assert_se(memcmp(&scratch[1], &data[1], sizeof(uint64_t)) == 0);
|
||||
zero(scratch);
|
||||
unaligned_write_le64(&scratch[2], 0x0908070605040302);
|
||||
assert_se(memcmp(&scratch[2], &data[2], sizeof(uint64_t)) == 0);
|
||||
zero(scratch);
|
||||
unaligned_write_le64(&scratch[3], 0x0a09080706050403);
|
||||
assert_se(memcmp(&scratch[3], &data[3], sizeof(uint64_t)) == 0);
|
||||
zero(scratch);
|
||||
unaligned_write_le64(&scratch[4], 0x0B0A090807060504);
|
||||
assert_se(memcmp(&scratch[4], &data[4], sizeof(uint64_t)) == 0);
|
||||
zero(scratch);
|
||||
unaligned_write_le64(&scratch[5], 0x0c0b0a0908070605);
|
||||
assert_se(memcmp(&scratch[5], &data[5], sizeof(uint64_t)) == 0);
|
||||
zero(scratch);
|
||||
unaligned_write_le64(&scratch[6], 0x0d0c0b0a09080706);
|
||||
assert_se(memcmp(&scratch[6], &data[6], sizeof(uint64_t)) == 0);
|
||||
zero(scratch);
|
||||
unaligned_write_le64(&scratch[7], 0x0e0d0c0b0a090807);
|
||||
assert_se(memcmp(&scratch[7], &data[7], sizeof(uint64_t)) == 0);
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
test_be();
|
||||
test_le();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user