static int encode_write_bit_pattern()

in source/huffman.c [59:105]


static int encode_write_bit_pattern(struct encoder_state *state, struct aws_huffman_code bit_pattern) {
    AWS_PRECONDITION(state->output_buf->len < state->output_buf->capacity);

    if (bit_pattern.num_bits == 0) {
        return aws_raise_error(AWS_ERROR_COMPRESSION_UNKNOWN_SYMBOL);
    }

    uint8_t bits_to_write = bit_pattern.num_bits;
    while (bits_to_write > 0) {
        uint8_t bits_for_current = bits_to_write > state->bit_pos ? state->bit_pos : bits_to_write;
        /* Chop off the top 0s and bits that have already been read */
        uint8_t bits_to_cut =
            (BITSIZEOF(bit_pattern.pattern) - bit_pattern.num_bits) + (bit_pattern.num_bits - bits_to_write);

        /* Write the appropiate number of bits to this byte
            Shift to the left to cut any unneeded bits
            Shift to the right to position the bits correctly */
        state->working |= (bit_pattern.pattern << bits_to_cut) >> (MAX_PATTERN_BITS - state->bit_pos);

        bits_to_write -= bits_for_current;
        state->bit_pos -= bits_for_current;

        if (state->bit_pos == 0) {
            /* Save the whole byte */
            aws_byte_buf_write_u8(state->output_buf, state->working);

            state->bit_pos = 8;
            state->working = 0;

            if (state->output_buf->len == state->output_buf->capacity) {
                state->encoder->overflow_bits.num_bits = bits_to_write;

                if (bits_to_write) {
                    /* If buffer is full and there are remaining bits, save them to overflow and return */
                    bits_to_cut += bits_for_current;

                    state->encoder->overflow_bits.pattern =
                        (bit_pattern.pattern << bits_to_cut) >> (MAX_PATTERN_BITS - bits_to_write);

                    return aws_raise_error(AWS_ERROR_SHORT_BUFFER);
                }
            }
        }
    }

    return AWS_OP_SUCCESS;
}