How to pack a struct to a ubyte[] in a more "The D way" style ?
Binghoo Dang
dangbinghoo at gmail.com
Thu Dec 21 13:25:22 UTC 2017
hi Davis,
Thanks for your great help to me!
Yeah, the library may had a design principle when it was
designed, as you can see the buffer appender is not that suitable
for an application-defined structured data packing.
And after I turn to the bitfield, I then got another trouble:
The bitfield template only allows (8, 64) bits to be packed, so
in a real application, and obviously, in my application, the
packet is greater than 8 bytes.
So, the appender and bitfield are not practical for my situation.
And now, I realized that the problem what I have done is only
using bit-shift other than using direct cast operator.
In C, one can directly cast a struct to memory bytes, for D, the
struct can have methods, and the alignment is also more complex.
So, I think that handy packing and unpacking elements in a struct
to D array is just OK. And better than C, the D array is
autoincremented, this feature already makes the thing more
simpler to understand.
So, before I can write my own template for generating the packing
and unpacking code, I would just remove the bit shit.
Again, Thank you very much!
On Thursday, 21 December 2017 at 12:21:55 UTC, Jonathan M Davis
wrote:
> On Monday, December 18, 2017 08:45:32 Binghoo Dang via
> Digitalmars-d-learn wrote:
>> hi Davis,
>>
>> I read the std.bitmanip, and I tried to test the code like
>> below:
>>
>> ```
>> import std.stdio;
>> import std.array;
>> import std.bitmanip;
>> void main(string[] args)
>> {
>> align(1) struct c {
>> ushort c1;
>> uint c2;
>> //ubyte[8] c3;
>> }
>> ubyte[] buffer;
>> auto ap = appender(&buffer);
>> uint a = 0x11223344;
>> ushort b = 0x6677;
>> ap.append!uint(a);
>> ap.append!ushort(b);
>>
>> c cobj;
>> cobj.c1 = 0xEEFF;
>> cobj.c2 = 0xDEADBEAF;
>> //cobj.c3 = [0x12, 0x34, 0x56, 0x78];
>> ap.append(cobj);
>>
>> ubyte[3] d = [0xAA, 0xBB, 0xCC];
>> ap.append(d);
>>
>> foreach(e; buffer) {
>> writef("%02X ", e);
>> }
>> }
>> ```
>> For compiling this code, I got error like this
>>
>> > onlineapp.d(22): Error: template std.bitmanip.append cannot
>> > deduce function from >argument types
>> > !()(RefAppender!(ubyte[]),
>> >
>> > c), candidates are:
>> >/dlang/dmd/linux/bin64/../../src/phobos/std/bitmanip.d(3623):
>> > std.bitmanip.append(T, Endian endianness =
>> > Endian.bigEndian,
>> >
>> >R)(R range, T value) >if (canSwapEndianness!T &&
>> >isOutputRange!(R, ubyte))
>> >onlineapp.d(25): Error: template std.bitmanip.append cannot
>> >deduce function from >argument types
>> >!()(RefAppender!(ubyte[]),
>> >ubyte[3]), candidates are:
>> >
>> >/dlang/dmd/linux/bin64/../../src/phobos/std/bitmanip.d(3623):
>> > std.bitmanip.append(T, Endian endianness =
>> > Endian.bigEndian,
>> >
>> >R)(R range, T value) >if (canSwapEndianness!T &&
>> >isOutputRange!(R, ubyte))
>>
>> It seems that the appending is just allow using the
>> fundamental types like uint, ushort, it does not support
>> struct, and can't support dynamic array too. As the hardware
>> protocol is a dynamic-length style, so I also need to support
>> append array or another buffer directly.
>>
>> It seems that I can't get the point how to using the bitmanip
>> to do the packing I need, and also I have no idea what the
>> unpacking will look like.
>
> write, append, peek, and read all operate on integral types
> only. If you have an array of int or whatnot that you want to
> put into an array of ubyte, then just use a loop, and if you
> have a struct, then write or append each of the members
> individually. Those functions are for making it clean and easy
> to write integral types to an array or range of ubyte (or to
> read them back out again) while properly taking endianness into
> account, not for directly serializing objects.
>
> I really don't know what to tell you if the examples in the
> docs aren't enough to figure out how to use the functions,
> because if I were trying to show you how, I'd give very similar
> examples, and I don't know why the docs wouldn't be clear as
> they are or how they could be made clearer for you.
>
> - Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list