struct tans_bit_writer;
struct tans_bit_writer_ops {
- uint16_t (*write)(struct tans_bit_writer *self, uint16_t value, uint8_t bits);
+ uint16_t (*write)(struct tans_bit_writer *self, uint32_t value, uint8_t bits);
};
struct tans_bit_writer {
struct tans_buf_bit_reader *self = (struct tans_buf_bit_reader *) reader;
uint32_t bit = self->bit % 8;
uint32_t byte = self->bit / 8;
-
- if (bits == 0) {
- return 0;
- }
+ uint32_t value;
if (self->bit + bits > self->len * 8) {
return (uint16_t) -1;
self->bit += bits;
- if (bit + bits <= 8) {
- return (uint16_t) (((1 << bits) - 1) & (self->buf[byte] >> bit));
- } else if (bit + bits <= 16) {
- return (uint16_t) (((1 << bits) - 1) & ((self->buf[byte] | (self->buf[byte+1] << 8)) >> bit));
- } else if (bit + bits <= 24) {
- return (uint16_t) (((1 << bits) - 1) & ((self->buf[byte] | (self->buf[byte+1] << 8) | (self->buf[byte+2] << 16)) >> bit));
- } else {
- return (uint16_t) -1;
- }
+ value = self->buf[byte];
+ if (bit + bits > 8) value |= (uint32_t) self->buf[byte+1] << 8;
+ if (bit + bits > 16) value |= (uint32_t) self->buf[byte+2] << 16;
+ value >>= bit;
+ value &= (uint16_t) ((1 << bits) - 1);
+
+ return (uint16_t) value;
}
static const struct tans_bit_reader_ops vtable = {
#include "tans_buf_bit_writer.h"
-static uint16_t tans_buf_bit_writer_write(struct tans_bit_writer *writer, uint16_t value, uint8_t bits)
+static uint16_t tans_buf_bit_writer_write(struct tans_bit_writer *writer, uint32_t value, uint8_t bits)
{
struct tans_buf_bit_writer *self = (struct tans_buf_bit_writer *) writer;
uint32_t bit = self->bit % 8;
uint32_t byte = self->bit / 8;
- if (bits == 0) {
- return 0;
- }
-
if (self->bit + bits > self->len * 8) {
return (uint16_t) -1;
}
self->bit += bits;
- if (bit + bits <= 8) {
- self->buf[byte] |= (uint8_t) ((value & ((1 << bits) - 1)) << bit);
- return bits;
- } else if (bit + bits <= 16) {
- self->buf[byte] |= (uint8_t) ((value << bit) & 0xff);
- self->buf[byte+1] |= (uint8_t) ((value & ((1 << bits) - 1)) >> (8 - bit));
- return bits;
- } else if (bit + bits <= 24) {
- self->buf[byte] |= (uint8_t) ((value << bit) & 0xff);
- self->buf[byte+1] |= (uint8_t) ((value >> (8 - bit)) & 0xff);
- self->buf[byte+2] |= (uint8_t) ((value & ((1 << bits) - 1)) >> (16 - bit));
- return bits;
- } else {
- return (uint16_t) -1;
- }
+ value &= (uint16_t) ((1 << bits) - 1);
+ value <<= bit;
+ self->buf[byte] |= (uint8_t) value;
+ if (bit + bits > 8) self->buf[byte+1] |= (uint8_t) (value >> 8);
+ if (bit + bits > 16) self->buf[byte+2] |= (uint8_t) (value >> 16);
+
+ return bits;
}
static const struct tans_bit_writer_ops vtable = {