Mstdlib-1.24.0
Bitwise Buffered Data Builder

Typedefs

typedef struct M_bit_buf M_bit_buf_t
 

Enumerations

enum  M_bit_buf_pad_t {
  M_BIT_BUF_PAD_NONE = 0 ,
  M_BIT_BUF_PAD_BEFORE ,
  M_BIT_BUF_PAD_AFTER
}
 

Functions

M_bit_buf_tM_bit_buf_create (void) M_WARN_UNUSED_RESULT M_MALLOC
 
void M_bit_buf_destroy (M_bit_buf_t *bbuf) M_FREE(1)
 
M_uint8 * M_bit_buf_finish (M_bit_buf_t *bbuf, size_t *nbytes) M_FREE(1) M_WARN_UNUSED_RESULT M_MALLOC
 
M_buf_tM_bit_buf_finish_buf (M_bit_buf_t *bbuf) M_FREE(1) M_WARN_UNUSED_RESULT M_MALLOC
 
size_t M_bit_buf_len (const M_bit_buf_t *bbuf)
 
size_t M_bit_buf_len_bytes (const M_bit_buf_t *bbuf)
 
const M_uint8 * M_bit_buf_peek (const M_bit_buf_t *bbuf)
 
void M_bit_buf_truncate (M_bit_buf_t *bbuf, size_t len_bits)
 
void M_bit_buf_fill (M_bit_buf_t *bbuf, M_uint8 bit, size_t len_bits)
 
void M_bit_buf_add_bit (M_bit_buf_t *bbuf, M_uint8 bit)
 
void M_bit_buf_set_bit (M_bit_buf_t *bbuf, M_uint8 bit, size_t bit_idx, M_uint8 fill_bit)
 
M_bool M_bit_buf_update_bit (M_bit_buf_t *bbuf, size_t bit_idx, M_uint8 bit)
 
void M_bit_buf_add_bytes (M_bit_buf_t *bbuf, const void *bytes, size_t nbits)
 
void M_bit_buf_add (M_bit_buf_t *bbuf, M_uint64 bits, size_t nbits, M_bit_buf_pad_t pad)
 
M_bool M_bit_buf_add_bitstr (M_bit_buf_t *bbuf, const char *bitstr, M_bit_buf_pad_t pad)
 
void M_bit_buf_reserve (M_bit_buf_t *bbuf, size_t nbits)
 

Detailed Description

Allows for buffered writing of data that's organized per-bit, instead of per-byte.

Also allows for changing bits that were previously added to the buffer (see M_bit_buf_update_bit()). This allows for random-access setting of individual bits. For example, if you're generating a bit-level image, you can fill the buffer with zero bits, and then set individual bits afterwards in whatever order you wish.

When you're done adding data, the contents of the buffer can be output as a continuous byte-array, either raw as an (M_uint8 *), or inside a regular per-byte M_buf_t.

Example (creating a buffer, adding data, finishing the buffer):

M_uint8 *out;
size_t out_nbytes;
M_bit_buf_add(bbuf, 0xA2C4, 14); // adds least-significant 14 bits of 0xA2C4
M_bit_buf_add_bitstr(bbuf, "100010000"); // adds 9 bits from binary-ASCII
out = M_bit_buf_finish(bbuf, &out_nbytes);
// out now points to a byte buffer containing 3 bytes. Now can output to disk, do further processing, etc.
M_free(out);
struct M_bit_buf M_bit_buf_t
Definition: m_bit_buf.h:72
M_bool M_bit_buf_add_bitstr(M_bit_buf_t *bbuf, const char *bitstr, M_bit_buf_pad_t pad)
void M_bit_buf_add(M_bit_buf_t *bbuf, M_uint64 bits, size_t nbits, M_bit_buf_pad_t pad)
M_bit_buf_t * M_bit_buf_create(void) M_WARN_UNUSED_RESULT M_MALLOC
M_uint8 * M_bit_buf_finish(M_bit_buf_t *bbuf, size_t *nbytes) M_FREE(1) M_WARN_UNUSED_RESULT M_MALLOC
void M_bit_buf_add_bit(M_bit_buf_t *bbuf, M_uint8 bit)
void M_free(void *ptr) M_FREE(1)

