diff --git a/compiler/src/dmd/dinterpret.d b/compiler/src/dmd/dinterpret.d index 2ce639f0dd..5ca13ec36b 100644 --- a/compiler/src/dmd/dinterpret.d +++ b/compiler/src/dmd/dinterpret.d @@ -6142,6 +6142,8 @@ public: return; } + import dmd.utils : arrayCastBigEndian; + auto str = arrayCastBigEndian(se.peekData(), sz); emplaceExp!(StringExp)(pue, e1.loc, str, se.len / sz, cast(ubyte) sz); result = pue.exp(); diff --git a/compiler/src/dmd/utils.d b/compiler/src/dmd/utils.d index cab7645312..3920858f2d 100644 --- a/compiler/src/dmd/utils.d +++ b/compiler/src/dmd/utils.d @@ -215,6 +215,39 @@ unittest assert(buf[] == expected); } +/** + * Cast a `ubyte[]` to an array of larger integers as if we are on a big endian architecture + * Params: + * data = array with big endian data + * size = 1 for ubyte[], 2 for ushort[], 4 for uint[], 8 for ulong[] + * Returns: copy of `data`, with bytes shuffled if compiled for `version(LittleEndian)` + */ +ubyte[] arrayCastBigEndian(const ubyte[] data, size_t size) +{ + ubyte[] impl(T)() + { + auto result = new T[](data.length / T.sizeof); + foreach (i; 0 .. result.length) + { + result[i] = 0; + foreach (j; 0 .. T.sizeof) + { + result[i] |= T(data[i * T.sizeof + j]) << ((T.sizeof - 1 - j) * 8); + } + } + return cast(ubyte[]) result; + } + switch (size) + { + case 1: return data.dup; + case 2: return impl!ushort; + case 4: return impl!uint; + case 8: return impl!ulong; + default: assert(0); + } +} + + /** * Convert string to integer. *