On Friday, 22 May 2015 at 19:10:41 UTC, H. S. Teoh wrote:
In the spirit of forum bickering, ;-) I stumbled upon this D
wart today:
I'm reading some data from a file into a ubyte[] buffer, and I
want to
use bigEndianToNative to convert ushort values in the file data
into
native byte order (whatever the native order might be).
Sounds simple, right? Unfortunately, bigEndianToNative asks for
ubyte[n]
as input. Meaning, this doesn't work:
ubyte[] buf = ... /* allocate buffer here */;
file.rawRead(buf); // Read the data
ushort myValue = bigEndianToNative!ushort(buf[4 .. 8]); // NG
The last line doesn't compile, 'cos you can't convert a slice
of ubyte[]
into ubyte[4].
I can think of no easy way to declare a temporary ubyte[4] to
make
bigEndianToNative happy, other than this silly verbosity:
ubyte[4] tmp;
tmp[] = buf[4 .. 8];
ushort myValue = bigEndianToNative!ushort(tmp);
and I have to do this for every single numerical field in the
data
buffer that I need to convert. :-( Why should I copy data
around that's
already sitting in a ubyte[] buffer intended precisely for the
purpose
of doing such conversions in the first place??
The docs for bigEndianToNative claims that this is to help
"prevent
accidentally using a swapped value as a regular one". But I
say, "Why,
oh why???" :-(
This is a very anti-user kind of API. How did we think such a
straitjacketed API was a good idea in the first place?!
Isn't the problem that you're trying to convert to a ushort, and
a ushort is _2_ bytes, not 4? If you sliced it correctly, it
would compile. For instance, this code compiles just fine for me
with dmd master:
void main()
{
import std.bitmanip;
auto buf = new ubyte[](32);
auto result = bigEndianToNative!ushort(buf[0 .. 2]);
}
But if I change it to buf[0 .. 4], then it fails to compile. So,
the fact that bigEndianToNative is taking a static array is
actually catching a bug for you.
- Jonathan M Davis