Typedef Documentation

◆ M_bit_buf_t

typedef struct M_bit_buf M_bit_buf_t

Enumeration Type Documentation

◆ M_bit_buf_pad_t

Enumeration for byte-alignment padding mode for M_bit_buf_add().

Enumerator
M_BIT_BUF_PAD_NONE 

Don't add any padding.

M_BIT_BUF_PAD_BEFORE 

Pad with zero bits before new value, so that bit stream after add is byte-aligned

M_BIT_BUF_PAD_AFTER 

Pad with zero bits after new value, so that bit stream after add is byte-aligned

Function Documentation

◆ M_bit_buf_create()

M_bit_buf_t * M_bit_buf_create ( void  )

Create a new bit buffer.

Returns
allocated buffer.
See also
M_bit_buf_destroy
M_bit_buf_finish
M_bit_buf_finish_buf

◆ M_bit_buf_destroy()

void M_bit_buf_destroy ( M_bit_buf_t bbuf)

Free a bit buffer, discarding its data.

Parameters
[in]bbufbit buffer to destroy

◆ M_bit_buf_finish()

M_uint8 * M_bit_buf_finish ( M_bit_buf_t bbuf,
size_t *  nbytes 
)

Free a buffer, saving its data.

The caller is responsible for freeing the data.

Parameters
[in]bbufBit buffer
[out]nbytesData length (in bytes)
Returns
The buffered data.
See also
M_free

◆ M_bit_buf_finish_buf()

M_buf_t * M_bit_buf_finish_buf ( M_bit_buf_t bbuf)

Free a buffer, saving its data in a per-byte buffer.

The caller is responsible for freeing the data.

Parameters
[in]bbufBit buffer
Returns
The buffered data.
See also
M_free

◆ M_bit_buf_len()

size_t M_bit_buf_len ( const M_bit_buf_t bbuf)

Return the length of the data held by a buffer, in bits.

Parameters
[in]bbufBit buffer
Returns
Data length (in bits)

◆ M_bit_buf_len_bytes()

size_t M_bit_buf_len_bytes ( const M_bit_buf_t bbuf)

Return the length of the data held by a buffer, in bytes.

Partial bytes will be rounded up (i.e., 9 bits stored == 2 bytes).

Parameters
[in]bbufBit buffer
Returns
Data length (in bytes)

◆ M_bit_buf_peek()

const M_uint8 * M_bit_buf_peek ( const M_bit_buf_t bbuf)

Return pointer to internal buffer data.

The internal data is stored as an array of bytes. The first bit in the buffer is always guaranteed to be the highest bit in the first byte, second bit in the buffer is the next highest bit, and so on. The implementation guarantees this will always be the case, regardless of what operations you may have done on the bit buffer.

Warning
The returned pointer may be invalidated when you add data to the buffer. For safety, it should be used immediately after you call M_bit_buf_peek(), and then discarded.
Parameters
[in]bbufBit buffer
Returns
pointer to current internal buffer data

◆ M_bit_buf_truncate()

void M_bit_buf_truncate ( M_bit_buf_t bbuf,
size_t  len_bits 
)

Truncate the length of the data to the specified size (in bits).

Removes data from the end of the buffer.

Parameters
[in,out]bbufBit buffer
[in]len_bitsLength (in bits) to truncate buffer to

◆ M_bit_buf_fill()

void M_bit_buf_fill ( M_bit_buf_t bbuf,
M_uint8  bit,
size_t  len_bits 
)

Add a number of repetitions of the same bit to the buffer.

Parameters
[in,out]bbufBit buffer
[in]bit1 (to add a set bit) or 0 (to add an unset bit)
[in]len_bitsNumber of bits to add

◆ M_bit_buf_add_bit()

void M_bit_buf_add_bit ( M_bit_buf_t bbuf,
M_uint8  bit 
)

Add the given bit to the buffer.

Parameters
[in,out]bbufBit buffer
[in]bit1 (to add a set bit) or 0 (to add an unset bit)

