digitalmars.D.learn - Converting C/C++ bit fields...
- Regan Heath (59/59) Aug 09 2005 I'd like to find out what techniques people have been using to convert
- Vathix (2/4) Aug 09 2005 How about masking and shifting DWORD bits
- Regan Heath (9/14) Aug 09 2005 Sure, but I want to be able to say:
- Ben Hinkle (33/36) Aug 09 2005 [snip]
- Burton Radons (18/61) Aug 09 2005 Clever boy. I'll need to remember that. I'd use the more general:
- Burton Radons (3/4) Aug 09 2005 That should be "const typeof (data) mask = (1UL << count) - 1;" so that
- Regan Heath (8/44) Aug 09 2005 Nice! Thanks.
- Ben Hinkle (7/11) Aug 09 2005 I haven't read the docs in detail but probably bit arrays have too much
- Regan Heath (10/24) Aug 09 2005 I think the problem with .h->.d translations is that there is no simple,...
I'd like to find out what techniques people have been using to convert C/C++ structs containing bitfields to D, take for example this struct: typedef struct _DCB { DWORD DCBlength; /* sizeof(DCB) */ DWORD BaudRate; /* Baudrate at which running */ DWORD fBinary: 1; /* Binary Mode (skip EOF check) */ DWORD fParity: 1; /* Enable parity checking */ DWORD fOutxCtsFlow:1; /* CTS handshaking on output */ DWORD fOutxDsrFlow:1; /* DSR handshaking on output */ DWORD fDtrControl:2; /* DTR Flow control */ DWORD fDsrSensitivity:1; /* DSR Sensitivity */ DWORD fTXContinueOnXoff: 1; /* Continue TX when Xoff sent */ DWORD fOutX: 1; /* Enable output X-ON/X-OFF */ DWORD fInX: 1; /* Enable input X-ON/X-OFF */ DWORD fErrorChar: 1; /* Enable Err Replacement */ DWORD fNull: 1; /* Enable Null stripping */ DWORD fRtsControl:2; /* Rts Flow control */ DWORD fAbortOnError:1; /* Abort all reads and writes on Error */ DWORD fDummy2:17; /* Reserved */ WORD wReserved; /* Not currently used */ WORD XonLim; /* Transmit X-ON threshold */ WORD XoffLim; /* Transmit X-OFF threshold */ BYTE ByteSize; /* Number of bits/byte, 4-8 */ BYTE Parity; /* 0-4=None,Odd,Even,Mark,Space */ BYTE StopBits; /* 0,1,2 = 1, 1.5, 2 */ char XonChar; /* Tx and Rx X-ON character */ char XoffChar; /* Tx and Rx X-OFF character */ char ErrorChar; /* Error replacement char */ char EofChar; /* End of Input character */ char EvtChar; /* Received Event character */ WORD wReserved1; /* Fill for now. */ } DCB, *LPDCB; My initial thought was to use bit, bit[2] and bit[17] but of course D allocates 1 byte for each stand alone 'bit' so the structure ends up totally the wrong size. Next I tried a bit[32] called _bits (this should make the struct size correct), and some aliases, eg. alias _bits[0] fBinary; but I get the error "_bits is used as a type". That is a little odd considering I can write "alias EvtChar bob" (is this using EvtChar as a type?) Lastly I tried to use properties, i.e. bit fBinary() { return _bits[0]; } bit fBinary(bit b) { _bits[0] = b; return fBinary; } these seem to work for the single bit ones, but the 2 bit ones: bit[2] fDtrControl() { return _bits[4..6]; } bit[2] fDtrControl(bit[2] b) { _bits[4..6] = b[]; return fDtrControl; } that's no good, you cannot return a 'static' bit[2]. I then tried: ubyte toUbyte(bit[] ba) { ubyte v = 0; foreach(bit b; ba) { v *= 2; v += b; } return v; } ubyte fDtrControl() { return toUbyte(_bits[4..6]); } ubyte fDtrControl(ubyte b) { _bits[4..6] = (cast(bit*)&b)[0..2]; return fDtrControl; } but that gives an array bounds error in the setter. I didn't investigate this any further, the effort required already is quite ridiculous, such that I figure there must or should be a better solution. Thoughts? Regan
Aug 09 2005
On Tue, 09 Aug 2005 07:54:16 -0400, Regan Heath <regan netwin.co.nz> wrote:I'd like to find out what techniques people have been using to convert C/C++ structs containing bitfields to DHow about masking and shifting DWORD bits
Aug 09 2005
On Tue, 09 Aug 2005 08:12:17 -0400, Vathix <chris dprogramming.com> wrote:On Tue, 09 Aug 2005 07:54:16 -0400, Regan Heath <regan netwin.co.nz> wrote:Sure, but I want to be able to say: DCB a; a.fParity = true; ..etc.. which I guess I can do, if I define a getter/setter for each one, and do all the bit shifting etc in them. All that effort/work.. seems like it _should_ be easier. ReganI'd like to find out what techniques people have been using to convert C/C++ structs containing bitfields to DHow about masking and shifting DWORD bits
Aug 09 2005
"Regan Heath" <regan netwin.co.nz> wrote in message news:opsu8ooqhn23k2f5 nrage.netwin.co.nz...I'd like to find out what techniques people have been using to convert C/C++ structs containing bitfields to D, take for example this struct:[snip]Thoughts?import std.intrinsic; // a bit field template BitField(uint n, alias data) { int get(){ return bt(&data,n); } void set(int m){m?bts(&data,n):btr(&data,n);} } // a two-bit field template BitField2(uint n, alias data) { int get(){ return data >> n & 3; } void set(int m){ data = (data & ~(3<<n)) | (m<<n) ;} } struct Foo { uint fields; mixin BitField!(0,fields) f1; mixin BitField!(1,fields) f2; mixin BitField2!(2,fields) f3; mixin BitField!(4,fields) f4; } int main() { Foo x; x.f1.set = true; x.f3.set = 3; x.f4.set = true; printf("fields: %d\n",x.fields); printf("x.f1 %d\n", x.f1.get); printf("x.f2 %d\n", x.f2.get); printf("x.f3 %d\n", x.f3.get); printf("x.f4 %d\n", x.f4.get); return 0; }
Aug 09 2005
Ben Hinkle wrote:"Regan Heath" <regan netwin.co.nz> wrote in message news:opsu8ooqhn23k2f5 nrage.netwin.co.nz...Clever boy. I'll need to remember that. I'd use the more general: template BitField (uint start, uint count, alias data, type = uint) { static assert ((1L << (start + count)) - 1 <= data.max); const uint mask = (1 << count) - 1; type get () { return cast (type) ((data >> start) & mask); } type set (type value) { data = (data & ~(mask << start)) | ((cast (typeof (data)) value & mask) << start); return value; } } Too bad opCall doesn't work with mixins.I'd like to find out what techniques people have been using to convert C/C++ structs containing bitfields to D, take for example this struct:[snip]Thoughts?import std.intrinsic; // a bit field template BitField(uint n, alias data) { int get(){ return bt(&data,n); } void set(int m){m?bts(&data,n):btr(&data,n);} } // a two-bit field template BitField2(uint n, alias data) { int get(){ return data >> n & 3; } void set(int m){ data = (data & ~(3<<n)) | (m<<n) ;} } struct Foo { uint fields; mixin BitField!(0,fields) f1; mixin BitField!(1,fields) f2; mixin BitField2!(2,fields) f3; mixin BitField!(4,fields) f4; } int main() { Foo x; x.f1.set = true; x.f3.set = 3; x.f4.set = true; printf("fields: %d\n",x.fields); printf("x.f1 %d\n", x.f1.get); printf("x.f2 %d\n", x.f2.get); printf("x.f3 %d\n", x.f3.get); printf("x.f4 %d\n", x.f4.get); return 0; }
Aug 09 2005
Burton Radons wrote:const uint mask = (1 << count) - 1;That should be "const typeof (data) mask = (1UL << count) - 1;" so that it works with long.
Aug 09 2005
Nice! Thanks. Still, it would be nice if D had a better way to handle bitfields, if only to ease conversion of C/C++ structs containing them. The fact that we're not using the built in bit support suggests to me that it's not as useful as it should be. Regan On Tue, 9 Aug 2005 10:25:44 -0400, Ben Hinkle <bhinkle mathworks.com> wrote:"Regan Heath" <regan netwin.co.nz> wrote in message news:opsu8ooqhn23k2f5 nrage.netwin.co.nz...I'd like to find out what techniques people have been using to convert C/C++ structs containing bitfields to D, take for example this struct:[snip]Thoughts?import std.intrinsic; // a bit field template BitField(uint n, alias data) { int get(){ return bt(&data,n); } void set(int m){m?bts(&data,n):btr(&data,n);} } // a two-bit field template BitField2(uint n, alias data) { int get(){ return data >> n & 3; } void set(int m){ data = (data & ~(3<<n)) | (m<<n) ;} } struct Foo { uint fields; mixin BitField!(0,fields) f1; mixin BitField!(1,fields) f2; mixin BitField2!(2,fields) f3; mixin BitField!(4,fields) f4; } int main() { Foo x; x.f1.set = true; x.f3.set = 3; x.f4.set = true; printf("fields: %d\n",x.fields); printf("x.f1 %d\n", x.f1.get); printf("x.f2 %d\n", x.f2.get); printf("x.f3 %d\n", x.f3.get); printf("x.f4 %d\n", x.f4.get); return 0; }
Aug 09 2005
Still, it would be nice if D had a better way to handle bitfields, if only to ease conversion of C/C++ structs containing them. The fact that we're not using the built in bit support suggests to me that it's not as useful as it should be.I haven't read the docs in detail but probably bit arrays have too much freedom in how they are implemented to be reliable for replacing C bit fields. ie- the packing and alignment become crucial and that's something that the shifting implementation can control (since they have to control it). To me the only problem with bitfields is that the auto .h->.d translator (I can't remember the name of the program) seems to ignore them so any struct with a bitfield gets hosed (without warning, I believe).
Aug 09 2005
On Tue, 9 Aug 2005 19:07:53 -0400, Ben Hinkle <ben.hinkle gmail.com> wrote:I think the problem with .h->.d translations is that there is no simple, easy way to translate bitfields. Why can't I use: bit[32] data; alias data[0] a; alias data[1] b; alias data[2] c; ..etc..? ReganStill, it would be nice if D had a better way to handle bitfields, if only to ease conversion of C/C++ structs containing them. The fact that we're not using the built in bit support suggests to me that it's not as useful as it should be.I haven't read the docs in detail but probably bit arrays have too much freedom in how they are implemented to be reliable for replacing C bit fields. ie- the packing and alignment become crucial and that's something that the shifting implementation can control (since they have to control it). To me the only problem with bitfields is that the auto .h->.d translator (I can't remember the name of the program) seems to ignore them so any struct with a bitfield gets hosed (without warning, I believe).
Aug 09 2005