Azure IoT common library

Fork of azure_c_shared_utility by Azure IoT

Committer:
AzureIoTClient
Date:
Fri Apr 21 14:51:10 2017 -0700
Revision:
25:8507bf644fdf
Parent:
20:95abdea56064
1.1.13

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"
Azure.IoT Build 0:fa2de1b79154 11
AzureIoTClient 11:77df6d7e65ae 12 #define NIBBLE_STR(c) (char)(c < 10 ? c + '0' : c - 10 + 'a')
AzureIoTClient 11:77df6d7e65ae 13 #define IS_PRINTABLE(c) ( \
AzureIoTClient 11:77df6d7e65ae 14 (c == 0) || \
AzureIoTClient 11:77df6d7e65ae 15 (c == '!') || \
AzureIoTClient 11:77df6d7e65ae 16 (c == '(') || (c == ')') || (c == '*') || \
AzureIoTClient 11:77df6d7e65ae 17 (c == '-') || (c == '.') || \
AzureIoTClient 11:77df6d7e65ae 18 ((c >= '0') && (c <= '9')) || \
AzureIoTClient 11:77df6d7e65ae 19 ((c >= 'A') && (c <= 'Z')) || \
AzureIoTClient 11:77df6d7e65ae 20 (c == '_') || \
AzureIoTClient 11:77df6d7e65ae 21 ((c >= 'a') && (c <= 'z')) \
AzureIoTClient 11:77df6d7e65ae 22 )
AzureIoTClient 11:77df6d7e65ae 23
AzureIoTClient 11:77df6d7e65ae 24 static size_t URL_PrintableChar(unsigned char charVal, char* buffer)
AzureIoTClient 11:77df6d7e65ae 25 {
AzureIoTClient 11:77df6d7e65ae 26 size_t size;
AzureIoTClient 11:77df6d7e65ae 27 if (IS_PRINTABLE(charVal))
AzureIoTClient 11:77df6d7e65ae 28 {
AzureIoTClient 11:77df6d7e65ae 29 buffer[0] = (char)charVal;
AzureIoTClient 11:77df6d7e65ae 30 size = 1;
AzureIoTClient 11:77df6d7e65ae 31 }
AzureIoTClient 11:77df6d7e65ae 32 else
AzureIoTClient 11:77df6d7e65ae 33 {
AzureIoTClient 11:77df6d7e65ae 34 char bigNibbleStr;
AzureIoTClient 11:77df6d7e65ae 35 char littleNibbleStr;
AzureIoTClient 11:77df6d7e65ae 36 unsigned char bigNibbleVal = charVal >> 4;
AzureIoTClient 11:77df6d7e65ae 37 unsigned char littleNibbleVal = charVal & 0x0F;
AzureIoTClient 11:77df6d7e65ae 38
AzureIoTClient 11:77df6d7e65ae 39 if (bigNibbleVal >= 0x0C)
AzureIoTClient 11:77df6d7e65ae 40 {
AzureIoTClient 11:77df6d7e65ae 41 bigNibbleVal -= 0x04;
AzureIoTClient 11:77df6d7e65ae 42 }
AzureIoTClient 11:77df6d7e65ae 43
AzureIoTClient 11:77df6d7e65ae 44 bigNibbleStr = NIBBLE_STR(bigNibbleVal);
AzureIoTClient 11:77df6d7e65ae 45 littleNibbleStr = NIBBLE_STR(littleNibbleVal);
AzureIoTClient 11:77df6d7e65ae 46
AzureIoTClient 11:77df6d7e65ae 47 buffer[0] = '%';
AzureIoTClient 11:77df6d7e65ae 48
AzureIoTClient 11:77df6d7e65ae 49 if (charVal < 0x80)
AzureIoTClient 11:77df6d7e65ae 50 {
AzureIoTClient 11:77df6d7e65ae 51 buffer[1] = bigNibbleStr;
AzureIoTClient 11:77df6d7e65ae 52 buffer[2] = littleNibbleStr;
AzureIoTClient 11:77df6d7e65ae 53 size = 3;
AzureIoTClient 11:77df6d7e65ae 54 }
AzureIoTClient 11:77df6d7e65ae 55 else
AzureIoTClient 11:77df6d7e65ae 56 {
AzureIoTClient 11:77df6d7e65ae 57 buffer[1] = 'c';
AzureIoTClient 11:77df6d7e65ae 58 buffer[3] = '%';
AzureIoTClient 11:77df6d7e65ae 59 buffer[4] = bigNibbleStr;
AzureIoTClient 11:77df6d7e65ae 60 buffer[5] = littleNibbleStr;
AzureIoTClient 11:77df6d7e65ae 61 if (charVal < 0xC0)
AzureIoTClient 11:77df6d7e65ae 62 {
AzureIoTClient 11:77df6d7e65ae 63 buffer[2] = '2';
AzureIoTClient 11:77df6d7e65ae 64 }
AzureIoTClient 11:77df6d7e65ae 65 else
AzureIoTClient 11:77df6d7e65ae 66 {
AzureIoTClient 11:77df6d7e65ae 67 buffer[2] = '3';
AzureIoTClient 11:77df6d7e65ae 68 }
AzureIoTClient 11:77df6d7e65ae 69 size = 6;
AzureIoTClient 11:77df6d7e65ae 70 }
AzureIoTClient 11:77df6d7e65ae 71 }
AzureIoTClient 11:77df6d7e65ae 72
AzureIoTClient 11:77df6d7e65ae 73 return size;
AzureIoTClient 11:77df6d7e65ae 74 }
AzureIoTClient 11:77df6d7e65ae 75
AzureIoTClient 11:77df6d7e65ae 76 static size_t URL_PrintableCharSize(unsigned char charVal)
AzureIoTClient 11:77df6d7e65ae 77 {
AzureIoTClient 11:77df6d7e65ae 78 size_t size;
AzureIoTClient 11:77df6d7e65ae 79 if (IS_PRINTABLE(charVal))
AzureIoTClient 11:77df6d7e65ae 80 {
AzureIoTClient 11:77df6d7e65ae 81 size = 1;
AzureIoTClient 11:77df6d7e65ae 82 }
AzureIoTClient 11:77df6d7e65ae 83 else
AzureIoTClient 11:77df6d7e65ae 84 {
AzureIoTClient 11:77df6d7e65ae 85 if (charVal < 0x80)
AzureIoTClient 11:77df6d7e65ae 86 {
AzureIoTClient 11:77df6d7e65ae 87 size = 3;
AzureIoTClient 11:77df6d7e65ae 88 }
AzureIoTClient 11:77df6d7e65ae 89 else
AzureIoTClient 11:77df6d7e65ae 90 {
AzureIoTClient 11:77df6d7e65ae 91 size = 6;
AzureIoTClient 11:77df6d7e65ae 92 }
AzureIoTClient 11:77df6d7e65ae 93 }
AzureIoTClient 11:77df6d7e65ae 94 return size;
AzureIoTClient 11:77df6d7e65ae 95 }
Azure.IoT Build 0:fa2de1b79154 96
Azure.IoT Build 0:fa2de1b79154 97 STRING_HANDLE URL_EncodeString(const char* textEncode)
Azure.IoT Build 0:fa2de1b79154 98 {
Azure.IoT Build 0:fa2de1b79154 99 STRING_HANDLE result;
Azure.IoT Build 0:fa2de1b79154 100 if (textEncode == NULL)
Azure.IoT Build 0:fa2de1b79154 101 {
Azure.IoT Build 0:fa2de1b79154 102 result = NULL;
Azure.IoT Build 0:fa2de1b79154 103 }
Azure.IoT Build 0:fa2de1b79154 104 else
Azure.IoT Build 0:fa2de1b79154 105 {
Azure.IoT Build 0:fa2de1b79154 106 STRING_HANDLE tempString = STRING_construct(textEncode);
Azure.IoT Build 0:fa2de1b79154 107 if (tempString == NULL)
Azure.IoT Build 0:fa2de1b79154 108 {
Azure.IoT Build 0:fa2de1b79154 109 result = NULL;
Azure.IoT Build 0:fa2de1b79154 110 }
Azure.IoT Build 0:fa2de1b79154 111 else
Azure.IoT Build 0:fa2de1b79154 112 {
Azure.IoT Build 0:fa2de1b79154 113 result = URL_Encode(tempString);
Azure.IoT Build 0:fa2de1b79154 114 STRING_delete(tempString);
Azure.IoT Build 0:fa2de1b79154 115 }
Azure.IoT Build 0:fa2de1b79154 116 }
Azure.IoT Build 0:fa2de1b79154 117 return result;
Azure.IoT Build 0:fa2de1b79154 118 }
Azure.IoT Build 0:fa2de1b79154 119
Azure.IoT Build 0:fa2de1b79154 120 STRING_HANDLE URL_Encode(STRING_HANDLE input)
Azure.IoT Build 0:fa2de1b79154 121 {
Azure.IoT Build 0:fa2de1b79154 122 STRING_HANDLE result;
Azure.IoT Build 0:fa2de1b79154 123 if (input == NULL)
Azure.IoT Build 0:fa2de1b79154 124 {
Azure.IoT Build 0:fa2de1b79154 125 /*Codes_SRS_URL_ENCODE_06_001: [If input is NULL then URL_Encode will return NULL.]*/
Azure.IoT Build 0:fa2de1b79154 126 result = NULL;
AzureIoTClient 1:9190c0f4d23a 127 LogError("URL_Encode:: NULL input");
Azure.IoT Build 0:fa2de1b79154 128 }
Azure.IoT Build 0:fa2de1b79154 129 else
Azure.IoT Build 0:fa2de1b79154 130 {
Azure.IoT Build 0:fa2de1b79154 131 size_t lengthOfResult = 0;
Azure.IoT Build 0:fa2de1b79154 132 char* encodedURL;
Azure.IoT Build 0:fa2de1b79154 133 const char* currentInput;
Azure.IoT Build 0:fa2de1b79154 134 unsigned char currentUnsignedChar;
Azure.IoT Build 0:fa2de1b79154 135 currentInput = STRING_c_str(input);
Azure.IoT Build 0:fa2de1b79154 136 /*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 137 do
Azure.IoT Build 0:fa2de1b79154 138 {
Azure.IoT Build 0:fa2de1b79154 139 currentUnsignedChar = (unsigned char)(*currentInput++);
AzureIoTClient 11:77df6d7e65ae 140 lengthOfResult += URL_PrintableCharSize(currentUnsignedChar);
Azure.IoT Build 0:fa2de1b79154 141 } while (currentUnsignedChar != 0);
AzureIoTClient 25:8507bf644fdf 142 if ((encodedURL = (char*)malloc(lengthOfResult)) == NULL)
Azure.IoT Build 0:fa2de1b79154 143 {
Azure.IoT Build 0:fa2de1b79154 144 /*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 145 result = NULL;
AzureIoTClient 1:9190c0f4d23a 146 LogError("URL_Encode:: MALLOC failure on encode.");
Azure.IoT Build 0:fa2de1b79154 147 }
Azure.IoT Build 0:fa2de1b79154 148 else
Azure.IoT Build 0:fa2de1b79154 149 {
Azure.IoT Build 0:fa2de1b79154 150 size_t currentEncodePosition = 0;
Azure.IoT Build 0:fa2de1b79154 151 currentInput = STRING_c_str(input);
Azure.IoT Build 0:fa2de1b79154 152 do
Azure.IoT Build 0:fa2de1b79154 153 {
Azure.IoT Build 0:fa2de1b79154 154 currentUnsignedChar = (unsigned char)(*currentInput++);
AzureIoTClient 11:77df6d7e65ae 155 currentEncodePosition += URL_PrintableChar(currentUnsignedChar, &encodedURL[currentEncodePosition]);
Azure.IoT Build 0:fa2de1b79154 156 } while (currentUnsignedChar != 0);
AzureIoTClient 11:77df6d7e65ae 157
Azure.IoT Build 0:fa2de1b79154 158 result = STRING_new_with_memory(encodedURL);
AzureIoTClient 11:77df6d7e65ae 159 if (result == NULL)
AzureIoTClient 11:77df6d7e65ae 160 {
AzureIoTClient 11:77df6d7e65ae 161 LogError("URL_Encode:: MALLOC failure on encode.");
AzureIoTClient 11:77df6d7e65ae 162 free(encodedURL);
AzureIoTClient 11:77df6d7e65ae 163 }
Azure.IoT Build 0:fa2de1b79154 164 }
Azure.IoT Build 0:fa2de1b79154 165 }
Azure.IoT Build 0:fa2de1b79154 166 return result;
Azure.IoT Build 0:fa2de1b79154 167 }