source: azure_iot_hub_riscv/trunk/azure_iot_sdk/serializer/src/datapublisher.c@ 453

Last change on this file since 453 was 453, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 28.2 KB
Line 
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 <stdbool.h>
8#include "datapublisher.h"
9#include "jsonencoder.h"
10#include "datamarshaller.h"
11#include "agenttypesystem.h"
12#include "schema.h"
13#include "azure_c_shared_utility/crt_abstractions.h"
14#include "azure_c_shared_utility/xlogging.h"
15#include "azure_c_shared_utility/vector.h"
16
17MU_DEFINE_ENUM_STRINGS_WITHOUT_INVALID(DATA_PUBLISHER_RESULT, DATA_PUBLISHER_RESULT_VALUES)
18
19#define LOG_DATA_PUBLISHER_ERROR \
20 LogError("(result = %s)", MU_ENUM_TO_STRING(DATA_PUBLISHER_RESULT, result))
21
22#define DEFAULT_MAX_BUFFER_SIZE 10240
23/* Codes_SRS_DATA_PUBLISHER_99_066:[ A single value shall be used by all instances of DataPublisher.] */
24/* Codes_SRS_DATA_PUBLISHER_99_067:[ Before any call to DataPublisher_SetMaxBufferSize, the default max buffer size shall be equal to 10KB.] */
25static size_t maxBufferSize_ = DEFAULT_MAX_BUFFER_SIZE;
26
27typedef struct DATA_PUBLISHER_HANDLE_DATA_TAG
28{
29 DATA_MARSHALLER_HANDLE DataMarshallerHandle;
30 SCHEMA_MODEL_TYPE_HANDLE ModelHandle;
31} DATA_PUBLISHER_HANDLE_DATA;
32
33typedef struct TRANSACTION_HANDLE_DATA_TAG
34{
35 DATA_PUBLISHER_HANDLE_DATA* DataPublisherInstance;
36 size_t ValueCount;
37 DATA_MARSHALLER_VALUE* Values;
38} TRANSACTION_HANDLE_DATA;
39
40typedef struct REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA_TAG
41{
42 DATA_PUBLISHER_HANDLE_DATA* DataPublisherInstance;
43 VECTOR_HANDLE value; /*holds (DATA_MARSHALLER_VALUE*) */
44}REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA;
45
46DATA_PUBLISHER_HANDLE DataPublisher_Create(SCHEMA_MODEL_TYPE_HANDLE modelHandle, bool includePropertyPath)
47{
48 DATA_PUBLISHER_HANDLE_DATA* result;
49
50 /* Codes_SRS_DATA_PUBLISHER_99_042:[ If a NULL argument is passed to it, DataPublisher_Create shall return NULL.] */
51 if (modelHandle == NULL)
52 {
53 result = NULL;
54 LogError("(result = %s)", MU_ENUM_TO_STRING(DATA_PUBLISHER_RESULT, DATA_PUBLISHER_INVALID_ARG));
55 }
56 else if ((result = (DATA_PUBLISHER_HANDLE_DATA*)malloc(sizeof(DATA_PUBLISHER_HANDLE_DATA))) == NULL)
57 {
58 /* Codes_SRS_DATA_PUBLISHER_99_047:[ For any other error not specified here, DataPublisher_Create shall return NULL.] */
59 result = NULL;
60 LogError("(result = %s)", MU_ENUM_TO_STRING(DATA_PUBLISHER_RESULT, DATA_PUBLISHER_ERROR));
61 }
62 else
63 {
64 /* Codes_SRS_DATA_PUBLISHER_99_043:[ DataPublisher_Create shall initialize and hold a handle to a DataMarshaller instance.] */
65 /* Codes_SRS_DATA_PUBLISHER_01_001: [DataPublisher_Create shall pass the includePropertyPath argument to DataMarshaller_Create.] */
66 if ((result->DataMarshallerHandle = DataMarshaller_Create(modelHandle, includePropertyPath)) == NULL)
67 {
68 free(result);
69
70 /* Codes_SRS_DATA_PUBLISHER_99_044:[ If the creation of the DataMarshaller instance fails, DataPublisher_Create shall return NULL.] */
71 result = NULL;
72 LogError("(result = %s)", MU_ENUM_TO_STRING(DATA_PUBLISHER_RESULT, DATA_PUBLISHER_MARSHALLER_ERROR));
73 }
74 else
75 {
76 /* Codes_SRS_DATA_PUBLISHER_99_041:[ DataPublisher_Create shall create a new DataPublisher instance and return a non-NULL handle in case of success.] */
77 result->ModelHandle = modelHandle;
78 }
79 }
80
81 return result;
82}
83
84void DataPublisher_Destroy(DATA_PUBLISHER_HANDLE dataPublisherHandle)
85{
86 if (dataPublisherHandle != NULL)
87 {
88 DATA_PUBLISHER_HANDLE_DATA* dataPublisherInstance = (DATA_PUBLISHER_HANDLE_DATA*)dataPublisherHandle;
89 DataMarshaller_Destroy(dataPublisherInstance->DataMarshallerHandle);
90
91 free(dataPublisherHandle);
92 }
93}
94
95TRANSACTION_HANDLE DataPublisher_StartTransaction(DATA_PUBLISHER_HANDLE dataPublisherHandle)
96{
97 TRANSACTION_HANDLE_DATA* transaction;
98
99 /* Codes_SRS_DATA_PUBLISHER_99_038:[ If DataPublisher_StartTransaction is called with a NULL argument it shall return NULL.] */
100 if (dataPublisherHandle == NULL)
101 {
102 transaction = NULL;
103 LogError("(Error code: %s)", MU_ENUM_TO_STRING(DATA_PUBLISHER_RESULT, DATA_PUBLISHER_INVALID_ARG));
104 }
105 else
106 {
107 /* Codes_SRS_DATA_PUBLISHER_99_007:[ A call to DataPublisher_StartTransaction shall start a new transaction.] */
108 transaction = (TRANSACTION_HANDLE_DATA*)calloc(1, sizeof(TRANSACTION_HANDLE_DATA));
109 if (transaction == NULL)
110 {
111 LogError("Allocating transaction failed (Error code: %s)", MU_ENUM_TO_STRING(DATA_PUBLISHER_RESULT, DATA_PUBLISHER_ERROR));
112 }
113 else
114 {
115 transaction->ValueCount = 0;
116 transaction->Values = NULL;
117 transaction->DataPublisherInstance = (DATA_PUBLISHER_HANDLE_DATA*)dataPublisherHandle;
118 }
119 }
120
121 /* Codes_SRS_DATA_PUBLISHER_99_008:[ DataPublisher_StartTransaction shall return a non-NULL handle upon success.] */
122 /* Codes_SRS_DATA_PUBLISHER_99_009:[ DataPublisher_StartTransaction shall return NULL upon failure.] */
123 return transaction;
124}
125
126DATA_PUBLISHER_RESULT DataPublisher_PublishTransacted(TRANSACTION_HANDLE transactionHandle, const char* propertyPath, const AGENT_DATA_TYPE* data)
127{
128 DATA_PUBLISHER_RESULT result;
129 char* propertyPathCopy;
130
131 /* Codes_SRS_DATA_PUBLISHER_99_017:[ When one or more NULL parameter(s) are specified, DataPublisher_PublishTransacted is called with a NULL transactionHandle, it shall return DATA_PUBLISHER_INVALID_ARG.] */
132 if ((transactionHandle == NULL) ||
133 (propertyPath == NULL) ||
134 (data == NULL))
135 {
136 result = DATA_PUBLISHER_INVALID_ARG;
137 LOG_DATA_PUBLISHER_ERROR;
138 }
139 else if (mallocAndStrcpy_s(&propertyPathCopy, propertyPath) != 0)
140 {
141 /* Codes_SRS_DATA_PUBLISHER_99_020:[ For any errors not explicitly mentioned here the DataPublisher APIs shall return DATA_PUBLISHER_ERROR.] */
142 result = DATA_PUBLISHER_ERROR;
143 LOG_DATA_PUBLISHER_ERROR;
144 }
145 else
146 {
147 TRANSACTION_HANDLE_DATA* transaction = (TRANSACTION_HANDLE_DATA*)transactionHandle;
148 AGENT_DATA_TYPE* propertyValue;
149
150 if (!Schema_ModelPropertyByPathExists(transaction->DataPublisherInstance->ModelHandle, propertyPath))
151 {
152 free(propertyPathCopy);
153
154 /* Codes_SRS_DATA_PUBLISHER_99_040:[ When propertyPath does not exist in the supplied model, DataPublisher_Publish shall return DATA_PUBLISHER_SCHEMA_FAILED without dispatching data.] */
155 result = DATA_PUBLISHER_SCHEMA_FAILED;
156 LOG_DATA_PUBLISHER_ERROR;
157 }
158 else if ((propertyValue = (AGENT_DATA_TYPE*)calloc(1, sizeof(AGENT_DATA_TYPE))) == NULL)
159 {
160 free(propertyPathCopy);
161
162 /* Codes_SRS_DATA_PUBLISHER_99_020:[ For any errors not explicitly mentioned here the DataPublisher APIs shall return DATA_PUBLISHER_ERROR.] */
163 result = DATA_PUBLISHER_ERROR;
164 LOG_DATA_PUBLISHER_ERROR;
165 }
166 else if (Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE(propertyValue, data) != AGENT_DATA_TYPES_OK)
167 {
168 free(propertyPathCopy);
169 free(propertyValue);
170
171 /* Codes_SRS_DATA_PUBLISHER_99_028:[ If creating the copy fails then DATA_PUBLISHER_AGENT_DATA_TYPES_ERROR shall be returned.] */
172 result = DATA_PUBLISHER_AGENT_DATA_TYPES_ERROR;
173 LOG_DATA_PUBLISHER_ERROR;
174 }
175 else
176 {
177 size_t i;
178 DATA_MARSHALLER_VALUE* propertySlot = NULL;
179
180 /* Codes_SRS_DATA_PUBLISHER_99_019:[ If the same property is associated twice with a transaction, then the last value shall be kept associated with the transaction.] */
181 for (i = 0; i < transaction->ValueCount; i++)
182 {
183 if (strcmp(transaction->Values[i].PropertyPath, propertyPath) == 0)
184 {
185 propertySlot = &transaction->Values[i];
186 break;
187 }
188 }
189
190 if (propertySlot == NULL)
191 {
192 DATA_MARSHALLER_VALUE* newValues = (DATA_MARSHALLER_VALUE*)realloc(transaction->Values, sizeof(DATA_MARSHALLER_VALUE)* (transaction->ValueCount + 1));
193 if (newValues != NULL)
194 {
195 transaction->Values = newValues;
196 propertySlot = &transaction->Values[transaction->ValueCount];
197 propertySlot->Value = NULL;
198 propertySlot->PropertyPath = NULL;
199 transaction->ValueCount++;
200 }
201 }
202
203 if (propertySlot == NULL)
204 {
205 Destroy_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)propertyValue);
206 free(propertyValue);
207 free(propertyPathCopy);
208
209 /* Codes_SRS_DATA_PUBLISHER_99_020:[ For any errors not explicitly mentioned here the DataPublisher APIs shall return DATA_PUBLISHER_ERROR.] */
210 result = DATA_PUBLISHER_ERROR;
211 LOG_DATA_PUBLISHER_ERROR;
212 }
213 else
214 {
215 if (propertySlot->Value != NULL)
216 {
217 Destroy_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)propertySlot->Value);
218 free((AGENT_DATA_TYPE*)propertySlot->Value);
219 }
220 if (propertySlot->PropertyPath != NULL)
221 {
222 char* existingValue = (char*)propertySlot->PropertyPath;
223 free(existingValue);
224 }
225
226 /* Codes_SRS_DATA_PUBLISHER_99_016:[ When DataPublisher_PublishTransacted is invoked, DataPublisher shall associate the data with the transaction identified by the transactionHandle argument and return DATA_PUBLISHER_OK. No data shall be dispatched at the time of the call.] */
227 propertySlot->PropertyPath = propertyPathCopy;
228 propertySlot->Value = propertyValue;
229
230 result = DATA_PUBLISHER_OK;
231 }
232 }
233 }
234
235 return result;
236}
237
238DATA_PUBLISHER_RESULT DataPublisher_EndTransaction(TRANSACTION_HANDLE transactionHandle, unsigned char** destination, size_t* destinationSize)
239{
240 DATA_PUBLISHER_RESULT result;
241
242 /*Codes_SRS_DATA_PUBLISHER_02_006: [If the destination argument is NULL, DataPublisher_EndTransaction shall return DATA_PUBLISHER_INVALID_ARG.] */
243 /*Codes_SRS_DATA_PUBLISHER_02_007: [If the destinationSize argument is NULL, DataPublisher_EndTransaction shall return DATA_PUBLISHER_INVALID_ARG.] */
244 if (
245 (transactionHandle == NULL) ||
246 (destination == NULL) ||
247 (destinationSize == NULL)
248 )
249 {
250 /* Codes_SRS_DATA_PUBLISHER_99_011:[ If the transactionHandle argument is NULL, DataPublisher_EndTransaction shall return DATA_PUBLISHER_INVALID_ARG.] */
251 result = DATA_PUBLISHER_INVALID_ARG;
252 LOG_DATA_PUBLISHER_ERROR;
253 }
254 else
255 {
256 TRANSACTION_HANDLE_DATA* transaction = (TRANSACTION_HANDLE_DATA*)transactionHandle;
257
258 if (transaction->ValueCount == 0)
259 {
260 /* Codes_SRS_DATA_PUBLISHER_99_024:[ If no values have been associated with the transaction, no data shall be dispatched
261 to DataMarshaller, the transaction shall be discarded and DataPublisher_EndTransaction shall return DATA_PUBLISHER_EMPTY_TRANSACTION.] */
262 result = DATA_PUBLISHER_EMPTY_TRANSACTION;
263 LOG_DATA_PUBLISHER_ERROR;
264 }
265 /* Codes_SRS_DATA_PUBLISHER_99_010:[ A call to DataPublisher_EndTransaction shall mark the end of a transaction and, trigger a dispatch of all the data grouped by that transaction.] */
266 else if (DataMarshaller_SendData(transaction->DataPublisherInstance->DataMarshallerHandle, transaction->ValueCount, transaction->Values, destination, destinationSize) != DATA_MARSHALLER_OK)
267 {
268 /* Codes_SRS_DATA_PUBLISHER_99_025:[ When the DataMarshaller_SendData call fails, DataPublisher_EndTransaction shall return DATA_PUBLISHER_MARSHALLER_ERROR.] */
269 result = DATA_PUBLISHER_MARSHALLER_ERROR;
270 LOG_DATA_PUBLISHER_ERROR;
271 }
272 else
273 {
274 /* Codes_SRS_DATA_PUBLISHER_99_026:[ On success, DataPublisher_EndTransaction shall return DATA_PUBLISHER_OK.] */
275 result = DATA_PUBLISHER_OK;
276 }
277
278 /* Codes_SRS_DATA_PUBLISHER_99_012:[ DataPublisher_EndTransaction shall dispose of any resources associated with the transaction.] */
279 (void)DataPublisher_CancelTransaction(transactionHandle);
280 }
281
282 return result;
283}
284
285DATA_PUBLISHER_RESULT DataPublisher_CancelTransaction(TRANSACTION_HANDLE transactionHandle)
286{
287 DATA_PUBLISHER_RESULT result;
288
289 if (transactionHandle == NULL)
290 {
291 /* Codes_SRS_DATA_PUBLISHER_99_014:[ If the transactionHandle argument is NULL DataPublisher_CancelTransaction shall return DATA_PUBLISHER_INVALID_ARG.] */
292 result = DATA_PUBLISHER_INVALID_ARG;
293 LOG_DATA_PUBLISHER_ERROR;
294 }
295 else
296 {
297 TRANSACTION_HANDLE_DATA* transaction = (TRANSACTION_HANDLE_DATA*)transactionHandle;
298 size_t i;
299
300 /* Codes_SRS_DATA_PUBLISHER_99_015:[ DataPublisher_CancelTransaction shall dispose of any resources associated with the transaction.] */
301 for (i = 0; i < transaction->ValueCount; i++)
302 {
303 Destroy_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)transaction->Values[i].Value);
304 free((char*)transaction->Values[i].PropertyPath);
305 free((AGENT_DATA_TYPE*)transaction->Values[i].Value);
306 }
307
308 /* Codes_SRS_DATA_PUBLISHER_99_015:[ DataPublisher_CancelTransaction shall dispose of any resources associated with the transaction.] */
309 free(transaction->Values);
310 free(transaction);
311
312 /* Codes_SRS_DATA_PUBLISHER_99_013:[ A call to DataPublisher_CancelTransaction shall dispose of the transaction without dispatching
313 the data to the DataMarshaller module and it shall return DATA_PUBLISHER_OK.] */
314 result = DATA_PUBLISHER_OK;
315 }
316
317 return result;
318}
319
320/* Codes_SRS_DATA_PUBLISHER_99_065:[ DataPublisher_SetMaxBufferSize shall directly update the value used to limit how much data (in bytes) can be buffered in the BufferStorage instance.] */
321void DataPublisher_SetMaxBufferSize(size_t value)
322{
323 maxBufferSize_ = value;
324}
325
326/* Codes_SRS_DATA_PUBLISHER_99_069:[ DataMarshaller_GetMaxBufferSize shall return the current max buffer size value used by any new instance of DataMarshaller.] */
327size_t DataPublisher_GetMaxBufferSize(void)
328{
329 return maxBufferSize_;
330}
331
332REPORTED_PROPERTIES_TRANSACTION_HANDLE DataPublisher_CreateTransaction_ReportedProperties(DATA_PUBLISHER_HANDLE dataPublisherHandle)
333{
334 REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA* result;
335 /*Codes_SRS_DATA_PUBLISHER_02_027: [ If argument dataPublisherHandle is NULL then DataPublisher_CreateTransaction_ReportedProperties shall fail and return NULL. ]*/
336 if (dataPublisherHandle == NULL)
337 {
338 LogError("invalid argument DATA_PUBLISHER_HANDLE dataPublisherHandle=%p", dataPublisherHandle);
339 result = NULL;
340 }
341 else
342 {
343 /*Codes_SRS_DATA_PUBLISHER_02_028: [ DataPublisher_CreateTransaction_ReportedProperties shall create a VECTOR_HANDLE holding the individual elements of the transaction (DATA_MARSHALLER_VALUE). ]*/
344 result = (REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA*)malloc(sizeof(REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA));
345 if (result == NULL)
346 {
347 /*Codes_SRS_DATA_PUBLISHER_02_029: [ If any error occurs then DataPublisher_CreateTransaction_ReportedProperties shall fail and return NULL. ]*/
348 LogError("unable to malloc");
349 /*return as is */
350 }
351 else
352 {
353 result->value = VECTOR_create(sizeof(DATA_MARSHALLER_VALUE*));
354 if (result->value == NULL)
355 {
356 /*Codes_SRS_DATA_PUBLISHER_02_029: [ If any error occurs then DataPublisher_CreateTransaction_ReportedProperties shall fail and return NULL. ]*/
357 LogError("unable to VECTOR_create");
358 free(result);
359 result = NULL;
360 }
361 else
362 {
363 /*Codes_SRS_DATA_PUBLISHER_02_030: [ Otherwise DataPublisher_CreateTransaction_ReportedProperties shall succeed and return a non-NULL handle. ]*/
364 result->DataPublisherInstance = dataPublisherHandle;
365 }
366 }
367 }
368
369 return result;
370}
371
372static bool reportedPropertyExistsByPath(const void* element, const void* value)
373{
374 DATA_MARSHALLER_VALUE* dataMarshallerValue = *(DATA_MARSHALLER_VALUE**)element;
375 return (strcmp(dataMarshallerValue->PropertyPath, (const char*)value) == 0);
376}
377
378DATA_PUBLISHER_RESULT DataPublisher_PublishTransacted_ReportedProperty(REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle, const char* reportedPropertyPath, const AGENT_DATA_TYPE* data)
379{
380 DATA_PUBLISHER_RESULT result;
381 /*Codes_SRS_DATA_PUBLISHER_02_009: [ If argument transactionHandle is NULL then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/
382 /*Codes_SRS_DATA_PUBLISHER_02_010: [ If argument reportedPropertyPath is NULL then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/
383 /*Codes_SRS_DATA_PUBLISHER_02_011: [ If argument data is NULL then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/
384 if (
385 (transactionHandle == NULL) ||
386 (reportedPropertyPath == NULL) ||
387 (data == NULL)
388 )
389 {
390 LogError("invalid argument REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle=%p, const char* reportedPropertyPath=%p, const AGENT_DATA_TYPE* data=%p", transactionHandle, reportedPropertyPath, data);
391 result = DATA_PUBLISHER_INVALID_ARG;
392 }
393 else
394 {
395 REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA* handleData = (REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA*)transactionHandle;
396 /*Codes_SRS_DATA_PUBLISHER_02_012: [ DataPublisher_PublishTransacted_ReportedProperty shall verify that a reported property having the path reportedPropertyPath exists in the model by calling Schema_ModelReportedPropertyByPathExists ]*/
397 if (!Schema_ModelReportedPropertyByPathExists(handleData->DataPublisherInstance->ModelHandle, reportedPropertyPath))
398 {
399 /*Codes_SRS_DATA_PUBLISHER_02_013: [ If a reported property with path reportedPropertyPath does not exist in the model then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/
400 LogError("unable to find a reported property by path \"%s\"", reportedPropertyPath);
401 result = DATA_PUBLISHER_INVALID_ARG;
402 }
403 else
404 {
405 DATA_MARSHALLER_VALUE** existingValue = VECTOR_find_if(handleData->value, reportedPropertyExistsByPath, reportedPropertyPath);
406 if(existingValue != NULL)
407 {
408 /*Codes_SRS_DATA_PUBLISHER_02_014: [ If the same (by reportedPropertypath) reported property has already been added to the transaction, then DataPublisher_PublishTransacted_ReportedProperty shall overwrite the previous reported property. ]*/
409 AGENT_DATA_TYPE *clone = (AGENT_DATA_TYPE *)calloc(1, sizeof(AGENT_DATA_TYPE));
410 if(clone == NULL)
411 {
412 /*Codes_SRS_DATA_PUBLISHER_02_016: [ If any error occurs then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_ERROR. ]*/
413 LogError("unable to malloc");
414 result = DATA_PUBLISHER_ERROR;
415 }
416 else
417 {
418 if (Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE(clone, data) != AGENT_DATA_TYPES_OK)
419 {
420 /*Codes_SRS_DATA_PUBLISHER_02_016: [ If any error occurs then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_ERROR. ]*/
421 LogError("unable to Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE");
422 free(clone);
423 result = DATA_PUBLISHER_ERROR;
424 }
425 else
426 {
427 /*Codes_SRS_DATA_PUBLISHER_02_017: [ Otherwise DataPublisher_PublishTransacted_ReportedProperty shall succeed and return DATA_PUBLISHER_OK. ]*/
428 Destroy_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)((*existingValue)->Value));
429 free((void*)((*existingValue)->Value));
430 (*existingValue)->Value = clone;
431 result = DATA_PUBLISHER_OK;
432 }
433 }
434 }
435 else
436 {
437 /*totally new reported property*/
438 DATA_MARSHALLER_VALUE* newValue = (DATA_MARSHALLER_VALUE*)malloc(sizeof(DATA_MARSHALLER_VALUE));
439 if (newValue == NULL)
440 {
441 /*Codes_SRS_DATA_PUBLISHER_02_016: [ If any error occurs then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_ERROR. ]*/
442 LogError("unable to malloc");
443 result = DATA_PUBLISHER_ERROR;
444 }
445 else
446 {
447 if (mallocAndStrcpy_s((char**)&(newValue->PropertyPath), reportedPropertyPath) != 0)
448 {
449 /*Codes_SRS_DATA_PUBLISHER_02_016: [ If any error occurs then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_ERROR. ]*/
450 LogError("unable to mallocAndStrcpy_s");
451 free(newValue);
452 result = DATA_PUBLISHER_ERROR;
453 }
454 else
455 {
456 if ((newValue->Value = (AGENT_DATA_TYPE*)calloc(1, sizeof(AGENT_DATA_TYPE))) == NULL)
457 {
458 LogError("unable to malloc");
459 free((void*)newValue->PropertyPath);
460 free(newValue);
461 result = DATA_PUBLISHER_ERROR;
462 }
463 else
464 {
465 if (Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)newValue->Value, data) != AGENT_DATA_TYPES_OK)
466 {
467 /*Codes_SRS_DATA_PUBLISHER_02_016: [ If any error occurs then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_ERROR. ]*/
468 LogError("unable to Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE");
469 free((void*)newValue->Value);
470 free((void*)newValue->PropertyPath);
471 free(newValue);
472 result = DATA_PUBLISHER_ERROR;
473 }
474 else
475 {
476 /*Codes_SRS_DATA_PUBLISHER_02_015: [ DataPublisher_PublishTransacted_ReportedProperty shall add a new DATA_MARSHALLER_VALUE to the VECTOR_HANDLE. ]*/
477 if (VECTOR_push_back(handleData->value, &newValue, 1) != 0)
478 {
479 /*Codes_SRS_DATA_PUBLISHER_02_016: [ If any error occurs then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_ERROR. */
480 LogError("unable to VECTOR_push_back");
481 Destroy_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)newValue->Value);
482 free((void*)newValue->Value);
483 free((void*)newValue->PropertyPath);
484 free(newValue);
485 result = DATA_PUBLISHER_ERROR;
486 }
487 else
488 {
489 /*Codes_SRS_DATA_PUBLISHER_02_017: [ Otherwise DataPublisher_PublishTransacted_ReportedProperty shall succeed and return DATA_PUBLISHER_OK. ]*/
490 result = DATA_PUBLISHER_OK;
491 }
492 }
493 }
494 }
495 }
496 }
497 }
498 }
499 return result;
500}
501
502DATA_PUBLISHER_RESULT DataPublisher_CommitTransaction_ReportedProperties(REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle, unsigned char** destination, size_t* destinationSize)
503{
504 DATA_PUBLISHER_RESULT result;
505 /*Codes_SRS_DATA_PUBLISHER_02_019: [ If argument transactionHandle is NULL then DataPublisher_CommitTransaction_ReportedProperties shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/
506 /*Codes_SRS_DATA_PUBLISHER_02_020: [ If argument destination is NULL then DataPublisher_CommitTransaction_ReportedProperties shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/
507 /*Codes_SRS_DATA_PUBLISHER_02_021: [ If argument destinationSize NULL then DataPublisher_CommitTransaction_ReportedProperties shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/
508 if (
509 (transactionHandle == NULL) ||
510 (destination == NULL) ||
511 (destinationSize == NULL)
512 )
513 {
514 LogError("invalid argument REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle=%p, unsigned char** destination=%p, size_t* destinationSize=%p", transactionHandle, destination, destinationSize);
515 result = DATA_PUBLISHER_INVALID_ARG;
516 }
517 else
518 {
519 /*Codes_SRS_DATA_PUBLISHER_02_031: [ If the transaction contains zero elements then DataPublisher_CommitTransaction_ReportedProperties shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/
520 REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA* handle = (REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA*)transactionHandle;
521 if (VECTOR_size(handle->value) == 0)
522 {
523 LogError("cannot commit empty transaction");
524 result = DATA_PUBLISHER_INVALID_ARG;
525 }
526 else
527 {
528 /*Codes_SRS_DATA_PUBLISHER_02_022: [ DataPublisher_CommitTransaction_ReportedProperties shall call DataMarshaller_SendData_ReportedProperties providing the VECTOR_HANDLE holding the transacted reported properties, destination and destinationSize. ]*/
529 if (DataMarshaller_SendData_ReportedProperties(handle->DataPublisherInstance->DataMarshallerHandle, handle->value, destination, destinationSize) != DATA_MARSHALLER_OK)
530 {
531 /*Codes_SRS_DATA_PUBLISHER_02_023: [ If any error occurs then DataPublisher_CommitTransaction_ReportedProperties shall fail and return DATA_PUBLISHER_ERROR. ]*/
532 LogError("unable to DataMarshaller_SendData_ReportedProperties");
533 result = DATA_PUBLISHER_ERROR;
534 }
535 else
536 {
537 /*Codes_SRS_DATA_PUBLISHER_02_024: [ Otherwise DataPublisher_CommitTransaction_ReportedProperties shall succeed and return DATA_PUBLISHER_OK. ]*/
538 result = DATA_PUBLISHER_OK;
539 }
540 }
541 }
542
543 return result;
544}
545
546void DataPublisher_DestroyTransaction_ReportedProperties(REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle)
547{
548 /*Codes_SRS_DATA_PUBLISHER_02_025: [ If argument transactionHandle is NULL then DataPublisher_DestroyTransaction_ReportedProperties shall return. ]*/
549 if (transactionHandle == NULL)
550 {
551 LogError("invalig argument REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle=%p", transactionHandle);
552 }
553 else
554 {
555 /*Codes_SRS_DATA_PUBLISHER_02_026: [ Otherwise DataPublisher_DestroyTransaction_ReportedProperties shall free all resources associated with the reported properties transactionHandle. ]*/
556 REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA* handleData = (REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA*)transactionHandle;
557 size_t i, nReportedProperties;
558 nReportedProperties = VECTOR_size(handleData->value);
559 for (i = 0;i < nReportedProperties;i++)
560 {
561 DATA_MARSHALLER_VALUE *value = *(DATA_MARSHALLER_VALUE**)VECTOR_element(handleData->value, i);
562 Destroy_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)value->Value);
563 free((void*)value->Value);
564 free((void*)value->PropertyPath);
565 free((void*)value);
566 }
567 VECTOR_destroy(handleData->value);
568 free(handleData);
569 }
570 return;
571}
Note: See TracBrowser for help on using the repository browser.