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