Actually call on_reset callback
[lsnes.git] / include / library / serialization.hpp
blobbcdba4715eee00c97a8fdd65b44e62bb71bb8109
1 #ifndef _library__serialization__hpp__included__
2 #define _library__serialization__hpp__included__
4 #include <cstdint>
5 #include <cstdlib>
6 #include <map>
8 namespace serialization
10 template<size_t n> struct unsigned_of {};
11 template<> struct unsigned_of<1> { typedef uint8_t t; };
12 template<> struct unsigned_of<2> { typedef uint16_t t; };
13 template<> struct unsigned_of<4> { typedef uint32_t t; };
14 template<> struct unsigned_of<8> { typedef uint64_t t; };
16 template<typename T1, bool be>
17 void write_common(uint8_t* target, T1 value)
19 for(size_t i = 0; i < sizeof(T1); i++)
20 if(be)
21 target[i] = static_cast<typename unsigned_of<sizeof(T1)>::t>(value) >> 8 * (sizeof(T1) - i - 1);
22 else
23 target[i] = static_cast<typename unsigned_of<sizeof(T1)>::t>(value) >> 8 * i;
26 template<typename T1, bool be>
27 T1 read_common(const uint8_t* source)
29 typename unsigned_of<sizeof(T1)>::t value = 0;
30 for(size_t i = 0; i < sizeof(T1); i++)
31 if(be)
32 value |= static_cast<typename unsigned_of<sizeof(T1)>::t>(source[i]) << 8 * (sizeof(T1) - i - 1);
33 else
34 value |= static_cast<typename unsigned_of<sizeof(T1)>::t>(source[i]) << 8 * i;
35 return static_cast<T1>(value);
38 inline void s8b(void* t, int8_t v)
40 write_common< int8_t, true>(reinterpret_cast<uint8_t*>(t), v);
42 inline void s8l(void* t, int8_t v)
44 write_common< int8_t, false>(reinterpret_cast<uint8_t*>(t), v);
46 inline void u8b(void* t, uint8_t v)
48 write_common< uint8_t, true>(reinterpret_cast<uint8_t*>(t), v);
50 inline void u8l(void* t, uint8_t v)
52 write_common< uint8_t, false>(reinterpret_cast<uint8_t*>(t), v);
54 inline void s16b(void* t, int16_t v)
56 write_common< int16_t, true>(reinterpret_cast<uint8_t*>(t), v);
58 inline void s16l(void* t, int16_t v)
60 write_common< int16_t, false>(reinterpret_cast<uint8_t*>(t), v);
62 inline void u16b(void* t, uint16_t v)
64 write_common<uint16_t, true>(reinterpret_cast<uint8_t*>(t), v);
66 inline void u16l(void* t, uint16_t v)
68 write_common<uint16_t, false>(reinterpret_cast<uint8_t*>(t), v);
70 inline void s32b(void* t, int32_t v)
72 write_common< int32_t, true>(reinterpret_cast<uint8_t*>(t), v);
74 inline void s32l(void* t, int32_t v)
76 write_common< int32_t, false>(reinterpret_cast<uint8_t*>(t), v);
78 inline void u32b(void* t, uint32_t v)
80 write_common<uint32_t, true>(reinterpret_cast<uint8_t*>(t), v);
82 inline void u32l(void* t, uint32_t v)
84 write_common<uint32_t, false>(reinterpret_cast<uint8_t*>(t), v);
86 inline void s64b(void* t, int64_t v)
88 write_common< int64_t, true>(reinterpret_cast<uint8_t*>(t), v);
90 inline void s64l(void* t, int64_t v)
92 write_common< int64_t, false>(reinterpret_cast<uint8_t*>(t), v);
94 inline void u64b(void* t, uint64_t v)
96 write_common<uint64_t, true>(reinterpret_cast<uint8_t*>(t), v);
98 inline void u64l(void* t, uint64_t v)
100 write_common<uint64_t, false>(reinterpret_cast<uint8_t*>(t), v);
102 inline int8_t s8b(const void* t)
104 return read_common< int8_t, true>(reinterpret_cast<const uint8_t*>(t));
106 inline int8_t s8l(const void* t)
108 return read_common< int8_t, false>(reinterpret_cast<const uint8_t*>(t));
110 inline uint8_t u8b(const void* t)
112 return read_common< uint8_t, true>(reinterpret_cast<const uint8_t*>(t));
114 inline uint8_t u8l(const void* t)
116 return read_common< uint8_t, false>(reinterpret_cast<const uint8_t*>(t));
118 inline int16_t s16b(const void* t)
120 return read_common< int16_t, true>(reinterpret_cast<const uint8_t*>(t));
122 inline int16_t s16l(const void* t)
124 return read_common< int16_t, false>(reinterpret_cast<const uint8_t*>(t));
126 inline uint16_t u16b(const void* t)
128 return read_common<uint16_t, true>(reinterpret_cast<const uint8_t*>(t));
130 inline uint16_t u16l(const void* t)
132 return read_common<uint16_t, false>(reinterpret_cast<const uint8_t*>(t));
134 inline int32_t s32b(const void* t)
136 return read_common< int32_t, true>(reinterpret_cast<const uint8_t*>(t));
138 inline int32_t s32l(const void* t)
140 return read_common< int32_t, false>(reinterpret_cast<const uint8_t*>(t));
142 inline uint32_t u32b(const void* t)
144 return read_common<uint32_t, true>(reinterpret_cast<const uint8_t*>(t));
146 inline uint32_t u32l(const void* t)
148 return read_common<uint32_t, false>(reinterpret_cast<const uint8_t*>(t));
150 inline int64_t s64b(const void* t)
152 return read_common< int64_t, true>(reinterpret_cast<const uint8_t*>(t));
154 inline int64_t s64l(const void* t)
156 return read_common< int64_t, false>(reinterpret_cast<const uint8_t*>(t));
158 inline uint64_t u64b(const void* t)
160 return read_common<uint64_t, true>(reinterpret_cast<const uint8_t*>(t));
162 inline uint64_t u64l(const void* t)
164 return read_common<uint64_t, false>(reinterpret_cast<const uint8_t*>(t));
167 template<typename T> void swap_endian(T& value)
169 char* _value = reinterpret_cast<char*>(&value);
170 for(size_t i = 0; i < sizeof(T)/2; i++)
171 std::swap(_value[i], _value[sizeof(T)-i-1]);
174 template<typename T> void swap_endian(T& value, int endian)
176 short _magic = 258;
177 char magic = *reinterpret_cast<char*>(&_magic);
178 bool do_swap = (endian == -1 && magic == 1) || (endian == 1 && magic == 2);
179 if(do_swap)
180 swap_endian(value);
183 template<typename T> T read_endian(const void* value, int endian)
185 T val;
186 memcpy(&val, value, sizeof(T));
187 swap_endian(val, endian);
188 return val;
191 template<typename T> void write_endian(void* value, const T& val, int endian)
193 memcpy(value, &val, sizeof(T));
194 swap_endian(*reinterpret_cast<T*>(value), endian);
198 #endif