[Scummvm-git-logs] scummvm master -> 58fea8dbcec28550e78f0cf861440c713ee2b2f4

sev- noreply at scummvm.org
Tue Feb 27 16:13:39 UTC 2024


This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
84fe1e2018 COMMON: Add multi-data IO templates and multi-value IO functions to streams
58fea8dbce MTROPOLIS: Use data IO templates from Common


Commit: 84fe1e2018e063bc405e93103e93f0d89e603440
    https://github.com/scummvm/scummvm/commit/84fe1e2018e063bc405e93103e93f0d89e603440
Author: elasota (1137273+elasota at users.noreply.github.com)
Date: 2024-02-27T17:13:35+01:00

Commit Message:
COMMON: Add multi-data IO templates and multi-value IO functions to streams

Changed paths:
  A common/data-io.h
    common/stream.h


diff --git a/common/data-io.h b/common/data-io.h
new file mode 100644
index 00000000000..419a8f3d5f4
--- /dev/null
+++ b/common/data-io.h
@@ -0,0 +1,252 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef COMMON_DATA_IO_H
+#define COMMON_DATA_IO_H
+
+#include "common/scummsys.h"
+
+namespace Common {
+
+enum class EndianStorageFormat {
+	Big,
+	Little,
+};
+
+// Traits for a storage format.  You can specialize this to make more storage formats
+// that have their own behavior.
+template<class TDataFormat>
+struct DataFormatTraits {
+};
+
+template<>
+struct DataFormatTraits<EndianStorageFormat> {
+	static inline bool isLittleEndian(EndianStorageFormat storageFormat) {
+		return storageFormat == EndianStorageFormat::Little;
+	}
+};
+
+template<class TDataFormat, class T>
+struct SimpleDataIO {
+	static const uint kMaxSize = sizeof(T);
+
+	static uint computeSize(TDataFormat dataFormat);
+
+	static void encode(TDataFormat dataFormat, byte *data, const T &value);
+	static void decode(TDataFormat dataFormat, const byte *data, T &value);
+};
+
+template<class TDataFormat, class T>
+uint SimpleDataIO<TDataFormat, T>::computeSize(TDataFormat dataFormat) {
+	return sizeof(T);
+}
+
+template<class TDataFormat, class T>
+void SimpleDataIO<TDataFormat, T>::encode(TDataFormat dataFormat, byte *data, const T &value) {
+	const byte *valueBytes = reinterpret_cast<const byte *>(&value);
+	byte *dataBytes = reinterpret_cast<byte *>(data);
+
+	const bool isTargetLE = DataFormatTraits<TDataFormat>::isLittleEndian(dataFormat);
+#ifdef SCUMM_LITTLE_ENDIAN
+	const bool isSystemLE = true;
+#endif
+#ifdef SCUMM_BIG_ENDIAN
+	const bool isSystemLE = false;
+#endif
+
+	const bool requiresSwap = (isSystemLE != isTargetLE);
+
+	byte temp[sizeof(T)];
+
+	if (requiresSwap) {
+		for (uint i = 0; i < sizeof(T); i++)
+			temp[i] = valueBytes[sizeof(T) - 1 - i];
+	} else {
+		for (uint i = 0; i < sizeof(T); i++)
+			temp[i] = valueBytes[i];
+	}
+
+	for (uint i = 0; i < sizeof(T); i++)
+		dataBytes[i] = temp[i];
+}
+
+template<class TDataFormat, class T>
+void SimpleDataIO<TDataFormat, T>::decode(TDataFormat dataFormat, const byte *data, T &value) {
+	byte *valueBytes = reinterpret_cast<byte *>(&value);
+	const byte *dataBytes = reinterpret_cast<const byte *>(data);
+
+	const bool isTargetLE = DataFormatTraits<TDataFormat>::isLittleEndian(dataFormat);
+#ifdef SCUMM_LITTLE_ENDIAN
+	const bool isSystemLE = true;
+#endif
+#ifdef SCUMM_BIG_ENDIAN
+	const bool isSystemLE = false;
+#endif
+
+	const bool requiresSwap = (isSystemLE != isTargetLE);
+
+	byte temp[sizeof(T)];
+
+	if (requiresSwap) {
+		for (uint i = 0; i < sizeof(T); i++)
+			temp[i] = dataBytes[sizeof(T) - 1 - i];
+	} else {
+		for (uint i = 0; i < sizeof(T); i++)
+			temp[i] = dataBytes[i];
+	}
+
+	for (uint i = 0; i < sizeof(T); i++)
+		valueBytes[i] = temp[i];
+}
+
+template<class TDataFormat, class T>
+struct DataIO {
+};
+
+template<class TDataFormat>
+struct DataIO<TDataFormat, uint8> : public SimpleDataIO<TDataFormat, uint8> {
+};
+
+template<class TDataFormat>
+struct DataIO<TDataFormat, uint16> : public SimpleDataIO<TDataFormat, uint16> {
+};
+template<class TDataFormat>
+struct DataIO<TDataFormat, uint32> : public SimpleDataIO<TDataFormat, uint32> {
+};
+template<class TDataFormat>
+struct DataIO<TDataFormat, uint64> : public SimpleDataIO<TDataFormat, uint64> {
+};
+
+template<class TDataFormat>
+struct DataIO<TDataFormat, int8> : public SimpleDataIO<TDataFormat, int8> {
+};
+
+template<class TDataFormat>
+struct DataIO<TDataFormat, int16> : public SimpleDataIO<TDataFormat, int16> {
+};
+
+template<class TDataFormat>
+struct DataIO<TDataFormat, int32> : public SimpleDataIO<TDataFormat, int32> {
+};
+
+template<class TDataFormat>
+struct DataIO<TDataFormat, int64> : public SimpleDataIO<TDataFormat, int64> {
+};
+
+template<class TDataFormat>
+struct DataIO<TDataFormat, char> : public SimpleDataIO<TDataFormat, char> {
+};
+
+template<class TDataFormat>
+struct DataIO<TDataFormat, float> : public SimpleDataIO<TDataFormat, float> {
+};
+
+template<class TDataFormat>
+struct DataIO<TDataFormat, double> : public SimpleDataIO<TDataFormat, double> {
+};
+
+template<class TDataFormat, class T, class... TMore>
+struct DataMultipleIO;
+
+template<class TDataFormat, class T>
+struct DataMultipleIO<TDataFormat, T> {
+	static const uint kMaxSize = DataIO<TDataFormat, T>::kMaxSize;
+
+	static uint computeSize(TDataFormat dataFormat);
+
+	static void encode(TDataFormat dataFormat, byte *data, const T &value);
+	static void decode(TDataFormat dataFormat, const byte *data, T &value);
+};
+
+template<class TDataFormat, class T>
+uint DataMultipleIO<TDataFormat, T>::computeSize(TDataFormat dataFormat) {
+	return DataIO<TDataFormat, T>::computeSize(dataFormat);
+}
+
+template<class TDataFormat, class T>
+void DataMultipleIO<TDataFormat, T>::encode(TDataFormat dataFormat, byte *data, const T &value) {
+	return DataIO<TDataFormat, T>::encode(dataFormat, data, value);
+}
+
+template<class TDataFormat, class T>
+void DataMultipleIO<TDataFormat, T>::decode(TDataFormat dataFormat, const byte *data, T &value) {
+	return DataIO<TDataFormat, T>::decode(dataFormat, data, value);
+}
+
+template<class TDataFormat, class T, uint TSize>
+struct DataMultipleIO<TDataFormat, T[TSize]> {
+	static const uint kMaxSize = DataIO<TDataFormat, T>::kMaxSize * TSize;
+
+	static uint computeSize(TDataFormat dataFormat);
+
+	static void encode(TDataFormat dataFormat, byte *data, const T (&value)[TSize]);
+	static void decode(TDataFormat dataFormat, const byte *data, T (&value)[TSize]);
+};
+
+template<class TDataFormat, class T, uint TSize>
+uint DataMultipleIO<TDataFormat, T[TSize]>::computeSize(TDataFormat dataFormat) {
+	return DataMultipleIO<TDataFormat, T>::computeSize(dataFormat) * TSize;
+}
+
+template<class TDataFormat, class T, uint TSize>
+void DataMultipleIO<TDataFormat, T[TSize]>::encode(TDataFormat dataFormat, byte *data, const T (&value)[TSize]) {
+	const uint elementSize = DataIO<TDataFormat, T>::computeSize(dataFormat);
+	for (uint i = 0; i < TSize; i++)
+		DataMultipleIO<TDataFormat, T>::encode(dataFormat, data + elementSize * i, value[i]);
+}
+
+template<class TDataFormat, class T, uint TSize>
+void DataMultipleIO<TDataFormat, T[TSize]>::decode(TDataFormat dataFormat, const byte *data, T (&value)[TSize]) {
+	const uint elementSize = DataIO<TDataFormat, T>::computeSize(dataFormat);
+	for (uint i = 0; i < TSize; i++)
+		DataMultipleIO<TDataFormat, T>::decode(dataFormat, data + elementSize * i, value[i]);
+}
+
+template<class TDataFormat, class T, class... TMore>
+struct DataMultipleIO {
+	static const uint kMaxSize = DataIO<TDataFormat, T>::kMaxSize + DataMultipleIO<TDataFormat, TMore...>::kMaxSize;
+
+	static uint computeSize(TDataFormat dataFormat);
+
+	static void encode(TDataFormat dataFormat, byte *data, const T &firstValue, const TMore &...moreValues);
+	static void decode(TDataFormat dataFormat, const byte *data, T &firstValue, TMore &...moreValues);
+};
+
+template<class TDataFormat, class T, class... TMore>
+uint DataMultipleIO<TDataFormat, T, TMore...>::computeSize(TDataFormat dataFormat) {
+	return DataMultipleIO<TDataFormat, T>::computeSize(dataFormat) + DataMultipleIO<TDataFormat, TMore...>::computeSize(dataFormat);
+}
+
+template<class TDataFormat, class T, class... TMore>
+void DataMultipleIO<TDataFormat, T, TMore...>::encode(TDataFormat dataFormat, byte *data, const T &firstValue, const TMore &...moreValues) {
+	DataMultipleIO<TDataFormat, T>::encode(dataFormat, data, firstValue);
+	DataMultipleIO<TDataFormat, TMore...>::encode(dataFormat, data + DataMultipleIO<TDataFormat, T>::computeSize(dataFormat), moreValues...);
+}
+
+template<class TDataFormat, class T, class... TMore>
+void DataMultipleIO<TDataFormat, T, TMore...>::decode(TDataFormat dataFormat, const byte *data, T &firstValue, TMore &...moreValues) {
+	DataMultipleIO<TDataFormat, T>::decode(dataFormat, data, firstValue);
+	DataMultipleIO<TDataFormat, TMore...>::decode(dataFormat, data + DataMultipleIO<TDataFormat, T>::computeSize(dataFormat), moreValues...);
+}
+
+} // End of namespace Common
+
+#endif
diff --git a/common/stream.h b/common/stream.h
index e290b76f3bc..5e0c48ecc48 100644
--- a/common/stream.h
+++ b/common/stream.h
@@ -26,6 +26,7 @@
 #include "common/ptr.h"
 #include "common/scummsys.h"
 #include "common/str.h"
+#include "common/data-io.h"
 
 namespace Common {
 
@@ -275,6 +276,52 @@ public:
 		writeUint64BE(n);
 	}
 
+	/**
+	 * Write multiple values to the stream using a specified data format,
+	 * return true on success and false on failure.
+	 */
+	template<class TDataFormat, class... T>
+	bool writeMultiple(const TDataFormat &dataFormat, const T &...values) {
+		const TDataFormat dataFormatCopy = dataFormat; // Copy to help compiler alias analysis, parameter is const ref to ensure TDataFormat is a concrete type
+
+		byte buffer[DataMultipleIO<TDataFormat, T...>::kMaxSize];
+		const uint actualSize = DataMultipleIO<TDataFormat, T...>::computeSize(dataFormatCopy);
+
+		DataMultipleIO<T...>::encode(dataFormatCopy, buffer, values...);
+
+		if (this->write(buffer, actualSize) != actualSize)
+			return false;
+
+		return true;
+	}
+
+	/**
+	 * Write multiple values to the stream using a specified endianness,
+	 * return true on success and false on failure.
+	 */
+	template<class... T>
+	inline bool writeMultipleEndian(bool isLittle, const T &...values) {
+		return this->writeMultiple<EndianStorageFormat, T...>(isLittle ? EndianStorageFormat::Little : EndianStorageFormat::Big, values...);
+	}
+
+	/**
+	 * Write multiple values to the stream in little endian format,
+	 * return true on success and false on failure.
+	 */
+	template<class... T>
+	inline bool writeMultipleLE(const T &...values) {
+		return this->writeMultiple<EndianStorageFormat, T...>(EndianStorageFormat::Little, values...);
+	}
+
+	/**
+	 * Write multiple values to the stream in big endian format,
+	 * return true on success and false on failure.
+	 */
+	template<class... T>
+	inline bool writeMultipleBE(const T &...values) {
+		return this->writeMultiple<EndianStorageFormat, T...>(EndianStorageFormat::Big, values...);
+	}
+
 	/**
 	 * Write at most @p dataSize of data from another stream into this one,
 	 * starting from the current stream position.
@@ -614,6 +661,51 @@ public:
 		return READ_BE_FLOAT64(val);
 	}
 
+	/**
+	 * Read multiple values from the stream using a specified data format,
+	 * return true on success and false on failure.
+	 */
+	template<class TDataFormat, class... T>
+	bool readMultiple(const TDataFormat &dataFormat, T &...values) {
+		const TDataFormat dataFormatCopy = dataFormat;	// Copy to help compiler alias analysis, parameter is const ref to ensure TDataFormat is a concrete type
+
+		byte buffer[DataMultipleIO<TDataFormat, T...>::kMaxSize];
+		const uint actualSize = DataMultipleIO<TDataFormat, T...>::computeSize(dataFormatCopy);
+
+		if (read(buffer, actualSize) != actualSize)
+			return false;
+
+		DataMultipleIO<T...>::decode(dataFormatCopy, buffer, values...);
+		return true;
+	}
+
+	/**
+	 * Read multiple values from the stream using a specified endianness,
+	 * return true on success and false on failure.
+	 */
+	template<class... T>
+	inline bool readMultipleEndian(bool isLittle, T &...values) {
+		return this->readMultiple<EndianStorageFormat, T...>(isLittle ? EndianStorageFormat::Little : EndianStorageFormat::Big, values...);
+	}
+
+	/**
+	 * Read multiple values from the stream in little endian format,
+	 * return true on success and false on failure.
+	 */
+	template<class... T>
+	inline bool readMultipleLE(T &...values) {
+		return this->readMultiple<EndianStorageFormat, T...>(EndianStorageFormat::Little, values...);
+	}
+
+	/**
+	 * Read multiple values from the stream in big endian format,
+	 * return true on success and false on failure.
+	 */
+	template<class... T>
+	inline bool readMultipleBE(T &...values) {
+		return this->readMultiple<EndianStorageFormat, T...>(EndianStorageFormat::Big, values...);
+	}
+
 	/**
 	 * Read the specified amount of data into a malloc'ed buffer
 	 * which is then wrapped into a MemoryReadStream.


Commit: 58fea8dbcec28550e78f0cf861440c713ee2b2f4
    https://github.com/scummvm/scummvm/commit/58fea8dbcec28550e78f0cf861440c713ee2b2f4
Author: elasota (1137273+elasota at users.noreply.github.com)
Date: 2024-02-27T17:13:35+01:00

Commit Message:
MTROPOLIS: Use data IO templates from Common

Changed paths:
    engines/mtropolis/data.cpp
    engines/mtropolis/data.h


diff --git a/engines/mtropolis/data.cpp b/engines/mtropolis/data.cpp
index df38225f6ad..9135f1e3d66 100644
--- a/engines/mtropolis/data.cpp
+++ b/engines/mtropolis/data.cpp
@@ -202,18 +202,7 @@ bool DataReader::readF64(double &value) {
 }
 
 bool DataReader::readPlatformFloat(Common::XPFloat &value) {
-	if (_dataFormat == kDataFormatMacintosh) {
-		return readMultiple(value.signAndExponent, value.mantissa);
-	} else if (_dataFormat == kDataFormatWindows) {
-		uint64 bits;
-		if (!readU64(bits))
-			return false;
-		value = Common::XPFloat::fromDoubleBits(bits);
-
-		return true;
-	}
-
-	return false;
+	return readMultiple(value);
 }
 
 bool DataReader::read(void *dest, size_t size) {
diff --git a/engines/mtropolis/data.h b/engines/mtropolis/data.h
index 569fbc873ac..7e9c37cd8f7 100644
--- a/engines/mtropolis/data.h
+++ b/engines/mtropolis/data.h
@@ -23,6 +23,7 @@
 #define MTROPOLIS_DATA_H
 
 #include "common/array.h"
+#include "common/data-io.h"
 #include "common/endian.h"
 #include "common/error.h"
 #include "common/hashmap.h"
@@ -38,6 +39,73 @@
 // This is separated from asset construction for a number of reasons, mainly that data parsing has
 // several quirky parses, and there are a lot of fields where, due to platform-specific byte
 // swaps, we know the size of the value but don't know what it means.
+
+namespace MTropolis {
+
+class PlugIn;
+
+namespace Data {
+
+enum DataFormat {
+	kDataFormatUnknown,
+
+	kDataFormatMacintosh,
+	kDataFormatWindows,
+};
+
+} // End of namespace Data
+
+} // End of namespace MTropolis
+
+namespace Common {
+
+template<>
+struct DataFormatTraits<MTropolis::Data::DataFormat> {
+	static inline bool isLittleEndian(MTropolis::Data::DataFormat dataFormat) {
+		return dataFormat != MTropolis::Data::kDataFormatMacintosh;
+	}
+};
+
+template<>
+struct DataIO<MTropolis::Data::DataFormat, Common::XPFloat> {
+	static const uint kMaxSize = 10;
+
+	static inline uint computeSize(MTropolis::Data::DataFormat dataFormat) {
+		if (dataFormat == MTropolis::Data::kDataFormatMacintosh)
+			return 10;
+		else if (dataFormat == MTropolis::Data::kDataFormatWindows)
+			return 8;
+		else
+			return 0;
+	}
+
+	static inline void encode(MTropolis::Data::DataFormat dataFormat, byte *data, const Common::XPFloat &value) {
+		if (dataFormat == MTropolis::Data::kDataFormatMacintosh) {
+			DataIO<MTropolis::Data::DataFormat, uint16>::encode(dataFormat, data + 0, value.signAndExponent);
+			DataIO<MTropolis::Data::DataFormat, uint64>::encode(dataFormat, data + 2, value.mantissa);
+		} else if (MTropolis::Data::kDataFormatWindows) {
+			uint64 doubleBits = 0;
+			bool overflowed = false;
+			value.toDoubleBitsSafe(doubleBits, overflowed);
+			DataIO<MTropolis::Data::DataFormat, uint64>::encode(dataFormat, data, doubleBits);
+		}
+	}
+
+	static inline void decode(MTropolis::Data::DataFormat dataFormat, const byte *data, Common::XPFloat &value) {
+		if (dataFormat == MTropolis::Data::kDataFormatMacintosh) {
+			DataIO<MTropolis::Data::DataFormat, uint16>::decode(dataFormat, data + 0, value.signAndExponent);
+			DataIO<MTropolis::Data::DataFormat, uint64>::decode(dataFormat, data + 2, value.mantissa);
+		} else if (MTropolis::Data::kDataFormatWindows) {
+			uint64 doubleBits = 0;
+			DataIO<MTropolis::Data::DataFormat, uint64>::decode(dataFormat, data, doubleBits);
+			value = value.fromDoubleBits(doubleBits);
+		}
+	}
+};
+
+} // End of namespace Common
+
+
 namespace MTropolis {
 
 class PlugIn;
@@ -70,13 +138,6 @@ enum ProjectFormat {
 	kProjectFormatNeutral,
 };
 
-enum DataFormat {
-	kDataFormatUnknown,
-
-	kDataFormatMacintosh,
-	kDataFormatWindows,
-};
-
 enum DataReadErrorCode {
 	kDataReadErrorNone = 0,
 
@@ -196,217 +257,6 @@ namespace StructuralFlags {
 	};
 } // End of namespace StructuralFlags
 
-template<class T>
-struct SimpleDataIO {
-	static const uint kMaxSize = sizeof(T);
-
-	static uint computeSize(DataFormat dataFormat);
-
-	static void encode(DataFormat dataFormat, byte *data, const T &value);
-	static void decode(DataFormat dataFormat, const byte *data, T &value);
-};
-
-template<class T>
-uint SimpleDataIO<T>::computeSize(DataFormat dataFormat) {
-	return sizeof(T);
-}
-
-template<class T>
-void SimpleDataIO<T>::encode(DataFormat dataFormat, byte *data, const T &value) {
-	const byte *valueBytes = reinterpret_cast<const byte *>(&value);
-	byte *dataBytes = reinterpret_cast<byte *>(data);
-
-	const bool isTargetLE = (dataFormat != kDataFormatMacintosh);
-#ifdef SCUMM_LITTLE_ENDIAN
-	const bool isSystemLE = true;
-#endif
-#ifdef SCUMM_BIG_ENDIAN
-	const bool isSystemLE = false;
-#endif
-
-	const bool requiresSwap = (isSystemLE != isTargetLE);
-
-	byte temp[sizeof(T)];
-
-	if (requiresSwap) {
-		for (uint i = 0; i < sizeof(T); i++)
-			temp[i] = valueBytes[sizeof(T) - 1 - i];
-	} else {
-		for (uint i = 0; i < sizeof(T); i++)
-			temp[i] = valueBytes[i];
-	}
-
-	for (uint i = 0; i < sizeof(T); i++)
-		dataBytes[i] = temp[i];
-}
-
-template<class T>
-void SimpleDataIO<T>::decode(DataFormat dataFormat, const byte *data, T &value) {
-	byte *valueBytes = reinterpret_cast<byte *>(&value);
-	const byte *dataBytes = reinterpret_cast<const byte *>(data);
-
-	const bool isTargetLE = (dataFormat != kDataFormatMacintosh);
-#ifdef SCUMM_LITTLE_ENDIAN
-	const bool isSystemLE = true;
-#endif
-#ifdef SCUMM_BIG_ENDIAN
-	const bool isSystemLE = false;
-#endif
-
-	const bool requiresSwap = (isSystemLE != isTargetLE);
-
-	byte temp[sizeof(T)];
-
-	if (requiresSwap) {
-		for (uint i = 0; i < sizeof(T); i++)
-			temp[i] = dataBytes[sizeof(T) - 1 - i];
-	} else {
-		for (uint i = 0; i < sizeof(T); i++)
-			temp[i] = dataBytes[i];
-	}
-
-	for (uint i = 0; i < sizeof(T); i++)
-		valueBytes[i] = temp[i];
-}
-
-template<class T>
-struct DataIO {
-};
-
-template<>
-struct DataIO<uint8> : public SimpleDataIO<uint8> {
-};
-
-template<>
-struct DataIO<uint16> : public SimpleDataIO<uint16> {
-};
-template<>
-struct DataIO<uint32> : public SimpleDataIO<uint32> {
-};
-template<>
-struct DataIO<uint64> : public SimpleDataIO<uint64> {
-};
-
-template<>
-struct DataIO<int8> : public SimpleDataIO<int8> {
-};
-
-template<>
-struct DataIO<int16> : public SimpleDataIO<int16> {
-};
-template<>
-struct DataIO<int32> : public SimpleDataIO<int32> {
-};
-template<>
-struct DataIO<int64> : public SimpleDataIO<int64> {
-};
-
-template<>
-struct DataIO<char> : public SimpleDataIO<char> {
-};
-
-template<>
-struct DataIO<float> : public SimpleDataIO<float> {
-};
-
-template<>
-struct DataIO<double> : public SimpleDataIO<double> {
-};
-
-template<>
-struct DataIO<Common::XPFloat> {
-	static const uint kMaxSize = 10;
-
-	static uint computeSize(DataFormat dataFormat);
-
-	static void encode(DataFormat dataFormat, byte *data, const Common::XPFloat &value);
-	static void decode(DataFormat dataFormat, const byte *data, Common::XPFloat &value);
-};
-
-template<class T, class... TMore>
-struct DataMultipleIO;
-
-template<class T>
-struct DataMultipleIO<T> {
-	static const uint kMaxSize = DataIO<T>::kMaxSize;
-
-	static uint computeSize(DataFormat dataFormat);
-
-	static void encode(DataFormat dataFormat, byte *data, const T &value);
-	static void decode(DataFormat dataFormat, const byte *data, T &value);
-};
-
-template<class T>
-uint DataMultipleIO<T>::computeSize(DataFormat dataFormat) {
-	return DataIO<T>::computeSize(dataFormat);
-}
-
-template<class T>
-void DataMultipleIO<T>::encode(DataFormat dataFormat, byte *data, const T &value) {
-	return DataIO<T>::encode(dataFormat, data, value);
-}
-
-template<class T>
-void DataMultipleIO<T>::decode(DataFormat dataFormat, const byte *data, T &value) {
-	return DataIO<T>::decode(dataFormat, data, value);
-}
-
-template<class T, uint TSize>
-struct DataMultipleIO<T[TSize]> {
-	static const uint kMaxSize = DataIO<T>::kMaxSize * TSize;
-
-	static uint computeSize(DataFormat dataFormat);
-
-	static void encode(DataFormat dataFormat, byte *data, const T (&value)[TSize]);
-	static void decode(DataFormat dataFormat, const byte *data, T(&value)[TSize]);
-};
-
-template<class T, uint TSize>
-uint DataMultipleIO<T[TSize]>::computeSize(DataFormat dataFormat) {
-	return DataMultipleIO<T>::computeSize(dataFormat) * TSize;
-}
-
-template<class T, uint TSize>
-void DataMultipleIO<T[TSize]>::encode(DataFormat dataFormat, byte *data, const T(&value)[TSize]) {
-	const uint elementSize = DataIO<T>::computeSize(dataFormat);
-	for (uint i = 0; i < TSize; i++)
-		DataMultipleIO<T>::encode(dataFormat, data + elementSize * i, value[i]);
-}
-
-template<class T, uint TSize>
-void DataMultipleIO<T[TSize]>::decode(DataFormat dataFormat, const byte *data, T(&value)[TSize]) {
-	const uint elementSize = DataIO<T>::computeSize(dataFormat);
-	for (uint i = 0; i < TSize; i++)
-		DataMultipleIO<T>::decode(dataFormat, data + elementSize * i, value[i]);
-}
-
-template<class T, class... TMore>
-struct DataMultipleIO {
-	static const uint kMaxSize = DataIO<T>::kMaxSize + DataMultipleIO<TMore...>::kMaxSize;
-
-	static uint computeSize(DataFormat dataFormat);
-
-	static void encode(DataFormat dataFormat, byte *data, const T &firstValue, const TMore &...moreValues);
-	static void decode(DataFormat dataFormat, const byte *data, T &firstValue, TMore &...moreValues);
-};
-
-template<class T, class... TMore>
-uint DataMultipleIO<T, TMore...>::computeSize(DataFormat dataFormat) {
-	return DataMultipleIO<T>::computeSize(dataFormat) + DataMultipleIO<TMore...>::computeSize(dataFormat);
-}
-
-template<class T, class... TMore>
-void DataMultipleIO<T, TMore...>::encode(DataFormat dataFormat, byte *data, const T &firstValue, const TMore &...moreValues) {
-	DataMultipleIO<T>::encode(dataFormat, data, firstValue);
-	DataMultipleIO<TMore...>::encode(dataFormat, data + DataMultipleIO<T>::computeSize(dataFormat), moreValues...);
-}
-
-template<class T, class... TMore>
-void DataMultipleIO<T, TMore...>::decode(DataFormat dataFormat, const byte *data, T &firstValue, TMore &...moreValues) {
-	DataMultipleIO<T>::decode(dataFormat, data, firstValue);
-	DataMultipleIO<TMore...>::decode(dataFormat, data + DataMultipleIO<T>::computeSize(dataFormat), moreValues...);
-}
-
 
 class DataReader {
 public:
@@ -462,13 +312,13 @@ private:
 
 template<class... T>
 bool DataReader::readMultiple(T &...values) {
-	byte buffer[DataMultipleIO<T...>::kMaxSize];
-	const uint actualSize = DataMultipleIO<T...>::computeSize(_dataFormat);
+	byte buffer[Common::DataMultipleIO<DataFormat, T...>::kMaxSize];
+	const uint actualSize = Common::DataMultipleIO<DataFormat, T...>::computeSize(_dataFormat);
 
 	if (!read(buffer, actualSize))
 		return false;
 
-	DataMultipleIO<T...>::decode(_dataFormat, buffer, values...);
+	Common::DataMultipleIO<DataFormat, T...>::decode(_dataFormat, buffer, values...);
 	return true;
 }
 




More information about the Scummvm-git-logs mailing list