How do I map a C structure to bitfields in JNR?
I have the following structure that I want to map using JNR-FFI . Note that this structure contains bit fields. Unfortunately there is no JavaDoc or any other document available.
typedef struct _DCB {
DWORD DCBlength;
DWORD BaudRate;
DWORD fBinary :1;
DWORD fParity :1;
DWORD fOutxCtsFlow :1;
DWORD fOutxDsrFlow :1;
DWORD fDtrControl :2;
DWORD fDsrSensitivity :1;
DWORD fTXContinueOnXoff :1;
DWORD fOutX :1;
DWORD fInX :1;
DWORD fErrorChar :1;
DWORD fNull :1;
DWORD fRtsControl :2;
DWORD fAbortOnError :1;
DWORD fDummy2 :17;
WORD wReserved;
WORD XonLim;
WORD XoffLim;
BYTE ByteSize;
BYTE Parity;
BYTE StopBits;
char XonChar;
char XoffChar;
char ErrorChar;
char EofChar;
char EvtChar;
WORD wReserved1;
}
+3
source to share
1 answer
Just an alternative to the specified type. The byte order used to represent integers with windows is not significant.
class DCB extends Struct {
private static int get(NumberField field, int off, int bits) {
return field.intValue() >>> off & ~(~0 << bits);
}
private static void set(NumberField field, int off, int bits, int value) {
int mask = ~(~0 << bits) << off;
field.set(field.intValue() & ~mask | (value << off) & mask);
}
private static boolean getBoolean(NumberField field, int off) {
return get(field, off, 1) != 0;
}
private static void setBoolean(NumberField field, int off, boolean value) {
set(field, off, 1, value ? 1 : 0);
}
private final DWORD DCBlength = new DWORD();
private final DWORD BaudRate = new DWORD();
// fBinary fParity fOutxCtsFlow fOutxDsrFlow fDtrControl:2 fDsrSensitivity fTXContinueOnXoff
private final Unsigned8 fBinaryTofTXContinueOnXoff = new Unsigned8();
// fOutX fInX fErrorChar fNull fRtsControl:2 fAbortOnError fDummy2:17[0]
private final Unsigned8 fOutXTofDummy2 = new Unsigned8();
// fDummy2:17[1-16]
private final Unsigned16 restfDummy2 = new Unsigned16();
private final WORD wReserved = new WORD();
private final WORD XonLim = new WORD();
private final WORD XoffLim = new WORD();
private final BYTE ByteSize = new BYTE();
private final BYTE Parity = new BYTE();
private final BYTE StopBits = new BYTE();
private final Unsigned8 XonChar = new Unsigned8();
private final Unsigned8 XoffChar = new Unsigned8();
private final Unsigned8 ErrorChar = new Unsigned8();
private final Unsigned8 EofChar = new Unsigned8();
private final Unsigned8 EvtChar = new Unsigned8();
private final Unsigned16 wReserved1 = new Unsigned16();
public DCB(jnr.ffi.Runtime runtime) {
super(runtime);
}
public long getDCBlength() {
return DCBlength.get();
}
public void setDCBlength(long dcbLength) {
DCBlength.set(dcbLength);
}
public long getBaudRate() {
return BaudRate.get();
}
public void setBaudRate(long baudRate) {
DCBlength.set(baudRate);
}
public boolean getFBinary() {
return getBoolean(fBinaryTofTXContinueOnXoff, 0);
}
public void setFBinary(boolean x) {
setBoolean(fBinaryTofTXContinueOnXoff, 0, x);
}
public boolean getFParity() {
return getBoolean(fBinaryTofTXContinueOnXoff, 1);
}
public void setFParity(boolean x) {
setBoolean(fBinaryTofTXContinueOnXoff, 1, x);
}
public boolean getFOutxCtsFlow() {
return getBoolean(fBinaryTofTXContinueOnXoff, 2);
}
public void setFOutxCtsFlow(boolean x) {
setBoolean(fBinaryTofTXContinueOnXoff, 2, x);
}
public boolean getFOutxDsrFlow() {
return getBoolean(fBinaryTofTXContinueOnXoff, 3);
}
public void setFOutxDsrFlow(boolean x) {
setBoolean(fBinaryTofTXContinueOnXoff, 3, x);
}
public int getFDtrControl() {
return get(fBinaryTofTXContinueOnXoff, 4, 2);
}
public void setFDtrControl(int x) {
set(fBinaryTofTXContinueOnXoff, 4, 2, x);
}
public boolean getFDsrSensitivity() {
return getBoolean(fBinaryTofTXContinueOnXoff, 6);
}
public void setFDsrSensitivity(boolean x) {
setBoolean(fBinaryTofTXContinueOnXoff, 6, x);
}
public boolean getFTXContinueOnXoff() {
return getBoolean(fBinaryTofTXContinueOnXoff, 7);
}
public void setFTXContinueOnXoff(boolean x) {
setBoolean(fBinaryTofTXContinueOnXoff, 7, x);
}
public boolean getFOutX() {
return getBoolean(fOutXTofDummy2, 0);
}
public void setFOutX(boolean x) {
setBoolean(fOutXTofDummy2, 0, x);
}
public boolean getFInX() {
return getBoolean(fOutXTofDummy2, 1);
}
public void setFInX(boolean x) {
setBoolean(fOutXTofDummy2, 1, x);
}
public boolean getFErrorChar() {
return getBoolean(fOutXTofDummy2, 2);
}
public void setFErrorChar(boolean x) {
setBoolean(fOutXTofDummy2, 2, x);
}
public boolean getFNull() {
return getBoolean(fOutXTofDummy2, 3);
}
public void setFNull(boolean x) {
setBoolean(fOutXTofDummy2, 3, x);
}
public int getFRtsControl() {
return get(fOutXTofDummy2, 4, 2);
}
public void setFRtsControl(int x) {
set(fOutXTofDummy2, 4, 2, x);
}
public boolean getFAbortOnError() {
return getBoolean(fOutXTofDummy2, 6);
}
public void setFAbortOnError(boolean x) {
setBoolean(fOutXTofDummy2, 6, x);
}
public int getFDummy2() {
return restfDummy2.get() << 1 | get(fOutXTofDummy2, 7, 1);
}
public void setFDummy2(int x) {
set(fOutXTofDummy2, 7, 1, x);
restfDummy2.set(x >> 1);
}
// ......
}
0
source to share