1153 lines
32 KiB
C++
1153 lines
32 KiB
C++
#pragma once
|
|
|
|
#include "Types.h"
|
|
#include "BaseObj.h"
|
|
#include "Util.h"
|
|
#include "Array.h"
|
|
#include "Vector.h"
|
|
#include "Str.h"
|
|
#include "Version.h"
|
|
#include "Vec2.h"
|
|
#include "Vec3.h"
|
|
#include "Color3.h"
|
|
#include "Vec4.h"
|
|
#include "Rect.h"
|
|
#include "Color4.h"
|
|
#include "Quat.h"
|
|
#include "Mat2.h"
|
|
#include "Mat3.h"
|
|
#include "Mat4.h"
|
|
|
|
namespace ehs
|
|
{
|
|
template<typename N = UInt_64>
|
|
class Serializer : public BaseObj
|
|
{
|
|
private:
|
|
Endianness endianness;
|
|
Byte* data;
|
|
N size;
|
|
N offset;
|
|
|
|
public:
|
|
~Serializer() override
|
|
{
|
|
delete[] data;
|
|
}
|
|
|
|
Serializer()
|
|
: endianness(Endianness::BE), data(nullptr), size(0), offset(0)
|
|
{
|
|
AddType("Serializer");
|
|
}
|
|
|
|
Serializer(const Endianness endianness)
|
|
: endianness(endianness), data(nullptr), size(0), offset(0)
|
|
{
|
|
AddType("Serializer");
|
|
}
|
|
|
|
Serializer(const Endianness endianness, const N size)
|
|
: endianness(endianness), data(new Byte[size]), size(size), offset(0)
|
|
{
|
|
AddType("Serializer");
|
|
}
|
|
|
|
Serializer(const Endianness endianness, const Byte* const data, const N size, const N offset = 0)
|
|
: endianness(endianness), data(new Byte[size]), size(size), offset(offset)
|
|
{
|
|
AddType("Serializer");
|
|
|
|
for (N i = 0; i < size; ++i)
|
|
this->data[i] = data[i];
|
|
}
|
|
|
|
Serializer(Serializer&& serializer) noexcept
|
|
: BaseObj((BaseObj&&)serializer), endianness(serializer.endianness), data(serializer.data),
|
|
size(serializer.size), offset(serializer.offset)
|
|
{
|
|
serializer.data = nullptr;
|
|
serializer.size = 0;
|
|
serializer.offset = 0;
|
|
}
|
|
|
|
Serializer(const Serializer& serializer)
|
|
: BaseObj(serializer), endianness(serializer.endianness), data(new Byte[serializer.size]),
|
|
size(serializer.size), offset(serializer.offset)
|
|
{
|
|
for (N i = 0; i < serializer.size; ++i)
|
|
data[i] = serializer.data[i];
|
|
}
|
|
|
|
Serializer& operator=(Serializer&& serializer) noexcept
|
|
{
|
|
if (this == &serializer)
|
|
return *this;
|
|
|
|
BaseObj::operator=((Serializer&&)serializer);
|
|
|
|
endianness = serializer.endianness;
|
|
delete[] data;
|
|
data = serializer.data;
|
|
size = serializer.size;
|
|
offset = serializer.offset;
|
|
|
|
serializer.data = nullptr;
|
|
serializer.size = 0;
|
|
serializer.offset = 0;
|
|
|
|
return *this;
|
|
}
|
|
|
|
Serializer& operator=(const Serializer& serializer)
|
|
{
|
|
if (this == &serializer)
|
|
return *this;
|
|
|
|
BaseObj::operator=(serializer);
|
|
|
|
endianness = serializer.endianness;
|
|
|
|
delete[] data;
|
|
data = new Byte[serializer.size];
|
|
for (N i = 0; i < serializer.size; ++i)
|
|
data[i] = serializer.data[i];
|
|
|
|
size = serializer.size;
|
|
offset = serializer.offset;
|
|
|
|
return *this;
|
|
}
|
|
|
|
bool operator==(const Serializer& in) const
|
|
{
|
|
if (size != in.size)
|
|
return false;
|
|
|
|
return Util::IsEqual(data, in.data, size);
|
|
}
|
|
|
|
bool operator!=(const Serializer& in) const
|
|
{
|
|
if (size != in.size)
|
|
return true;
|
|
|
|
return !Util::IsEqual(data, in.data, size);
|
|
}
|
|
|
|
Serializer& operator+=(const N size)
|
|
{
|
|
offset += size;
|
|
return *this;
|
|
}
|
|
|
|
Serializer& operator-=(const N size)
|
|
{
|
|
offset -= size;
|
|
return *this;
|
|
}
|
|
|
|
Serializer& operator*=(const N size)
|
|
{
|
|
offset *= size;
|
|
return *this;
|
|
}
|
|
|
|
Serializer& operator/=(const N size)
|
|
{
|
|
offset /= size;
|
|
return *this;
|
|
}
|
|
|
|
Serializer& operator%=(const N size)
|
|
{
|
|
offset %= size;
|
|
return *this;
|
|
}
|
|
|
|
operator const Byte* () const
|
|
{
|
|
return data;
|
|
}
|
|
|
|
operator Byte* ()
|
|
{
|
|
return data;
|
|
}
|
|
|
|
void SetEndianness(const Endianness newEndianness)
|
|
{
|
|
endianness = newEndianness;
|
|
}
|
|
|
|
Endianness GetEndianness() const
|
|
{
|
|
return endianness;
|
|
}
|
|
|
|
template<typename T, typename O = UInt_64>
|
|
void WriteArray(const T* const value, const O size)
|
|
{
|
|
if (sizeof(N) + size * sizeof(T) > this->size - offset)
|
|
{
|
|
N remainder = sizeof(N) + size * sizeof(T) - (this->size - offset);
|
|
|
|
Byte* r = new Byte[this->size + remainder];
|
|
|
|
for (N i = 0; i < this->size; ++i)
|
|
r[i] = data[i];
|
|
|
|
delete[] data;
|
|
data = r;
|
|
this->size += remainder;
|
|
}
|
|
|
|
if (CPU::GetEndianness() == Endianness::LE)
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
{
|
|
*(N*)&data[offset] = (N)size;
|
|
|
|
offset += sizeof(N);
|
|
|
|
for (N i = 0; i < size; ++i)
|
|
*(T*)&data[offset + i * sizeof(T)] = value[i];
|
|
}
|
|
else
|
|
{
|
|
N tmp = (N)size;
|
|
|
|
for (N i = 0; i < sizeof(N); ++i)
|
|
data[offset + i] = ((Byte*)&tmp)[sizeof(N) - i - 1];
|
|
|
|
offset += sizeof(N);
|
|
|
|
for (N i = 0; i < size; ++i)
|
|
for (N b = 0; b < sizeof(T); ++b)
|
|
data[offset + i * sizeof(T) + b] = ((Byte*)&value[i])[sizeof(T) - i - 1];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
{
|
|
N tmp = (N)size;
|
|
|
|
for (N i = 0; i < sizeof(N); ++i)
|
|
data[offset + i] = ((Byte*)&tmp)[sizeof(N) - i - 1];
|
|
|
|
offset += sizeof(N);
|
|
|
|
for (N i = 0; i < size; ++i)
|
|
for (N b = 0; b < sizeof(T); ++b)
|
|
data[offset + i * sizeof(T) + b] = ((Byte*)&value[i])[sizeof(T) - i - 1];
|
|
}
|
|
else
|
|
{
|
|
*(N*)&data[offset] = (N)size;
|
|
|
|
offset += sizeof(N);
|
|
|
|
for (N i = 0; i < size; ++i)
|
|
*(T*)&data[offset + i * sizeof(T)] = value[i];
|
|
}
|
|
}
|
|
|
|
offset += sizeof(T) * size;
|
|
}
|
|
|
|
template<typename T, typename O = UInt_64>
|
|
void WriteArray(const Array<T, O>& value)
|
|
{
|
|
if (sizeof(N) + value.Size() * sizeof(T) > size - offset)
|
|
{
|
|
N remainder = sizeof(N) + value.Size() * sizeof(T) - (size - offset);
|
|
|
|
Byte* r = new Byte[size + remainder];
|
|
|
|
for (N i = 0; i < size; ++i)
|
|
r[i] = data[i];
|
|
|
|
delete[] data;
|
|
data = r;
|
|
size += remainder;
|
|
}
|
|
|
|
if (CPU::GetEndianness() == Endianness::LE)
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
{
|
|
*(N*)&data[offset] = (N)value.Size();
|
|
|
|
offset += sizeof(N);
|
|
|
|
for (N i = 0; i < value.Size(); ++i)
|
|
*(T*)&data[offset + i * sizeof(T)] = value[i];
|
|
}
|
|
else
|
|
{
|
|
N tmpSize = (N)value.Size();
|
|
|
|
for (N i = 0; i < sizeof(N); ++i)
|
|
data[offset + i] = ((Byte*)&tmpSize)[sizeof(N) - i - 1];
|
|
|
|
offset += sizeof(N);
|
|
|
|
for (N i = 0; i < value.Size(); ++i)
|
|
for (N b = 0; b < sizeof(T); ++b)
|
|
data[offset + i * sizeof(T) + b] = ((Byte*)&value[i])[sizeof(T) - i - 1];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
{
|
|
N tmpSize = (N)value.Size();
|
|
|
|
for (N i = 0; i < sizeof(N); ++i)
|
|
data[offset + i] = ((Byte*)&tmpSize)[sizeof(N) - i - 1];
|
|
|
|
offset += sizeof(N);
|
|
|
|
for (N i = 0; i < value.Size(); ++i)
|
|
for (N b = 0; b < sizeof(T); ++b)
|
|
data[offset + i * sizeof(T) + b] = ((Byte*)&value[i])[sizeof(T) - i - 1];
|
|
}
|
|
else
|
|
{
|
|
*(N*)&data[offset] = (N)value.Size();
|
|
|
|
offset += sizeof(N);
|
|
|
|
for (N i = 0; i < value.Size(); ++i)
|
|
*(T*)&data[offset + i * sizeof(T)] = value[i];
|
|
}
|
|
}
|
|
|
|
offset += sizeof(T) * value.Size();
|
|
}
|
|
|
|
template<typename T, typename O = UInt_64>
|
|
void WriteVector(const Vector<T, O>& value)
|
|
{
|
|
if (sizeof(N) + value.Size() * sizeof(T) > size - offset)
|
|
{
|
|
N remainder = sizeof(N) + value.Size() * sizeof(T) - (size - offset);
|
|
|
|
Byte* r = new Byte[size + remainder];
|
|
|
|
for (N i = 0; i < size; ++i)
|
|
r[i] = data[i];
|
|
|
|
delete[] data;
|
|
data = r;
|
|
size += remainder;
|
|
}
|
|
|
|
if (CPU::GetEndianness() == Endianness::LE)
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
{
|
|
*(N*)&data[offset] = (N)value.Size();
|
|
|
|
offset += sizeof(N);
|
|
|
|
for (N i = 0; i < value.Size(); ++i)
|
|
*(T*)&data[offset + i * sizeof(T)] = value[i];
|
|
}
|
|
else
|
|
{
|
|
N tmpSize = (N)value.Size();
|
|
|
|
for (N i = 0; i < sizeof(N); ++i)
|
|
data[offset + i] = ((Byte*)&tmpSize)[sizeof(N) - i - 1];
|
|
|
|
offset += sizeof(N);
|
|
|
|
for (N i = 0; i < value.Size(); ++i)
|
|
for (N b = 0; b < sizeof(T); ++b)
|
|
data[offset + i * sizeof(T) + b] = ((Byte*)&value[i])[sizeof(T) - i - 1];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
{
|
|
N tmpSize = (N)value.Size();
|
|
|
|
for (N i = 0; i < sizeof(N); ++i)
|
|
data[offset + i] = ((Byte*)&tmpSize)[sizeof(N) - i - 1];
|
|
|
|
offset += sizeof(N);
|
|
|
|
for (N i = 0; i < value.Size(); ++i)
|
|
for (N b = 0; b < sizeof(T); ++b)
|
|
data[offset + i * sizeof(T) + b] = ((Byte*)&value[i])[sizeof(T) - i - 1];
|
|
}
|
|
else
|
|
{
|
|
*(N*)&data[offset] = (N)value.Size();
|
|
|
|
offset += sizeof(N);
|
|
|
|
for (N i = 0; i < value.Size(); ++i)
|
|
*(T*)&data[offset + i * sizeof(T)] = value[i];
|
|
}
|
|
}
|
|
|
|
offset += sizeof(T) * value.Size();
|
|
}
|
|
|
|
template<typename T, typename O = UInt_64>
|
|
void WriteStr(const Str<T, O>& str)
|
|
{
|
|
if (sizeof(N) + sizeof(T) * str.Size() > size - offset)
|
|
{
|
|
N remainder = sizeof(N) + sizeof(T) * str.Size() - (size - offset);
|
|
|
|
Byte* r = new Byte[size + remainder];
|
|
|
|
for (N i = 0; i < size; ++i)
|
|
r[i] = data[i];
|
|
|
|
delete[] data;
|
|
data = r;
|
|
size += remainder;
|
|
}
|
|
|
|
if (CPU::GetEndianness() == Endianness::LE)
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
{
|
|
*(N*)&data[offset] = (N)str.Size();
|
|
|
|
offset += sizeof(N);
|
|
|
|
for (N i = 0; i < str.Size(); ++i)
|
|
*(T*)&data[offset + i * sizeof(T)] = str[i];
|
|
}
|
|
else
|
|
{
|
|
N tmpSize = (N)str.Size();
|
|
|
|
for (N i = 0; i < sizeof(N); ++i)
|
|
data[offset + i] = ((Byte*)&tmpSize)[sizeof(N) - i - 1];
|
|
|
|
offset += sizeof(N);
|
|
|
|
for (N i = 0; i < str.Size(); ++i)
|
|
for (N b = 0; b < sizeof(T); ++b)
|
|
data[offset + i * sizeof(T) + b] = ((Byte*)&str[i])[sizeof(T) - i - 1];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
{
|
|
N tmpSize = (N)str.Size();
|
|
|
|
for (N i = 0; i < sizeof(N); ++i)
|
|
data[offset + i] = ((Byte*)&tmpSize)[sizeof(N) - i - 1];
|
|
|
|
offset += sizeof(N);
|
|
|
|
for (N i = 0; i < str.Size(); ++i)
|
|
for (N b = 0; b < sizeof(T); ++b)
|
|
data[offset + i * sizeof(T) + b] = ((Byte*)&str[i])[sizeof(T) - i - 1];
|
|
}
|
|
else
|
|
{
|
|
*(N*)&data[offset] = (N)str.Size();
|
|
|
|
offset += sizeof(N);
|
|
|
|
for (N i = 0; i < str.Size(); ++i)
|
|
*(T*)&data[offset + i * sizeof(T)] = str[i];
|
|
}
|
|
}
|
|
|
|
offset += str.Size() * sizeof(T);
|
|
}
|
|
|
|
void WriteVersion(const Version& value)
|
|
{
|
|
if (sizeof(unsigned int) * 3 > size - offset)
|
|
{
|
|
N remainder = sizeof(unsigned int) * 3 - (size - offset);
|
|
|
|
Byte* r = new Byte[size + remainder];
|
|
|
|
for (N i = 0; i < size; ++i)
|
|
r[i] = data[i];
|
|
|
|
delete[] data;
|
|
data = r;
|
|
size += remainder;
|
|
}
|
|
|
|
if (CPU::GetEndianness() == Endianness::LE)
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
for (N i = 0; i < 3; ++i)
|
|
*(unsigned int*)&data[offset + i * sizeof(unsigned int)] = value[i];
|
|
else
|
|
for (N i = 0; i < 3; ++i)
|
|
for (N b = 0; b < sizeof(unsigned int); ++b)
|
|
data[offset + i * sizeof(unsigned int) + b] = value[sizeof(unsigned int) - i - 1];
|
|
}
|
|
else
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
for (N i = 0; i < 3; ++i)
|
|
for (N b = 0; b < sizeof(unsigned int); ++b)
|
|
data[offset + i * sizeof(unsigned int) + b] = value[sizeof(unsigned int) - i - 1];
|
|
else
|
|
for (N i = 0; i < 3; ++i)
|
|
*(unsigned int*)&data[offset + i * sizeof(unsigned int)] = value[i];
|
|
}
|
|
|
|
offset += sizeof(unsigned int) * 3;
|
|
}
|
|
|
|
template<typename T>
|
|
void WriteVec2(const Vec2<T>& value)
|
|
{
|
|
if (sizeof(T) * 2 > size - offset)
|
|
{
|
|
N remainder = sizeof(T) * 2 - (size - offset);
|
|
|
|
Byte* r = new Byte[size + remainder];
|
|
|
|
for (N i = 0; i < size; ++i)
|
|
r[i] = data[i];
|
|
|
|
delete[] data;
|
|
data = r;
|
|
size += remainder;
|
|
}
|
|
|
|
if (CPU::GetEndianness() == Endianness::LE)
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
for (N i = 0; i < 2; ++i)
|
|
*(T*)&data[offset + i * sizeof(T)] = value[i];
|
|
else
|
|
for (N i = 0; i < 2; ++i)
|
|
for (N b = 0; b < sizeof(T); ++b)
|
|
data[offset + i * sizeof(T) + b] = value[sizeof(T) - i - 1];
|
|
}
|
|
else
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
for (N i = 0; i < 2; ++i)
|
|
for (N b = 0; b < sizeof(T); ++b)
|
|
data[offset + i * sizeof(T) + b] = value[sizeof(T) - i - 1];
|
|
else
|
|
for (N i = 0; i < 2; ++i)
|
|
*(T*)&data[offset + i * sizeof(T)] = value[i];
|
|
}
|
|
|
|
offset += sizeof(T) * 2;
|
|
}
|
|
|
|
template<typename T>
|
|
void WriteVec3(const Vec3<T>& value)
|
|
{
|
|
if (sizeof(T) * 3 > size - offset)
|
|
{
|
|
N remainder = sizeof(T) * 3 - (size - offset);
|
|
|
|
Byte* r = new Byte[size + remainder];
|
|
|
|
for (N i = 0; i < size; ++i)
|
|
r[i] = data[i];
|
|
|
|
delete[] data;
|
|
data = r;
|
|
size += remainder;
|
|
}
|
|
|
|
if (CPU::GetEndianness() == Endianness::LE)
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
for (N i = 0; i < 3; ++i)
|
|
*(T*)&data[offset + i * sizeof(T)] = value[i];
|
|
else
|
|
for (N i = 0; i < 3; ++i)
|
|
for (N b = 0; b < sizeof(T); ++b)
|
|
data[offset + i * sizeof(T) + b] = value[sizeof(T) - i - 1];
|
|
}
|
|
else
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
for (N i = 0; i < 3; ++i)
|
|
for (N b = 0; b < sizeof(T); ++b)
|
|
data[offset + i * sizeof(T) + b] = value[sizeof(T) - i - 1];
|
|
else
|
|
for (N i = 0; i < 3; ++i)
|
|
*(T*)&data[offset + i * sizeof(T)] = value[i];
|
|
}
|
|
|
|
offset += sizeof(T) * 3;
|
|
}
|
|
|
|
void WriteColor3(const Color3& value)
|
|
{
|
|
if (sizeof(float) * 3 > size - offset)
|
|
{
|
|
N remainder = sizeof(float) * 3 - (size - offset);
|
|
|
|
Byte* r = new Byte[size + remainder];
|
|
|
|
for (N i = 0; i < size; ++i)
|
|
r[i] = data[i];
|
|
|
|
delete[] data;
|
|
data = r;
|
|
size += remainder;
|
|
}
|
|
|
|
if (CPU::GetEndianness() == Endianness::LE)
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
for (N i = 0; i < 3; ++i)
|
|
*(float*)&data[offset + i * sizeof(float)] = value[i];
|
|
else
|
|
for (N i = 0; i < 3; ++i)
|
|
for (N b = 0; b < sizeof(float); ++b)
|
|
data[offset + i * sizeof(float) + b] = value[sizeof(float) - i - 1];
|
|
}
|
|
else
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
for (N i = 0; i < 3; ++i)
|
|
for (N b = 0; b < sizeof(float); ++b)
|
|
data[offset + i * sizeof(float) + b] = value[sizeof(float) - i - 1];
|
|
else
|
|
for (N i = 0; i < 3; ++i)
|
|
*(float*)&data[offset + i * sizeof(float)] = value[i];
|
|
}
|
|
|
|
offset += sizeof(float) * 3;
|
|
}
|
|
|
|
template<typename T>
|
|
void WriteVec4(const Vec4<T>& value)
|
|
{
|
|
if (sizeof(T) * 4 > size - offset)
|
|
{
|
|
N remainder = sizeof(T) * 4 - (size - offset);
|
|
|
|
Byte* r = new Byte[size + remainder];
|
|
|
|
for (N i = 0; i < size; ++i)
|
|
r[i] = data[i];
|
|
|
|
delete[] data;
|
|
data = r;
|
|
size += remainder;
|
|
}
|
|
|
|
if (CPU::GetEndianness() == Endianness::LE)
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
for (N i = 0; i < 4; ++i)
|
|
*(T*)&data[offset + i * sizeof(T)] = value[i];
|
|
else
|
|
for (N i = 0; i < 4; ++i)
|
|
for (N b = 0; b < sizeof(T); ++b)
|
|
data[offset + i * sizeof(T) + b] = value[sizeof(T) - i - 1];
|
|
}
|
|
else
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
for (N i = 0; i < 4; ++i)
|
|
for (N b = 0; b < sizeof(T); ++b)
|
|
data[offset + i * sizeof(T) + b] = value[sizeof(T) - i - 1];
|
|
else
|
|
for (N i = 0; i < 4; ++i)
|
|
*(T*)&data[offset + i * sizeof(T)] = value[i];
|
|
}
|
|
|
|
offset += sizeof(T) * 4;
|
|
}
|
|
|
|
template<typename T>
|
|
void WriteRect(const Rect<T>& value)
|
|
{
|
|
if (sizeof(T) * 4 > size - offset)
|
|
{
|
|
N remainder = sizeof(T) * 4 - (size - offset);
|
|
|
|
Byte* r = new Byte[size + remainder];
|
|
|
|
for (N i = 0; i < size; ++i)
|
|
r[i] = data[i];
|
|
|
|
delete[] data;
|
|
data = r;
|
|
size += remainder;
|
|
}
|
|
|
|
if (CPU::GetEndianness() == Endianness::LE)
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
for (N i = 0; i < 4; ++i)
|
|
*(T*)&data[offset + i * sizeof(T)] = value[i];
|
|
else
|
|
for (N i = 0; i < 4; ++i)
|
|
for (N b = 0; b < sizeof(T); ++b)
|
|
data[offset + i * sizeof(T) + b] = value[sizeof(T) - i - 1];
|
|
}
|
|
else
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
for (N i = 0; i < 4; ++i)
|
|
for (N b = 0; b < sizeof(T); ++b)
|
|
data[offset + i * sizeof(T) + b] = value[sizeof(T) - i - 1];
|
|
else
|
|
for (N i = 0; i < 4; ++i)
|
|
*(T*)&data[offset + i * sizeof(T)] = value[i];
|
|
}
|
|
|
|
offset += sizeof(T) * 4;
|
|
}
|
|
|
|
void WriteColor4(const Color4& value)
|
|
{
|
|
if (sizeof(float) * 4 > size - offset)
|
|
{
|
|
N remainder = sizeof(float) * 4 - (size - offset);
|
|
|
|
Byte* r = new Byte[size + remainder];
|
|
|
|
for (N i = 0; i < size; ++i)
|
|
r[i] = data[i];
|
|
|
|
delete[] data;
|
|
data = r;
|
|
size += remainder;
|
|
}
|
|
|
|
if (CPU::GetEndianness() == Endianness::LE)
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
for (N i = 0; i < 4; ++i)
|
|
*(float*)&data[offset + i * sizeof(float)] = value[i];
|
|
else
|
|
for (N i = 0; i < 4; ++i)
|
|
for (N b = 0; b < sizeof(float); ++b)
|
|
data[offset + i * sizeof(float) + b] = value[sizeof(float) - i - 1];
|
|
}
|
|
else
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
for (N i = 0; i < 4; ++i)
|
|
for (N b = 0; b < sizeof(float); ++b)
|
|
data[offset + i * sizeof(float) + b] = value[sizeof(float) - i - 1];
|
|
else
|
|
for (N i = 0; i < 4; ++i)
|
|
*(float*)&data[offset + i * sizeof(float)] = value[i];
|
|
}
|
|
|
|
offset += sizeof(float) * 4;
|
|
}
|
|
|
|
template<typename T>
|
|
void WriteQuat(const Quat<T>& value)
|
|
{
|
|
if (sizeof(T) * 4 > size - offset)
|
|
{
|
|
N remainder = sizeof(T) * 4 - (size - offset);
|
|
|
|
Byte* r = new Byte[size + remainder];
|
|
|
|
for (N i = 0; i < size; ++i)
|
|
r[i] = data[i];
|
|
|
|
delete[] data;
|
|
data = r;
|
|
size += remainder;
|
|
}
|
|
|
|
if (CPU::GetEndianness() == Endianness::LE)
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
for (N i = 0; i < 4; ++i)
|
|
*(T*)&data[offset + i * sizeof(T)] = value[i];
|
|
else
|
|
for (N i = 0; i < 4; ++i)
|
|
for (N b = 0; b < sizeof(T); ++b)
|
|
data[offset + i * sizeof(T) + b] = value[sizeof(T) - i - 1];
|
|
}
|
|
else
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
for (N i = 0; i < 4; ++i)
|
|
for (N b = 0; b < sizeof(T); ++b)
|
|
data[offset + i * sizeof(T) + b] = value[sizeof(T) - i - 1];
|
|
else
|
|
for (N i = 0; i < 4; ++i)
|
|
*(T*)&data[offset + i * sizeof(T)] = value[i];
|
|
}
|
|
|
|
offset += sizeof(T) * 4;
|
|
}
|
|
|
|
template<typename T>
|
|
void WriteMat2(const Mat2<T>& value)
|
|
{
|
|
if (sizeof(T) * 4 > size - offset)
|
|
{
|
|
N remainder = sizeof(T) * 4 - (size - offset);
|
|
|
|
Byte* r = new Byte[size + remainder];
|
|
|
|
for (N i = 0; i < size; ++i)
|
|
r[i] = data[i];
|
|
|
|
delete[] data;
|
|
data = r;
|
|
size += remainder;
|
|
}
|
|
|
|
if (CPU::GetEndianness() == Endianness::LE)
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
for (N i = 0; i < 4; ++i)
|
|
*(T*)&data[offset + i * sizeof(T)] = value[i];
|
|
else
|
|
for (N i = 0; i < 4; ++i)
|
|
for (N b = 0; b < sizeof(T); ++b)
|
|
data[offset + i * sizeof(T) + b] = ((Byte*)&value[i])[sizeof(T) - b - 1];
|
|
}
|
|
else
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
for (N i = 0; i < 4; ++i)
|
|
for (N b = 0; b < sizeof(T); ++b)
|
|
data[offset + i * sizeof(T) + b] = ((Byte*)&value[i])[sizeof(T) - b - 1];
|
|
else
|
|
for (N i = 0; i < 4; ++i)
|
|
*(T*)&data[offset + i * sizeof(T)] = value[i];
|
|
}
|
|
|
|
offset += sizeof(T) * 4;
|
|
}
|
|
|
|
template<typename T>
|
|
void WriteMat3(const Mat3<T>& value)
|
|
{
|
|
if (sizeof(T) * 9 > size - offset)
|
|
{
|
|
N remainder = sizeof(T) * 9 - (size - offset);
|
|
|
|
Byte* r = new Byte[size + remainder];
|
|
|
|
for (N i = 0; i < size; ++i)
|
|
r[i] = data[i];
|
|
|
|
delete[] data;
|
|
data = r;
|
|
size += remainder;
|
|
}
|
|
|
|
if (CPU::GetEndianness() == Endianness::LE)
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
for (N i = 0; i < 9; ++i)
|
|
*(T*)&data[offset + i * sizeof(T)] = value[i];
|
|
else
|
|
for (N i = 0; i < 9; ++i)
|
|
for (N b = 0; b < sizeof(T); ++b)
|
|
data[offset + i * sizeof(T) + b] = ((Byte*)&value[i])[sizeof(T) - b - 1];
|
|
}
|
|
else
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
for (N i = 0; i < 9; ++i)
|
|
for (N b = 0; b < sizeof(T); ++b)
|
|
data[offset + i * sizeof(T) + b] = ((Byte*)&value[i])[sizeof(T) - b - 1];
|
|
else
|
|
for (N i = 0; i < 9; ++i)
|
|
*(T*)&data[offset + i * sizeof(T)] = value[i];
|
|
}
|
|
|
|
offset += sizeof(T) * 9;
|
|
}
|
|
|
|
template<typename T>
|
|
void WriteMat4(const Mat4<T>& value)
|
|
{
|
|
if (sizeof(T) * 16 > size - offset)
|
|
{
|
|
N remainder = sizeof(T) * 16 - (size - offset);
|
|
|
|
Byte* r = new Byte[size + remainder];
|
|
|
|
for (N i = 0; i < size; ++i)
|
|
r[i] = data[i];
|
|
|
|
delete[] data;
|
|
data = r;
|
|
size += remainder;
|
|
}
|
|
|
|
if (CPU::GetEndianness() == Endianness::LE)
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
for (N y = 0; y < 4; ++y)
|
|
for (N x = 0; x < 4; ++x)
|
|
*(T*)&data[offset + y * sizeof(T) * 4 + x * sizeof(T)] = value[y][x];
|
|
else
|
|
for (N y = 0; y < 4; ++y)
|
|
for (N x = 0; x < 4; ++x)
|
|
for (N i = 0; i < sizeof(T); ++i)
|
|
data[offset + y * sizeof(T) * 4 + x * sizeof(T) + i] = ((Byte*)&value[y][x])[sizeof(T) - i - 1];
|
|
}
|
|
else
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
for (N y = 0; y < 4; ++y)
|
|
for (N x = 0; x < 4; ++x)
|
|
for (N i = 0; i < sizeof(T); ++i)
|
|
data[offset + y * sizeof(T) * 4 + x * sizeof(T) + i] = ((Byte*)&value[y][x])[sizeof(T) - i - 1];
|
|
else
|
|
for (N y = 0; y < 4; ++y)
|
|
for (N x = 0; x < 4; ++x)
|
|
*(T*)&data[offset + y * sizeof(T) * 4 + x * sizeof(T)] = value[y][x];
|
|
}
|
|
|
|
offset += sizeof(T) * 16;
|
|
}
|
|
|
|
void WriteSer(const Serializer& ser)
|
|
{
|
|
if (ser.endianness != endianness)
|
|
return;
|
|
|
|
if (ser.Size() > size - offset)
|
|
{
|
|
N remainder = ser.Size() - (size - offset);
|
|
|
|
Byte* result = new Byte[size + remainder];
|
|
|
|
Util::Copy(result, data, size);
|
|
|
|
delete[] data;
|
|
data = result;
|
|
size += remainder;
|
|
}
|
|
|
|
Util::Copy(&data[offset], &ser[0], ser.Size());
|
|
|
|
offset += ser.Size();
|
|
}
|
|
|
|
template<typename T>
|
|
void Write(const T value)
|
|
{
|
|
if (sizeof(T) > size - offset)
|
|
{
|
|
N remainder = sizeof(T) - (size - offset);
|
|
|
|
Byte* r = new Byte[size + remainder];
|
|
|
|
for (N i = 0; i < size; ++i)
|
|
r[i] = data[i];
|
|
|
|
delete[] data;
|
|
data = r;
|
|
size += remainder;
|
|
}
|
|
|
|
if (CPU::GetEndianness() == Endianness::LE)
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
*(T*)&data[offset] = value;
|
|
else
|
|
for (N i = 0; i < sizeof(T); ++i)
|
|
data[offset + i] = ((Byte*)&value)[sizeof(T) - i - 1];
|
|
}
|
|
else
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
for (N i = 0; i < sizeof(T); ++i)
|
|
data[offset + i] = ((Byte*)&value)[sizeof(T) - i - 1];
|
|
else
|
|
*(T*)&data[offset] = value;
|
|
}
|
|
|
|
offset += sizeof(T);
|
|
}
|
|
|
|
template<typename T, typename O>
|
|
void ReadArray(T* const value, O* const size)
|
|
{
|
|
if (!*size)
|
|
*size = (O)Read<N>();
|
|
|
|
for (N i = 0; i < *size; ++i)
|
|
value[i] = Read<T>();
|
|
}
|
|
|
|
template<typename T, typename O>
|
|
Array<T, O> ReadArray(const O size = 0)
|
|
{
|
|
Array<T, O> result(size ? size : (O)Read<N>());
|
|
|
|
for (O i = 0; i < result.Size(); ++i)
|
|
result[i] = Read<T>();
|
|
|
|
return result;
|
|
}
|
|
|
|
template<typename T, typename O>
|
|
Vector<T, O> ReadVector(const O size = 0)
|
|
{
|
|
Vector<T, O> result(size ? size : (O)Read<N>());
|
|
|
|
for (O i = 0; i < result.Size(); ++i)
|
|
result[i] = Read<T>();
|
|
|
|
return result;
|
|
}
|
|
|
|
template<typename T, typename O>
|
|
Str<T, O> ReadStr(const O size = 0)
|
|
{
|
|
Str<T, O> result(size ? size : (O)Read<N>());
|
|
|
|
for (O i = 0; i < result.Size(); ++i)
|
|
result[i] = Read<T>();
|
|
|
|
return result;
|
|
}
|
|
|
|
Version ReadVersion()
|
|
{
|
|
return {Read<unsigned int>(), Read<unsigned int>(), Read<unsigned int>()};
|
|
}
|
|
|
|
template<typename T>
|
|
Vec2<T> ReadVec2()
|
|
{
|
|
return {Read<T>(), Read<T>()};
|
|
}
|
|
|
|
template<typename T>
|
|
Vec3<T> ReadVec3()
|
|
{
|
|
return {Read<T>(), Read<T>(), Read<T>()};
|
|
}
|
|
|
|
Color3 ReadColor3()
|
|
{
|
|
return {Read<float>(), Read<float>(), Read<float>()};
|
|
}
|
|
|
|
template<typename T>
|
|
Vec4<T> ReadVec4()
|
|
{
|
|
return {Read<T>(), Read<T>(), Read<T>(), Read<T>()};
|
|
}
|
|
|
|
template<typename T>
|
|
Rect<T> ReadRect()
|
|
{
|
|
return {Read<T>(), Read<T>(), Read<T>(), Read<T>()};
|
|
}
|
|
|
|
Color4 ReadColor4()
|
|
{
|
|
return {Read<float>(), Read<float>(), Read<float>(), Read<float>()};
|
|
}
|
|
|
|
template<typename T>
|
|
Quat<T> ReadQuat()
|
|
{
|
|
return {Read<T>(), Read<T>(), Read<T>(), Read<T>()};
|
|
}
|
|
|
|
template<typename T>
|
|
Mat2<T> ReadMat2()
|
|
{
|
|
Mat2<T> result;
|
|
for (N i = 0; i < 4; ++i)
|
|
result[i] = Read<float>();
|
|
|
|
return result;
|
|
}
|
|
|
|
template<typename T>
|
|
Mat3<T> ReadMat3()
|
|
{
|
|
Mat3<T> result;
|
|
for (N i = 0; i < 9; ++i)
|
|
result[i] = Read<float>();
|
|
|
|
return result;
|
|
}
|
|
|
|
template<typename T>
|
|
Mat4<T> ReadMat4()
|
|
{
|
|
Mat4<T> result;
|
|
for (N i = 0; i < 16; ++i)
|
|
result[i] = Read<float>();
|
|
|
|
return result;
|
|
}
|
|
|
|
template<typename T>
|
|
T Read()
|
|
{
|
|
T value = (T)0;
|
|
|
|
if (CPU::GetEndianness() == Endianness::LE)
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
value = *(T*)&data[offset];
|
|
else
|
|
for (N i = 0; i < sizeof(T); ++i)
|
|
((Byte*)&value)[sizeof(T) - i - 1] = data[offset + i];
|
|
}
|
|
else
|
|
{
|
|
if (endianness == Endianness::LE)
|
|
for (N i = 0; i < sizeof(T); ++i)
|
|
((Byte*)&value)[sizeof(T) - i - 1] = data[offset + i];
|
|
else
|
|
value = *(T*)&data[offset];
|
|
}
|
|
|
|
offset += sizeof(T);
|
|
|
|
return value;
|
|
}
|
|
|
|
void SetOffset(const N offset)
|
|
{
|
|
this->offset = offset;
|
|
}
|
|
|
|
N GetOffset() const
|
|
{
|
|
return offset;
|
|
}
|
|
|
|
void Resize(const N newSize)
|
|
{
|
|
Byte* result = new Byte[newSize];
|
|
Util::Copy(result, data, size);
|
|
delete[] data;
|
|
data = result;
|
|
size = newSize;
|
|
}
|
|
|
|
N Size() const
|
|
{
|
|
return size;
|
|
}
|
|
};
|
|
} |