Converting a ubyte[] to a struct with respect to endianness?

Ali Çehreli via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Jun 23 23:06:56 PDT 2017


On 06/23/2017 10:18 PM, H. S. Teoh via Digitalmars-d-learn wrote:
> On Fri, Jun 23, 2017 at 10:10:22PM -0700, Ali Çehreli via Digitalmars-d-learn wrote:
>> On 06/23/2017 09:26 PM, Felix wrote:
>>> That works, thanks!
>>
>> I've just tried this, which seems cleaner:
>>
>> import std.stdio;
>> import std.system;
>> import std.bitmanip;
>>
>> void ensureBigEndian(T)(ref T value) {
>>     if (endian == Endian.littleEndian) {
>>         value = *cast(T*)nativeToBigEndian(value).ptr;
>>     }
>
> This is wrong, you should be detecting the endianness of the input and
> use {big,little}EndianToNative instead.  For example, if the input is
> big endian, you should use bigEndianToNative.  Internally, if native is
> already big endian, it will do nothing; otherwise it will swap the
> endianness. This way you don't have to check the current machine's
> endianness yourself; you can just recompile on a machine of different
> endianness and it will Just Work.
>
>
> T
>

Thanks. Something like this:

import std.stdio;
import std.system;
import std.bitmanip;

void ensureCorrectFromBigEndian(T)(ref T value) {
     value = bigEndianToNative!(T, T.sizeof)(*cast(ubyte[T.sizeof]*)&value);
}

struct S {
     uint u;
}

void main() {
     // Bytes on the wire
     ubyte[] bytes = [ 0, 0, 0, 13 ];

     // Overlaying an object on those bytes
     S s = *cast(S*)bytes.ptr;

     void checkValue(uint expectedOnLE, uint expectedOnBE) {
         if (endian == Endian.littleEndian) {
             assert(s.u == expectedOnLE);
         } else if (endian == Endian.bigEndian) {
             assert(s.u == expectedOnBE);
         } else {
             assert(false, "What is this?");
         }
     }

     // The value should be wrong no a little-endian system
     checkValue(218103808, 13);

     s.u.ensureCorrectFromBigEndian;

     // No matter what, now the result will be correct on any system
     checkValue(13, 13);
}

Ali



More information about the Digitalmars-d-learn mailing list