A modelling and serializer library for Microsoft Azure IoTHub client applications

Dependents:   sht15_remote_monitoring f767zi_mqtt remote_monitoring simplesample_amqp ... more

This library implements a serializer library to be used in projects involving Microsoft Azure IoT Hub connectivity. The code is replicated from https://github.com/Azure/azure-iot-sdks

Revision:
0:1f9b2707ec7d
Child:
10:c2aee3965a83
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/schemaserializer.c	Tue Sep 15 21:57:26 2015 -0700
@@ -0,0 +1,177 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+#include <stdlib.h>
+#ifdef _CRTDBG_MAP_ALLOC
+#include <crtdbg.h>
+#endif
+#include "gballoc.h"
+
+#include <stddef.h>
+#include "schemaserializer.h"
+#include "iot_logging.h"
+#include "macro_utils.h"
+
+DEFINE_ENUM_STRINGS(SCHEMA_SERIALIZER_RESULT, SCHEMA_SERIALIZER_RESULT_VALUES);
+
+#define LOG_SCHEMA_SERIALIZER_ERROR(result) LogError("(result = %s)\r\n", ENUM_TO_STRING(SCHEMA_SERIALIZER_RESULT, (result)))
+
+static const char* ConvertType(const char* sourceType)
+{
+    /* Codes_SRS_SCHEMA_SERIALIZER_01_016: ["ascii_char_ptr" shall be translated to "string".] */
+    if (strcmp(sourceType, "ascii_char_ptr") == 0)
+    {
+        return "string";
+    }
+    else
+    {
+        /* Codes_SRS_SCHEMA_SERIALIZER_01_017: [All other types shall be kept as they are.] */
+        return sourceType;
+    }
+}
+
+/* Codes_SRS_SCHEMA_SERIALIZER_01_001: [SchemaSerializer_SerializeCommandMetadata shall serialize a specific model to a string using JSON as format.] */
+SCHEMA_SERIALIZER_RESULT SchemaSerializer_SerializeCommandMetadata(SCHEMA_MODEL_TYPE_HANDLE modelHandle, STRING_HANDLE schemaText)
+{
+    SCHEMA_SERIALIZER_RESULT result;
+
+    /* Codes_SRS_SCHEMA_SERIALIZER_01_013: [If the modelHandle argument is NULL, SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_INVALID_ARG.] */
+    if ((modelHandle == NULL) ||
+        /* Codes_SRS_SCHEMA_SERIALIZER_01_014: [If the schemaText argument is NULL, SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_INVALID_ARG.] */
+        (schemaText == NULL))
+    {
+        result = SCHEMA_SERIALIZER_INVALID_ARG;
+        LogError("(result = %s), modelHandle = %p, schemaText = %p\r\n", ENUM_TO_STRING(SCHEMA_SERIALIZER_RESULT, result), modelHandle, schemaText);
+    }
+    else
+    {
+        size_t commandCount;
+
+        /* Codes_SRS_SCHEMA_SERIALIZER_01_002: [Only commands shall be serialized, the properties of a model shall be ignored.] */
+
+        /* Codes_SRS_SCHEMA_SERIALIZER_01_003: [The output JSON shall have an array, where each array element shall represent a command.] */
+        /* Codes_SRS_SCHEMA_SERIALIZER_01_011: [The JSON text shall be built into the string indicated by the schemaText argument by using String APIs.] */
+        if ((STRING_concat(schemaText, "[") != 0) ||
+            /* Codes_SRS_SCHEMA_SERIALIZER_01_006: [The object for a command shall have a member named Name, whose value shall be the command name as obtained by using Schema APIs.] */
+            (Schema_GetModelActionCount(modelHandle, &commandCount) != SCHEMA_OK))
+        {
+            /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */
+            result = SCHEMA_SERIALIZER_ERROR;
+            LOG_SCHEMA_SERIALIZER_ERROR(result);
+        }
+        else
+        {
+            size_t i;
+
+            for (i = 0; i < commandCount; i++)
+            {
+                SCHEMA_ACTION_HANDLE actionHandle = Schema_GetModelActionByIndex(modelHandle, i);
+                const char* commandName;
+                size_t argCount;
+                size_t j;
+
+                /* Codes_SRS_SCHEMA_SERIALIZER_01_005: [Each array element shall be a JSON object.] */
+                if ((actionHandle == NULL) ||
+                    (STRING_concat(schemaText, "{ \"Name\":\"") != 0) ||
+                    ((commandName = Schema_GetModelActionName(actionHandle)) == NULL) ||
+                    (STRING_concat(schemaText, commandName) != 0) ||
+                    /* Codes_SRS_SCHEMA_SERIALIZER_01_007: [The object for a command shall also have a "Parameters" member.] */
+                    (STRING_concat(schemaText, "\", \"Parameters\":[") != 0) ||
+                    (Schema_GetModelActionArgumentCount(actionHandle, &argCount) != SCHEMA_OK))
+                {
+                    /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */
+                    LogError("Failed encoding action.\r\n");
+                    break;
+                }
+                else
+                {
+                    for (j = 0; j < argCount; j++)
+                    {
+                        /* Codes_SRS_SCHEMA_SERIALIZER_01_008: [The parameters member shall be an array, where each entry is a command parameter.] */
+                        SCHEMA_ACTION_ARGUMENT_HANDLE argHandle = Schema_GetModelActionArgumentByIndex(actionHandle, j);
+                        const char* argName;
+                        const char* argType;
+
+                        /* Codes_SRS_SCHEMA_SERIALIZER_01_009: [Each command parameter shall have a member named "Name", that should have as value the command argument name as obtained by using Schema APIs.] */
+                        if ((argHandle == NULL) ||
+                            (STRING_concat(schemaText, "{\"Name\":\"") != 0) ||
+                            ((argName = Schema_GetActionArgumentName(argHandle)) == NULL) ||
+                            (STRING_concat(schemaText, argName) != 0) ||
+                            /* Codes_SRS_SCHEMA_SERIALIZER_01_010: [Each command parameter shall have a member named "Type", that should have as value the command argument type as obtained by using Schema APIs.] */
+                            (STRING_concat(schemaText, "\",\"Type\":\"") != 0) ||
+                            ((argType = Schema_GetActionArgumentType(argHandle)) == NULL) ||
+                            (STRING_concat(schemaText, ConvertType(argType)) != 0))
+                        {
+                            /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */
+                            LogError("Failed encoding argument.\r\n");
+                            break;
+                        }
+                        else
+                        {
+                            if (j + 1 < argCount)
+                            {
+                                if (STRING_concat(schemaText, "\"},") != 0)
+                                {
+                                    /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */
+                                    LogError("Failed to concatenate arg end.\r\n");
+                                    break;
+                                }
+                            }
+                            else
+                            {
+                                if (STRING_concat(schemaText, "\"}") != 0)
+                                {
+                                    /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */
+                                    LogError("Failed to concatenate arg end.\r\n");
+                                    break;
+                                }
+                            }
+                        }
+                    }
+
+                    if (j < argCount)
+                    {
+                        break;
+                    }
+
+                    if (i + 1 < commandCount)
+                    {
+                        if (STRING_concat(schemaText, "]},") != 0)
+                        {
+                            /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */
+                            LogError("Failed to concatenate.\r\n");
+                            break;
+                        }
+                    }
+                    else
+                    {
+                        if (STRING_concat(schemaText, "]}") != 0)
+                        {
+                            /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */
+                            LogError("Failed to concatenate.\r\n");
+                            break;
+                        }
+                    }
+                }
+            }
+
+            if (i < commandCount)
+            {
+                result = SCHEMA_SERIALIZER_ERROR;
+            }
+            else if (STRING_concat(schemaText, "]") != 0)
+            {
+                /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */
+                LogError("Failed to concatenate commands object end.\r\n");
+                result = SCHEMA_SERIALIZER_ERROR;
+            }
+            else
+            {
+                /* Codes_SRS_SCHEMA_SERIALIZER_01_012: [On success SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_OK.] */
+                result = SCHEMA_SERIALIZER_OK;
+            }
+        }
+    }
+
+    return result;
+}