Convert serialization code to use less virtuals and allow more inlining.
This was SVN commit r7582.
This commit is contained in:
parent
9090d25ef8
commit
01bec7a454
@ -23,14 +23,11 @@
|
||||
#include "simulation2/serialization/BinarySerializer.h"
|
||||
#include "simulation2/serialization/StdDeserializer.h"
|
||||
|
||||
/**
|
||||
* Serializer instance that writes directly to a buffer (which must be long enough).
|
||||
*/
|
||||
class CBufferBinarySerializer : public CBinarySerializer
|
||||
class CBufferBinarySerializerImpl
|
||||
{
|
||||
public:
|
||||
CBufferBinarySerializer(ScriptInterface& scriptInterface, u8* buffer) :
|
||||
CBinarySerializer(scriptInterface), m_Buffer(buffer)
|
||||
CBufferBinarySerializerImpl(u8* buffer) :
|
||||
m_Buffer(buffer)
|
||||
{
|
||||
}
|
||||
|
||||
@ -44,16 +41,25 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* Serializer instance that simply counts how many bytes would be written.
|
||||
* Serializer instance that writes directly to a buffer (which must be long enough).
|
||||
*/
|
||||
class CLengthBinarySerializer : public CBinarySerializer
|
||||
class CBufferBinarySerializer : public CBinarySerializer<CBufferBinarySerializerImpl>
|
||||
{
|
||||
public:
|
||||
CLengthBinarySerializer(ScriptInterface& scriptInterface) :
|
||||
CBinarySerializer(scriptInterface), m_Length(0)
|
||||
CBufferBinarySerializer(ScriptInterface& scriptInterface, u8* buffer) :
|
||||
CBinarySerializer<CBufferBinarySerializerImpl>(scriptInterface, buffer)
|
||||
{
|
||||
}
|
||||
|
||||
u8* GetBuffer()
|
||||
{
|
||||
return m_Impl.m_Buffer;
|
||||
}
|
||||
};
|
||||
|
||||
class CLengthBinarySerializerImpl
|
||||
{
|
||||
public:
|
||||
void Put(const char* UNUSED(name), const u8* UNUSED(data), size_t len)
|
||||
{
|
||||
m_Length += len;
|
||||
@ -62,6 +68,23 @@ public:
|
||||
size_t m_Length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Serializer instance that simply counts how many bytes would be written.
|
||||
*/
|
||||
class CLengthBinarySerializer : public CBinarySerializer<CLengthBinarySerializerImpl>
|
||||
{
|
||||
public:
|
||||
CLengthBinarySerializer(ScriptInterface& scriptInterface) :
|
||||
CBinarySerializer<CLengthBinarySerializerImpl>(scriptInterface)
|
||||
{
|
||||
}
|
||||
|
||||
size_t GetLength()
|
||||
{
|
||||
return m_Impl.m_Length;
|
||||
}
|
||||
};
|
||||
|
||||
CSimulationMessage::CSimulationMessage(ScriptInterface& scriptInterface) :
|
||||
CNetMessage(NMT_SIMULATION_COMMAND), m_ScriptInterface(scriptInterface)
|
||||
{
|
||||
@ -84,7 +107,7 @@ u8* CSimulationMessage::Serialize(u8* pBuffer) const
|
||||
serializer.NumberI32_Unbounded("player", m_Player);
|
||||
serializer.NumberU32_Unbounded("turn", m_Turn);
|
||||
serializer.ScriptVal("command", m_Data);
|
||||
return serializer.m_Buffer;
|
||||
return serializer.GetBuffer();
|
||||
}
|
||||
|
||||
const u8* CSimulationMessage::Deserialize(const u8* pStart, const u8* pEnd)
|
||||
@ -112,7 +135,7 @@ size_t CSimulationMessage::GetSerializedLength() const
|
||||
serializer.NumberI32_Unbounded("player", m_Player);
|
||||
serializer.NumberU32_Unbounded("turn", m_Turn);
|
||||
serializer.ScriptVal("command", m_Data);
|
||||
return CNetMessage::GetSerializedLength() + serializer.m_Length;
|
||||
return CNetMessage::GetSerializedLength() + serializer.GetLength();
|
||||
}
|
||||
|
||||
CStr CSimulationMessage::ToString() const
|
||||
|
@ -21,10 +21,7 @@
|
||||
|
||||
#include "SerializedScriptTypes.h"
|
||||
|
||||
#include "lib/byte_order.h"
|
||||
#include "lib/utf8.h"
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/utf16string.h"
|
||||
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "scriptinterface/AutoRooters.h"
|
||||
@ -42,77 +39,12 @@
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
CBinarySerializer::CBinarySerializer(ScriptInterface& scriptInterface) :
|
||||
m_ScriptInterface(scriptInterface), m_ScriptBackrefsNext(1), m_Rooter(scriptInterface)
|
||||
CBinarySerializerScriptImpl::CBinarySerializerScriptImpl(ScriptInterface& scriptInterface, ISerializer& serializer) :
|
||||
m_ScriptInterface(scriptInterface), m_Serializer(serializer), m_ScriptBackrefsNext(1), m_Rooter(m_ScriptInterface)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
The Put* implementations here are designed for subclasses
|
||||
that want an efficient, portable, deserializable representation.
|
||||
(Subclasses with different requirements should override these methods.)
|
||||
|
||||
Numbers are converted to little-endian byte strings, for portability
|
||||
and efficiency.
|
||||
|
||||
Data is not aligned, for storage efficiency.
|
||||
|
||||
*/
|
||||
|
||||
void CBinarySerializer::PutNumber(const char* name, uint8_t value)
|
||||
{
|
||||
Put(name, (const u8*)&value, sizeof(uint8_t));
|
||||
}
|
||||
|
||||
void CBinarySerializer::PutNumber(const char* name, int32_t value)
|
||||
{
|
||||
int32_t v = (i32)to_le32((u32)value);
|
||||
Put(name, (const u8*)&v, sizeof(int32_t));
|
||||
}
|
||||
|
||||
void CBinarySerializer::PutNumber(const char* name, uint32_t value)
|
||||
{
|
||||
uint32_t v = to_le32(value);
|
||||
Put(name, (const u8*)&v, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
void CBinarySerializer::PutNumber(const char* name, float value)
|
||||
{
|
||||
Put(name, (const u8*)&value, sizeof(float));
|
||||
}
|
||||
|
||||
void CBinarySerializer::PutNumber(const char* name, double value)
|
||||
{
|
||||
Put(name, (const u8*)&value, sizeof(double));
|
||||
}
|
||||
|
||||
void CBinarySerializer::PutNumber(const char* name, fixed value)
|
||||
{
|
||||
PutNumber(name, value.GetInternalValue());
|
||||
}
|
||||
|
||||
void CBinarySerializer::PutBool(const char* name, bool value)
|
||||
{
|
||||
NumberU8(name, value ? 1 : 0, 0, 1);
|
||||
}
|
||||
|
||||
void CBinarySerializer::PutString(const char* name, const std::string& value)
|
||||
{
|
||||
// TODO: should intern strings, particularly to save space with script property names
|
||||
PutNumber("string length", (uint32_t)value.length());
|
||||
Put(name, (u8*)value.data(), value.length());
|
||||
}
|
||||
|
||||
void CBinarySerializer::PutScriptVal(const char* UNUSED(name), jsval value)
|
||||
{
|
||||
HandleScriptVal(value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
void CBinarySerializer::HandleScriptVal(jsval val)
|
||||
void CBinarySerializerScriptImpl::HandleScriptVal(jsval val)
|
||||
{
|
||||
JSContext* cx = m_ScriptInterface.GetContext();
|
||||
|
||||
@ -120,19 +52,19 @@ void CBinarySerializer::HandleScriptVal(jsval val)
|
||||
{
|
||||
case JSTYPE_VOID:
|
||||
{
|
||||
NumberU8_Unbounded("type", SCRIPT_TYPE_VOID);
|
||||
m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_VOID);
|
||||
break;
|
||||
}
|
||||
case JSTYPE_NULL: // This type is never actually returned (it's a JS2 feature)
|
||||
{
|
||||
NumberU8_Unbounded("type", SCRIPT_TYPE_NULL);
|
||||
m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_NULL);
|
||||
break;
|
||||
}
|
||||
case JSTYPE_OBJECT:
|
||||
{
|
||||
if (JSVAL_IS_NULL(val))
|
||||
{
|
||||
NumberU8_Unbounded("type", SCRIPT_TYPE_NULL);
|
||||
m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -142,19 +74,19 @@ void CBinarySerializer::HandleScriptVal(jsval val)
|
||||
u32 tag = GetScriptBackrefTag(obj);
|
||||
if (tag)
|
||||
{
|
||||
NumberU8_Unbounded("type", SCRIPT_TYPE_BACKREF);
|
||||
NumberU32_Unbounded("tag", tag);
|
||||
m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_BACKREF);
|
||||
m_Serializer.NumberU32_Unbounded("tag", tag);
|
||||
break;
|
||||
}
|
||||
|
||||
if (JS_IsArrayObject(cx, obj))
|
||||
{
|
||||
NumberU8_Unbounded("type", SCRIPT_TYPE_ARRAY);
|
||||
m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_ARRAY);
|
||||
// TODO: probably should have a more efficient storage format
|
||||
}
|
||||
else
|
||||
{
|
||||
NumberU8_Unbounded("type", SCRIPT_TYPE_OBJECT);
|
||||
m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_OBJECT);
|
||||
|
||||
// if (JS_GetClass(cx, obj))
|
||||
// {
|
||||
@ -184,7 +116,7 @@ void CBinarySerializer::HandleScriptVal(jsval val)
|
||||
// we can't distinguish that from really having 0 properties without performing the actual iteration,
|
||||
// so just assume the object always returns the correct count
|
||||
|
||||
NumberU32_Unbounded("num props", (uint32_t)n);
|
||||
m_Serializer.NumberU32_Unbounded("num props", (uint32_t)n);
|
||||
|
||||
jsid id;
|
||||
|
||||
@ -230,7 +162,7 @@ void CBinarySerializer::HandleScriptVal(jsval val)
|
||||
}
|
||||
case JSTYPE_STRING:
|
||||
{
|
||||
NumberU8_Unbounded("type", SCRIPT_TYPE_STRING);
|
||||
m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_STRING);
|
||||
ScriptString("string", JSVAL_TO_STRING(val));
|
||||
break;
|
||||
}
|
||||
@ -239,24 +171,24 @@ void CBinarySerializer::HandleScriptVal(jsval val)
|
||||
// For efficiency, handle ints and doubles separately.
|
||||
if (JSVAL_IS_INT(val))
|
||||
{
|
||||
NumberU8_Unbounded("type", SCRIPT_TYPE_INT);
|
||||
m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_INT);
|
||||
// jsvals are limited to JSVAL_INT_BITS == 31 bits, even on 64-bit platforms
|
||||
NumberI32("value", (int32_t)JSVAL_TO_INT(val), JSVAL_INT_MIN, JSVAL_INT_MAX);
|
||||
m_Serializer.NumberI32("value", (int32_t)JSVAL_TO_INT(val), JSVAL_INT_MIN, JSVAL_INT_MAX);
|
||||
}
|
||||
else
|
||||
{
|
||||
debug_assert(JSVAL_IS_DOUBLE(val));
|
||||
NumberU8_Unbounded("type", SCRIPT_TYPE_DOUBLE);
|
||||
m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_DOUBLE);
|
||||
jsdouble* dbl = JSVAL_TO_DOUBLE(val);
|
||||
NumberDouble_Unbounded("value", *dbl);
|
||||
m_Serializer.NumberDouble_Unbounded("value", *dbl);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case JSTYPE_BOOLEAN:
|
||||
{
|
||||
NumberU8_Unbounded("type", SCRIPT_TYPE_BOOLEAN);
|
||||
m_Serializer.NumberU8_Unbounded("type", SCRIPT_TYPE_BOOLEAN);
|
||||
JSBool b = JSVAL_TO_BOOLEAN(val);
|
||||
NumberU8_Unbounded("value", b ? 1 : 0);
|
||||
m_Serializer.NumberU8_Unbounded("value", b ? 1 : 0);
|
||||
break;
|
||||
}
|
||||
case JSTYPE_XML:
|
||||
@ -272,7 +204,7 @@ void CBinarySerializer::HandleScriptVal(jsval val)
|
||||
}
|
||||
}
|
||||
|
||||
void CBinarySerializer::ScriptString(const char* name, JSString* string)
|
||||
void CBinarySerializerScriptImpl::ScriptString(const char* name, JSString* string)
|
||||
{
|
||||
jschar* chars = JS_GetStringChars(string);
|
||||
size_t length = JS_GetStringLength(string);
|
||||
@ -282,11 +214,11 @@ void CBinarySerializer::ScriptString(const char* name, JSString* string)
|
||||
#endif
|
||||
|
||||
// Serialize strings directly as UTF-16, to avoid expensive encoding conversions
|
||||
NumberU32_Unbounded("string length", (uint32_t)length);
|
||||
RawBytes(name, (const u8*)chars, length*2);
|
||||
m_Serializer.NumberU32_Unbounded("string length", (uint32_t)length);
|
||||
m_Serializer.RawBytes(name, (const u8*)chars, length*2);
|
||||
}
|
||||
|
||||
u32 CBinarySerializer::GetScriptBackrefTag(JSObject* obj)
|
||||
u32 CBinarySerializerScriptImpl::GetScriptBackrefTag(JSObject* obj)
|
||||
{
|
||||
// To support non-tree structures (e.g. "var x = []; var y = [x, x];"), we need a way
|
||||
// to indicate multiple references to one object(/array). So every time we serialize a
|
||||
|
@ -22,35 +22,24 @@
|
||||
|
||||
#include "scriptinterface/AutoRooters.h"
|
||||
|
||||
#include "lib/byte_order.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
/**
|
||||
* Serialize to a binary stream. Subclasses should just need to implement
|
||||
* the Put() method.
|
||||
* PutScriptVal implementation details.
|
||||
* (Split out from the main class because it's too big to be inlined.)
|
||||
*/
|
||||
class CBinarySerializer : public ISerializer
|
||||
class CBinarySerializerScriptImpl
|
||||
{
|
||||
NONCOPYABLE(CBinarySerializer);
|
||||
public:
|
||||
CBinarySerializer(ScriptInterface& scriptInterface);
|
||||
CBinarySerializerScriptImpl(ScriptInterface& scriptInterface, ISerializer& serializer);
|
||||
|
||||
protected:
|
||||
virtual void PutNumber(const char* name, uint8_t value);
|
||||
virtual void PutNumber(const char* name, int32_t value);
|
||||
virtual void PutNumber(const char* name, uint32_t value);
|
||||
virtual void PutNumber(const char* name, float value);
|
||||
virtual void PutNumber(const char* name, double value);
|
||||
virtual void PutNumber(const char* name, fixed value);
|
||||
virtual void PutBool(const char* name, bool value);
|
||||
virtual void PutString(const char* name, const std::string& value);
|
||||
virtual void PutScriptVal(const char* name, jsval value);
|
||||
|
||||
private:
|
||||
// PutScriptVal implementation details:
|
||||
void ScriptString(const char* name, JSString* string);
|
||||
void HandleScriptVal(jsval val);
|
||||
|
||||
private:
|
||||
ScriptInterface& m_ScriptInterface;
|
||||
ISerializer& m_Serializer;
|
||||
|
||||
typedef std::map<JSObject*, u32> backrefs_t;
|
||||
|
||||
@ -61,4 +50,99 @@ private:
|
||||
AutoGCRooter m_Rooter;
|
||||
};
|
||||
|
||||
/**
|
||||
* Serialize to a binary stream. T must just implement the Put() method.
|
||||
* (We use this templated approach to allow compiler inlining.)
|
||||
*/
|
||||
template <typename T>
|
||||
class CBinarySerializer : public ISerializer
|
||||
{
|
||||
NONCOPYABLE(CBinarySerializer);
|
||||
public:
|
||||
CBinarySerializer(ScriptInterface& scriptInterface) :
|
||||
m_ScriptImpl(new CBinarySerializerScriptImpl(scriptInterface, *this))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename A>
|
||||
CBinarySerializer(ScriptInterface& scriptInterface, A& a) :
|
||||
m_ScriptImpl(new CBinarySerializerScriptImpl(scriptInterface, *this)),
|
||||
m_Impl(a)
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
/*
|
||||
The Put* implementations here are designed for subclasses
|
||||
that want an efficient, portable, deserializable representation.
|
||||
(Subclasses with different requirements should override these methods.)
|
||||
|
||||
Numbers are converted to little-endian byte strings, for portability
|
||||
and efficiency.
|
||||
|
||||
Data is not aligned, for storage efficiency.
|
||||
*/
|
||||
|
||||
virtual void PutNumber(const char* name, uint8_t value)
|
||||
{
|
||||
m_Impl.Put(name, (const u8*)&value, sizeof(uint8_t));
|
||||
}
|
||||
|
||||
virtual void PutNumber(const char* name, int32_t value)
|
||||
{
|
||||
int32_t v = (i32)to_le32((u32)value);
|
||||
m_Impl.Put(name, (const u8*)&v, sizeof(int32_t));
|
||||
}
|
||||
|
||||
virtual void PutNumber(const char* name, uint32_t value)
|
||||
{
|
||||
uint32_t v = to_le32(value);
|
||||
m_Impl.Put(name, (const u8*)&v, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
virtual void PutNumber(const char* name, float value)
|
||||
{
|
||||
m_Impl.Put(name, (const u8*)&value, sizeof(float));
|
||||
}
|
||||
|
||||
virtual void PutNumber(const char* name, double value)
|
||||
{
|
||||
m_Impl.Put(name, (const u8*)&value, sizeof(double));
|
||||
}
|
||||
|
||||
virtual void PutNumber(const char* name, fixed value)
|
||||
{
|
||||
int32_t v = (i32)to_le32((u32)value.GetInternalValue());
|
||||
m_Impl.Put(name, (const u8*)&v, sizeof(int32_t));
|
||||
}
|
||||
|
||||
virtual void PutBool(const char* name, bool value)
|
||||
{
|
||||
NumberU8(name, value ? 1 : 0, 0, 1);
|
||||
}
|
||||
|
||||
virtual void PutString(const char* name, const std::string& value)
|
||||
{
|
||||
// TODO: maybe should intern strings, particularly to save space with script property names
|
||||
PutNumber("string length", (uint32_t)value.length());
|
||||
m_Impl.Put(name, (u8*)value.data(), value.length());
|
||||
}
|
||||
|
||||
virtual void PutScriptVal(const char* UNUSED(name), jsval value)
|
||||
{
|
||||
m_ScriptImpl->HandleScriptVal(value);
|
||||
}
|
||||
|
||||
virtual void PutRaw(const char* name, const u8* data, size_t len)
|
||||
{
|
||||
m_Impl.Put(name, data, len);
|
||||
}
|
||||
|
||||
protected:
|
||||
T m_Impl;
|
||||
|
||||
private:
|
||||
std::auto_ptr<CBinarySerializerScriptImpl> m_ScriptImpl;
|
||||
};
|
||||
|
||||
#endif // INCLUDED_BINARYSERIALIZER
|
||||
|
@ -140,7 +140,7 @@ void CDebugSerializer::PutScriptVal(const char* name, jsval value)
|
||||
m_Stream << INDENT << name << ": " << source << "\n";
|
||||
}
|
||||
|
||||
void CDebugSerializer::Put(const char* name, const u8* data, size_t len)
|
||||
void CDebugSerializer::PutRaw(const char* name, const u8* data, size_t len)
|
||||
{
|
||||
m_Stream << INDENT << name << ": (" << len << " bytes)";
|
||||
|
||||
|
@ -50,8 +50,7 @@ protected:
|
||||
virtual void PutBool(const char* name, bool value);
|
||||
virtual void PutString(const char* name, const std::string& value);
|
||||
virtual void PutScriptVal(const char* name, jsval value);
|
||||
|
||||
virtual void Put(const char* name, const u8* data, size_t len);
|
||||
virtual void PutRaw(const char* name, const u8* data, size_t len);
|
||||
|
||||
private:
|
||||
ScriptInterface& m_ScriptInterface;
|
||||
|
@ -20,22 +20,27 @@
|
||||
#include "HashSerializer.h"
|
||||
|
||||
CHashSerializer::CHashSerializer(ScriptInterface& scriptInterface) :
|
||||
CBinarySerializer(scriptInterface)
|
||||
CBinarySerializer<CHashSerializerImpl>(scriptInterface)
|
||||
{
|
||||
}
|
||||
|
||||
size_t CHashSerializer::GetHashLength()
|
||||
{
|
||||
return HashFunc::DIGESTSIZE;
|
||||
return m_Impl.GetHashLength();
|
||||
}
|
||||
|
||||
const u8* CHashSerializer::ComputeHash()
|
||||
{
|
||||
return m_Impl.ComputeHash();
|
||||
}
|
||||
|
||||
size_t CHashSerializerImpl::GetHashLength()
|
||||
{
|
||||
return HashFunc::DIGESTSIZE;
|
||||
}
|
||||
|
||||
const u8* CHashSerializerImpl::ComputeHash()
|
||||
{
|
||||
m_Hash.Final(m_HashData);
|
||||
return m_HashData;
|
||||
}
|
||||
|
||||
void CHashSerializer::Put(const char* UNUSED(name), const u8* data, size_t len)
|
||||
{
|
||||
m_Hash.Update(data, len);
|
||||
}
|
||||
|
@ -22,22 +22,33 @@
|
||||
|
||||
#include "maths/MD5.h"
|
||||
|
||||
class CHashSerializer : public CBinarySerializer
|
||||
class CHashSerializerImpl
|
||||
{
|
||||
// We don't care about cryptographic strength, just about detection of
|
||||
// unintended changes and about performance, so MD5 is an adequate choice
|
||||
typedef MD5 HashFunc;
|
||||
|
||||
public:
|
||||
CHashSerializer(ScriptInterface& scriptInterface);
|
||||
size_t GetHashLength();
|
||||
const u8* ComputeHash();
|
||||
|
||||
protected:
|
||||
virtual void Put(const char* name, const u8* data, size_t len);
|
||||
void Put(const char* UNUSED(name), const u8* data, size_t len)
|
||||
{
|
||||
m_Hash.Update(data, len);
|
||||
}
|
||||
|
||||
private:
|
||||
HashFunc m_Hash;
|
||||
u8 m_HashData[HashFunc::DIGESTSIZE];
|
||||
};
|
||||
|
||||
class CHashSerializer : public CBinarySerializer<CHashSerializerImpl>
|
||||
{
|
||||
public:
|
||||
CHashSerializer(ScriptInterface& scriptInterface);
|
||||
|
||||
size_t GetHashLength();
|
||||
const u8* ComputeHash();
|
||||
};
|
||||
|
||||
#endif // INCLUDED_HASHSERIALIZER
|
||||
|
@ -46,41 +46,6 @@ void ISerializer::NumberU32(const char* name, uint32_t value, uint32_t lower, ui
|
||||
PutNumber(name, value);
|
||||
}
|
||||
|
||||
void ISerializer::NumberU8_Unbounded(const char* name, uint8_t value)
|
||||
{
|
||||
PutNumber(name, value);
|
||||
}
|
||||
|
||||
void ISerializer::NumberI32_Unbounded(const char* name, int32_t value)
|
||||
{
|
||||
PutNumber(name, value);
|
||||
}
|
||||
|
||||
void ISerializer::NumberU32_Unbounded(const char* name, uint32_t value)
|
||||
{
|
||||
PutNumber(name, value);
|
||||
}
|
||||
|
||||
void ISerializer::NumberFloat_Unbounded(const char* name, float value)
|
||||
{
|
||||
PutNumber(name, value);
|
||||
}
|
||||
|
||||
void ISerializer::NumberDouble_Unbounded(const char* name, double value)
|
||||
{
|
||||
PutNumber(name, value);
|
||||
}
|
||||
|
||||
void ISerializer::NumberFixed_Unbounded(const char* name, fixed value)
|
||||
{
|
||||
PutNumber(name, value);
|
||||
}
|
||||
|
||||
void ISerializer::Bool(const char* name, bool value)
|
||||
{
|
||||
PutBool(name, value);
|
||||
}
|
||||
|
||||
void ISerializer::StringASCII(const char* name, const std::string& value, uint32_t minlength, uint32_t maxlength)
|
||||
{
|
||||
if (!(minlength <= value.length() && value.length() <= maxlength))
|
||||
@ -123,7 +88,7 @@ void ISerializer::ScriptVal(const char* name, CScriptValRooted value)
|
||||
|
||||
void ISerializer::RawBytes(const char* name, const u8* data, size_t len)
|
||||
{
|
||||
Put(name, data, len);
|
||||
PutRaw(name, data, len);
|
||||
}
|
||||
|
||||
bool ISerializer::IsDebug() const
|
||||
|
@ -144,17 +144,44 @@ public:
|
||||
* @param name informative name for debug output
|
||||
* @param value value to serialize
|
||||
*/
|
||||
void NumberU8_Unbounded(const char* name, uint8_t value);
|
||||
void NumberI32_Unbounded(const char* name, int32_t value); ///< @copydoc NumberU8_Unbounded
|
||||
void NumberU32_Unbounded(const char* name, uint32_t value); ///< @copydoc NumberU8_Unbounded
|
||||
void NumberFloat_Unbounded(const char* name, float value); ///< @copydoc NumberU8_Unbounded
|
||||
void NumberDouble_Unbounded(const char* name, double value); ///< @copydoc NumberU8_Unbounded
|
||||
void NumberFixed_Unbounded(const char* name, fixed value); ///< @copydoc NumberU8_Unbounded
|
||||
void NumberU8_Unbounded(const char* name, uint8_t value)
|
||||
{
|
||||
// (These functions are defined inline for efficiency)
|
||||
PutNumber(name, value);
|
||||
}
|
||||
|
||||
void NumberI32_Unbounded(const char* name, int32_t value) ///< @copydoc NumberU8_Unbounded
|
||||
{
|
||||
PutNumber(name, value);
|
||||
}
|
||||
|
||||
void NumberU32_Unbounded(const char* name, uint32_t value) ///< @copydoc NumberU8_Unbounded
|
||||
{
|
||||
PutNumber(name, value);
|
||||
}
|
||||
|
||||
void NumberFloat_Unbounded(const char* name, float value) ///< @copydoc NumberU8_Unbounded
|
||||
{
|
||||
PutNumber(name, value);
|
||||
}
|
||||
|
||||
void NumberDouble_Unbounded(const char* name, double value) ///< @copydoc NumberU8_Unbounded
|
||||
{
|
||||
PutNumber(name, value);
|
||||
}
|
||||
|
||||
void NumberFixed_Unbounded(const char* name, fixed value) ///< @copydoc NumberU8_Unbounded
|
||||
{
|
||||
PutNumber(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize a boolean.
|
||||
*/
|
||||
void Bool(const char* name, bool value);
|
||||
void Bool(const char* name, bool value)
|
||||
{
|
||||
PutBool(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize an ASCII string.
|
||||
@ -215,8 +242,7 @@ protected:
|
||||
virtual void PutBool(const char* name, bool value) = 0;
|
||||
virtual void PutString(const char* name, const std::string& value) = 0;
|
||||
virtual void PutScriptVal(const char* name, jsval value) = 0;
|
||||
|
||||
virtual void Put(const char* name, const u8* data, size_t len) = 0;
|
||||
virtual void PutRaw(const char* name, const u8* data, size_t len) = 0;
|
||||
};
|
||||
|
||||
#endif // INCLUDED_ISERIALIZER
|
||||
|
@ -21,9 +21,6 @@
|
||||
|
||||
#include "SerializedScriptTypes.h"
|
||||
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/CStr.h"
|
||||
|
||||
#include "scriptinterface/ScriptInterface.h"
|
||||
#include "js/jsapi.h"
|
||||
|
||||
|
@ -22,20 +22,12 @@
|
||||
#include <ostream>
|
||||
#include <cstring>
|
||||
|
||||
CStdSerializerImpl::CStdSerializerImpl(std::ostream& stream) :
|
||||
m_Stream(stream)
|
||||
{
|
||||
}
|
||||
|
||||
CStdSerializer::CStdSerializer(ScriptInterface& scriptInterface, std::ostream& stream) :
|
||||
CBinarySerializer(scriptInterface), m_Stream(stream)
|
||||
CBinarySerializer<CStdSerializerImpl>(scriptInterface, stream)
|
||||
{
|
||||
}
|
||||
|
||||
void CStdSerializer::Put(const char* name, const u8* data, size_t len)
|
||||
{
|
||||
#if 0 // annotate the stream to help debugging if you're reading the output in a hex editor
|
||||
m_Stream.put('[');
|
||||
m_Stream.write(name, strlen(name));
|
||||
m_Stream.put(']');
|
||||
#else
|
||||
UNUSED2(name);
|
||||
#endif
|
||||
|
||||
m_Stream.write((const char*)data, len);
|
||||
}
|
||||
|
@ -20,16 +20,31 @@
|
||||
|
||||
#include "BinarySerializer.h"
|
||||
|
||||
class CStdSerializer : public CBinarySerializer
|
||||
class CStdSerializerImpl
|
||||
{
|
||||
public:
|
||||
CStdSerializer(ScriptInterface& scriptInterface, std::ostream& stream);
|
||||
CStdSerializerImpl(std::ostream& stream);
|
||||
|
||||
protected:
|
||||
virtual void Put(const char* name, const u8* data, size_t len);
|
||||
void Put(const char* name, const u8* data, size_t len)
|
||||
{
|
||||
#if 0 // annotate the stream to help debugging if you're reading the output in a hex editor
|
||||
m_Stream.put('[');
|
||||
m_Stream.write(name, strlen(name));
|
||||
m_Stream.put(']');
|
||||
#else
|
||||
UNUSED2(name);
|
||||
#endif
|
||||
m_Stream.write((const char*)data, len);
|
||||
}
|
||||
|
||||
private:
|
||||
std::ostream& m_Stream;
|
||||
};
|
||||
|
||||
class CStdSerializer : public CBinarySerializer<CStdSerializerImpl>
|
||||
{
|
||||
public:
|
||||
CStdSerializer(ScriptInterface& scriptInterface, std::ostream& stream);
|
||||
};
|
||||
|
||||
#endif // INCLUDED_STDSERIALIZER
|
||||
|
Loading…
Reference in New Issue
Block a user