Xin Zhang / azure-iot-c-sdk-f767zi

Dependents:   samplemqtt

Committer:
XinZhangMS
Date:
Thu Aug 23 06:52:14 2018 +0000
Revision:
0:f7f1f0d76dd6
azure-c-sdk for mbed os supporting NUCLEO_F767ZI

Who changed what in which revision?

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