在Java中实现C风格的位域

sha*_*dog 7 java bitset bit-fields

我有一个问题,我有点困惑,一位同事告诉我,这将是一个寻求帮助的好地方.

我试图在Java中实现C风格的位域.这是一个粗略的例子(此时我没有在我面前的实际代码).

typedef union
{
  typedef struct
  {
     unsigned short a :1;
     unsigned short b :1;
     unsigned short c :2;
     unsigned short d :10;
  } bitfield;

  unsigned short bitmap;
}example_bitfield;
Run Code Online (Sandbox Code Playgroud)

遗留代码中我有一些类似的样式位域.我需要为Java提供等效方法的原因是我正在研究将使用Java与使用UDP的其他遗留应用程序进行通信的代码.

我没有重写代码的选项.我知道这种方法不可移植,有字节序问题(和填充/对齐等),如果我能够重写代码,可以做得更好.不幸的是,我需要回答这个非常具体的问题.系统已关闭,因此我不需要担心编译器/操作系统等每一种可能的组合.

使用Java EnumSet的方法不起作用,因为我认为只允许每个值为一位.我需要能够打包值,例如占用10位的d值.

我知道Java Bitset但它有局限性.我使用的是旧版本的Java,因此我没有一些较新的Java Bitset方法(即可能肯定有帮助的valueOf方法).

有没有人有任何关于如何使这个尽可能易于管理的想法?我有超过10个位域需要为我的通信实现.

感谢您提供任何帮助!

Ale*_*dov 7

由于 UDP 只接受字节数组,您可以以任何合适的方式声明 Java 类,唯一关键的步骤是定义其序列化和反序列化方法:

class example_bitfield {
  byte a;
  byte b;
  byte c;
  short d;

  public void fromArray(byte[] m) {
    byte b0=m[0];
    byte b1=m[1];
    a=b0>>>7;
    b=(b0>>6)&1;
    c=(b0>>4)&3;
    d=(b0&0xF<<6)|(b1>>>2);
  }
  public void toArray(byte[] m) {
    m[0]=(a<<7)|(b<<6)|(c<<4)|(d>>>6);
    m[1]=(d&0x3F)<<2;
  }
}
Run Code Online (Sandbox Code Playgroud)


小智 5

Javolution 库中的类 Struct 可以满足您的需求(http://www.javolution.org/apidocs/index.html?javolution/io/Struct.html)参见“时钟”示例:

 import java.nio.ByteBuffer;
 class Clock extends Struct { // Hardware clock mapped to memory.
     Unsigned16 seconds  = new Unsigned16(5); // unsigned short seconds:5
     Unsigned16 minutes  = new Unsigned16(5); // unsigned short minutes:5
     Unsigned16 hours    = new Unsigned16(4); // unsigned short hours:4
     Clock() {
         setByteBuffer(Clock.nativeBuffer(), 0);
     }
     private static native ByteBuffer nativeBuffer();
 }
Run Code Online (Sandbox Code Playgroud)