/* Copyright (c) 2014 Alex Diener This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Alex Diener alex@ludobloom.com */ #ifndef __SerializationContext_H__ #define __SerializationContext_H__ #ifdef __cplusplus extern "C" { #endif #include "gamemath/FixedPoint.h" #include "serialization/SerializationShared.h" #include "stemobject/StemObject.h" #include #include #include // Assumptions: // - In its full serialized form, object is written as a top-level structure with format_type and format_version fields. // - An untyped SerializationContext is passed to the function using this macro, with the name serializationContext. // - Constants *_FORMAT_TYPE and *_FORMAT_VERSION are defined with the shared prefix given by format_type_version_prefix. // - object_type is both the type name of the object being serialized, and the prefix for a _serializeMinimal() function. // - _serializeMinimal() takes the object as its first argument, the format version as a uint16_t as its second argument, // and any additional arguments in the same order as _serialize() (or the function using this macro). #define serialize_implementation_v2(object_type, object, format_type_version_prefix, ...) \ SerializationContext * context = serializationContext; \ call_virtual(beginStructure, context, stemobject_cat(format_type_version_prefix, FORMAT_TYPE)); \ call_virtual(writeString, context, "format_type", stemobject_cat(format_type_version_prefix, FORMAT_TYPE)); \ call_virtual(writeUInt16, context, "format_version", stemobject_cat(format_type_version_prefix, FORMAT_VERSION)); \ object_type##_serializeMinimal(object, context, ##__VA_ARGS__); \ call_virtual(endStructure, context); typedef struct SerializationContext SerializationContext; #define SerializationContext_superclass StemObject #define SerializationContext_ivars \ StemObject_ivars \ \ jmp_buf * jmpBuf; \ int status; #define SerializationContext_vtable(self_type) \ StemObject_vtable(self_type) \ \ const char * (* errorString)(int status); \ \ void (* beginStructure)(self_type * self, const char * key); \ void (* beginDictionary)(self_type * self, const char * key); \ void (* beginArray)(self_type * self, const char * key); \ \ void (* endStructure)(self_type * self); \ void (* endDictionary)(self_type * self); \ void (* endArray)(self_type * self); \ \ void (* writeBoolean)(self_type * self, const char * key, bool value); \ void (* writeInt8)(self_type * self, const char * key, int8_t value); \ void (* writeUInt8)(self_type * self, const char * key, uint8_t value); \ void (* writeInt16)(self_type * self, const char * key, int16_t value); \ void (* writeUInt16)(self_type * self, const char * key, uint16_t value); \ void (* writeInt32)(self_type * self, const char * key, int32_t value); \ void (* writeUInt32)(self_type * self, const char * key, uint32_t value); \ void (* writeInt64)(self_type * self, const char * key, int64_t value); \ void (* writeUInt64)(self_type * self, const char * key, uint64_t value); \ void (* writeFloat)(self_type * self, const char * key, float value); \ void (* writeDouble)(self_type * self, const char * key, double value); \ void (* writeFixed16_16)(self_type * self, const char * key, fixed16_16 value); \ \ /* All possible values of the value argument must be represented in values. Writing an unrepresented value */ \ /* results in status being set to SERIALIZATION_ERROR_ENUM_NOT_NAMED and serialization failing. Keys and */ \ /* values must also be unique (SERIALIZATION_ERROR_DUPLICATE_ENUM_NAME, SERIALIZATION_ERROR_DUPLICATE_ENUM_VALUE). */ \ void (* writeEnumeration)(self_type * self, const char * key, int value, unsigned int valueCount, Serialization_enumKeyValue * values); \ void (* writeEnumeration8)(self_type * self, const char * key, int8_t value, unsigned int valueCount, Serialization_enumKeyValue * values); \ void (* writeEnumeration16)(self_type * self, const char * key, int16_t value, unsigned int valueCount, Serialization_enumKeyValue * values); \ void (* writeEnumeration32)(self_type * self, const char * key, int32_t value, unsigned int valueCount, Serialization_enumKeyValue * values); \ \ /* All possible bits that can be set must be represented in bitNames. Writing a value where an unnamed bit is set */ \ /* results in status being set to SERIALIZATION_ERROR_UNNAMED_BIT. Bit names and indexes must also be unique */ \ /* (SERIALIZATION_ERROR_DUPLICATE_BIT). */ \ void (* writeBitfield8)(self_type * self, const char * key, uint8_t value, unsigned int bitNameCount, Serialization_bitName * bitNames); \ void (* writeBitfield16)(self_type * self, const char * key, uint16_t value, unsigned int bitNameCount, Serialization_bitName * bitNames); \ void (* writeBitfield32)(self_type * self, const char * key, uint32_t value, unsigned int bitNameCount, Serialization_bitName * bitNames); \ void (* writeBitfield64)(self_type * self, const char * key, uint64_t value, unsigned int bitNameCount, Serialization_bitName * bitNames); \ \ void (* writeString)(self_type * self, const char * key, const char * value); \ void (* writeStringNullable)(self_type * self, const char * key, const char * value); \ void (* writeBlob)(self_type * self, const char * key, const void * bytes, size_t length); stemobject_declare(SerializationContext) bool SerializationContext_init(SerializationContext * self); void SerializationContext_dispose(SerializationContext * self); #ifdef __cplusplus } #endif #endif