1 | // Copyright (c) Microsoft. All rights reserved.
|
---|
2 | // Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
---|
3 |
|
---|
4 | #include <stdlib.h>
|
---|
5 | #include "azure_c_shared_utility/gballoc.h"
|
---|
6 |
|
---|
7 | #include <stddef.h>
|
---|
8 | #include "schemaserializer.h"
|
---|
9 | #include "azure_c_shared_utility/xlogging.h"
|
---|
10 | #include "azure_macro_utils/macro_utils.h"
|
---|
11 |
|
---|
12 | MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(SCHEMA_SERIALIZER_RESULT, SCHEMA_SERIALIZER_RESULT_VALUES);
|
---|
13 |
|
---|
14 | #define LOG_SCHEMA_SERIALIZER_ERROR(result) LogError("(result = %s)", MU_ENUM_TO_STRING(SCHEMA_SERIALIZER_RESULT, (result)))
|
---|
15 |
|
---|
16 | static const char* ConvertType(const char* sourceType)
|
---|
17 | {
|
---|
18 | /* Codes_SRS_SCHEMA_SERIALIZER_01_016: ["ascii_char_ptr" shall be translated to "string".] */
|
---|
19 | if (strcmp(sourceType, "ascii_char_ptr") == 0)
|
---|
20 | {
|
---|
21 | return "string";
|
---|
22 | }
|
---|
23 | else
|
---|
24 | {
|
---|
25 | /* Codes_SRS_SCHEMA_SERIALIZER_01_017: [All other types shall be kept as they are.] */
|
---|
26 | return sourceType;
|
---|
27 | }
|
---|
28 | }
|
---|
29 |
|
---|
30 | /* Codes_SRS_SCHEMA_SERIALIZER_01_001: [SchemaSerializer_SerializeCommandMetadata shall serialize a specific model to a string using JSON as format.] */
|
---|
31 | SCHEMA_SERIALIZER_RESULT SchemaSerializer_SerializeCommandMetadata(SCHEMA_MODEL_TYPE_HANDLE modelHandle, STRING_HANDLE schemaText)
|
---|
32 | {
|
---|
33 | SCHEMA_SERIALIZER_RESULT result;
|
---|
34 |
|
---|
35 | /* Codes_SRS_SCHEMA_SERIALIZER_01_013: [If the modelHandle argument is NULL, SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_INVALID_ARG.] */
|
---|
36 | if ((modelHandle == NULL) ||
|
---|
37 | /* Codes_SRS_SCHEMA_SERIALIZER_01_014: [If the schemaText argument is NULL, SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_INVALID_ARG.] */
|
---|
38 | (schemaText == NULL))
|
---|
39 | {
|
---|
40 | result = SCHEMA_SERIALIZER_INVALID_ARG;
|
---|
41 | LogError("(result = %s), modelHandle = %p, schemaText = %p", MU_ENUM_TO_STRING(SCHEMA_SERIALIZER_RESULT, result), modelHandle, schemaText);
|
---|
42 | }
|
---|
43 | else
|
---|
44 | {
|
---|
45 | size_t commandCount;
|
---|
46 |
|
---|
47 | /* Codes_SRS_SCHEMA_SERIALIZER_01_002: [Only commands shall be serialized, the properties of a model shall be ignored.] */
|
---|
48 |
|
---|
49 | /* Codes_SRS_SCHEMA_SERIALIZER_01_003: [The output JSON shall have an array, where each array element shall represent a command.] */
|
---|
50 | /* Codes_SRS_SCHEMA_SERIALIZER_01_011: [The JSON text shall be built into the string indicated by the schemaText argument by using String APIs.] */
|
---|
51 | if ((STRING_concat(schemaText, "[") != 0) ||
|
---|
52 | /* 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.] */
|
---|
53 | (Schema_GetModelActionCount(modelHandle, &commandCount) != SCHEMA_OK))
|
---|
54 | {
|
---|
55 | /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */
|
---|
56 | result = SCHEMA_SERIALIZER_ERROR;
|
---|
57 | LOG_SCHEMA_SERIALIZER_ERROR(result);
|
---|
58 | }
|
---|
59 | else
|
---|
60 | {
|
---|
61 | size_t i;
|
---|
62 |
|
---|
63 | for (i = 0; i < commandCount; i++)
|
---|
64 | {
|
---|
65 | SCHEMA_ACTION_HANDLE actionHandle = Schema_GetModelActionByIndex(modelHandle, i);
|
---|
66 | const char* commandName;
|
---|
67 | size_t argCount;
|
---|
68 | size_t j;
|
---|
69 |
|
---|
70 | /* Codes_SRS_SCHEMA_SERIALIZER_01_005: [Each array element shall be a JSON object.] */
|
---|
71 | if ((actionHandle == NULL) ||
|
---|
72 | (STRING_concat(schemaText, "{ \"Name\":\"") != 0) ||
|
---|
73 | ((commandName = Schema_GetModelActionName(actionHandle)) == NULL) ||
|
---|
74 | (STRING_concat(schemaText, commandName) != 0) ||
|
---|
75 | /* Codes_SRS_SCHEMA_SERIALIZER_01_007: [The object for a command shall also have a "Parameters" member.] */
|
---|
76 | (STRING_concat(schemaText, "\", \"Parameters\":[") != 0) ||
|
---|
77 | (Schema_GetModelActionArgumentCount(actionHandle, &argCount) != SCHEMA_OK))
|
---|
78 | {
|
---|
79 | /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */
|
---|
80 | LogError("Failed encoding action.");
|
---|
81 | break;
|
---|
82 | }
|
---|
83 | else
|
---|
84 | {
|
---|
85 | for (j = 0; j < argCount; j++)
|
---|
86 | {
|
---|
87 | /* Codes_SRS_SCHEMA_SERIALIZER_01_008: [The parameters member shall be an array, where each entry is a command parameter.] */
|
---|
88 | SCHEMA_ACTION_ARGUMENT_HANDLE argHandle = Schema_GetModelActionArgumentByIndex(actionHandle, j);
|
---|
89 | const char* argName;
|
---|
90 | const char* argType;
|
---|
91 |
|
---|
92 | /* 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.] */
|
---|
93 | if ((argHandle == NULL) ||
|
---|
94 | (STRING_concat(schemaText, "{\"Name\":\"") != 0) ||
|
---|
95 | ((argName = Schema_GetActionArgumentName(argHandle)) == NULL) ||
|
---|
96 | (STRING_concat(schemaText, argName) != 0) ||
|
---|
97 | /* 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.] */
|
---|
98 | (STRING_concat(schemaText, "\",\"Type\":\"") != 0) ||
|
---|
99 | ((argType = Schema_GetActionArgumentType(argHandle)) == NULL) ||
|
---|
100 | (STRING_concat(schemaText, ConvertType(argType)) != 0))
|
---|
101 | {
|
---|
102 | /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */
|
---|
103 | LogError("Failed encoding argument.");
|
---|
104 | break;
|
---|
105 | }
|
---|
106 | else
|
---|
107 | {
|
---|
108 | if (j + 1 < argCount)
|
---|
109 | {
|
---|
110 | if (STRING_concat(schemaText, "\"},") != 0)
|
---|
111 | {
|
---|
112 | /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */
|
---|
113 | LogError("Failed to concatenate arg end.");
|
---|
114 | break;
|
---|
115 | }
|
---|
116 | }
|
---|
117 | else
|
---|
118 | {
|
---|
119 | if (STRING_concat(schemaText, "\"}") != 0)
|
---|
120 | {
|
---|
121 | /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */
|
---|
122 | LogError("Failed to concatenate arg end.");
|
---|
123 | break;
|
---|
124 | }
|
---|
125 | }
|
---|
126 | }
|
---|
127 | }
|
---|
128 |
|
---|
129 | if (j < argCount)
|
---|
130 | {
|
---|
131 | break;
|
---|
132 | }
|
---|
133 |
|
---|
134 | if (i + 1 < commandCount)
|
---|
135 | {
|
---|
136 | if (STRING_concat(schemaText, "]},") != 0)
|
---|
137 | {
|
---|
138 | /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */
|
---|
139 | LogError("Failed to concatenate.");
|
---|
140 | break;
|
---|
141 | }
|
---|
142 | }
|
---|
143 | else
|
---|
144 | {
|
---|
145 | if (STRING_concat(schemaText, "]}") != 0)
|
---|
146 | {
|
---|
147 | /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */
|
---|
148 | LogError("Failed to concatenate.");
|
---|
149 | break;
|
---|
150 | }
|
---|
151 | }
|
---|
152 | }
|
---|
153 | }
|
---|
154 |
|
---|
155 | if (i < commandCount)
|
---|
156 | {
|
---|
157 | result = SCHEMA_SERIALIZER_ERROR;
|
---|
158 | }
|
---|
159 | else if (STRING_concat(schemaText, "]") != 0)
|
---|
160 | {
|
---|
161 | /* Codes_SRS_SCHEMA_SERIALIZER_01_015: [If any of the Schema or String APIs fail then SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_ERROR.] */
|
---|
162 | LogError("Failed to concatenate commands object end.");
|
---|
163 | result = SCHEMA_SERIALIZER_ERROR;
|
---|
164 | }
|
---|
165 | else
|
---|
166 | {
|
---|
167 | /* Codes_SRS_SCHEMA_SERIALIZER_01_012: [On success SchemaSerializer_SerializeCommandMetadata shall return SCHEMA_SERIALIZER_OK.] */
|
---|
168 | result = SCHEMA_SERIALIZER_OK;
|
---|
169 | }
|
---|
170 | }
|
---|
171 | }
|
---|
172 |
|
---|
173 | return result;
|
---|
174 | }
|
---|