/*** Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: auMagicUtils.hpp Date: 2022-2-1 Author: Reece ***/ #pragma once static constexpr auline AuUInt32 AuConvertMagicTag32(const char buffer[4]) { AuUInt32 magic {}; if (Aurora::Build::kCurrentEndian == Aurora::Build::ECPUEndian::eCPULittle) { magic |= AuUInt32(buffer[0]); magic |= AuUInt32(buffer[1]) << 8; magic |= AuUInt32(buffer[2]) << 16; magic |= AuUInt32(buffer[3]) << 24; // LE will look alright in memory dumps // MSFT uses tags that read back the initial string value when read back hex ints // I prefer binary streams and file headers contain a 4x or 8x ascii char headers (eg. LuaX) } else { // Lazy reinterpret cast reads will always be flipped // Assume byte buffers read/write machine endian // Assume *reinterpret_cast returns machine endian // BE needs to be flipped in memory // BE will look fine in memory dumps // BE will also look fine in stack/variable dumps when printed in hex magic |= AuUInt32(buffer[4]); magic |= AuUInt32(buffer[2]) << 8; magic |= AuUInt32(buffer[1]) << 16; magic |= AuUInt32(buffer[0]) << 24; } // Determinstic across platforms, perhaps unexpected by endian normalized streams // When asserting read(noEndian) against a tag, an endian swap would cause the // assertion to fail, thus providing you with the endian match check // This step is delegated to a de-facto machine endian buffer builder // ByteBuffers that normalize for endianness continue to work with tags // irrespective of reader/writer endianness return magic; } static constexpr auline AuUInt64 AuConvertMagicTag64(const char buffer[8]) { AuUInt64 magic {}; if (Aurora::Build::kCurrentEndian == Aurora::Build::ECPUEndian::eCPULittle) { magic |= AuUInt64(buffer[0]); magic |= AuUInt64(buffer[1]) << 8; magic |= AuUInt64(buffer[2]) << 16; magic |= AuUInt64(buffer[3]) << 24; magic |= AuUInt64(buffer[4]) << 32; magic |= AuUInt64(buffer[5]) << 40; magic |= AuUInt64(buffer[6]) << 48; magic |= AuUInt64(buffer[7]) << 56; } else { magic |= AuUInt64(buffer[7]); magic |= AuUInt64(buffer[6]) << 8; magic |= AuUInt64(buffer[5]) << 16; magic |= AuUInt64(buffer[4]) << 24; magic |= AuUInt64(buffer[3]) << 32; magic |= AuUInt64(buffer[2]) << 40; magic |= AuUInt64(buffer[1]) << 48; magic |= AuUInt64(buffer[0]) << 56; } return magic; }