Add helper functions for reading binary numbers
And make use of them.
This commit is contained in:
parent
c5424e6992
commit
f32bcbd7f4
2
LICENSE
2
LICENSE
|
@ -1,4 +1,4 @@
|
||||||
Copyright (c) 2014 - 2023, Přemysl Eric Janouch <p@janouch.name>
|
Copyright (c) 2014 - 2024, Přemysl Eric Janouch <p@janouch.name>
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted.
|
purpose with or without fee is hereby granted.
|
||||||
|
|
76
liberty.c
76
liberty.c
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* liberty.c: the ultimate C unlibrary
|
* liberty.c: the ultimate C unlibrary
|
||||||
*
|
*
|
||||||
* Copyright (c) 2014 - 2022, Přemysl Eric Janouch <p@janouch.name>
|
* Copyright (c) 2014 - 2024, Přemysl Eric Janouch <p@janouch.name>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and/or distribute this software for any
|
* Permission to use, copy, modify, and/or distribute this software for any
|
||||||
* purpose with or without fee is hereby granted.
|
* purpose with or without fee is hereby granted.
|
||||||
|
@ -652,6 +652,60 @@ str_pack_u64 (struct str *self, uint64_t x)
|
||||||
#define str_pack_i32(self, x) str_pack_u32 ((self), (uint32_t) (x))
|
#define str_pack_i32(self, x) str_pack_u32 ((self), (uint32_t) (x))
|
||||||
#define str_pack_i64(self, x) str_pack_u64 ((self), (uint64_t) (x))
|
#define str_pack_i64(self, x) str_pack_u64 ((self), (uint64_t) (x))
|
||||||
|
|
||||||
|
// --- Reading binary numbers --------------------------------------------------
|
||||||
|
|
||||||
|
// Doing this byte by byte prevents unaligned memory access issues.
|
||||||
|
|
||||||
|
static uint64_t
|
||||||
|
peek_u64be (const uint8_t *p)
|
||||||
|
{
|
||||||
|
return (uint64_t) p[0] << 56 | (uint64_t) p[1] << 48
|
||||||
|
| (uint64_t) p[2] << 40 | (uint64_t) p[3] << 32
|
||||||
|
| (uint64_t) p[4] << 24 | (uint64_t) p[5] << 16 | p[6] << 8 | p[7];
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
peek_u32be (const uint8_t *p)
|
||||||
|
{
|
||||||
|
return (uint32_t) p[0] << 24 | (uint32_t) p[1] << 16 | p[2] << 8 | p[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t
|
||||||
|
peek_u16be (const uint8_t *p)
|
||||||
|
{
|
||||||
|
return (uint16_t) p[0] << 8 | p[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64_t
|
||||||
|
peek_u64le (const uint8_t *p)
|
||||||
|
{
|
||||||
|
return (uint64_t) p[7] << 56 | (uint64_t) p[6] << 48
|
||||||
|
| (uint64_t) p[5] << 40 | (uint64_t) p[4] << 32
|
||||||
|
| (uint64_t) p[3] << 24 | (uint64_t) p[2] << 16 | p[1] << 8 | p[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
peek_u32le (const uint8_t *p)
|
||||||
|
{
|
||||||
|
return (uint32_t) p[3] << 24 | (uint32_t) p[2] << 16 | p[1] << 8 | p[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t
|
||||||
|
peek_u16le (const uint8_t *p)
|
||||||
|
{
|
||||||
|
return (uint16_t) p[1] << 8 | p[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
struct peeker
|
||||||
|
{
|
||||||
|
uint64_t (*u64) (const uint8_t *);
|
||||||
|
uint32_t (*u32) (const uint8_t *);
|
||||||
|
uint16_t (*u16) (const uint8_t *);
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct peeker peeker_be = {peek_u64be, peek_u32be, peek_u16be};
|
||||||
|
static const struct peeker peeker_le = {peek_u64le, peek_u32le, peek_u16le};
|
||||||
|
|
||||||
// --- Errors ------------------------------------------------------------------
|
// --- Errors ------------------------------------------------------------------
|
||||||
|
|
||||||
// Error reporting utilities. Inspired by GError, only much simpler.
|
// Error reporting utilities. Inspired by GError, only much simpler.
|
||||||
|
@ -2503,12 +2557,7 @@ msg_reader_get (struct msg_reader *self, size_t *len)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
uint8_t *x = (uint8_t *) self->buf.str + self->offset;
|
uint8_t *x = (uint8_t *) self->buf.str + self->offset;
|
||||||
uint64_t msg_len
|
uint64_t msg_len = peek_u64be (x);
|
||||||
= (uint64_t) x[0] << 56 | (uint64_t) x[1] << 48
|
|
||||||
| (uint64_t) x[2] << 40 | (uint64_t) x[3] << 32
|
|
||||||
| (uint64_t) x[4] << 24 | (uint64_t) x[5] << 16
|
|
||||||
| (uint64_t) x[6] << 8 | (uint64_t) x[7];
|
|
||||||
|
|
||||||
if (msg_len < sizeof msg_len)
|
if (msg_len < sizeof msg_len)
|
||||||
{
|
{
|
||||||
// The message is shorter than its header
|
// The message is shorter than its header
|
||||||
|
@ -2573,8 +2622,7 @@ static bool
|
||||||
msg_unpacker_u16 (struct msg_unpacker *self, uint16_t *value)
|
msg_unpacker_u16 (struct msg_unpacker *self, uint16_t *value)
|
||||||
{
|
{
|
||||||
UNPACKER_INT_BEGIN
|
UNPACKER_INT_BEGIN
|
||||||
*value
|
*value = peek_u16be (x);
|
||||||
= (uint16_t) x[0] << 8 | (uint16_t) x[1];
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2582,9 +2630,7 @@ static bool
|
||||||
msg_unpacker_u32 (struct msg_unpacker *self, uint32_t *value)
|
msg_unpacker_u32 (struct msg_unpacker *self, uint32_t *value)
|
||||||
{
|
{
|
||||||
UNPACKER_INT_BEGIN
|
UNPACKER_INT_BEGIN
|
||||||
*value
|
*value = peek_u32be (x);
|
||||||
= (uint32_t) x[0] << 24 | (uint32_t) x[1] << 16
|
|
||||||
| (uint32_t) x[2] << 8 | (uint32_t) x[3];
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2592,11 +2638,7 @@ static bool
|
||||||
msg_unpacker_u64 (struct msg_unpacker *self, uint64_t *value)
|
msg_unpacker_u64 (struct msg_unpacker *self, uint64_t *value)
|
||||||
{
|
{
|
||||||
UNPACKER_INT_BEGIN
|
UNPACKER_INT_BEGIN
|
||||||
*value
|
*value = peek_u64be (x);
|
||||||
= (uint64_t) x[0] << 56 | (uint64_t) x[1] << 48
|
|
||||||
| (uint64_t) x[2] << 40 | (uint64_t) x[3] << 32
|
|
||||||
| (uint64_t) x[4] << 24 | (uint64_t) x[5] << 16
|
|
||||||
| (uint64_t) x[6] << 8 | (uint64_t) x[7];
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue