[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