Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: sht15_remote_monitoring f767zi_mqtt remote_monitoring simplesample_amqp ... more
datapublisher.c
00001 // Copyright (c) Microsoft. All rights reserved. 00002 // Licensed under the MIT license. See LICENSE file in the project root for full license information. 00003 00004 #include <stdlib.h> 00005 #include "azure_c_shared_utility/gballoc.h" 00006 00007 #include <stdbool.h> 00008 #include "datapublisher.h" 00009 #include "jsonencoder.h" 00010 #include "datamarshaller.h" 00011 #include "agenttypesystem.h" 00012 #include "schema.h" 00013 #include "azure_c_shared_utility/crt_abstractions.h" 00014 #include "azure_c_shared_utility/xlogging.h" 00015 #include "azure_c_shared_utility/vector.h" 00016 00017 DEFINE_ENUM_STRINGS(DATA_PUBLISHER_RESULT, DATA_PUBLISHER_RESULT_VALUES) 00018 00019 #define LOG_DATA_PUBLISHER_ERROR \ 00020 LogError("(result = %s)", ENUM_TO_STRING(DATA_PUBLISHER_RESULT, result)) 00021 00022 #define DEFAULT_MAX_BUFFER_SIZE 10240 00023 /* Codes_SRS_DATA_PUBLISHER_99_066:[ A single value shall be used by all instances of DataPublisher.] */ 00024 /* Codes_SRS_DATA_PUBLISHER_99_067:[ Before any call to DataPublisher_SetMaxBufferSize, the default max buffer size shall be equal to 10KB.] */ 00025 static size_t maxBufferSize_ = DEFAULT_MAX_BUFFER_SIZE; 00026 00027 typedef struct DATA_PUBLISHER_HANDLE_DATA_TAG 00028 { 00029 DATA_MARSHALLER_HANDLE DataMarshallerHandle; 00030 SCHEMA_MODEL_TYPE_HANDLE ModelHandle; 00031 } DATA_PUBLISHER_HANDLE_DATA; 00032 00033 typedef struct TRANSACTION_HANDLE_DATA_TAG 00034 { 00035 DATA_PUBLISHER_HANDLE_DATA* DataPublisherInstance; 00036 size_t ValueCount; 00037 DATA_MARSHALLER_VALUE* Values; 00038 } TRANSACTION_HANDLE_DATA; 00039 00040 typedef struct REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA_TAG 00041 { 00042 DATA_PUBLISHER_HANDLE_DATA* DataPublisherInstance; 00043 VECTOR_HANDLE value; /*holds (DATA_MARSHALLER_VALUE*) */ 00044 }REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA; 00045 00046 DATA_PUBLISHER_HANDLE DataPublisher_Create(SCHEMA_MODEL_TYPE_HANDLE modelHandle, bool includePropertyPath) 00047 { 00048 DATA_PUBLISHER_HANDLE_DATA* result; 00049 00050 /* Codes_SRS_DATA_PUBLISHER_99_042:[ If a NULL argument is passed to it, DataPublisher_Create shall return NULL.] */ 00051 if (modelHandle == NULL) 00052 { 00053 result = NULL; 00054 LogError("(result = %s)", ENUM_TO_STRING(DATA_PUBLISHER_RESULT, DATA_PUBLISHER_INVALID_ARG)); 00055 } 00056 else if ((result = (DATA_PUBLISHER_HANDLE_DATA*)malloc(sizeof(DATA_PUBLISHER_HANDLE_DATA))) == NULL) 00057 { 00058 /* Codes_SRS_DATA_PUBLISHER_99_047:[ For any other error not specified here, DataPublisher_Create shall return NULL.] */ 00059 result = NULL; 00060 LogError("(result = %s)", ENUM_TO_STRING(DATA_PUBLISHER_RESULT, DATA_PUBLISHER_ERROR)); 00061 } 00062 else 00063 { 00064 /* Codes_SRS_DATA_PUBLISHER_99_043:[ DataPublisher_Create shall initialize and hold a handle to a DataMarshaller instance.] */ 00065 /* Codes_SRS_DATA_PUBLISHER_01_001: [DataPublisher_Create shall pass the includePropertyPath argument to DataMarshaller_Create.] */ 00066 if ((result->DataMarshallerHandle = DataMarshaller_Create(modelHandle, includePropertyPath)) == NULL) 00067 { 00068 free(result); 00069 00070 /* Codes_SRS_DATA_PUBLISHER_99_044:[ If the creation of the DataMarshaller instance fails, DataPublisher_Create shall return NULL.] */ 00071 result = NULL; 00072 LogError("(result = %s)", ENUM_TO_STRING(DATA_PUBLISHER_RESULT, DATA_PUBLISHER_MARSHALLER_ERROR)); 00073 } 00074 else 00075 { 00076 /* Codes_SRS_DATA_PUBLISHER_99_041:[ DataPublisher_Create shall create a new DataPublisher instance and return a non-NULL handle in case of success.] */ 00077 result->ModelHandle = modelHandle; 00078 } 00079 } 00080 00081 return result; 00082 } 00083 00084 void DataPublisher_Destroy(DATA_PUBLISHER_HANDLE dataPublisherHandle) 00085 { 00086 if (dataPublisherHandle != NULL) 00087 { 00088 DATA_PUBLISHER_HANDLE_DATA* dataPublisherInstance = (DATA_PUBLISHER_HANDLE_DATA*)dataPublisherHandle; 00089 DataMarshaller_Destroy(dataPublisherInstance->DataMarshallerHandle); 00090 00091 free(dataPublisherHandle); 00092 } 00093 } 00094 00095 TRANSACTION_HANDLE DataPublisher_StartTransaction(DATA_PUBLISHER_HANDLE dataPublisherHandle) 00096 { 00097 TRANSACTION_HANDLE_DATA* transaction; 00098 00099 /* Codes_SRS_DATA_PUBLISHER_99_038:[ If DataPublisher_StartTransaction is called with a NULL argument it shall return NULL.] */ 00100 if (dataPublisherHandle == NULL) 00101 { 00102 transaction = NULL; 00103 LogError("(Error code: %s)", ENUM_TO_STRING(DATA_PUBLISHER_RESULT, DATA_PUBLISHER_INVALID_ARG)); 00104 } 00105 else 00106 { 00107 /* Codes_SRS_DATA_PUBLISHER_99_007:[ A call to DataPublisher_StartTransaction shall start a new transaction.] */ 00108 transaction = (TRANSACTION_HANDLE_DATA*)malloc(sizeof(TRANSACTION_HANDLE_DATA)); 00109 if (transaction == NULL) 00110 { 00111 LogError("Allocating transaction failed (Error code: %s)", ENUM_TO_STRING(DATA_PUBLISHER_RESULT, DATA_PUBLISHER_ERROR)); 00112 } 00113 else 00114 { 00115 transaction->ValueCount = 0; 00116 transaction->Values = NULL; 00117 transaction->DataPublisherInstance = (DATA_PUBLISHER_HANDLE_DATA*)dataPublisherHandle; 00118 } 00119 } 00120 00121 /* Codes_SRS_DATA_PUBLISHER_99_008:[ DataPublisher_StartTransaction shall return a non-NULL handle upon success.] */ 00122 /* Codes_SRS_DATA_PUBLISHER_99_009:[ DataPublisher_StartTransaction shall return NULL upon failure.] */ 00123 return transaction; 00124 } 00125 00126 DATA_PUBLISHER_RESULT DataPublisher_PublishTransacted(TRANSACTION_HANDLE transactionHandle, const char* propertyPath, const AGENT_DATA_TYPE* data) 00127 { 00128 DATA_PUBLISHER_RESULT result; 00129 char* propertyPathCopy; 00130 00131 /* 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.] */ 00132 if ((transactionHandle == NULL) || 00133 (propertyPath == NULL) || 00134 (data == NULL)) 00135 { 00136 result = DATA_PUBLISHER_INVALID_ARG; 00137 LOG_DATA_PUBLISHER_ERROR; 00138 } 00139 else if (mallocAndStrcpy_s(&propertyPathCopy, propertyPath) != 0) 00140 { 00141 /* Codes_SRS_DATA_PUBLISHER_99_020:[ For any errors not explicitly mentioned here the DataPublisher APIs shall return DATA_PUBLISHER_ERROR.] */ 00142 result = DATA_PUBLISHER_ERROR; 00143 LOG_DATA_PUBLISHER_ERROR; 00144 } 00145 else 00146 { 00147 TRANSACTION_HANDLE_DATA* transaction = (TRANSACTION_HANDLE_DATA*)transactionHandle; 00148 AGENT_DATA_TYPE* propertyValue; 00149 00150 if (!Schema_ModelPropertyByPathExists(transaction->DataPublisherInstance->ModelHandle, propertyPath)) 00151 { 00152 free(propertyPathCopy); 00153 00154 /* 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.] */ 00155 result = DATA_PUBLISHER_SCHEMA_FAILED; 00156 LOG_DATA_PUBLISHER_ERROR; 00157 } 00158 else if ((propertyValue = (AGENT_DATA_TYPE*)malloc(sizeof(AGENT_DATA_TYPE))) == NULL) 00159 { 00160 free(propertyPathCopy); 00161 00162 /* Codes_SRS_DATA_PUBLISHER_99_020:[ For any errors not explicitly mentioned here the DataPublisher APIs shall return DATA_PUBLISHER_ERROR.] */ 00163 result = DATA_PUBLISHER_ERROR; 00164 LOG_DATA_PUBLISHER_ERROR; 00165 } 00166 else if (Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE(propertyValue, data) != AGENT_DATA_TYPES_OK) 00167 { 00168 free(propertyPathCopy); 00169 free(propertyValue); 00170 00171 /* Codes_SRS_DATA_PUBLISHER_99_028:[ If creating the copy fails then DATA_PUBLISHER_AGENT_DATA_TYPES_ERROR shall be returned.] */ 00172 result = DATA_PUBLISHER_AGENT_DATA_TYPES_ERROR; 00173 LOG_DATA_PUBLISHER_ERROR; 00174 } 00175 else 00176 { 00177 size_t i; 00178 DATA_MARSHALLER_VALUE* propertySlot = NULL; 00179 00180 /* 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.] */ 00181 for (i = 0; i < transaction->ValueCount; i++) 00182 { 00183 if (strcmp(transaction->Values[i].PropertyPath, propertyPath) == 0) 00184 { 00185 propertySlot = &transaction->Values[i]; 00186 break; 00187 } 00188 } 00189 00190 if (propertySlot == NULL) 00191 { 00192 DATA_MARSHALLER_VALUE* newValues = (DATA_MARSHALLER_VALUE*)realloc(transaction->Values, sizeof(DATA_MARSHALLER_VALUE)* (transaction->ValueCount + 1)); 00193 if (newValues != NULL) 00194 { 00195 transaction->Values = newValues; 00196 propertySlot = &transaction->Values[transaction->ValueCount]; 00197 propertySlot->Value = NULL; 00198 propertySlot->PropertyPath = NULL; 00199 transaction->ValueCount++; 00200 } 00201 } 00202 00203 if (propertySlot == NULL) 00204 { 00205 Destroy_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)propertyValue); 00206 free(propertyValue); 00207 free(propertyPathCopy); 00208 00209 /* Codes_SRS_DATA_PUBLISHER_99_020:[ For any errors not explicitly mentioned here the DataPublisher APIs shall return DATA_PUBLISHER_ERROR.] */ 00210 result = DATA_PUBLISHER_ERROR; 00211 LOG_DATA_PUBLISHER_ERROR; 00212 } 00213 else 00214 { 00215 if (propertySlot->Value != NULL) 00216 { 00217 Destroy_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)propertySlot->Value); 00218 free((AGENT_DATA_TYPE*)propertySlot->Value); 00219 } 00220 if (propertySlot->PropertyPath != NULL) 00221 { 00222 char* existingValue = (char*)propertySlot->PropertyPath; 00223 free(existingValue); 00224 } 00225 00226 /* 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.] */ 00227 propertySlot->PropertyPath = propertyPathCopy; 00228 propertySlot->Value = propertyValue; 00229 00230 result = DATA_PUBLISHER_OK; 00231 } 00232 } 00233 } 00234 00235 return result; 00236 } 00237 00238 DATA_PUBLISHER_RESULT DataPublisher_EndTransaction(TRANSACTION_HANDLE transactionHandle, unsigned char** destination, size_t* destinationSize) 00239 { 00240 DATA_PUBLISHER_RESULT result; 00241 00242 /*Codes_SRS_DATA_PUBLISHER_02_006: [If the destination argument is NULL, DataPublisher_EndTransaction shall return DATA_PUBLISHER_INVALID_ARG.] */ 00243 /*Codes_SRS_DATA_PUBLISHER_02_007: [If the destinationSize argument is NULL, DataPublisher_EndTransaction shall return DATA_PUBLISHER_INVALID_ARG.] */ 00244 if ( 00245 (transactionHandle == NULL) || 00246 (destination == NULL) || 00247 (destinationSize == NULL) 00248 ) 00249 { 00250 /* Codes_SRS_DATA_PUBLISHER_99_011:[ If the transactionHandle argument is NULL, DataPublisher_EndTransaction shall return DATA_PUBLISHER_INVALID_ARG.] */ 00251 result = DATA_PUBLISHER_INVALID_ARG; 00252 LOG_DATA_PUBLISHER_ERROR; 00253 } 00254 else 00255 { 00256 TRANSACTION_HANDLE_DATA* transaction = (TRANSACTION_HANDLE_DATA*)transactionHandle; 00257 00258 if (transaction->ValueCount == 0) 00259 { 00260 /* Codes_SRS_DATA_PUBLISHER_99_024:[ If no values have been associated with the transaction, no data shall be dispatched 00261 to DataMarshaller, the transaction shall be discarded and DataPublisher_EndTransaction shall return DATA_PUBLISHER_EMPTY_TRANSACTION.] */ 00262 result = DATA_PUBLISHER_EMPTY_TRANSACTION; 00263 LOG_DATA_PUBLISHER_ERROR; 00264 } 00265 /* 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.] */ 00266 else if (DataMarshaller_SendData(transaction->DataPublisherInstance->DataMarshallerHandle, transaction->ValueCount, transaction->Values, destination, destinationSize) != DATA_MARSHALLER_OK) 00267 { 00268 /* Codes_SRS_DATA_PUBLISHER_99_025:[ When the DataMarshaller_SendData call fails, DataPublisher_EndTransaction shall return DATA_PUBLISHER_MARSHALLER_ERROR.] */ 00269 result = DATA_PUBLISHER_MARSHALLER_ERROR; 00270 LOG_DATA_PUBLISHER_ERROR; 00271 } 00272 else 00273 { 00274 /* Codes_SRS_DATA_PUBLISHER_99_026:[ On success, DataPublisher_EndTransaction shall return DATA_PUBLISHER_OK.] */ 00275 result = DATA_PUBLISHER_OK; 00276 } 00277 00278 /* Codes_SRS_DATA_PUBLISHER_99_012:[ DataPublisher_EndTransaction shall dispose of any resources associated with the transaction.] */ 00279 (void)DataPublisher_CancelTransaction(transactionHandle); 00280 } 00281 00282 return result; 00283 } 00284 00285 DATA_PUBLISHER_RESULT DataPublisher_CancelTransaction(TRANSACTION_HANDLE transactionHandle) 00286 { 00287 DATA_PUBLISHER_RESULT result; 00288 00289 if (transactionHandle == NULL) 00290 { 00291 /* Codes_SRS_DATA_PUBLISHER_99_014:[ If the transactionHandle argument is NULL DataPublisher_CancelTransaction shall return DATA_PUBLISHER_INVALID_ARG.] */ 00292 result = DATA_PUBLISHER_INVALID_ARG; 00293 LOG_DATA_PUBLISHER_ERROR; 00294 } 00295 else 00296 { 00297 TRANSACTION_HANDLE_DATA* transaction = (TRANSACTION_HANDLE_DATA*)transactionHandle; 00298 size_t i; 00299 00300 /* Codes_SRS_DATA_PUBLISHER_99_015:[ DataPublisher_CancelTransaction shall dispose of any resources associated with the transaction.] */ 00301 for (i = 0; i < transaction->ValueCount; i++) 00302 { 00303 Destroy_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)transaction->Values[i].Value); 00304 free((char*)transaction->Values[i].PropertyPath); 00305 free((AGENT_DATA_TYPE*)transaction->Values[i].Value); 00306 } 00307 00308 /* Codes_SRS_DATA_PUBLISHER_99_015:[ DataPublisher_CancelTransaction shall dispose of any resources associated with the transaction.] */ 00309 free(transaction->Values); 00310 free(transaction); 00311 00312 /* Codes_SRS_DATA_PUBLISHER_99_013:[ A call to DataPublisher_CancelTransaction shall dispose of the transaction without dispatching 00313 the data to the DataMarshaller module and it shall return DATA_PUBLISHER_OK.] */ 00314 result = DATA_PUBLISHER_OK; 00315 } 00316 00317 return result; 00318 } 00319 00320 /* 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.] */ 00321 void DataPublisher_SetMaxBufferSize(size_t value) 00322 { 00323 maxBufferSize_ = value; 00324 } 00325 00326 /* Codes_SRS_DATA_PUBLISHER_99_069:[ DataMarshaller_GetMaxBufferSize shall return the current max buffer size value used by any new instance of DataMarshaller.] */ 00327 size_t DataPublisher_GetMaxBufferSize(void) 00328 { 00329 return maxBufferSize_; 00330 } 00331 00332 REPORTED_PROPERTIES_TRANSACTION_HANDLE DataPublisher_CreateTransaction_ReportedProperties(DATA_PUBLISHER_HANDLE dataPublisherHandle) 00333 { 00334 REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA* result; 00335 /*Codes_SRS_DATA_PUBLISHER_02_027: [ If argument dataPublisherHandle is NULL then DataPublisher_CreateTransaction_ReportedProperties shall fail and return NULL. ]*/ 00336 if (dataPublisherHandle == NULL) 00337 { 00338 LogError("invalid argument DATA_PUBLISHER_HANDLE dataPublisherHandle=%p", dataPublisherHandle); 00339 result = NULL; 00340 } 00341 else 00342 { 00343 /*Codes_SRS_DATA_PUBLISHER_02_028: [ DataPublisher_CreateTransaction_ReportedProperties shall create a VECTOR_HANDLE holding the individual elements of the transaction (DATA_MARSHALLER_VALUE). ]*/ 00344 result = (REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA*)malloc(sizeof(REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA)); 00345 if (result == NULL) 00346 { 00347 /*Codes_SRS_DATA_PUBLISHER_02_029: [ If any error occurs then DataPublisher_CreateTransaction_ReportedProperties shall fail and return NULL. ]*/ 00348 LogError("unable to malloc"); 00349 /*return as is */ 00350 } 00351 else 00352 { 00353 result->value = VECTOR_create(sizeof(DATA_MARSHALLER_VALUE*)); 00354 if (result->value == NULL) 00355 { 00356 /*Codes_SRS_DATA_PUBLISHER_02_029: [ If any error occurs then DataPublisher_CreateTransaction_ReportedProperties shall fail and return NULL. ]*/ 00357 LogError("unable to VECTOR_create"); 00358 free(result); 00359 result = NULL; 00360 } 00361 else 00362 { 00363 /*Codes_SRS_DATA_PUBLISHER_02_030: [ Otherwise DataPublisher_CreateTransaction_ReportedProperties shall succeed and return a non-NULL handle. ]*/ 00364 result->DataPublisherInstance = dataPublisherHandle; 00365 } 00366 } 00367 } 00368 00369 return result; 00370 } 00371 00372 static bool reportedPropertyExistsByPath(const void* element, const void* value) 00373 { 00374 DATA_MARSHALLER_VALUE* dataMarshallerValue = *(DATA_MARSHALLER_VALUE**)element; 00375 return (strcmp(dataMarshallerValue->PropertyPath, (const char*)value) == 0); 00376 } 00377 00378 DATA_PUBLISHER_RESULT DataPublisher_PublishTransacted_ReportedProperty(REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle, const char* reportedPropertyPath, const AGENT_DATA_TYPE* data) 00379 { 00380 DATA_PUBLISHER_RESULT result; 00381 /*Codes_SRS_DATA_PUBLISHER_02_009: [ If argument transactionHandle is NULL then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/ 00382 /*Codes_SRS_DATA_PUBLISHER_02_010: [ If argument reportedPropertyPath is NULL then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/ 00383 /*Codes_SRS_DATA_PUBLISHER_02_011: [ If argument data is NULL then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/ 00384 if ( 00385 (transactionHandle == NULL) || 00386 (reportedPropertyPath == NULL) || 00387 (data == NULL) 00388 ) 00389 { 00390 LogError("invalid argument REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle=%p, const char* reportedPropertyPath=%p, const AGENT_DATA_TYPE* data=%p", transactionHandle, reportedPropertyPath, data); 00391 result = DATA_PUBLISHER_INVALID_ARG; 00392 } 00393 else 00394 { 00395 REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA* handleData = (REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA*)transactionHandle; 00396 /*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 ]*/ 00397 if (!Schema_ModelReportedPropertyByPathExists(handleData->DataPublisherInstance->ModelHandle, reportedPropertyPath)) 00398 { 00399 /*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. ]*/ 00400 LogError("unable to find a reported property by path \"%s\"", reportedPropertyPath); 00401 result = DATA_PUBLISHER_INVALID_ARG; 00402 } 00403 else 00404 { 00405 DATA_MARSHALLER_VALUE** existingValue = VECTOR_find_if(handleData->value, reportedPropertyExistsByPath, reportedPropertyPath); 00406 if(existingValue != NULL) 00407 { 00408 /*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. ]*/ 00409 AGENT_DATA_TYPE *clone = (AGENT_DATA_TYPE *)malloc(sizeof(AGENT_DATA_TYPE)); 00410 if(clone == NULL) 00411 { 00412 /*Codes_SRS_DATA_PUBLISHER_02_016: [ If any error occurs then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_ERROR. ]*/ 00413 LogError("unable to malloc"); 00414 result = DATA_PUBLISHER_ERROR; 00415 } 00416 else 00417 { 00418 if (Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE(clone, data) != AGENT_DATA_TYPES_OK) 00419 { 00420 /*Codes_SRS_DATA_PUBLISHER_02_016: [ If any error occurs then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_ERROR. ]*/ 00421 LogError("unable to Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE"); 00422 free(clone); 00423 result = DATA_PUBLISHER_ERROR; 00424 } 00425 else 00426 { 00427 /*Codes_SRS_DATA_PUBLISHER_02_017: [ Otherwise DataPublisher_PublishTransacted_ReportedProperty shall succeed and return DATA_PUBLISHER_OK. ]*/ 00428 Destroy_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)((*existingValue)->Value)); 00429 free((void*)((*existingValue)->Value)); 00430 (*existingValue)->Value = clone; 00431 result = DATA_PUBLISHER_OK; 00432 } 00433 } 00434 } 00435 else 00436 { 00437 /*totally new reported property*/ 00438 DATA_MARSHALLER_VALUE* newValue = (DATA_MARSHALLER_VALUE*)malloc(sizeof(DATA_MARSHALLER_VALUE)); 00439 if (newValue == NULL) 00440 { 00441 /*Codes_SRS_DATA_PUBLISHER_02_016: [ If any error occurs then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_ERROR. ]*/ 00442 LogError("unable to malloc"); 00443 result = DATA_PUBLISHER_ERROR; 00444 } 00445 else 00446 { 00447 if (mallocAndStrcpy_s((char**)&(newValue->PropertyPath), reportedPropertyPath) != 0) 00448 { 00449 /*Codes_SRS_DATA_PUBLISHER_02_016: [ If any error occurs then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_ERROR. ]*/ 00450 LogError("unable to mallocAndStrcpy_s"); 00451 free(newValue); 00452 result = DATA_PUBLISHER_ERROR; 00453 } 00454 else 00455 { 00456 if ((newValue->Value = (AGENT_DATA_TYPE*)malloc(sizeof(AGENT_DATA_TYPE))) == NULL) 00457 { 00458 LogError("unable to malloc"); 00459 free((void*)newValue->PropertyPath); 00460 free(newValue); 00461 result = DATA_PUBLISHER_ERROR; 00462 } 00463 else 00464 { 00465 if (Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)newValue->Value, data) != AGENT_DATA_TYPES_OK) 00466 { 00467 /*Codes_SRS_DATA_PUBLISHER_02_016: [ If any error occurs then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_ERROR. ]*/ 00468 LogError("unable to Create_AGENT_DATA_TYPE_from_AGENT_DATA_TYPE"); 00469 free((void*)newValue->Value); 00470 free((void*)newValue->PropertyPath); 00471 free(newValue); 00472 result = DATA_PUBLISHER_ERROR; 00473 } 00474 else 00475 { 00476 /*Codes_SRS_DATA_PUBLISHER_02_015: [ DataPublisher_PublishTransacted_ReportedProperty shall add a new DATA_MARSHALLER_VALUE to the VECTOR_HANDLE. ]*/ 00477 if (VECTOR_push_back(handleData->value, &newValue, 1) != 0) 00478 { 00479 /*Codes_SRS_DATA_PUBLISHER_02_016: [ If any error occurs then DataPublisher_PublishTransacted_ReportedProperty shall fail and return DATA_PUBLISHER_ERROR. */ 00480 LogError("unable to VECTOR_push_back"); 00481 Destroy_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)newValue->Value); 00482 free((void*)newValue->Value); 00483 free((void*)newValue->PropertyPath); 00484 free(newValue); 00485 result = DATA_PUBLISHER_ERROR; 00486 } 00487 else 00488 { 00489 /*Codes_SRS_DATA_PUBLISHER_02_017: [ Otherwise DataPublisher_PublishTransacted_ReportedProperty shall succeed and return DATA_PUBLISHER_OK. ]*/ 00490 result = DATA_PUBLISHER_OK; 00491 } 00492 } 00493 } 00494 } 00495 } 00496 } 00497 } 00498 } 00499 return result; 00500 } 00501 00502 DATA_PUBLISHER_RESULT DataPublisher_CommitTransaction_ReportedProperties(REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle, unsigned char** destination, size_t* destinationSize) 00503 { 00504 DATA_PUBLISHER_RESULT result; 00505 /*Codes_SRS_DATA_PUBLISHER_02_019: [ If argument transactionHandle is NULL then DataPublisher_CommitTransaction_ReportedProperties shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/ 00506 /*Codes_SRS_DATA_PUBLISHER_02_020: [ If argument destination is NULL then DataPublisher_CommitTransaction_ReportedProperties shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/ 00507 /*Codes_SRS_DATA_PUBLISHER_02_021: [ If argument destinationSize NULL then DataPublisher_CommitTransaction_ReportedProperties shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/ 00508 if ( 00509 (transactionHandle == NULL) || 00510 (destination == NULL) || 00511 (destinationSize == NULL) 00512 ) 00513 { 00514 LogError("invalid argument REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle=%p, unsigned char** destination=%p, size_t* destinationSize=%p", transactionHandle, destination, destinationSize); 00515 result = DATA_PUBLISHER_INVALID_ARG; 00516 } 00517 else 00518 { 00519 /*Codes_SRS_DATA_PUBLISHER_02_031: [ If the transaction contains zero elements then DataPublisher_CommitTransaction_ReportedProperties shall fail and return DATA_PUBLISHER_INVALID_ARG. ]*/ 00520 REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA* handle = (REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA*)transactionHandle; 00521 if (VECTOR_size(handle->value) == 0) 00522 { 00523 LogError("cannot commit empty transaction"); 00524 result = DATA_PUBLISHER_INVALID_ARG; 00525 } 00526 else 00527 { 00528 /*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. ]*/ 00529 if (DataMarshaller_SendData_ReportedProperties(handle->DataPublisherInstance->DataMarshallerHandle, handle->value, destination, destinationSize) != DATA_MARSHALLER_OK) 00530 { 00531 /*Codes_SRS_DATA_PUBLISHER_02_023: [ If any error occurs then DataPublisher_CommitTransaction_ReportedProperties shall fail and return DATA_PUBLISHER_ERROR. ]*/ 00532 LogError("unable to DataMarshaller_SendData_ReportedProperties"); 00533 result = DATA_PUBLISHER_ERROR; 00534 } 00535 else 00536 { 00537 /*Codes_SRS_DATA_PUBLISHER_02_024: [ Otherwise DataPublisher_CommitTransaction_ReportedProperties shall succeed and return DATA_PUBLISHER_OK. ]*/ 00538 result = DATA_PUBLISHER_OK; 00539 } 00540 } 00541 } 00542 00543 return result; 00544 } 00545 00546 void DataPublisher_DestroyTransaction_ReportedProperties(REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle) 00547 { 00548 /*Codes_SRS_DATA_PUBLISHER_02_025: [ If argument transactionHandle is NULL then DataPublisher_DestroyTransaction_ReportedProperties shall return. ]*/ 00549 if (transactionHandle == NULL) 00550 { 00551 LogError("invalig argument REPORTED_PROPERTIES_TRANSACTION_HANDLE transactionHandle=%p", transactionHandle); 00552 } 00553 else 00554 { 00555 /*Codes_SRS_DATA_PUBLISHER_02_026: [ Otherwise DataPublisher_DestroyTransaction_ReportedProperties shall free all resources associated with the reported properties transactionHandle. ]*/ 00556 REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA* handleData = (REPORTED_PROPERTIES_TRANSACTION_HANDLE_DATA*)transactionHandle; 00557 size_t i, nReportedProperties; 00558 nReportedProperties = VECTOR_size(handleData->value); 00559 for (i = 0;i < nReportedProperties;i++) 00560 { 00561 DATA_MARSHALLER_VALUE *value = *(DATA_MARSHALLER_VALUE**)VECTOR_element(handleData->value, i); 00562 Destroy_AGENT_DATA_TYPE((AGENT_DATA_TYPE*)value->Value); 00563 free((void*)value->Value); 00564 free((void*)value->PropertyPath); 00565 free((void*)value); 00566 } 00567 VECTOR_destroy(handleData->value); 00568 free(handleData); 00569 } 00570 return; 00571 }
Generated on Tue Jul 12 2022 19:56:37 by
1.7.2