Azure IoT common library

Fork of azure_c_shared_utility by Azure IoT

Committer:
AzureIoTClient
Date:
Thu Oct 20 17:08:18 2016 -0700
Revision:
13:920e00014ee3
Parent:
11:77df6d7e65ae
Child:
19:2e0811512ceb
1.0.10

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 //
Azure.IoT Build 0:fa2de1b79154 5 // PUT NO INCLUDES BEFORE HERE !!!!
Azure.IoT Build 0:fa2de1b79154 6 //
Azure.IoT Build 0:fa2de1b79154 7 #include <stdlib.h>
Azure.IoT Build 0:fa2de1b79154 8 #ifdef _CRTDBG_MAP_ALLOC
Azure.IoT Build 0:fa2de1b79154 9 #include <crtdbg.h>
Azure.IoT Build 0:fa2de1b79154 10 #endif
Azure.IoT Build 0:fa2de1b79154 11 #include "azure_c_shared_utility/gballoc.h"
Azure.IoT Build 0:fa2de1b79154 12
Azure.IoT Build 0:fa2de1b79154 13 #include <stddef.h>
Azure.IoT Build 0:fa2de1b79154 14 #include <string.h>
AzureIoTClient 13:920e00014ee3 15 #include <stdint.h>
Azure.IoT Build 0:fa2de1b79154 16 //
Azure.IoT Build 0:fa2de1b79154 17 // PUT NO CLIENT LIBRARY INCLUDES BEFORE HERE !!!!
Azure.IoT Build 0:fa2de1b79154 18 //
Azure.IoT Build 0:fa2de1b79154 19 #include "azure_c_shared_utility/base64.h"
Azure.IoT Build 6:c55b013dfc2a 20 #include "azure_c_shared_utility/xlogging.h"
Azure.IoT Build 0:fa2de1b79154 21
AzureIoTClient 13:920e00014ee3 22
AzureIoTClient 13:920e00014ee3 23 #define splitInt(intVal, bytePos) (char)((intVal >> (bytePos << 3)) & 0xFF)
AzureIoTClient 13:920e00014ee3 24 #define joinChars(a, b, c, d) (uint32_t)((uint32_t)a + ((uint32_t)b << 8) + ((uint32_t)c << 16) + ((uint32_t)d << 24))
AzureIoTClient 13:920e00014ee3 25
AzureIoTClient 13:920e00014ee3 26 static char base64char(unsigned char val)
AzureIoTClient 13:920e00014ee3 27 {
AzureIoTClient 13:920e00014ee3 28 char result;
Azure.IoT Build 0:fa2de1b79154 29
AzureIoTClient 13:920e00014ee3 30 if (val < 26)
AzureIoTClient 13:920e00014ee3 31 {
AzureIoTClient 13:920e00014ee3 32 result = 'A' + (char)val;
AzureIoTClient 13:920e00014ee3 33 }
AzureIoTClient 13:920e00014ee3 34 else if (val < 52)
AzureIoTClient 13:920e00014ee3 35 {
AzureIoTClient 13:920e00014ee3 36 result = 'a' + ((char)val - 26);
AzureIoTClient 13:920e00014ee3 37 }
AzureIoTClient 13:920e00014ee3 38 else if (val < 62)
AzureIoTClient 13:920e00014ee3 39 {
AzureIoTClient 13:920e00014ee3 40 result = '0' + ((char)val - 52);
AzureIoTClient 13:920e00014ee3 41 }
AzureIoTClient 13:920e00014ee3 42 else if (val == 62)
AzureIoTClient 13:920e00014ee3 43 {
AzureIoTClient 13:920e00014ee3 44 result = '+';
AzureIoTClient 13:920e00014ee3 45 }
AzureIoTClient 13:920e00014ee3 46 else
AzureIoTClient 13:920e00014ee3 47 {
AzureIoTClient 13:920e00014ee3 48 result = '/';
AzureIoTClient 13:920e00014ee3 49 }
Azure.IoT Build 0:fa2de1b79154 50
AzureIoTClient 13:920e00014ee3 51 return result;
AzureIoTClient 13:920e00014ee3 52 }
AzureIoTClient 13:920e00014ee3 53
AzureIoTClient 13:920e00014ee3 54 static char base64b16(unsigned char val)
AzureIoTClient 13:920e00014ee3 55 {
AzureIoTClient 13:920e00014ee3 56 const uint32_t base64b16values[4] = {
AzureIoTClient 13:920e00014ee3 57 joinChars('A', 'E', 'I', 'M'),
AzureIoTClient 13:920e00014ee3 58 joinChars('Q', 'U', 'Y', 'c'),
AzureIoTClient 13:920e00014ee3 59 joinChars('g', 'k', 'o', 's'),
AzureIoTClient 13:920e00014ee3 60 joinChars('w', '0', '4', '8')
AzureIoTClient 13:920e00014ee3 61 };
AzureIoTClient 13:920e00014ee3 62 return splitInt(base64b16values[val >> 2], (val & 0x03));
AzureIoTClient 13:920e00014ee3 63 }
AzureIoTClient 13:920e00014ee3 64
AzureIoTClient 13:920e00014ee3 65 static char base64b8(unsigned char val)
AzureIoTClient 13:920e00014ee3 66 {
AzureIoTClient 13:920e00014ee3 67 const uint32_t base64b8values = joinChars('A', 'Q', 'g', 'w');
AzureIoTClient 13:920e00014ee3 68 return splitInt(base64b8values, val);
AzureIoTClient 13:920e00014ee3 69 }
Azure.IoT Build 0:fa2de1b79154 70
Azure.IoT Build 0:fa2de1b79154 71 static int base64toValue(char base64character, unsigned char* value)
Azure.IoT Build 0:fa2de1b79154 72 {
Azure.IoT Build 0:fa2de1b79154 73 int result = 0;
Azure.IoT Build 0:fa2de1b79154 74 if (('A' <= base64character) && (base64character <= 'Z'))
Azure.IoT Build 0:fa2de1b79154 75 {
Azure.IoT Build 0:fa2de1b79154 76 *value = base64character - 'A';
Azure.IoT Build 0:fa2de1b79154 77 }
Azure.IoT Build 0:fa2de1b79154 78 else if (('a' <= base64character) && (base64character <= 'z'))
Azure.IoT Build 0:fa2de1b79154 79 {
Azure.IoT Build 0:fa2de1b79154 80 *value = ('Z' - 'A') + 1 + (base64character - 'a');
Azure.IoT Build 0:fa2de1b79154 81 }
Azure.IoT Build 0:fa2de1b79154 82 else if (('0' <= base64character) && (base64character <= '9'))
Azure.IoT Build 0:fa2de1b79154 83 {
Azure.IoT Build 0:fa2de1b79154 84 *value = ('Z' - 'A') + 1 + ('z' - 'a') + 1 + (base64character - '0');
Azure.IoT Build 0:fa2de1b79154 85 }
Azure.IoT Build 0:fa2de1b79154 86 else if ('+' == base64character)
Azure.IoT Build 0:fa2de1b79154 87 {
Azure.IoT Build 0:fa2de1b79154 88 *value = 62;
Azure.IoT Build 0:fa2de1b79154 89 }
Azure.IoT Build 0:fa2de1b79154 90 else if ('/' == base64character)
Azure.IoT Build 0:fa2de1b79154 91 {
Azure.IoT Build 0:fa2de1b79154 92 *value = 63;
Azure.IoT Build 0:fa2de1b79154 93 }
Azure.IoT Build 0:fa2de1b79154 94 else
Azure.IoT Build 0:fa2de1b79154 95 {
Azure.IoT Build 0:fa2de1b79154 96 *value = 0;
Azure.IoT Build 0:fa2de1b79154 97 result = -1;
Azure.IoT Build 0:fa2de1b79154 98 }
Azure.IoT Build 0:fa2de1b79154 99 return result;
Azure.IoT Build 0:fa2de1b79154 100 }
Azure.IoT Build 0:fa2de1b79154 101
Azure.IoT Build 0:fa2de1b79154 102 static size_t numberOfBase64Characters(const char* encodedString)
Azure.IoT Build 0:fa2de1b79154 103 {
Azure.IoT Build 0:fa2de1b79154 104 size_t length = 0;
Azure.IoT Build 0:fa2de1b79154 105 unsigned char junkChar;
Azure.IoT Build 0:fa2de1b79154 106 while (base64toValue(encodedString[length],&junkChar) != -1)
Azure.IoT Build 0:fa2de1b79154 107 {
Azure.IoT Build 0:fa2de1b79154 108 length++;
Azure.IoT Build 0:fa2de1b79154 109 }
Azure.IoT Build 0:fa2de1b79154 110 return length;
Azure.IoT Build 0:fa2de1b79154 111 }
AzureIoTClient 5:921351ce6973 112
AzureIoTClient 5:921351ce6973 113 /*returns the count of original bytes before being base64 encoded*/
AzureIoTClient 5:921351ce6973 114 /*notice NO validation of the content of encodedString. Its length is validated to be a multiple of 4.*/
Azure.IoT Build 0:fa2de1b79154 115 static size_t Base64decode_len(const char *encodedString)
Azure.IoT Build 0:fa2de1b79154 116 {
AzureIoTClient 5:921351ce6973 117 size_t result;
AzureIoTClient 5:921351ce6973 118 size_t sourceLength = strlen(encodedString);
AzureIoTClient 5:921351ce6973 119
AzureIoTClient 5:921351ce6973 120 if (sourceLength == 0)
Azure.IoT Build 0:fa2de1b79154 121 {
AzureIoTClient 5:921351ce6973 122 result = 0;
AzureIoTClient 5:921351ce6973 123 }
AzureIoTClient 5:921351ce6973 124 else
AzureIoTClient 5:921351ce6973 125 {
AzureIoTClient 5:921351ce6973 126 result = sourceLength / 4 * 3;
AzureIoTClient 5:921351ce6973 127 if (encodedString[sourceLength - 1] == '=')
Azure.IoT Build 0:fa2de1b79154 128 {
AzureIoTClient 5:921351ce6973 129 if (encodedString[sourceLength - 2] == '=')
Azure.IoT Build 0:fa2de1b79154 130 {
AzureIoTClient 5:921351ce6973 131 result --;
Azure.IoT Build 0:fa2de1b79154 132 }
AzureIoTClient 5:921351ce6973 133 result--;
Azure.IoT Build 0:fa2de1b79154 134 }
Azure.IoT Build 0:fa2de1b79154 135 }
AzureIoTClient 5:921351ce6973 136 return result;
Azure.IoT Build 0:fa2de1b79154 137 }
Azure.IoT Build 0:fa2de1b79154 138
Azure.IoT Build 0:fa2de1b79154 139 static void Base64decode(unsigned char *decodedString, const char *base64String)
Azure.IoT Build 0:fa2de1b79154 140 {
Azure.IoT Build 0:fa2de1b79154 141
Azure.IoT Build 0:fa2de1b79154 142 size_t numberOfEncodedChars;
Azure.IoT Build 0:fa2de1b79154 143 size_t indexOfFirstEncodedChar;
Azure.IoT Build 0:fa2de1b79154 144 size_t decodedIndex;
Azure.IoT Build 0:fa2de1b79154 145
Azure.IoT Build 0:fa2de1b79154 146 //
Azure.IoT Build 0:fa2de1b79154 147 // We can only operate on individual bytes. If we attempt to work
Azure.IoT Build 0:fa2de1b79154 148 // on anything larger we could get an alignment fault on some
Azure.IoT Build 0:fa2de1b79154 149 // architectures
Azure.IoT Build 0:fa2de1b79154 150 //
Azure.IoT Build 0:fa2de1b79154 151
Azure.IoT Build 0:fa2de1b79154 152 numberOfEncodedChars = numberOfBase64Characters(base64String);
Azure.IoT Build 0:fa2de1b79154 153 indexOfFirstEncodedChar = 0;
Azure.IoT Build 0:fa2de1b79154 154 decodedIndex = 0;
Azure.IoT Build 0:fa2de1b79154 155 while (numberOfEncodedChars >= 4)
Azure.IoT Build 0:fa2de1b79154 156 {
Azure.IoT Build 0:fa2de1b79154 157 unsigned char c1;
Azure.IoT Build 0:fa2de1b79154 158 unsigned char c2;
Azure.IoT Build 0:fa2de1b79154 159 unsigned char c3;
Azure.IoT Build 0:fa2de1b79154 160 unsigned char c4;
Azure.IoT Build 0:fa2de1b79154 161 (void)base64toValue(base64String[indexOfFirstEncodedChar], &c1);
Azure.IoT Build 0:fa2de1b79154 162 (void)base64toValue(base64String[indexOfFirstEncodedChar + 1], &c2);
Azure.IoT Build 0:fa2de1b79154 163 (void)base64toValue(base64String[indexOfFirstEncodedChar + 2], &c3);
Azure.IoT Build 0:fa2de1b79154 164 (void)base64toValue(base64String[indexOfFirstEncodedChar + 3], &c4);
Azure.IoT Build 0:fa2de1b79154 165 decodedString[decodedIndex] = (c1 << 2) | (c2 >> 4);
Azure.IoT Build 0:fa2de1b79154 166 decodedIndex++;
Azure.IoT Build 0:fa2de1b79154 167 decodedString[decodedIndex] = ((c2 & 0x0f) << 4) | (c3 >> 2);
Azure.IoT Build 0:fa2de1b79154 168 decodedIndex++;
Azure.IoT Build 0:fa2de1b79154 169 decodedString[decodedIndex] = ((c3 & 0x03) << 6) | c4;
Azure.IoT Build 0:fa2de1b79154 170 decodedIndex++;
Azure.IoT Build 0:fa2de1b79154 171 numberOfEncodedChars -= 4;
Azure.IoT Build 0:fa2de1b79154 172 indexOfFirstEncodedChar += 4;
Azure.IoT Build 0:fa2de1b79154 173
Azure.IoT Build 0:fa2de1b79154 174 }
Azure.IoT Build 0:fa2de1b79154 175
Azure.IoT Build 0:fa2de1b79154 176 if (numberOfEncodedChars == 2)
Azure.IoT Build 0:fa2de1b79154 177 {
Azure.IoT Build 0:fa2de1b79154 178 unsigned char c1;
Azure.IoT Build 0:fa2de1b79154 179 unsigned char c2;
Azure.IoT Build 0:fa2de1b79154 180 (void)base64toValue(base64String[indexOfFirstEncodedChar], &c1);
Azure.IoT Build 0:fa2de1b79154 181 (void)base64toValue(base64String[indexOfFirstEncodedChar + 1], &c2);
Azure.IoT Build 0:fa2de1b79154 182 decodedString[decodedIndex] = (c1 << 2) | (c2 >> 4);
Azure.IoT Build 0:fa2de1b79154 183 }
Azure.IoT Build 0:fa2de1b79154 184 else if (numberOfEncodedChars == 3)
Azure.IoT Build 0:fa2de1b79154 185 {
Azure.IoT Build 0:fa2de1b79154 186 unsigned char c1;
Azure.IoT Build 0:fa2de1b79154 187 unsigned char c2;
Azure.IoT Build 0:fa2de1b79154 188 unsigned char c3;
Azure.IoT Build 0:fa2de1b79154 189 (void)base64toValue(base64String[indexOfFirstEncodedChar], &c1);
Azure.IoT Build 0:fa2de1b79154 190 (void)base64toValue(base64String[indexOfFirstEncodedChar + 1], &c2);
Azure.IoT Build 0:fa2de1b79154 191 (void)base64toValue(base64String[indexOfFirstEncodedChar + 2], &c3);
Azure.IoT Build 0:fa2de1b79154 192 decodedString[decodedIndex] = (c1 << 2) | (c2 >> 4);
Azure.IoT Build 0:fa2de1b79154 193 decodedIndex++;
Azure.IoT Build 0:fa2de1b79154 194 decodedString[decodedIndex] = ((c2 & 0x0f) << 4) | (c3 >> 2);
Azure.IoT Build 0:fa2de1b79154 195 }
Azure.IoT Build 0:fa2de1b79154 196 }
Azure.IoT Build 0:fa2de1b79154 197
Azure.IoT Build 0:fa2de1b79154 198 BUFFER_HANDLE Base64_Decoder(const char* source)
Azure.IoT Build 0:fa2de1b79154 199 {
AzureIoTClient 5:921351ce6973 200 BUFFER_HANDLE result;
Azure.IoT Build 0:fa2de1b79154 201 /*Codes_SRS_BASE64_06_008: [If source is NULL then Base64_Decode shall return NULL.]*/
AzureIoTClient 5:921351ce6973 202 if (source == NULL)
Azure.IoT Build 0:fa2de1b79154 203 {
AzureIoTClient 5:921351ce6973 204 LogError("invalid parameter const char* source=%p", source);
AzureIoTClient 5:921351ce6973 205 result = NULL;
AzureIoTClient 5:921351ce6973 206 }
AzureIoTClient 5:921351ce6973 207 else
AzureIoTClient 5:921351ce6973 208 {
AzureIoTClient 5:921351ce6973 209 if ((strlen(source) % 4) != 0)
Azure.IoT Build 0:fa2de1b79154 210 {
Azure.IoT Build 0:fa2de1b79154 211 /*Codes_SRS_BASE64_06_011: [If the source string has an invalid length for a base 64 encoded string then Base64_Decode shall return NULL.]*/
AzureIoTClient 1:9190c0f4d23a 212 LogError("Invalid length Base64 string!");
AzureIoTClient 5:921351ce6973 213 result = NULL;
Azure.IoT Build 0:fa2de1b79154 214 }
Azure.IoT Build 0:fa2de1b79154 215 else
Azure.IoT Build 0:fa2de1b79154 216 {
Azure.IoT Build 0:fa2de1b79154 217 if ((result = BUFFER_new()) == NULL)
Azure.IoT Build 0:fa2de1b79154 218 {
Azure.IoT Build 0:fa2de1b79154 219 /*Codes_SRS_BASE64_06_010: [If there is any memory allocation failure during the decode then Base64_Decode shall return NULL.]*/
AzureIoTClient 1:9190c0f4d23a 220 LogError("Could not create a buffer to decoding.");
Azure.IoT Build 0:fa2de1b79154 221 }
Azure.IoT Build 0:fa2de1b79154 222 else
Azure.IoT Build 0:fa2de1b79154 223 {
Azure.IoT Build 0:fa2de1b79154 224 size_t sizeOfOutputBuffer = Base64decode_len(source);
Azure.IoT Build 0:fa2de1b79154 225 /*Codes_SRS_BASE64_06_009: [If the string pointed to by source is zero length then the handle returned shall refer to a zero length buffer.]*/
Azure.IoT Build 0:fa2de1b79154 226 if (sizeOfOutputBuffer > 0)
Azure.IoT Build 0:fa2de1b79154 227 {
Azure.IoT Build 0:fa2de1b79154 228 if (BUFFER_pre_build(result, sizeOfOutputBuffer) != 0)
Azure.IoT Build 0:fa2de1b79154 229 {
Azure.IoT Build 0:fa2de1b79154 230 /*Codes_SRS_BASE64_06_010: [If there is any memory allocation failure during the decode then Base64_Decode shall return NULL.]*/
AzureIoTClient 1:9190c0f4d23a 231 LogError("Could not prebuild a buffer for base 64 decoding.");
Azure.IoT Build 0:fa2de1b79154 232 BUFFER_delete(result);
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 Base64decode(BUFFER_u_char(result), source);
Azure.IoT Build 0:fa2de1b79154 238 }
Azure.IoT Build 0:fa2de1b79154 239 }
Azure.IoT Build 0:fa2de1b79154 240 }
Azure.IoT Build 0:fa2de1b79154 241 }
Azure.IoT Build 0:fa2de1b79154 242 }
Azure.IoT Build 0:fa2de1b79154 243 return result;
Azure.IoT Build 0:fa2de1b79154 244 }
Azure.IoT Build 0:fa2de1b79154 245
Azure.IoT Build 0:fa2de1b79154 246
Azure.IoT Build 0:fa2de1b79154 247 static STRING_HANDLE Base64_Encode_Internal(const unsigned char* source, size_t size)
Azure.IoT Build 0:fa2de1b79154 248 {
Azure.IoT Build 0:fa2de1b79154 249 STRING_HANDLE result;
Azure.IoT Build 0:fa2de1b79154 250 size_t neededSize = 0;
Azure.IoT Build 0:fa2de1b79154 251 char* encoded;
Azure.IoT Build 0:fa2de1b79154 252 size_t currentPosition = 0;
Azure.IoT Build 0:fa2de1b79154 253 neededSize += (size == 0) ? (0) : ((((size - 1) / 3) + 1) * 4);
Azure.IoT Build 0:fa2de1b79154 254 neededSize += 1; /*+1 because \0 at the end of the string*/
Azure.IoT Build 0:fa2de1b79154 255 /*Codes_SRS_BASE64_06_006: [If when allocating memory to produce the encoding a failure occurs then Base64_Encode shall return NULL.]*/
Azure.IoT Build 0:fa2de1b79154 256 encoded = (char*)malloc(neededSize);
Azure.IoT Build 0:fa2de1b79154 257 if (encoded == NULL)
Azure.IoT Build 0:fa2de1b79154 258 {
Azure.IoT Build 0:fa2de1b79154 259 result = NULL;
AzureIoTClient 1:9190c0f4d23a 260 LogError("Base64_Encode:: Allocation failed.");
Azure.IoT Build 0:fa2de1b79154 261 }
Azure.IoT Build 0:fa2de1b79154 262 else
Azure.IoT Build 0:fa2de1b79154 263 {
Azure.IoT Build 0:fa2de1b79154 264 /*b0 b1(+1) b2(+2)
Azure.IoT Build 0:fa2de1b79154 265 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
Azure.IoT Build 0:fa2de1b79154 266 |----c1---| |----c2---| |----c3---| |----c4---|
Azure.IoT Build 0:fa2de1b79154 267 */
Azure.IoT Build 0:fa2de1b79154 268
Azure.IoT Build 0:fa2de1b79154 269 size_t destinationPosition = 0;
Azure.IoT Build 0:fa2de1b79154 270 while (size - currentPosition >= 3)
Azure.IoT Build 0:fa2de1b79154 271 {
AzureIoTClient 13:920e00014ee3 272 char c1 = base64char(source[currentPosition] >> 2);
AzureIoTClient 13:920e00014ee3 273 char c2 = base64char(
Azure.IoT Build 0:fa2de1b79154 274 ((source[currentPosition] & 3) << 4) |
Azure.IoT Build 0:fa2de1b79154 275 (source[currentPosition + 1] >> 4)
AzureIoTClient 13:920e00014ee3 276 );
AzureIoTClient 13:920e00014ee3 277 char c3 = base64char(
Azure.IoT Build 0:fa2de1b79154 278 ((source[currentPosition + 1] & 0x0F) << 2) |
Azure.IoT Build 0:fa2de1b79154 279 ((source[currentPosition + 2] >> 6) & 3)
AzureIoTClient 13:920e00014ee3 280 );
AzureIoTClient 13:920e00014ee3 281 char c4 = base64char(
Azure.IoT Build 0:fa2de1b79154 282 source[currentPosition + 2] & 0x3F
AzureIoTClient 13:920e00014ee3 283 );
Azure.IoT Build 0:fa2de1b79154 284 currentPosition += 3;
Azure.IoT Build 0:fa2de1b79154 285 encoded[destinationPosition++] = c1;
Azure.IoT Build 0:fa2de1b79154 286 encoded[destinationPosition++] = c2;
Azure.IoT Build 0:fa2de1b79154 287 encoded[destinationPosition++] = c3;
Azure.IoT Build 0:fa2de1b79154 288 encoded[destinationPosition++] = c4;
Azure.IoT Build 0:fa2de1b79154 289
Azure.IoT Build 0:fa2de1b79154 290 }
Azure.IoT Build 0:fa2de1b79154 291 if (size - currentPosition == 2)
Azure.IoT Build 0:fa2de1b79154 292 {
AzureIoTClient 13:920e00014ee3 293 char c1 = base64char(source[currentPosition] >> 2);
AzureIoTClient 13:920e00014ee3 294 char c2 = base64char(
Azure.IoT Build 0:fa2de1b79154 295 ((source[currentPosition] & 0x03) << 4) |
Azure.IoT Build 0:fa2de1b79154 296 (source[currentPosition + 1] >> 4)
AzureIoTClient 13:920e00014ee3 297 );
AzureIoTClient 13:920e00014ee3 298 char c3 = base64b16(source[currentPosition + 1] & 0x0F);
Azure.IoT Build 0:fa2de1b79154 299 encoded[destinationPosition++] = c1;
Azure.IoT Build 0:fa2de1b79154 300 encoded[destinationPosition++] = c2;
Azure.IoT Build 0:fa2de1b79154 301 encoded[destinationPosition++] = c3;
Azure.IoT Build 0:fa2de1b79154 302 encoded[destinationPosition++] = '=';
Azure.IoT Build 0:fa2de1b79154 303 }
Azure.IoT Build 0:fa2de1b79154 304 else if (size - currentPosition == 1)
Azure.IoT Build 0:fa2de1b79154 305 {
AzureIoTClient 13:920e00014ee3 306 char c1 = base64char(source[currentPosition] >> 2);
AzureIoTClient 13:920e00014ee3 307 char c2 = base64b8(source[currentPosition] & 0x03);
Azure.IoT Build 0:fa2de1b79154 308 encoded[destinationPosition++] = c1;
Azure.IoT Build 0:fa2de1b79154 309 encoded[destinationPosition++] = c2;
Azure.IoT Build 0:fa2de1b79154 310 encoded[destinationPosition++] = '=';
Azure.IoT Build 0:fa2de1b79154 311 encoded[destinationPosition++] = '=';
Azure.IoT Build 0:fa2de1b79154 312 }
Azure.IoT Build 0:fa2de1b79154 313
Azure.IoT Build 0:fa2de1b79154 314 /*null terminating the string*/
Azure.IoT Build 0:fa2de1b79154 315 encoded[destinationPosition] = '\0';
Azure.IoT Build 0:fa2de1b79154 316 /*Codes_SRS_BASE64_06_007: [Otherwise Base64_Encode shall return a pointer to STRING, that string contains the base 64 encoding of input.]*/
Azure.IoT Build 0:fa2de1b79154 317 result = STRING_new_with_memory(encoded);
Azure.IoT Build 0:fa2de1b79154 318 if (result == NULL)
Azure.IoT Build 0:fa2de1b79154 319 {
Azure.IoT Build 0:fa2de1b79154 320 free(encoded);
AzureIoTClient 1:9190c0f4d23a 321 LogError("Base64_Encode:: Allocation failed for return value.");
Azure.IoT Build 0:fa2de1b79154 322 }
Azure.IoT Build 0:fa2de1b79154 323 }
Azure.IoT Build 0:fa2de1b79154 324 return result;
Azure.IoT Build 0:fa2de1b79154 325 }
Azure.IoT Build 0:fa2de1b79154 326
Azure.IoT Build 0:fa2de1b79154 327 STRING_HANDLE Base64_Encode_Bytes(const unsigned char* source, size_t size)
Azure.IoT Build 0:fa2de1b79154 328 {
Azure.IoT Build 0:fa2de1b79154 329 STRING_HANDLE result;
Azure.IoT Build 0:fa2de1b79154 330 /*Codes_SRS_BASE64_02_001: [If source is NULL then Base64_Encode_Bytes shall return NULL.] */
Azure.IoT Build 0:fa2de1b79154 331 if (source == NULL)
Azure.IoT Build 0:fa2de1b79154 332 {
Azure.IoT Build 0:fa2de1b79154 333 result = NULL;
Azure.IoT Build 0:fa2de1b79154 334 }
Azure.IoT Build 0:fa2de1b79154 335 /*Codes_SRS_BASE64_02_002: [If source is not NULL and size is zero, then Base64_Encode_Bytes shall produce an empty STRING_HANDLE.] */
Azure.IoT Build 0:fa2de1b79154 336 else if (size == 0)
Azure.IoT Build 0:fa2de1b79154 337 {
Azure.IoT Build 0:fa2de1b79154 338 result = STRING_new(); /*empty string*/
Azure.IoT Build 0:fa2de1b79154 339 }
Azure.IoT Build 0:fa2de1b79154 340 else
Azure.IoT Build 0:fa2de1b79154 341 {
Azure.IoT Build 0:fa2de1b79154 342 result = Base64_Encode_Internal(source, size);
Azure.IoT Build 0:fa2de1b79154 343 }
Azure.IoT Build 0:fa2de1b79154 344 return result;
Azure.IoT Build 0:fa2de1b79154 345 }
Azure.IoT Build 0:fa2de1b79154 346
Azure.IoT Build 0:fa2de1b79154 347 STRING_HANDLE Base64_Encode(BUFFER_HANDLE input)
Azure.IoT Build 0:fa2de1b79154 348 {
Azure.IoT Build 0:fa2de1b79154 349 STRING_HANDLE result;
Azure.IoT Build 0:fa2de1b79154 350 /*the following will happen*/
Azure.IoT Build 0:fa2de1b79154 351 /*1. the "data" of the binary shall be "eaten" 3 characters at a time and produce 4 base64 encoded characters for as long as there are more than 3 characters still to process*/
Azure.IoT Build 0:fa2de1b79154 352 /*2. the remaining characters (1 or 2) shall be encoded.*/
Azure.IoT Build 0:fa2de1b79154 353 /*there's a level of assumption that 'a' corresponds to 0b000000 and that '_' corresponds to 0b111111*/
Azure.IoT Build 0:fa2de1b79154 354 /*the encoding will use the optional [=] or [==] at the end of the encoded string, so that other less standard aware libraries can do their work*/
Azure.IoT Build 0:fa2de1b79154 355 /*these are the bits of the 3 normal bytes to be encoded*/
Azure.IoT Build 0:fa2de1b79154 356
Azure.IoT Build 0:fa2de1b79154 357 /*Codes_SRS_BASE64_06_001: [If input is NULL then Base64_Encode shall return NULL.]*/
Azure.IoT Build 0:fa2de1b79154 358 if (input == NULL)
Azure.IoT Build 0:fa2de1b79154 359 {
Azure.IoT Build 0:fa2de1b79154 360 result = NULL;
AzureIoTClient 1:9190c0f4d23a 361 LogError("Base64_Encode:: NULL input");
Azure.IoT Build 0:fa2de1b79154 362 }
Azure.IoT Build 0:fa2de1b79154 363 else
Azure.IoT Build 0:fa2de1b79154 364 {
Azure.IoT Build 0:fa2de1b79154 365 size_t inputSize;
Azure.IoT Build 0:fa2de1b79154 366 const unsigned char* inputBinary;
Azure.IoT Build 0:fa2de1b79154 367 if ((BUFFER_content(input, &inputBinary) != 0) ||
Azure.IoT Build 0:fa2de1b79154 368 (BUFFER_size(input, &inputSize) != 0))
Azure.IoT Build 0:fa2de1b79154 369 {
Azure.IoT Build 0:fa2de1b79154 370 result = NULL;
AzureIoTClient 1:9190c0f4d23a 371 LogError("Base64_Encode:: BUFFER_routines failure.");
Azure.IoT Build 0:fa2de1b79154 372 }
Azure.IoT Build 0:fa2de1b79154 373 else
Azure.IoT Build 0:fa2de1b79154 374 {
Azure.IoT Build 0:fa2de1b79154 375 result = Base64_Encode_Internal(inputBinary, inputSize);
Azure.IoT Build 0:fa2de1b79154 376 }
Azure.IoT Build 0:fa2de1b79154 377 }
Azure.IoT Build 0:fa2de1b79154 378 return result;
Azure.IoT Build 0:fa2de1b79154 379 }