◆ M_bit_buf_set_bit()

void M_bit_buf_set_bit ( M_bit_buf_t bbuf,
M_uint8  bit,
size_t  bit_idx,
M_uint8  fill_bit 
)

Add given bit at given location in buffer, filling in gaps as necessary.

If the requested bit_idx has already been set in the buffer, this function will simply update it to the requested value.

If the requested bit_idx hasn't already been set, the size of the buffer will be increased up to the requested bit_idx, and then that bit will be set. Any new bits that had to be added before the requested bit_idx will be set to the value of 'fill_bit'.

If you only want to update bits that have already been set, use M_bit_buf_update_bit().

Usage example:

M_bit_buf_add_bitstr(bbuf, "101"); // bit buf contains "101"
M_bit_buf_set_bit(bbuf, 1, 5, 0); // bit buf now contains "101001" (idx 3 and 4 get 'fill_bit', 5 gets 'bit')
void M_bit_buf_set_bit(M_bit_buf_t *bbuf, M_uint8 bit, size_t bit_idx, M_uint8 fill_bit)
See also
M_bit_buf_update_bit

◆ M_bit_buf_update_bit()

M_bool M_bit_buf_update_bit ( M_bit_buf_t bbuf,
size_t  bit_idx,
M_uint8  bit 
)

Change one of the bits already in the buffer.

This function is guaranteed to never change the length of the bit stream - it will only update bits that are already present. If you want to add a bit past the end of the stream, and automatically fill any bits between the old end of the stream and the new bit, use M_bit_buf_set_bit().

See also
M_bit_buf_set_bit
Parameters
[in]bbufBit buffer
[in]bit_idxindex of bit to change, must be less than M_bit_buf_len()
[in]bit1 to set the bit, 0 to unset it
Returns
M_TRUE on success, M_FALSE if requested bit index too large (not in buffer yet)

◆ M_bit_buf_add_bytes()

void M_bit_buf_add_bytes ( M_bit_buf_t bbuf,
const void *  bytes,
size_t  nbits 
)

Add bits from the given variable-length chunk of data.

Parameters
[in,out]bbufBit buffer
[in]bytesdata to add
[in]nbitsnumber of bits to add from the given data

◆ M_bit_buf_add()

void M_bit_buf_add ( M_bit_buf_t bbuf,
M_uint64  bits,
size_t  nbits,
M_bit_buf_pad_t  pad 
)

Add bits from a given integer to the buffer.

Note that the bit region being read is assumed to be justified against the least-significant end of the integer, though the bits within that region are read from most-significant to least-significant.

For example, if bits == 0x8B == (10001011)b, and nbits == 4, the bits "1011" will be added to the buffer.

Parameters
[in,out]bbufBit buffer
[in]bitsValue to draw bits from
[in]nbitsNumber of bits to use (counted from least-significant end, right-to-left)
[in]padShould any bits be added to force the result to end on a byte-boundary

◆ M_bit_buf_add_bitstr()

M_bool M_bit_buf_add_bitstr ( M_bit_buf_t bbuf,
const char *  bitstr,
M_bit_buf_pad_t  pad 
)

Add bits from a given binary-ascii string to the buffer.

A binary-ascii string is a list of 1 and 0 characters (e.g., "100010").

Any whitespace in the string will be silently ignored. So, " 1000 1 0" will add the same data as "100010".

Parameters
[in,out]bbufBit buffer
[in]bitstrString to draw bits from
[in]padShould any bits be added to force the result to end on a byte-boundary
Returns
M_FALSE on error (given bitstr had characters other than '0', '1', or whitespace).

◆ M_bit_buf_reserve()

void M_bit_buf_reserve ( M_bit_buf_t bbuf,
size_t  nbits 
)

Provide hint to buffer about how many bits we're going to add.

If you know ahead of time how many bits are going to get added to the buffer, you can use this function to grow the buffer all at once ahead of time, instead of on-demand as the buffer runs out of internal space.

This is provided purely as a performance hint.

Parameters
bbufBit buffer
nbitsNumber of bits that we expect to add in the future