Blame buffer.c

9953f6
9953f6
#include "buffer.h"
9953f6
9953f6
#include <assert.h></assert.h>
9953f6
9953f6
9953f6
// read
9953f6
9953f6
int buf_read_bits(Buffer *b, Word *word, Bits bits) {
9953f6
    assert(b);
9953f6
    if (!bits) return 1;
9953f6
    TinySize remain = b->end - b->cur;
9953f6
    if (remain*8 - bits < bits || bits > 32 || !*word) return 0;
9953f6
9953f6
    Word w;
9953f6
    Byte *c = b->cur;
9953f6
    Bits bb = b->bits;
9953f6
    if (bb) {
9953f6
        assert(bb < 8);
9953f6
        w = ( ((Code)c[0]) << (bb+24) );
9953f6
        if (remain > 4) {
9953f6
            w |= ( ((Code)c[1]) << (bb+16) );
9953f6
            w |= ( ((Code)c[2]) << (bb+8)  );
9953f6
            w |= ( ((Code)c[3]) <<  bb     );
9953f6
            w |= ( ((Code)c[4]) >> (8-bb)  );
9953f6
        } else {
9953f6
            if (remain > 1) w |= ( ((Code)c[1]) << (bb+16) );
9953f6
            if (remain > 2) w |= ( ((Code)c[2]) << (bb+8)  );
9953f6
            if (remain > 3) w |= ( ((Code)c[3]) <<  bb     );
9953f6
        }
9953f6
    } else {
9953f6
        w = ( ((Code)c[0]) << 24 );
9953f6
        if (remain > 3) {
9953f6
            w |= ( ((Code)c[1]) << 16 );
9953f6
            w |= ( ((Code)c[2]) << 8  );
9953f6
            w |= ( ((Code)c[3])       );
9953f6
        } else {
9953f6
            if (remain > 1) w |= ( ((Code)c[1]) << 16 );
9953f6
            if (remain > 2) w |= ( ((Code)c[2]) << 8  );
9953f6
        }
9953f6
    }
9953f6
9953f6
    bb += bits;
9953f6
    b->cur += bb >> 3;
9953f6
    b->bits = bb & 0x7;
9953f6
9953f6
    *word = w >> (32 - bits);
9953f6
    return 1;
9953f6
}
9953f6
9953f6
9953f6
void buf_read_pad(Buffer *b) {
9953f6
    if (b->bits) {
9953f6
        assert(b->cur < b->end);
9953f6
        assert(b->bits < 8);
9953f6
        ++*b->cur;
9953f6
        b->bits = 0;
9953f6
    }
9953f6
}
9953f6
9953f6
9953f6
int buf_read_byte(Buffer *b, Byte *byte) {
9953f6
    if (b->bits) buf_read_pad(b);
9953f6
    if (b->cur >= b->end || !*byte) return 0;
9953f6
    *byte = *b->cur++;
9953f6
    return 1;
9953f6
}
9953f6
9953f6
9953f6
9953f6
// write
9953f6
9953f6
int buf_write_bits(Buffer *b, Word word, Bits bits) {
9953f6
    assert(b);
9953f6
    if (!bits) return 1;
9953f6
    if (b->end - b->cur < 5 || bits > 32) return 0;
9953f6
9953f6
    word <<= 32 - bits;
9953f6
9953f6
    Byte *c = b->cur;
9953f6
    Bits bb = b->bits;
9953f6
    if (bb) {
9953f6
        assert(bb < 8);
9953f6
        c[0] = (c[0] << (8-bb)) | (word >> (bb+24));
9953f6
        c[1] = word >> (bb+16);
9953f6
        c[2] = word >> (bb+8);
9953f6
        c[3] = word >> bb;
9953f6
        c[4] = word;
9953f6
    } else {
9953f6
        c[0] = word >> 24;
9953f6
        c[1] = word >> 16;
9953f6
        c[2] = word >> 8;
9953f6
        c[3] = word;
9953f6
    }
9953f6
9953f6
    bb += bits;
9953f6
    b->cur += bb >> 3;
9953f6
    b->bits = bb & 0x7;
9953f6
9953f6
    return 1;
9953f6
}
9953f6
9953f6
9953f6
void buf_write_pad(Buffer *b) {
9953f6
    if (b->bits) {
9953f6
        assert(b->cur < b->end);
9953f6
        assert(b->bits < 8);
9953f6
        *b->cur <<= 8 - b->bits;
9953f6
        ++*b->cur;
9953f6
        b->bits = 0;
9953f6
    }
9953f6
}
9953f6
9953f6
9953f6
int buf_write_byte(Buffer *b, Byte byte) {
9953f6
    if (b->bits) buf_write_pad(b);
9953f6
    if (b->cur >= b->end) return 0;
9953f6
    *b->cur++ = byte;
9953f6
    return 1;
9953f6
}
9953f6