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







All Articles