用于获取/设置bytearray中特定位的Java类

时间:2013-10-28 14:03:02

标签: java byte bytearray

我正在寻找一个可以修改bytearray中特定位的辅助类,其API类似于以下内容:

void Set(int startPos, int lengthInBits, int value) {
  // Set the bits starting at startPos to the binary representation of value
  // Error if the binary representation of value is too long (ie. exceeds lengthInBits)
}

目的是能够将任意长度的特定值放入bytearray中 - 某些值的长度小于一个字节,其他值更多,有些值将“跨越”字节。

我看过ByteBuffer,但这似乎有点过高,只能处理整个字节,并将int和short转换为多个字节,而不是让你选择它们的最大位数。

我也看了BitSet,但这次它看起来有点太低了,因为它只适用于单个位级别(尽管我可以将它作为构建具有上述排序的东西的起点) API)。

Stack Overflow上还有一个旧的somewhat similar question,主要与有符号/无符号位的使用有关,但图中所示的数据结构是我想要构建的东西(要发送给一个消息)外部客户端),我想隐藏尽可能多的位移复杂性。

2 个答案:

答案 0 :(得分:0)

这并不难。也许这可以帮助你作为一个起点:

ByteBuffer data;

int getBits(int bitOff, int bitSize)
{
  if(bitSize>32) throw new UnsupportedOperationException();
  final int mask= bitSize==32? -1: (1<<bitSize)-1;
  return (int)((data.getLong(bitOff>>>3) >>> (64-bitSize-(bitOff&7))) & mask);
}
void putBits(int bitOff, int bitSize, int intValue)
{
  final int byteOff=bitOff>>>3;
  bitOff -= byteOff<<3;
  final int shift = 64-bitSize-bitOff;
  long mask=Long.rotateLeft((-1L)<<bitSize, shift), lValue=intValue&0xffffffffL;
  data.putLong(byteOff, (lValue << shift) | (data.getLong(byteOff)&mask));
}

答案 1 :(得分:0)

您可以扩展java.util.BitSet,它已经处理了任意位数的存储。您需要添加的是批量获取/设置操作:

public class BulkBitSet extends BitSet {

    public void bulkSet(int offset, int count, int data) {
        int ptr = offset + count;
        for (int i=0; i<count; ++i) {
            set(--ptr, (data & (1 << i)) == 0 ? false : true);
        }
    }

    public int bulkGet(int offset, int count) {
        int result = 0;
        for (int i=0; i<count; ++i) {
            result <<= 1;
            if (get(offset + i))
                result |= 1;
        }
        return result;
    }

}