Urho3D/Engine/IO/Serializer.cpp

348 строки
9.3 KiB
C++

//
// Copyright (c) 2008-2013 the Urho3D project.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#include "Precompiled.h"
#include "BoundingBox.h"
#include "Serializer.h"
#include "Variant.h"
#include "DebugNew.h"
namespace Urho3D
{
static const float q = 32767.0f;
Serializer::~Serializer()
{
}
bool Serializer::WriteInt(int value)
{
return Write(&value, sizeof value) == sizeof value;
}
bool Serializer::WriteShort(short value)
{
return Write(&value, sizeof value) == sizeof value;
}
bool Serializer::WriteByte(signed char value)
{
return Write(&value, sizeof value) == sizeof value;
}
bool Serializer::WriteUInt(unsigned value)
{
return Write(&value, sizeof value) == sizeof value;
}
bool Serializer::WriteUShort(unsigned short value)
{
return Write(&value, sizeof value) == sizeof value;
}
bool Serializer::WriteUByte(unsigned char value)
{
return Write(&value, sizeof value) == sizeof value;
}
bool Serializer::WriteBool(bool value)
{
return WriteUByte(value ? 1 : 0) == 1;
}
bool Serializer::WriteFloat(float value)
{
return Write(&value, sizeof value) == sizeof value;
}
bool Serializer::WriteIntRect(const IntRect& value)
{
return Write(value.Data(), sizeof value) == sizeof value;
}
bool Serializer::WriteIntVector2(const IntVector2& value)
{
return Write(value.Data(), sizeof value) == sizeof value;
}
bool Serializer::WriteRect(const Rect& value)
{
return Write(value.Data(), sizeof value) == sizeof value;
}
bool Serializer::WriteVector2(const Vector2& value)
{
return Write(value.Data(), sizeof value) == sizeof value;
}
bool Serializer::WriteVector3(const Vector3& value)
{
return Write(value.Data(), sizeof value) == sizeof value;
}
bool Serializer::WritePackedVector3(const Vector3& value, float maxAbsCoord)
{
short coords[3];
float v = 32767.0f / maxAbsCoord;
coords[0] = (short)(Clamp(value.x_, -maxAbsCoord, maxAbsCoord) * v + 0.5f);
coords[1] = (short)(Clamp(value.y_, -maxAbsCoord, maxAbsCoord) * v + 0.5f);
coords[2] = (short)(Clamp(value.z_, -maxAbsCoord, maxAbsCoord) * v + 0.5f);
return Write(&coords[0], sizeof coords) == sizeof coords;
}
bool Serializer::WriteVector4(const Vector4& value)
{
return Write(value.Data(), sizeof value) == sizeof value;
}
bool Serializer::WriteQuaternion(const Quaternion& value)
{
return Write(value.Data(), sizeof value) == sizeof value;
}
bool Serializer::WritePackedQuaternion(const Quaternion& value)
{
short coords[4];
Quaternion norm = value.Normalized();
coords[0] = (short)(Clamp(norm.w_, -1.0f, 1.0f) * q + 0.5f);
coords[1] = (short)(Clamp(norm.x_, -1.0f, 1.0f) * q + 0.5f);
coords[2] = (short)(Clamp(norm.y_, -1.0f, 1.0f) * q + 0.5f);
coords[3] = (short)(Clamp(norm.z_, -1.0f, 1.0f) * q + 0.5f);
return Write(&coords[0], sizeof coords) == sizeof value;
}
bool Serializer::WriteColor(const Color& value)
{
return Write(value.Data(), sizeof value) == sizeof value;
}
bool Serializer::WriteBoundingBox(const BoundingBox& value)
{
bool success = true;
success &= WriteVector3(value.min_);
success &= WriteVector3(value.max_);
return success;
}
bool Serializer::WriteString(const String& value)
{
const char* chars = value.CString();
// Count length to the first zero, because ReadString() does the same
unsigned length = strlen(chars);
return Write(chars, length + 1) == length + 1;
}
bool Serializer::WriteFileID(const String& value)
{
bool success = true;
unsigned length = Min((int)value.Length(), 4);
success &= Write(value.CString(), length) == length;
for (unsigned i = value.Length(); i < 4; ++i)
success &= WriteByte(' ');
return success;
}
bool Serializer::WriteStringHash(const StringHash& value)
{
return WriteUInt(value.Value());
}
bool Serializer::WriteShortStringHash(const ShortStringHash& value)
{
return WriteUShort(value.Value());
}
bool Serializer::WriteBuffer(const PODVector<unsigned char>& value)
{
bool success = true;
unsigned size = value.Size();
success &= WriteVLE(size);
if (size)
success &= Write(&value[0], size) == size;
return success;
}
bool Serializer::WriteResourceRef(const ResourceRef& value)
{
bool success = true;
success &= WriteShortStringHash(value.type_);
success &= WriteStringHash(value.id_);
return success;
}
bool Serializer::WriteResourceRefList(const ResourceRefList& value)
{
bool success = true;
unsigned size = value.ids_.Size() * sizeof(StringHash);
success &= WriteShortStringHash(value.type_);
success &= WriteVLE(value.ids_.Size());
if (size)
success &= Write(&value.ids_[0], size) == size;
return success;
}
bool Serializer::WriteVariant(const Variant& value)
{
bool success = true;
VariantType type = value.GetType();
success &= WriteUByte((unsigned char)type);
success &= WriteVariantData(value);
return success;
}
bool Serializer::WriteVariantData(const Variant& value)
{
switch (value.GetType())
{
case VAR_NONE:
return true;
case VAR_INT:
return WriteInt(value.GetInt());
case VAR_BOOL:
return WriteBool(value.GetBool());
case VAR_FLOAT:
return WriteFloat(value.GetFloat());
case VAR_VECTOR2:
return WriteVector2(value.GetVector2());
case VAR_VECTOR3:
return WriteVector3(value.GetVector3());
case VAR_VECTOR4:
return WriteVector4(value.GetVector4());
case VAR_QUATERNION:
return WriteQuaternion(value.GetQuaternion());
case VAR_COLOR:
return WriteColor(value.GetColor());
case VAR_STRING:
return WriteString(value.GetString());
case VAR_BUFFER:
return WriteBuffer(value.GetBuffer());
case VAR_PTR:
return WriteUInt(0);
case VAR_RESOURCEREF:
return WriteResourceRef(value.GetResourceRef());
case VAR_RESOURCEREFLIST:
return WriteResourceRefList(value.GetResourceRefList());
case VAR_VARIANTVECTOR:
return WriteVariantVector(value.GetVariantVector());
case VAR_VARIANTMAP:
return WriteVariantMap(value.GetVariantMap());
case VAR_INTRECT:
return WriteIntRect(value.GetIntRect());
case VAR_INTVECTOR2:
return WriteIntVector2(value.GetIntVector2());
default:
return false;
}
}
bool Serializer::WriteVariantVector(const VariantVector& value)
{
bool success = true;
success &= WriteVLE(value.Size());
for (VariantVector::ConstIterator i = value.Begin(); i != value.End(); ++i)
success &= WriteVariant(*i);
return success;
}
bool Serializer::WriteVariantMap(const VariantMap& value)
{
bool success = true;
success &= WriteVLE(value.Size());
for (VariantMap::ConstIterator i = value.Begin(); i != value.End(); ++i)
{
WriteShortStringHash(i->first_);
WriteVariant(i->second_);
}
return success;
}
bool Serializer::WriteVLE(unsigned value)
{
unsigned char data[4];
if (value < 0x80)
return WriteUByte(value);
else if (value < 0x4000)
{
data[0] = value | 0x80;
data[1] = value >> 7;
return Write(data, 2) == 2;
}
else if (value < 0x200000)
{
data[0] = value | 0x80;
data[1] = (value >> 7) | 0x80;
data[2] = value >> 14;
return Write(data, 3) == 3;
}
else
{
data[0] = value | 0x80;
data[1] = (value >> 7) | 0x80;
data[2] = (value >> 14) | 0x80;
data[3] = (value >> 21);
return Write(data, 4) == 4;
}
}
bool Serializer::WriteNetID(unsigned value)
{
return Write(&value, 3) == 3;
}
bool Serializer::WriteLine(const String& value)
{
bool success = true;
success &= Write(value.CString(), value.Length()) == value.Length();
success &= WriteUByte(13);
success &= WriteUByte(10);
return success;
}
}