Azure IoT common library

Dependents:   STM32F746_iothub_client_sample_mqtt f767zi_mqtt iothub_client_sample_amqp iothub_client_sample_http ... more

Committer:
AzureIoTClient
Date:
Mon Apr 16 14:27:59 2018 -0700
Revision:
43:00b607807827
Parent:
25:8507bf644fdf
Child:
49:6bb8b9a66642
1.2.3

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Azure.IoT Build 0:fa2de1b79154 1 // Copyright (c) Microsoft. All rights reserved.
Azure.IoT Build 0:fa2de1b79154 2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
Azure.IoT Build 0:fa2de1b79154 3
Azure.IoT Build 0:fa2de1b79154 4 #include <stdlib.h>
Azure.IoT Build 0:fa2de1b79154 5 #include <stddef.h>
Azure.IoT Build 0:fa2de1b79154 6 #include <string.h>
AzureIoTClient 20:95abdea56064 7 #include "azure_c_shared_utility/gballoc.h"
Azure.IoT Build 0:fa2de1b79154 8 #include "azure_c_shared_utility/urlencode.h"
Azure.IoT Build 6:c55b013dfc2a 9 #include "azure_c_shared_utility/xlogging.h"
Azure.IoT Build 0:fa2de1b79154 10 #include "azure_c_shared_utility/strings.h"
AzureIoTClient 43:00b607807827 11 #include "azure_c_shared_utility/crt_abstractions.h"
Azure.IoT Build 0:fa2de1b79154 12
AzureIoTClient 43:00b607807827 13 #define NIBBLE_TO_STRING(c) (char)((c) < 10 ? (c) + '0' : (c) - 10 + 'a')
AzureIoTClient 43:00b607807827 14 #define NIBBLE_FROM_STRING(c) (char)(ISDIGIT(c) ? (c) - '0' : TOUPPER(c) + 10 - 'A')
AzureIoTClient 43:00b607807827 15 #define IS_HEXDIGIT(c) ( \
AzureIoTClient 43:00b607807827 16 ((c >= '0') && (c <= '9')) || \
AzureIoTClient 43:00b607807827 17 ((c >= 'A') && (c <= 'F')) || \
AzureIoTClient 43:00b607807827 18 ((c >= 'a') && (c <= 'f')) \
AzureIoTClient 43:00b607807827 19 )
AzureIoTClient 11:77df6d7e65ae 20 #define IS_PRINTABLE(c) ( \
AzureIoTClient 11:77df6d7e65ae 21 (c == 0) || \
AzureIoTClient 11:77df6d7e65ae 22 (c == '!') || \
AzureIoTClient 11:77df6d7e65ae 23 (c == '(') || (c == ')') || (c == '*') || \
AzureIoTClient 11:77df6d7e65ae 24 (c == '-') || (c == '.') || \
AzureIoTClient 11:77df6d7e65ae 25 ((c >= '0') && (c <= '9')) || \
AzureIoTClient 11:77df6d7e65ae 26 ((c >= 'A') && (c <= 'Z')) || \
AzureIoTClient 11:77df6d7e65ae 27 (c == '_') || \
AzureIoTClient 11:77df6d7e65ae 28 ((c >= 'a') && (c <= 'z')) \
AzureIoTClient 11:77df6d7e65ae 29 )
AzureIoTClient 11:77df6d7e65ae 30
AzureIoTClient 43:00b607807827 31 /*The below macros are to be called on the big nibble of a hex value*/
AzureIoTClient 43:00b607807827 32 #define IS_IN_ASCII_RANGE(c) ( \
AzureIoTClient 43:00b607807827 33 (c >= '0') && (c <= '7') \
AzureIoTClient 43:00b607807827 34 )
AzureIoTClient 43:00b607807827 35 #define IS_IN_EXTENDED_ASCII_RANGE(c) ( \
AzureIoTClient 43:00b607807827 36 ((c >= '8') && (c <= '9')) || \
AzureIoTClient 43:00b607807827 37 ((c >= 'A') && (c <= 'F')) || \
AzureIoTClient 43:00b607807827 38 ((c >= 'a') && (c <= 'f')) \
AzureIoTClient 43:00b607807827 39 )
AzureIoTClient 43:00b607807827 40 #define IS_IN_CONTINUATION_BYTE_RANGE(c) ( \
AzureIoTClient 43:00b607807827 41 (c == '8') || (c == '9') || \
AzureIoTClient 43:00b607807827 42 (c == 'A') || (c == 'B') || \
AzureIoTClient 43:00b607807827 43 (c == 'a') || (c == 'b') \
AzureIoTClient 43:00b607807827 44 )
AzureIoTClient 43:00b607807827 45 #define IS_IN_LEADING_BYTE_RANGE(c) ( \
AzureIoTClient 43:00b607807827 46 ((c >= 'C') && (c <= 'F')) || \
AzureIoTClient 43:00b607807827 47 ((c >= 'c') && (c <= 'f')) \
AzureIoTClient 43:00b607807827 48 )
AzureIoTClient 43:00b607807827 49 #define IS_IN_UNSUPPORTED_LEADING_BYTE_RANGE(c) ( \
AzureIoTClient 43:00b607807827 50 ((c >= 'D') && (c <= 'F')) || \
AzureIoTClient 43:00b607807827 51 ((c >= 'd') && (c <= 'f')) \
AzureIoTClient 43:00b607807827 52 )
AzureIoTClient 43:00b607807827 53
AzureIoTClient 11:77df6d7e65ae 54 static size_t URL_PrintableChar(unsigned char charVal, char* buffer)
AzureIoTClient 11:77df6d7e65ae 55 {
AzureIoTClient 11:77df6d7e65ae 56 size_t size;
AzureIoTClient 11:77df6d7e65ae 57 if (IS_PRINTABLE(charVal))
AzureIoTClient 11:77df6d7e65ae 58 {
AzureIoTClient 11:77df6d7e65ae 59 buffer[0] = (char)charVal;
AzureIoTClient 11:77df6d7e65ae 60 size = 1;
AzureIoTClient 11:77df6d7e65ae 61 }
AzureIoTClient 11:77df6d7e65ae 62 else
AzureIoTClient 11:77df6d7e65ae 63 {
AzureIoTClient 11:77df6d7e65ae 64 char bigNibbleStr;
AzureIoTClient 11:77df6d7e65ae 65 char littleNibbleStr;
AzureIoTClient 11:77df6d7e65ae 66 unsigned char bigNibbleVal = charVal >> 4;
AzureIoTClient 11:77df6d7e65ae 67 unsigned char littleNibbleVal = charVal & 0x0F;
AzureIoTClient 11:77df6d7e65ae 68
AzureIoTClient 11:77df6d7e65ae 69 if (bigNibbleVal >= 0x0C)
AzureIoTClient 11:77df6d7e65ae 70 {
AzureIoTClient 11:77df6d7e65ae 71 bigNibbleVal -= 0x04;
AzureIoTClient 11:77df6d7e65ae 72 }
AzureIoTClient 11:77df6d7e65ae 73
AzureIoTClient 43:00b607807827 74 bigNibbleStr = NIBBLE_TO_STRING(bigNibbleVal);
AzureIoTClient 43:00b607807827 75 littleNibbleStr = NIBBLE_TO_STRING(littleNibbleVal);
AzureIoTClient 11:77df6d7e65ae 76
AzureIoTClient 11:77df6d7e65ae 77 buffer[0] = '%';
AzureIoTClient 11:77df6d7e65ae 78
AzureIoTClient 11:77df6d7e65ae 79 if (charVal < 0x80)
AzureIoTClient 11:77df6d7e65ae 80 {
AzureIoTClient 11:77df6d7e65ae 81 buffer[1] = bigNibbleStr;
AzureIoTClient 11:77df6d7e65ae 82 buffer[2] = littleNibbleStr;
AzureIoTClient 11:77df6d7e65ae 83 size = 3;
AzureIoTClient 11:77df6d7e65ae 84 }
AzureIoTClient 11:77df6d7e65ae 85 else
AzureIoTClient 11:77df6d7e65ae 86 {
AzureIoTClient 11:77df6d7e65ae 87 buffer[1] = 'c';
AzureIoTClient 11:77df6d7e65ae 88 buffer[3] = '%';
AzureIoTClient 11:77df6d7e65ae 89 buffer[4] = bigNibbleStr;
AzureIoTClient 11:77df6d7e65ae 90 buffer[5] = littleNibbleStr;
AzureIoTClient 11:77df6d7e65ae 91 if (charVal < 0xC0)
AzureIoTClient 11:77df6d7e65ae 92 {
AzureIoTClient 11:77df6d7e65ae 93 buffer[2] = '2';
AzureIoTClient 11:77df6d7e65ae 94 }
AzureIoTClient 11:77df6d7e65ae 95 else
AzureIoTClient 11:77df6d7e65ae 96 {
AzureIoTClient 11:77df6d7e65ae 97 buffer[2] = '3';
AzureIoTClient 11:77df6d7e65ae 98 }
AzureIoTClient 11:77df6d7e65ae 99 size = 6;
AzureIoTClient 11:77df6d7e65ae 100 }
AzureIoTClient 11:77df6d7e65ae 101 }
AzureIoTClient 11:77df6d7e65ae 102
AzureIoTClient 11:77df6d7e65ae 103 return size;
AzureIoTClient 11:77df6d7e65ae 104 }
AzureIoTClient 11:77df6d7e65ae 105
AzureIoTClient 43:00b607807827 106 static size_t calculateDecodedStringSize(const char* encodedString, size_t len)
AzureIoTClient 43:00b607807827 107 {
AzureIoTClient 43:00b607807827 108 size_t decodedSize = 0;
AzureIoTClient 43:00b607807827 109
AzureIoTClient 43:00b607807827 110 if (encodedString == NULL)
AzureIoTClient 43:00b607807827 111 {
AzureIoTClient 43:00b607807827 112 LogError("Null encoded string");
AzureIoTClient 43:00b607807827 113 }
AzureIoTClient 43:00b607807827 114 else if (len == 0)
AzureIoTClient 43:00b607807827 115 {
AzureIoTClient 43:00b607807827 116 decodedSize = 1; //for null terminator
AzureIoTClient 43:00b607807827 117 }
AzureIoTClient 43:00b607807827 118 else
AzureIoTClient 43:00b607807827 119 {
AzureIoTClient 43:00b607807827 120 size_t remaining_len = len;
AzureIoTClient 43:00b607807827 121 size_t next_step = 0;
AzureIoTClient 43:00b607807827 122 size_t i = 0;
AzureIoTClient 43:00b607807827 123 while (i < len)
AzureIoTClient 43:00b607807827 124 {
AzureIoTClient 43:00b607807827 125 //percent encoded character
AzureIoTClient 43:00b607807827 126 if (encodedString[i] == '%')
AzureIoTClient 43:00b607807827 127 {
AzureIoTClient 43:00b607807827 128 if (remaining_len < 3 || !IS_HEXDIGIT(encodedString[i+1]) || !IS_HEXDIGIT(encodedString[i+2]))
AzureIoTClient 43:00b607807827 129 {
AzureIoTClient 43:00b607807827 130 LogError("Incomplete or invalid percent encoding");
AzureIoTClient 43:00b607807827 131 break;
AzureIoTClient 43:00b607807827 132 }
AzureIoTClient 43:00b607807827 133 else if (!IS_IN_ASCII_RANGE(encodedString[i+1]))
AzureIoTClient 43:00b607807827 134 {
AzureIoTClient 43:00b607807827 135 LogError("Out of range of characters accepted by this decoder");
AzureIoTClient 43:00b607807827 136 break;
AzureIoTClient 43:00b607807827 137 }
AzureIoTClient 43:00b607807827 138 else
AzureIoTClient 43:00b607807827 139 {
AzureIoTClient 43:00b607807827 140 decodedSize++;
AzureIoTClient 43:00b607807827 141 next_step = 3;
AzureIoTClient 43:00b607807827 142 }
AzureIoTClient 43:00b607807827 143 }
AzureIoTClient 43:00b607807827 144 else if (!IS_PRINTABLE(encodedString[i]))
AzureIoTClient 43:00b607807827 145 {
AzureIoTClient 43:00b607807827 146 LogError("Unprintable value in encoded string");
AzureIoTClient 43:00b607807827 147 break;
AzureIoTClient 43:00b607807827 148 }
AzureIoTClient 43:00b607807827 149 //safe character
AzureIoTClient 43:00b607807827 150 else
AzureIoTClient 43:00b607807827 151 {
AzureIoTClient 43:00b607807827 152 decodedSize++;
AzureIoTClient 43:00b607807827 153 next_step = 1;
AzureIoTClient 43:00b607807827 154 }
AzureIoTClient 43:00b607807827 155
AzureIoTClient 43:00b607807827 156 i += next_step;
AzureIoTClient 43:00b607807827 157 remaining_len -= next_step;
AzureIoTClient 43:00b607807827 158 }
AzureIoTClient 43:00b607807827 159
AzureIoTClient 43:00b607807827 160 if (encodedString[i] != '\0') //i.e. broke out of above loop due to error
AzureIoTClient 43:00b607807827 161 {
AzureIoTClient 43:00b607807827 162 decodedSize = 0;
AzureIoTClient 43:00b607807827 163 }
AzureIoTClient 43:00b607807827 164 else
AzureIoTClient 43:00b607807827 165 {
AzureIoTClient 43:00b607807827 166 decodedSize++; //add space for the null terminator
AzureIoTClient 43:00b607807827 167 }
AzureIoTClient 43:00b607807827 168 }
AzureIoTClient 43:00b607807827 169 return decodedSize;
AzureIoTClient 43:00b607807827 170 }
AzureIoTClient 43:00b607807827 171
AzureIoTClient 43:00b607807827 172 static unsigned char charFromNibbles(char bigNibbleStr, char littleNibbleStr)
AzureIoTClient 43:00b607807827 173 {
AzureIoTClient 43:00b607807827 174 unsigned char bigNibbleVal = NIBBLE_FROM_STRING(bigNibbleStr);
AzureIoTClient 43:00b607807827 175 unsigned char littleNibbleVal = NIBBLE_FROM_STRING(littleNibbleStr);
AzureIoTClient 43:00b607807827 176
AzureIoTClient 43:00b607807827 177 return bigNibbleVal << 4 | littleNibbleVal;
AzureIoTClient 43:00b607807827 178 }
AzureIoTClient 43:00b607807827 179
AzureIoTClient 43:00b607807827 180 static void createDecodedString(const char* input, size_t input_size, char* output)
AzureIoTClient 43:00b607807827 181 {
AzureIoTClient 43:00b607807827 182 /* Note that there is no danger of reckless indexing here, as calculateDecodedStringSize()
AzureIoTClient 43:00b607807827 183 has already checked lengths of strings to ensure the formatting is always correct*/
AzureIoTClient 43:00b607807827 184 size_t i = 0;
AzureIoTClient 43:00b607807827 185 while (i <= input_size) //the <= instead of < ensures the '\0' will be copied
AzureIoTClient 43:00b607807827 186 {
AzureIoTClient 43:00b607807827 187 if (input[i] != '%')
AzureIoTClient 43:00b607807827 188 {
AzureIoTClient 43:00b607807827 189 *output++ = input[i];
AzureIoTClient 43:00b607807827 190 i++;
AzureIoTClient 43:00b607807827 191 }
AzureIoTClient 43:00b607807827 192 else
AzureIoTClient 43:00b607807827 193 {
AzureIoTClient 43:00b607807827 194 *output++ = charFromNibbles(input[i+1], input[i+2]);
AzureIoTClient 43:00b607807827 195 i += 3;
AzureIoTClient 43:00b607807827 196 }
AzureIoTClient 43:00b607807827 197 }
AzureIoTClient 43:00b607807827 198 }
AzureIoTClient 43:00b607807827 199
AzureIoTClient 11:77df6d7e65ae 200 static size_t URL_PrintableCharSize(unsigned char charVal)
AzureIoTClient 11:77df6d7e65ae 201 {
AzureIoTClient 11:77df6d7e65ae 202 size_t size;
AzureIoTClient 11:77df6d7e65ae 203 if (IS_PRINTABLE(charVal))
AzureIoTClient 11:77df6d7e65ae 204 {
AzureIoTClient 11:77df6d7e65ae 205 size = 1;
AzureIoTClient 11:77df6d7e65ae 206 }
AzureIoTClient 11:77df6d7e65ae 207 else
AzureIoTClient 11:77df6d7e65ae 208 {
AzureIoTClient 11:77df6d7e65ae 209 if (charVal < 0x80)
AzureIoTClient 11:77df6d7e65ae 210 {
AzureIoTClient 11:77df6d7e65ae 211 size = 3;
AzureIoTClient 11:77df6d7e65ae 212 }
AzureIoTClient 11:77df6d7e65ae 213 else
AzureIoTClient 11:77df6d7e65ae 214 {
AzureIoTClient 11:77df6d7e65ae 215 size = 6;
AzureIoTClient 11:77df6d7e65ae 216 }
AzureIoTClient 11:77df6d7e65ae 217 }
AzureIoTClient 11:77df6d7e65ae 218 return size;
AzureIoTClient 11:77df6d7e65ae 219 }
Azure.IoT Build 0:fa2de1b79154 220
Azure.IoT Build 0:fa2de1b79154 221 STRING_HANDLE URL_EncodeString(const char* textEncode)
Azure.IoT Build 0:fa2de1b79154 222 {
Azure.IoT Build 0:fa2de1b79154 223 STRING_HANDLE result;
Azure.IoT Build 0:fa2de1b79154 224 if (textEncode == NULL)
Azure.IoT Build 0:fa2de1b79154 225 {
Azure.IoT Build 0:fa2de1b79154 226 result = NULL;
Azure.IoT Build 0:fa2de1b79154 227 }
Azure.IoT Build 0:fa2de1b79154 228 else
Azure.IoT Build 0:fa2de1b79154 229 {
Azure.IoT Build 0:fa2de1b79154 230 STRING_HANDLE tempString = STRING_construct(textEncode);
Azure.IoT Build 0:fa2de1b79154 231 if (tempString == NULL)
Azure.IoT Build 0:fa2de1b79154 232 {
Azure.IoT Build 0:fa2de1b79154 233 result = NULL;
Azure.IoT Build 0:fa2de1b79154 234 }
Azure.IoT Build 0:fa2de1b79154 235 else
Azure.IoT Build 0:fa2de1b79154 236 {
Azure.IoT Build 0:fa2de1b79154 237 result = URL_Encode(tempString);
Azure.IoT Build 0:fa2de1b79154 238 STRING_delete(tempString);
Azure.IoT Build 0:fa2de1b79154 239 }
Azure.IoT Build 0:fa2de1b79154 240 }
Azure.IoT Build 0:fa2de1b79154 241 return result;
Azure.IoT Build 0:fa2de1b79154 242 }
Azure.IoT Build 0:fa2de1b79154 243
Azure.IoT Build 0:fa2de1b79154 244 STRING_HANDLE URL_Encode(STRING_HANDLE input)
Azure.IoT Build 0:fa2de1b79154 245 {
Azure.IoT Build 0:fa2de1b79154 246 STRING_HANDLE result;
Azure.IoT Build 0:fa2de1b79154 247 if (input == NULL)
Azure.IoT Build 0:fa2de1b79154 248 {
Azure.IoT Build 0:fa2de1b79154 249 /*Codes_SRS_URL_ENCODE_06_001: [If input is NULL then URL_Encode will return NULL.]*/
Azure.IoT Build 0:fa2de1b79154 250 result = NULL;
AzureIoTClient 1:9190c0f4d23a 251 LogError("URL_Encode:: NULL input");
Azure.IoT Build 0:fa2de1b79154 252 }
Azure.IoT Build 0:fa2de1b79154 253 else
Azure.IoT Build 0:fa2de1b79154 254 {
Azure.IoT Build 0:fa2de1b79154 255 size_t lengthOfResult = 0;
Azure.IoT Build 0:fa2de1b79154 256 char* encodedURL;
Azure.IoT Build 0:fa2de1b79154 257 const char* currentInput;
Azure.IoT Build 0:fa2de1b79154 258 unsigned char currentUnsignedChar;
Azure.IoT Build 0:fa2de1b79154 259 currentInput = STRING_c_str(input);
Azure.IoT Build 0:fa2de1b79154 260 /*Codes_SRS_URL_ENCODE_06_003: [If input is a zero length string then URL_Encode will return a zero length string.]*/
Azure.IoT Build 0:fa2de1b79154 261 do
Azure.IoT Build 0:fa2de1b79154 262 {
Azure.IoT Build 0:fa2de1b79154 263 currentUnsignedChar = (unsigned char)(*currentInput++);
AzureIoTClient 11:77df6d7e65ae 264 lengthOfResult += URL_PrintableCharSize(currentUnsignedChar);
Azure.IoT Build 0:fa2de1b79154 265 } while (currentUnsignedChar != 0);
AzureIoTClient 25:8507bf644fdf 266 if ((encodedURL = (char*)malloc(lengthOfResult)) == NULL)
Azure.IoT Build 0:fa2de1b79154 267 {
Azure.IoT Build 0:fa2de1b79154 268 /*Codes_SRS_URL_ENCODE_06_002: [If an error occurs during the encoding of input then URL_Encode will return NULL.]*/
Azure.IoT Build 0:fa2de1b79154 269 result = NULL;
AzureIoTClient 1:9190c0f4d23a 270 LogError("URL_Encode:: MALLOC failure on encode.");
Azure.IoT Build 0:fa2de1b79154 271 }
Azure.IoT Build 0:fa2de1b79154 272 else
Azure.IoT Build 0:fa2de1b79154 273 {
Azure.IoT Build 0:fa2de1b79154 274 size_t currentEncodePosition = 0;
Azure.IoT Build 0:fa2de1b79154 275 currentInput = STRING_c_str(input);
Azure.IoT Build 0:fa2de1b79154 276 do
Azure.IoT Build 0:fa2de1b79154 277 {
Azure.IoT Build 0:fa2de1b79154 278 currentUnsignedChar = (unsigned char)(*currentInput++);
AzureIoTClient 11:77df6d7e65ae 279 currentEncodePosition += URL_PrintableChar(currentUnsignedChar, &encodedURL[currentEncodePosition]);
Azure.IoT Build 0:fa2de1b79154 280 } while (currentUnsignedChar != 0);
AzureIoTClient 11:77df6d7e65ae 281
Azure.IoT Build 0:fa2de1b79154 282 result = STRING_new_with_memory(encodedURL);
AzureIoTClient 11:77df6d7e65ae 283 if (result == NULL)
AzureIoTClient 11:77df6d7e65ae 284 {
AzureIoTClient 11:77df6d7e65ae 285 LogError("URL_Encode:: MALLOC failure on encode.");
AzureIoTClient 11:77df6d7e65ae 286 free(encodedURL);
AzureIoTClient 11:77df6d7e65ae 287 }
Azure.IoT Build 0:fa2de1b79154 288 }
Azure.IoT Build 0:fa2de1b79154 289 }
Azure.IoT Build 0:fa2de1b79154 290 return result;
Azure.IoT Build 0:fa2de1b79154 291 }
AzureIoTClient 43:00b607807827 292
AzureIoTClient 43:00b607807827 293 STRING_HANDLE URL_DecodeString(const char* textDecode)
AzureIoTClient 43:00b607807827 294 {
AzureIoTClient 43:00b607807827 295 STRING_HANDLE result;
AzureIoTClient 43:00b607807827 296 if (textDecode == NULL)
AzureIoTClient 43:00b607807827 297 {
AzureIoTClient 43:00b607807827 298 result = NULL;
AzureIoTClient 43:00b607807827 299 }
AzureIoTClient 43:00b607807827 300 else
AzureIoTClient 43:00b607807827 301 {
AzureIoTClient 43:00b607807827 302 STRING_HANDLE tempString = STRING_construct(textDecode);
AzureIoTClient 43:00b607807827 303 if (tempString == NULL)
AzureIoTClient 43:00b607807827 304 {
AzureIoTClient 43:00b607807827 305 result = NULL;
AzureIoTClient 43:00b607807827 306 }
AzureIoTClient 43:00b607807827 307 else
AzureIoTClient 43:00b607807827 308 {
AzureIoTClient 43:00b607807827 309 result = URL_Decode(tempString);
AzureIoTClient 43:00b607807827 310 STRING_delete(tempString);
AzureIoTClient 43:00b607807827 311 }
AzureIoTClient 43:00b607807827 312 }
AzureIoTClient 43:00b607807827 313 return result;
AzureIoTClient 43:00b607807827 314 }
AzureIoTClient 43:00b607807827 315
AzureIoTClient 43:00b607807827 316 STRING_HANDLE URL_Decode(STRING_HANDLE input)
AzureIoTClient 43:00b607807827 317 {
AzureIoTClient 43:00b607807827 318 STRING_HANDLE result;
AzureIoTClient 43:00b607807827 319 if (input == NULL)
AzureIoTClient 43:00b607807827 320 {
AzureIoTClient 43:00b607807827 321 LogError("URL_Decode:: NULL input");
AzureIoTClient 43:00b607807827 322 result = NULL;
AzureIoTClient 43:00b607807827 323 }
AzureIoTClient 43:00b607807827 324 else
AzureIoTClient 43:00b607807827 325 {
AzureIoTClient 43:00b607807827 326 size_t decodedStringSize;
AzureIoTClient 43:00b607807827 327 char* decodedString;
AzureIoTClient 43:00b607807827 328 const char* inputString = STRING_c_str(input);
AzureIoTClient 43:00b607807827 329 size_t inputLen = strlen(inputString);
AzureIoTClient 43:00b607807827 330 if ((decodedStringSize = calculateDecodedStringSize(inputString, inputLen)) == 0)
AzureIoTClient 43:00b607807827 331 {
AzureIoTClient 43:00b607807827 332 LogError("URL_Decode:: Invalid input string");
AzureIoTClient 43:00b607807827 333 result = NULL;
AzureIoTClient 43:00b607807827 334 }
AzureIoTClient 43:00b607807827 335 else if ((decodedString = (char*)malloc(decodedStringSize)) == NULL)
AzureIoTClient 43:00b607807827 336 {
AzureIoTClient 43:00b607807827 337 LogError("URL_Decode:: MALLOC failure on decode.");
AzureIoTClient 43:00b607807827 338 result = NULL;
AzureIoTClient 43:00b607807827 339 }
AzureIoTClient 43:00b607807827 340 else
AzureIoTClient 43:00b607807827 341 {
AzureIoTClient 43:00b607807827 342 createDecodedString(inputString, inputLen, decodedString);
AzureIoTClient 43:00b607807827 343 result = STRING_new_with_memory(decodedString);
AzureIoTClient 43:00b607807827 344 if (result == NULL)
AzureIoTClient 43:00b607807827 345 {
AzureIoTClient 43:00b607807827 346 LogError("URL_Decode:: MALLOC failure on decode");
AzureIoTClient 43:00b607807827 347 free(decodedString);
AzureIoTClient 43:00b607807827 348 }
AzureIoTClient 43:00b607807827 349 }
AzureIoTClient 43:00b607807827 350 }
AzureIoTClient 43:00b607807827 351 return result;
AzureIoTClient 43:00b607807827 352 }