Defining a shared interface
Given these prerequisites, I came up with the following interface for the Serializer
and Deserializer
class.
#ifndef VTE_CORE_SERIALIZER_H #define VTE_CORE_SERIALIZER_H #include <core/Types.h> namespace vte { namespace core { class Serializer { public: virtual ~Serializer() { } virtual void beginAttribute( const std::string& name ) = 0; virtual void writeNumberOfElements( u32 numElements ) = 0; virtual void writeParameter( const std::string& name, const std::string& value ) = 0; virtual void writeParameter( const std::string& name, s32 value, const std::string& readable ) = 0; virtual void writeParameter( const std::string& name, const bool& value ) = 0; virtual void writeParameter( const std::string& name, const u32& value ) = 0; virtual void writeParameter( const std::string& name, const f32& value ) = 0; virtual void writeParameter( const std::string& name, const vec3& value ) = 0; virtual void writeParameter( const std::string& name, const irr::video::SColorf& value ) = 0; virtual void endAttribute() = 0; }; } // namespace core } // namespace vte #endif
#ifndef VTE_CORE_DESERIALIZER_H #define VTE_CORE_DESERIALIZER_H #include <core/Types.h> namespace vte { namespace core { class Deserializer { public: Deserializer() { } virtual ~Deserializer() { } virtual void beginAttribute( const std::string& name ) = 0; virtual u32 readNumberOfElements() = 0; virtual void readParameter( const std::string& name, std::string& value ) = 0; virtual void readParameter( const std::string& name, s32& value, std::string& readable ) = 0; virtual void readParameter( const std::string& name, bool& value ) = 0; virtual void readParameter( const std::string& name, u32& value ) = 0; virtual void readParameter( const std::string& name, f32& value ) = 0; virtual void readParameter( const std::string& name, vec3& value ) = 0; virtual void readParameter( const std::string& name, irr::video::SColorf& value ) = 0; virtual void endAttribute() = 0; }; } // namespace core } // namespace vte #endif
Let’s have a look at the methods available.
beginAttribute
starts a logical group of data. It’s required from the XML point of view where it will introduce a new enclosing tag. Therefore, this would be the very first method you would call in order to serialize something. Technically speaking, the XML serializer we will implement later appends a child element. Because no such information is required for binary serialization, the binary serializer implementation of this method would be empty.writeNumberOfElements
writes the number of child elements, if any. Now it’s the other way round: the XML serializer won’t write anything since the number of children is implicitly known by the number of child elements in the XML tree, contrary the the binary format, where we need to know how many child elements will follow.writeParameter
writes an actual item of information, like astd::string
or anf32
(which is atypedef
for afloat
)or some application-dependent types likeirr::video::SColorf
(which is the structure which holds color information in the Irrlicht engine, in case you were curious).endAttribute
finally closes a logical group of data. As withbeginAttribute
, the underlying implementation for XML serialization closes the enclosing tag while the binary one does nothing.
4 Comments