/* 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 */ #include "serialization/SerializationShared.h" #include #include #include const char * Serialization_errorString(int status) { switch (status) { #ifdef DEBUG case SERIALIZATION_ERROR_OK: return "No error"; case SERIALIZATION_ERROR_INVALID_OPERATION: return "Incorrect API usage"; case SERIALIZATION_ERROR_KEY_NOT_FOUND: return "The requested key is not present in the current dictionary or structure"; case SERIALIZATION_ERROR_CONTAINER_TYPE_MISMATCH: return "A call to begin wasn't paired with the correct one of end"; case SERIALIZATION_ERROR_CONTAINER_UNDERFLOW: return "More calls to end than to begin"; case SERIALIZATION_ERROR_MULTIPLE_TOP_LEVEL_CONTAINERS: return "After a matched number of calls to , begin is called again"; case SERIALIZATION_ERROR_UNNAMED_BIT: return "In a call to Bitfield<8|16|32|64>, one or more of set bits isn't named in function arguments"; case SERIALIZATION_ERROR_DUPLICATE_BIT: return "In a call to Bitfield<8|16|32|64>, multiple bits are given the same name"; case SERIALIZATION_ERROR_ENUM_NOT_NAMED: return "In a call to Enumeration, the enumeration value is not named"; case SERIALIZATION_ERROR_DUPLICATE_ENUM_NAME: return "In a call to Enumeration, multiple enumeration values are given the same name"; case SERIALIZATION_ERROR_DUPLICATE_ENUM_VALUE: return "In a call to Enumeration, multiple enumeration names are given the same value"; case SERIALIZATION_ERROR_NULL_KEY: return "key parameter is NULL when reading from/writing to a structure or dictionary"; case SERIALIZATION_ERROR_INCORRECT_TYPE: return "The value being deserialized is not of the requested data type"; case SERIALIZATION_ERROR_NUMBER_OUT_OF_RANGE: return "The number value being deserialized is too large or small to fit in the requested data type"; case SERIALIZATION_ERROR_END_OF_CONTAINER: return "More fields requested for deserialization than exist in the container being deserialized"; case SERIALIZATION_ERROR_NO_CONTAINER_STARTED: return "A read or write call was issued before the first begin call, or after the last end call"; case SERIALIZATION_ERROR_NO_TOP_LEVEL_CONTAINER: return "An attempt was made to save data without having serialized anything"; case SERIALIZATION_ERROR_BIT_OUT_OF_RANGE: return "A bit was specified at an index beyond the maximum range of its type"; case SERIALIZATION_ERROR_FORMAT_TYPE_MISMATCH: return "Reported format of data being read does not match expected format"; case SERIALIZATION_ERROR_FORMAT_VERSION_TOO_OLD: return "Reported version of data being read is older than oldest supported"; case SERIALIZATION_ERROR_FORMAT_VERSION_TOO_NEW: return "Reported version of data being read is newer than newest supported"; case SERIALIZATION_ERROR_ARRAY_COUNT_OUT_OF_RANGE: return "Array has too many (or too few) items for the data being read"; #endif default: return "Unknown error"; } } #define checkBitfieldErrors(bit_count) \ for (unsigned int bitIndex = 0; bitIndex < bitNameCount; bitIndex++) { \ for (unsigned int bitIndex2 = 0; bitIndex2 < bitIndex; bitIndex2++) { \ if (bitNames[bitIndex2].index == bitNames[bitIndex].index || !strcmp(bitNames[bitIndex2].name, bitNames[bitIndex].name)) { \ return SERIALIZATION_ERROR_DUPLICATE_BIT; \ } \ } \ if (bitNames[bitIndex].index >= bit_count) { \ return SERIALIZATION_ERROR_BIT_OUT_OF_RANGE; \ } \ value &= ~(1 << bitNames[bitIndex].index); \ } \ if (value != 0) { \ return SERIALIZATION_ERROR_UNNAMED_BIT; \ } \ return SERIALIZATION_ERROR_OK int Serialization_checkBitfield8Errors(uint8_t value, unsigned int bitNameCount, Serialization_bitName * bitNames) { checkBitfieldErrors(8); } int Serialization_checkBitfield16Errors(uint16_t value, unsigned int bitNameCount, Serialization_bitName * bitNames) { checkBitfieldErrors(16); } int Serialization_checkBitfield32Errors(uint32_t value, unsigned int bitNameCount, Serialization_bitName * bitNames) { checkBitfieldErrors(32); } int Serialization_checkBitfield64Errors(uint64_t value, unsigned int bitNameCount, Serialization_bitName * bitNames) { checkBitfieldErrors(64); } int Serialization_checkEnumerationErrors(int value, unsigned int valueCount, Serialization_enumKeyValue * values) { bool found = false; for (unsigned int valueIndex = 0; valueIndex < valueCount; valueIndex++) { for (unsigned int valueIndex2 = 0; valueIndex2 < valueIndex; valueIndex2++) { if (values[valueIndex2].value == values[valueIndex].value) { return SERIALIZATION_ERROR_DUPLICATE_ENUM_VALUE; } if (!strcmp(values[valueIndex2].key, values[valueIndex].key)) { return SERIALIZATION_ERROR_DUPLICATE_ENUM_NAME; } } if (values[valueIndex].value == value) { found = true; } } if (!found) { \ return SERIALIZATION_ERROR_ENUM_NOT_NAMED; } return SERIALIZATION_ERROR_OK; }