docker_images/c/wrapper/glue/GlueUtils.cpp (131 lines of code) (raw):
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
#include <iostream>
#include <mutex>
#include <condition_variable>
#include <stdexcept>
#include "GlueUtils.h"
#include "json.h"
static const char* const PARSON_ERROR = "parson error";
#ifndef MU_ENUM_TO_STRING
#define MU_ENUM_TO_STRING ENUM_TO_STRING
#endif
void ThrowIfFailed(IOTHUB_CLIENT_RESULT ret, std::string functionName)
{
if (ret != IOTHUB_CLIENT_OK)
{
throw new std::runtime_error(std::string(functionName) + " returned " + MU_ENUM_TO_STRING(IOTHUB_CLIENT_RESULT, ret));
}
}
void ThrowIfFailed(IOTHUB_MESSAGING_RESULT ret, std::string functionName)
{
if (ret != IOTHUB_MESSAGING_OK)
{
throw new std::runtime_error(std::string(functionName) + " returned " + MU_ENUM_TO_STRING(IOTHUB_MESSAGING_RESULT, ret));
}
}
IOTHUB_CLIENT_TRANSPORT_PROVIDER protocolFromTransportName(std::string transportType)
{
if (strcmp(transportType.c_str(), "mqtt") == 0)
{
return MQTT_Protocol;
}
else if (strcmp(transportType.c_str(), "mqttws") == 0)
{
return MQTT_WebSocket_Protocol;
}
else if (strcmp(transportType.c_str(), "amqp") == 0)
{
return AMQP_Protocol;
}
else if (strcmp(transportType.c_str(), "amqpws") == 0)
{
return AMQP_Protocol_over_WebSocketsTls;
}
else
{
std::string transport_string = "Unknown transport: ";
throw new std::runtime_error(transport_string + transportType);
}
}
void parseMethodInvokeParameters(std::string methodInvokeParameters, std::string *methodName, std::string *payload, unsigned int *timeout)
{
Json json(methodInvokeParameters);
*methodName = json.getString("methodName");
*payload = json.getSubObject("payload");
*timeout = (unsigned int)json.getNumber("responseTimeoutInSeconds");
}
std::string makeInvokeResponse(int statusCode, std::string payload)
{
Json json;
json.setNumber("status", (double)statusCode);
json.setString("payload", payload);
return json.serializeToString();
}
void parseMethodRequestAndResponse(std::string requestAndResponse, std::string *expectedRequest, std::string *response, int *statusCode)
{
Json json(requestAndResponse);
*expectedRequest = json.getSubObject("requestPayload.payload");
*response = json.getSubObject("responsePayload");
*statusCode = (int)json.getNumber("statusCode");
}
std::string addJsonWrapperObject(std::string old_root_string, std::string wrapperDotname)
{
JSON_Value* old_root_value = NULL;
JSON_Value* new_root_value = NULL;
char *new_string = NULL;
try
{
JSON_Object* new_root_object;
if ((old_root_value = json_parse_string(old_root_string.c_str())) == NULL)
{
throw new std::runtime_error(PARSON_ERROR);
}
else if ((new_root_value = json_value_init_object()) == NULL)
{
throw new std::runtime_error(PARSON_ERROR);
}
else if ((new_root_object = json_value_get_object(new_root_value)) == NULL)
{
throw new std::runtime_error(PARSON_ERROR);
}
else if (json_object_dotset_value(new_root_object, wrapperDotname.c_str(), old_root_value) != JSONSuccess)
{
throw new std::runtime_error(PARSON_ERROR);
}
new_string = json_serialize_to_string(new_root_value);
std::string result = new_string;
json_free_serialized_string(new_string);
new_string = NULL;
json_value_free(new_root_value); //implicitly frees old_root_value and new_root_object as well
new_root_value = NULL;
return result;
}
catch (...)
{
if (new_string)
{
json_free_serialized_string(new_string);
new_string = NULL;
}
if (old_root_value)
{
json_value_free(old_root_value);
old_root_value = NULL;
}
if (new_root_value)
{
json_value_free(new_root_value); //implicitly frees new_root_object as well
new_root_value = NULL;
}
throw;
}
}
IOTHUB_MESSAGE_HANDLE stringToMessage(std::string eventBody)
{
return IoTHubMessage_CreateFromString(Json(eventBody).getSubObject("body").c_str());
}
void sendEventCallback(IOTHUB_CLIENT_CONFIRMATION_RESULT result, void *userContextCallback)
{
std::cout << "sendEventCallback called with " << MU_ENUM_TO_STRING(IOTHUB_CLIENT_CONFIRMATION_RESULT, result) << std::endl;
std::condition_variable *cv = (std::condition_variable *)userContextCallback;
cv->notify_one();
}