Получить биты из ByteBuffer - PullRequest
0 голосов
/ 03 мая 2019

Я работаю над BitBuffer, который будет принимать x бит из ByteBuffer как int, long и т. Д., Но у меня, похоже, много проблем.

Я пытался загружать длинную за раз и использовать сдвиг битов, но трудность заключается в переходе от одной длинной к другой. Мне интересно, есть ли просто лучший способ. У кого-нибудь есть предложения?

public class BitBuffer 
{
    final private ByteBuffer bb;

    public BitBuffer(byte[] bytes) 
    {       
        this.bb = ByteBuffer.wrap(bytes);
    }

    public int takeInt(int bits) 
    {
        int bytes = toBytes(bits);
        if (bytes > 4) throw new RuntimeException("Too many bits requested");

        int i=0;
        // take bits from bb and fill it into an int
        return i;
    }
}

Более конкретно, я пытаюсь взять x битов из буфера и вернуть их как int (минимальный регистр). Я могу получить доступ к байту из буфера, но, скажем, я хочу использовать только первые 4 бита.

Пример:

Если мой буфер заполнен "101100001111", если я запускаю их по порядку:

takeInt(4) // should return 11    (1011)
takeInt(2) // should return 0     (00)
takeInt(2) // should return 0     (00)
takeInt(1) // should return 1     (1)
takeInt(3) // should return 7     (111)

Я хотел бы использовать что-то подобное для битовых кодированных данных, где целое число может храниться всего в нескольких битах байта.

Ответы [ 2 ]

0 голосов
/ 03 мая 2019

Идеями BitSet и ByteBuffer было слишком сложно управлять, поэтому вместо этого я выбрал подход с двоичными строками, который в основном избавляет от головной боли при управлении промежуточным буфером битов.

public class BitBuffer 
{
    final private String bin;
    private int start;

    public BitBuffer(byte[] bytes) 
    {       
        this.bin = toBinaryString(bytes); // TODO: create this function
        this.start = 0;
    }

    public int takeInt(int nbits) 
    {
        // TODO: handle edge cases
        String bits = bin.substring(start, start+=nbits);
        return Integer.parseInt(bits, 2);
    }
}

Из всего, что я пробовал, это был самый чистый и простой подход, но я открыт для предложений!

0 голосов
/ 03 мая 2019

Вы можете преобразовать ByteBuffer в BitSet, и тогда у вас будет непрерывный доступ к битам

public class BitBuffer 
{
    final private BitSet bs;

    public BitBuffer(byte[] bytes) 
    {       
        this.bs = BitSet.valueOf(bytes);
    }

    public int takeInt(int bits) 
    {
        int bytes = toBytes(bits);
        if (bytes > 4) throw new RuntimeException("Too many bits requested");

        int i=0;
        // take bits from bs and fill it into an int
        return i;
    }
}
...