1#ifndef SEAD_ENDIAN_H_
2#define SEAD_ENDIAN_H_
3
4#include <basis/seadRawPrint.h>
5#include <basis/seadTypes.h>
6#include <prim/seadBitUtil.h>
7
8namespace sead
9{
10class Endian
11{
12public:
13 enum Types
14 {
15 cBig = 0,
16 cLittle = 1,
17 };
18
19 struct ConvFuncTable
20 {
21 typedef u8 (*CONV8FUNC)(u8);
22 typedef u16 (*CONV16FUNC)(u16);
23 typedef u32 (*CONV32FUNC)(u32);
24 typedef u64 (*CONV64FUNC)(u64);
25
26 CONV8FUNC conv8[2];
27 CONV16FUNC conv16[2];
28 CONV32FUNC conv32[2];
29 CONV64FUNC conv64[2];
30 };
31
32 static Types getHostEndian() { return cHostEndian; }
33
34 static Types markToEndian(u16 bom)
35 {
36 u8* bom_ = reinterpret_cast<u8*>(&bom);
37 if (*bom_ == 0xff && *(bom_ + 1) == 0xfe)
38 return cLittle;
39
40 if (*bom_ == 0xfe && *(bom_ + 1) == 0xff)
41 return cBig;
42
43 SEAD_ASSERT_MSG(false, "Undefined endian mark(0x%02x 0x%02x)", bom_[0], bom_[1]);
44 return cLittle;
45 }
46
47 static u16 endianToMark(Types endian) { return endian == cBig ? 0xFEFF : 0xFFFE; }
48
49 static u8 swapU8(u8 v) { return cConvFuncTable.conv8[1](v); }
50 static u16 swapU16(u16 v) { return cConvFuncTable.conv16[1](v); }
51 static u32 swapU32(u32 v) { return cConvFuncTable.conv32[1](v); }
52 static u64 swapU64(u64 v) { return cConvFuncTable.conv64[1](v); }
53 static s8 swapS8(s8 v) { return swapU8(v); }
54 static s16 swapS16(s16 v) { return swapU16(v); }
55 static s32 swapS32(s32 v) { return swapU32(v); }
56 static s64 swapS64(s64 v) { return swapU64(v); }
57 static f32 swapF32(f32 v) { return BitUtil::bitCast<f32>(value: swapU32(v: BitUtil::bitCast<u32>(value: v))); }
58
59 static u8 convertU8(Types from, Types to, u8 v) { return cConvFuncTable.conv8[from ^ to](v); }
60 static u16 convertU16(Types from, Types to, u16 v)
61 {
62 return cConvFuncTable.conv16[from ^ to](v);
63 }
64 static u32 convertU32(Types from, Types to, u32 v)
65 {
66 return cConvFuncTable.conv32[from ^ to](v);
67 }
68 static u64 convertU64(Types from, Types to, u64 v)
69 {
70 return cConvFuncTable.conv64[from ^ to](v);
71 }
72
73 static s8 convertS8(Types from, Types to, s8 v) { return convertU8(from, to, v); }
74 static s16 convertS16(Types from, Types to, s16 v) { return convertU16(from, to, v); }
75 static s32 convertS32(Types from, Types to, s32 v) { return convertU32(from, to, v); }
76 static s64 convertS64(Types from, Types to, s64 v) { return convertU64(from, to, v); }
77 static u32 convertF32(Types from, Types to, const void* ptr)
78 {
79 return convertU32(from, to, v: *static_cast<const u32*>(ptr));
80 }
81
82 static u8 toHostU8(Types from, u8 v) { return convertU8(from, to: cHostEndian, v); }
83 static u16 toHostU16(Types from, u16 v) { return convertU16(from, to: cHostEndian, v); }
84 static u32 toHostU32(Types from, u32 v) { return convertU32(from, to: cHostEndian, v); }
85 static u64 toHostU64(Types from, u64 v) { return convertU64(from, to: cHostEndian, v); }
86
87 static u8 fromHostU8(Types to, u8 v) { return convertU8(from: cHostEndian, to, v); }
88 static u16 fromHostU16(Types to, u16 v) { return convertU16(from: cHostEndian, to, v); }
89 static u32 fromHostU32(Types to, u32 v) { return convertU32(from: cHostEndian, to, v); }
90 static u64 fromHostU64(Types to, u64 v) { return convertU64(from: cHostEndian, to, v); }
91
92 static s8 toHostS8(Types from, s8 v) { return toHostU8(from, v); }
93 static s16 toHostS16(Types from, s16 v) { return toHostU16(from, v); }
94 static s32 toHostS32(Types from, s32 v) { return toHostU32(from, v); }
95 static s64 toHostS64(Types from, s64 v) { return toHostU64(from, v); }
96
97 static s8 fromHostS8(Types to, s8 v) { return fromHostU8(to, v); }
98 static s16 fromHostS16(Types to, s16 v) { return fromHostU8(to, v); }
99 static s32 fromHostS32(Types to, s32 v) { return fromHostU8(to, v); }
100 static s64 fromHostS64(Types to, s64 v) { return fromHostU8(to, v); }
101
102 static f32 toHostF32(Types from, const u32* ptr)
103 {
104 return BitUtil::bitCast<f32>(value: convertF32(from, to: cHostEndian, ptr));
105 }
106 static u32 fromHostF32(Types to, const f32* ptr) { return convertF32(from: cHostEndian, to, ptr); }
107
108private:
109 static const Types cHostEndian;
110 static const ConvFuncTable cConvFuncTable;
111};
112} // namespace sead
113
114#endif // SEAD_ENDIAN_H_
115