Skip to content

BitVecToBytes

Description

Export bitvector to byte array. Copies the internal bit representation to the provided byte array.

Parameters

Name Direction Description
bv in Bitvector to export
bytes out Byte array to write to (must be large enough)
max_len in Maximum bytes to write

Usage example (from documentation)

  u8 buffer[16];
  u64 written = BitVecToBytes(&flags, buffer, 16);

Success

Returns the number of bytes written into bytes, which is min(ceil(length / 8), max_len). The bitvector is not modified.

Failure

Returns 0 for an empty bitvector. LOG_FATAL when bytes is NULL or max_len is 0.

Usage example (Cross-references)

Usage examples (Cross-references)
    }
    
    u64 BitVecToBytes(BitVec *bv, u8 *bytes, u64 max_len) {
        ValidateBitVec(bv);
        if (!bytes) {
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        WriteFmt("Testing BitVecToBytes\n");
    
        BitVec bv = BitVecInit(ALLOCATOR_OF(&alloc));
    
        u8  bytes[2];           // Buffer for byte output
        u64 byte_count = BitVecToBytes(&bv, bytes, sizeof(bytes));
    
        // Check result
        // Test empty bitvec to bytes
        u8  bytes[1] = {0};
        u64 written  = BitVecToBytes(&bv, bytes, 1);
        result       = result && (written == 0); // Empty bitvec should write 0 bytes
            BitVec bv             = BitVecFromBytes(&test_bytes[i], 8, ALLOCATOR_OF(&alloc));
            u8     recovered_byte = 0;
            u64    written        = BitVecToBytes(&bv, &recovered_byte, 1);
    
            result = result && (written == 1);
    
        u8  empty_bytes[1] = {0xFF};
        u64 empty_written  = BitVecToBytes(&empty, empty_bytes, 1);
        result             = result && (empty_written == 0);
        result             = result && (empty_bytes[0] == 0xFF); // Should be unchanged
            // bytes the table records, not just the written count.
            u8  bytes[8] = {0};
            u64 written  = BitVecToBytes(&bv, bytes, 8);
            result       = result && (written == test_cases[i].byte_count);
            for (size b = 0; b < test_cases[i].byte_count; b++) {
        // Test byte conversion
        u8  large_bytes[125]; // 1000 bits = 125 bytes
        u64 written = BitVecToBytes(&large_bv, large_bytes, 125);
        result      = result && (written == 125);
        // Zero max_len is a contract violation - should abort.
        u8 small_buffer[1];
        BitVecToBytes(&bv, small_buffer, 0);
    
        BitVecDeinit(&bv);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        WriteFmt("Testing BitVecToBytes 4-bit pack does not over-read\n");
    
        BitVec bv = BitVecInit(ALLOCATOR_OF(&alloc));
    
        u8  bytes[1] = {0};
        u64 written  = BitVecToBytes(&bv, bytes, sizeof(bytes));
    
        bool result = (written == 1) && (bytes[0] == 0x0D);
        DefaultAllocator alloc = DefaultAllocatorInit();
    
        WriteFmt("Testing BitVecToBytes truncation respects max_len\n");
    
        BitVec bv = BitVecInit(ALLOCATOR_OF(&alloc));
    
        u8  bytes[2] = {0x00, 0xEE}; // sentinel in the byte beyond max_len
        u64 written  = BitVecToBytes(&bv, bytes, 1);
    
        // Real: one byte written, byte[1] untouched. 0xEE | 0x01 == 0xEF would
    // must abort, so removing the validator is a contract loss => DEADEND.
    bool test_tobytes_zeroed_bitvec_aborts(void) {
        WriteFmt("Testing BitVecToBytes aborts on an invalid (zeroed) bitvec\n");
    
        BitVec bv = {0}; // bad magic -> ValidateBitVec must abort
    
        // Real code aborts here; mutant returns 0 and we fall through.
        BitVecToBytes(&bv, bytes, sizeof(bytes));
    
        return false;
Last updated on