ScummVM API documentation
data-io.h
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef COMMON_DATA_IO_H
23 #define COMMON_DATA_IO_H
24 
25 #include "common/scummsys.h"
26 
27 namespace Common {
28 
29 enum class EndianStorageFormat {
30  Big,
31  Little,
32 };
33 
34 // Traits for a storage format. You can specialize this to make more storage formats
35 // that have their own behavior.
36 template<class TDataFormat>
38 };
39 
40 template<>
41 struct DataFormatTraits<EndianStorageFormat> {
42  static inline bool isLittleEndian(EndianStorageFormat storageFormat) {
43  return storageFormat == EndianStorageFormat::Little;
44  }
45 };
46 
47 template<class TDataFormat, class T>
48 struct SimpleDataIO {
49  static const uint kMaxSize = sizeof(T);
50 
51  static uint computeSize(TDataFormat dataFormat);
52 
53  static void encode(TDataFormat dataFormat, byte *data, const T &value);
54  static void decode(TDataFormat dataFormat, const byte *data, T &value);
55 };
56 
57 template<class TDataFormat, class T>
58 uint SimpleDataIO<TDataFormat, T>::computeSize(TDataFormat dataFormat) {
59  return sizeof(T);
60 }
61 
62 template<class TDataFormat, class T>
63 void SimpleDataIO<TDataFormat, T>::encode(TDataFormat dataFormat, byte *data, const T &value) {
64  const byte *valueBytes = reinterpret_cast<const byte *>(&value);
65  byte *dataBytes = reinterpret_cast<byte *>(data);
66 
67  const bool isTargetLE = DataFormatTraits<TDataFormat>::isLittleEndian(dataFormat);
68 #ifdef SCUMM_LITTLE_ENDIAN
69  const bool isSystemLE = true;
70 #endif
71 #ifdef SCUMM_BIG_ENDIAN
72  const bool isSystemLE = false;
73 #endif
74 
75  const bool requiresSwap = (isSystemLE != isTargetLE);
76 
77  byte temp[sizeof(T)];
78 
79  if (requiresSwap) {
80  for (uint i = 0; i < sizeof(T); i++)
81  temp[i] = valueBytes[sizeof(T) - 1 - i];
82  } else {
83  for (uint i = 0; i < sizeof(T); i++)
84  temp[i] = valueBytes[i];
85  }
86 
87  for (uint i = 0; i < sizeof(T); i++)
88  dataBytes[i] = temp[i];
89 }
90 
91 template<class TDataFormat, class T>
92 void SimpleDataIO<TDataFormat, T>::decode(TDataFormat dataFormat, const byte *data, T &value) {
93  byte *valueBytes = reinterpret_cast<byte *>(&value);
94  const byte *dataBytes = reinterpret_cast<const byte *>(data);
95 
96  const bool isTargetLE = DataFormatTraits<TDataFormat>::isLittleEndian(dataFormat);
97 #ifdef SCUMM_LITTLE_ENDIAN
98  const bool isSystemLE = true;
99 #endif
100 #ifdef SCUMM_BIG_ENDIAN
101  const bool isSystemLE = false;
102 #endif
103 
104  const bool requiresSwap = (isSystemLE != isTargetLE);
105 
106  byte temp[sizeof(T)];
107 
108  if (requiresSwap) {
109  for (uint i = 0; i < sizeof(T); i++)
110  temp[i] = dataBytes[sizeof(T) - 1 - i];
111  } else {
112  for (uint i = 0; i < sizeof(T); i++)
113  temp[i] = dataBytes[i];
114  }
115 
116  for (uint i = 0; i < sizeof(T); i++)
117  valueBytes[i] = temp[i];
118 }
119 
120 template<class TDataFormat, class T>
121 struct DataIO {
122 };
123 
124 template<class TDataFormat>
125 struct DataIO<TDataFormat, uint8> : public SimpleDataIO<TDataFormat, uint8> {
126 };
127 
128 template<class TDataFormat>
129 struct DataIO<TDataFormat, uint16> : public SimpleDataIO<TDataFormat, uint16> {
130 };
131 template<class TDataFormat>
132 struct DataIO<TDataFormat, uint32> : public SimpleDataIO<TDataFormat, uint32> {
133 };
134 template<class TDataFormat>
135 struct DataIO<TDataFormat, uint64> : public SimpleDataIO<TDataFormat, uint64> {
136 };
137 
138 template<class TDataFormat>
139 struct DataIO<TDataFormat, int8> : public SimpleDataIO<TDataFormat, int8> {
140 };
141 
142 template<class TDataFormat>
143 struct DataIO<TDataFormat, int16> : public SimpleDataIO<TDataFormat, int16> {
144 };
145 
146 template<class TDataFormat>
147 struct DataIO<TDataFormat, int32> : public SimpleDataIO<TDataFormat, int32> {
148 };
149 
150 template<class TDataFormat>
151 struct DataIO<TDataFormat, int64> : public SimpleDataIO<TDataFormat, int64> {
152 };
153 
154 template<class TDataFormat>
155 struct DataIO<TDataFormat, char> : public SimpleDataIO<TDataFormat, char> {
156 };
157 
158 template<class TDataFormat>
159 struct DataIO<TDataFormat, float> : public SimpleDataIO<TDataFormat, float> {
160 };
161 
162 template<class TDataFormat>
163 struct DataIO<TDataFormat, double> : public SimpleDataIO<TDataFormat, double> {
164 };
165 
166 template<class TDataFormat, class T, class... TMore>
168 
169 template<class TDataFormat, class T>
170 struct DataMultipleIO<TDataFormat, T> {
171  static const uint kMaxSize = DataIO<TDataFormat, T>::kMaxSize;
172 
173  static uint computeSize(TDataFormat dataFormat);
174 
175  static void encode(TDataFormat dataFormat, byte *data, const T &value);
176  static void decode(TDataFormat dataFormat, const byte *data, T &value);
177 };
178 
179 template<class TDataFormat, class T>
180 uint DataMultipleIO<TDataFormat, T>::computeSize(TDataFormat dataFormat) {
181  return DataIO<TDataFormat, T>::computeSize(dataFormat);
182 }
183 
184 template<class TDataFormat, class T>
185 void DataMultipleIO<TDataFormat, T>::encode(TDataFormat dataFormat, byte *data, const T &value) {
186  return DataIO<TDataFormat, T>::encode(dataFormat, data, value);
187 }
188 
189 template<class TDataFormat, class T>
190 void DataMultipleIO<TDataFormat, T>::decode(TDataFormat dataFormat, const byte *data, T &value) {
191  return DataIO<TDataFormat, T>::decode(dataFormat, data, value);
192 }
193 
194 template<class TDataFormat, class T, uint TSize>
195 struct DataMultipleIO<TDataFormat, T[TSize]> {
196  static const uint kMaxSize = DataIO<TDataFormat, T>::kMaxSize * TSize;
197 
198  static uint computeSize(TDataFormat dataFormat);
199 
200  static void encode(TDataFormat dataFormat, byte *data, const T (&value)[TSize]);
201  static void decode(TDataFormat dataFormat, const byte *data, T (&value)[TSize]);
202 };
203 
204 template<class TDataFormat, class T, uint TSize>
205 uint DataMultipleIO<TDataFormat, T[TSize]>::computeSize(TDataFormat dataFormat) {
206  return DataMultipleIO<TDataFormat, T>::computeSize(dataFormat) * TSize;
207 }
208 
209 template<class TDataFormat, class T, uint TSize>
210 void DataMultipleIO<TDataFormat, T[TSize]>::encode(TDataFormat dataFormat, byte *data, const T (&value)[TSize]) {
211  const uint elementSize = DataIO<TDataFormat, T>::computeSize(dataFormat);
212  for (uint i = 0; i < TSize; i++)
213  DataMultipleIO<TDataFormat, T>::encode(dataFormat, data + elementSize * i, value[i]);
214 }
215 
216 template<class TDataFormat, class T, uint TSize>
217 void DataMultipleIO<TDataFormat, T[TSize]>::decode(TDataFormat dataFormat, const byte *data, T (&value)[TSize]) {
218  const uint elementSize = DataIO<TDataFormat, T>::computeSize(dataFormat);
219  for (uint i = 0; i < TSize; i++)
220  DataMultipleIO<TDataFormat, T>::decode(dataFormat, data + elementSize * i, value[i]);
221 }
222 
223 template<class TDataFormat, class T, class... TMore>
224 struct DataMultipleIO {
225  static const uint kMaxSize = DataIO<TDataFormat, T>::kMaxSize + DataMultipleIO<TDataFormat, TMore...>::kMaxSize;
226 
227  static uint computeSize(TDataFormat dataFormat);
228 
229  static void encode(TDataFormat dataFormat, byte *data, const T &firstValue, const TMore &...moreValues);
230  static void decode(TDataFormat dataFormat, const byte *data, T &firstValue, TMore &...moreValues);
231 };
232 
233 template<class TDataFormat, class T, class... TMore>
234 uint DataMultipleIO<TDataFormat, T, TMore...>::computeSize(TDataFormat dataFormat) {
236 }
237 
238 template<class TDataFormat, class T, class... TMore>
239 void DataMultipleIO<TDataFormat, T, TMore...>::encode(TDataFormat dataFormat, byte *data, const T &firstValue, const TMore &...moreValues) {
240  DataMultipleIO<TDataFormat, T>::encode(dataFormat, data, firstValue);
242 }
243 
244 template<class TDataFormat, class T, class... TMore>
245 void DataMultipleIO<TDataFormat, T, TMore...>::decode(TDataFormat dataFormat, const byte *data, T &firstValue, TMore &...moreValues) {
246  DataMultipleIO<TDataFormat, T>::decode(dataFormat, data, firstValue);
248 }
249 
250 } // End of namespace Common
251 
252 #endif
Definition: data-io.h:167
Definition: data-io.h:48
Definition: data-io.h:37
Definition: algorithm.h:29
Definition: data-io.h:121