Azure IoT common library
Fork of azure_c_shared_utility by
base64.c@6:c55b013dfc2a, 2016-07-01 (annotated)
- Committer:
- Azure.IoT Build
- Date:
- Fri Jul 01 10:43:23 2016 -0700
- Revision:
- 6:c55b013dfc2a
- Parent:
- 5:921351ce6973
- Child:
- 7:1af47e3a19b6
1.0.10
Who changed what in which revision?
User | Revision | Line number | New 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> |
Azure.IoT Build | 0:fa2de1b79154 | 15 | // |
Azure.IoT Build | 0:fa2de1b79154 | 16 | // PUT NO CLIENT LIBRARY INCLUDES BEFORE HERE !!!! |
Azure.IoT Build | 0:fa2de1b79154 | 17 | // |
Azure.IoT Build | 0:fa2de1b79154 | 18 | #include "azure_c_shared_utility/base64.h" |
Azure.IoT Build | 6:c55b013dfc2a | 19 | #include "azure_c_shared_utility/xlogging.h" |
Azure.IoT Build | 0:fa2de1b79154 | 20 | |
Azure.IoT Build | 0:fa2de1b79154 | 21 | static const char base64char[64] = { |
Azure.IoT Build | 0:fa2de1b79154 | 22 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', |
Azure.IoT Build | 0:fa2de1b79154 | 23 | 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', |
Azure.IoT Build | 0:fa2de1b79154 | 24 | 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', |
Azure.IoT Build | 0:fa2de1b79154 | 25 | 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', |
Azure.IoT Build | 0:fa2de1b79154 | 26 | 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', |
Azure.IoT Build | 0:fa2de1b79154 | 27 | 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', |
Azure.IoT Build | 0:fa2de1b79154 | 28 | '8', '9', '+', '/' |
Azure.IoT Build | 0:fa2de1b79154 | 29 | }; |
Azure.IoT Build | 0:fa2de1b79154 | 30 | |
Azure.IoT Build | 0:fa2de1b79154 | 31 | static const char base64b16[16] = { |
Azure.IoT Build | 0:fa2de1b79154 | 32 | 'A', 'E', 'I', 'M', 'Q', 'U', 'Y', 'c', 'g', 'k', |
Azure.IoT Build | 0:fa2de1b79154 | 33 | 'o', 's', 'w', '0', '4', '8' |
Azure.IoT Build | 0:fa2de1b79154 | 34 | }; |
Azure.IoT Build | 0:fa2de1b79154 | 35 | |
Azure.IoT Build | 0:fa2de1b79154 | 36 | static const char base64b8[4] = { |
Azure.IoT Build | 0:fa2de1b79154 | 37 | 'A', 'Q', 'g', 'w' |
Azure.IoT Build | 0:fa2de1b79154 | 38 | }; |
Azure.IoT Build | 0:fa2de1b79154 | 39 | |
Azure.IoT Build | 0:fa2de1b79154 | 40 | static int base64toValue(char base64character, unsigned char* value) |
Azure.IoT Build | 0:fa2de1b79154 | 41 | { |
Azure.IoT Build | 0:fa2de1b79154 | 42 | int result = 0; |
Azure.IoT Build | 0:fa2de1b79154 | 43 | if (('A' <= base64character) && (base64character <= 'Z')) |
Azure.IoT Build | 0:fa2de1b79154 | 44 | { |
Azure.IoT Build | 0:fa2de1b79154 | 45 | *value = base64character - 'A'; |
Azure.IoT Build | 0:fa2de1b79154 | 46 | } |
Azure.IoT Build | 0:fa2de1b79154 | 47 | else if (('a' <= base64character) && (base64character <= 'z')) |
Azure.IoT Build | 0:fa2de1b79154 | 48 | { |
Azure.IoT Build | 0:fa2de1b79154 | 49 | *value = ('Z' - 'A') + 1 + (base64character - 'a'); |
Azure.IoT Build | 0:fa2de1b79154 | 50 | } |
Azure.IoT Build | 0:fa2de1b79154 | 51 | else if (('0' <= base64character) && (base64character <= '9')) |
Azure.IoT Build | 0:fa2de1b79154 | 52 | { |
Azure.IoT Build | 0:fa2de1b79154 | 53 | *value = ('Z' - 'A') + 1 + ('z' - 'a') + 1 + (base64character - '0'); |
Azure.IoT Build | 0:fa2de1b79154 | 54 | } |
Azure.IoT Build | 0:fa2de1b79154 | 55 | else if ('+' == base64character) |
Azure.IoT Build | 0:fa2de1b79154 | 56 | { |
Azure.IoT Build | 0:fa2de1b79154 | 57 | *value = 62; |
Azure.IoT Build | 0:fa2de1b79154 | 58 | } |
Azure.IoT Build | 0:fa2de1b79154 | 59 | else if ('/' == base64character) |
Azure.IoT Build | 0:fa2de1b79154 | 60 | { |
Azure.IoT Build | 0:fa2de1b79154 | 61 | *value = 63; |
Azure.IoT Build | 0:fa2de1b79154 | 62 | } |
Azure.IoT Build | 0:fa2de1b79154 | 63 | else |
Azure.IoT Build | 0:fa2de1b79154 | 64 | { |
Azure.IoT Build | 0:fa2de1b79154 | 65 | *value = 0; |
Azure.IoT Build | 0:fa2de1b79154 | 66 | result = -1; |
Azure.IoT Build | 0:fa2de1b79154 | 67 | } |
Azure.IoT Build | 0:fa2de1b79154 | 68 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 69 | } |
Azure.IoT Build | 0:fa2de1b79154 | 70 | |
Azure.IoT Build | 0:fa2de1b79154 | 71 | static size_t numberOfBase64Characters(const char* encodedString) |
Azure.IoT Build | 0:fa2de1b79154 | 72 | { |
Azure.IoT Build | 0:fa2de1b79154 | 73 | size_t length = 0; |
Azure.IoT Build | 0:fa2de1b79154 | 74 | unsigned char junkChar; |
Azure.IoT Build | 0:fa2de1b79154 | 75 | while (base64toValue(encodedString[length],&junkChar) != -1) |
Azure.IoT Build | 0:fa2de1b79154 | 76 | { |
Azure.IoT Build | 0:fa2de1b79154 | 77 | length++; |
Azure.IoT Build | 0:fa2de1b79154 | 78 | } |
Azure.IoT Build | 0:fa2de1b79154 | 79 | return length; |
Azure.IoT Build | 0:fa2de1b79154 | 80 | } |
AzureIoTClient | 5:921351ce6973 | 81 | |
AzureIoTClient | 5:921351ce6973 | 82 | /*returns the count of original bytes before being base64 encoded*/ |
AzureIoTClient | 5:921351ce6973 | 83 | /*notice NO validation of the content of encodedString. Its length is validated to be a multiple of 4.*/ |
Azure.IoT Build | 0:fa2de1b79154 | 84 | static size_t Base64decode_len(const char *encodedString) |
Azure.IoT Build | 0:fa2de1b79154 | 85 | { |
AzureIoTClient | 5:921351ce6973 | 86 | size_t result; |
AzureIoTClient | 5:921351ce6973 | 87 | size_t sourceLength = strlen(encodedString); |
AzureIoTClient | 5:921351ce6973 | 88 | |
AzureIoTClient | 5:921351ce6973 | 89 | if (sourceLength == 0) |
Azure.IoT Build | 0:fa2de1b79154 | 90 | { |
AzureIoTClient | 5:921351ce6973 | 91 | result = 0; |
AzureIoTClient | 5:921351ce6973 | 92 | } |
AzureIoTClient | 5:921351ce6973 | 93 | else |
AzureIoTClient | 5:921351ce6973 | 94 | { |
AzureIoTClient | 5:921351ce6973 | 95 | result = sourceLength / 4 * 3; |
AzureIoTClient | 5:921351ce6973 | 96 | if (encodedString[sourceLength - 1] == '=') |
Azure.IoT Build | 0:fa2de1b79154 | 97 | { |
AzureIoTClient | 5:921351ce6973 | 98 | if (encodedString[sourceLength - 2] == '=') |
Azure.IoT Build | 0:fa2de1b79154 | 99 | { |
AzureIoTClient | 5:921351ce6973 | 100 | result --; |
Azure.IoT Build | 0:fa2de1b79154 | 101 | } |
AzureIoTClient | 5:921351ce6973 | 102 | result--; |
Azure.IoT Build | 0:fa2de1b79154 | 103 | } |
Azure.IoT Build | 0:fa2de1b79154 | 104 | } |
AzureIoTClient | 5:921351ce6973 | 105 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 106 | } |
Azure.IoT Build | 0:fa2de1b79154 | 107 | |
Azure.IoT Build | 0:fa2de1b79154 | 108 | static void Base64decode(unsigned char *decodedString, const char *base64String) |
Azure.IoT Build | 0:fa2de1b79154 | 109 | { |
Azure.IoT Build | 0:fa2de1b79154 | 110 | |
Azure.IoT Build | 0:fa2de1b79154 | 111 | size_t numberOfEncodedChars; |
Azure.IoT Build | 0:fa2de1b79154 | 112 | size_t indexOfFirstEncodedChar; |
Azure.IoT Build | 0:fa2de1b79154 | 113 | size_t decodedIndex; |
Azure.IoT Build | 0:fa2de1b79154 | 114 | |
Azure.IoT Build | 0:fa2de1b79154 | 115 | // |
Azure.IoT Build | 0:fa2de1b79154 | 116 | // We can only operate on individual bytes. If we attempt to work |
Azure.IoT Build | 0:fa2de1b79154 | 117 | // on anything larger we could get an alignment fault on some |
Azure.IoT Build | 0:fa2de1b79154 | 118 | // architectures |
Azure.IoT Build | 0:fa2de1b79154 | 119 | // |
Azure.IoT Build | 0:fa2de1b79154 | 120 | |
Azure.IoT Build | 0:fa2de1b79154 | 121 | numberOfEncodedChars = numberOfBase64Characters(base64String); |
Azure.IoT Build | 0:fa2de1b79154 | 122 | indexOfFirstEncodedChar = 0; |
Azure.IoT Build | 0:fa2de1b79154 | 123 | decodedIndex = 0; |
Azure.IoT Build | 0:fa2de1b79154 | 124 | while (numberOfEncodedChars >= 4) |
Azure.IoT Build | 0:fa2de1b79154 | 125 | { |
Azure.IoT Build | 0:fa2de1b79154 | 126 | unsigned char c1; |
Azure.IoT Build | 0:fa2de1b79154 | 127 | unsigned char c2; |
Azure.IoT Build | 0:fa2de1b79154 | 128 | unsigned char c3; |
Azure.IoT Build | 0:fa2de1b79154 | 129 | unsigned char c4; |
Azure.IoT Build | 0:fa2de1b79154 | 130 | (void)base64toValue(base64String[indexOfFirstEncodedChar], &c1); |
Azure.IoT Build | 0:fa2de1b79154 | 131 | (void)base64toValue(base64String[indexOfFirstEncodedChar + 1], &c2); |
Azure.IoT Build | 0:fa2de1b79154 | 132 | (void)base64toValue(base64String[indexOfFirstEncodedChar + 2], &c3); |
Azure.IoT Build | 0:fa2de1b79154 | 133 | (void)base64toValue(base64String[indexOfFirstEncodedChar + 3], &c4); |
Azure.IoT Build | 0:fa2de1b79154 | 134 | decodedString[decodedIndex] = (c1 << 2) | (c2 >> 4); |
Azure.IoT Build | 0:fa2de1b79154 | 135 | decodedIndex++; |
Azure.IoT Build | 0:fa2de1b79154 | 136 | decodedString[decodedIndex] = ((c2 & 0x0f) << 4) | (c3 >> 2); |
Azure.IoT Build | 0:fa2de1b79154 | 137 | decodedIndex++; |
Azure.IoT Build | 0:fa2de1b79154 | 138 | decodedString[decodedIndex] = ((c3 & 0x03) << 6) | c4; |
Azure.IoT Build | 0:fa2de1b79154 | 139 | decodedIndex++; |
Azure.IoT Build | 0:fa2de1b79154 | 140 | numberOfEncodedChars -= 4; |
Azure.IoT Build | 0:fa2de1b79154 | 141 | indexOfFirstEncodedChar += 4; |
Azure.IoT Build | 0:fa2de1b79154 | 142 | |
Azure.IoT Build | 0:fa2de1b79154 | 143 | } |
Azure.IoT Build | 0:fa2de1b79154 | 144 | |
Azure.IoT Build | 0:fa2de1b79154 | 145 | if (numberOfEncodedChars == 2) |
Azure.IoT Build | 0:fa2de1b79154 | 146 | { |
Azure.IoT Build | 0:fa2de1b79154 | 147 | unsigned char c1; |
Azure.IoT Build | 0:fa2de1b79154 | 148 | unsigned char c2; |
Azure.IoT Build | 0:fa2de1b79154 | 149 | (void)base64toValue(base64String[indexOfFirstEncodedChar], &c1); |
Azure.IoT Build | 0:fa2de1b79154 | 150 | (void)base64toValue(base64String[indexOfFirstEncodedChar + 1], &c2); |
Azure.IoT Build | 0:fa2de1b79154 | 151 | decodedString[decodedIndex] = (c1 << 2) | (c2 >> 4); |
Azure.IoT Build | 0:fa2de1b79154 | 152 | } |
Azure.IoT Build | 0:fa2de1b79154 | 153 | else if (numberOfEncodedChars == 3) |
Azure.IoT Build | 0:fa2de1b79154 | 154 | { |
Azure.IoT Build | 0:fa2de1b79154 | 155 | unsigned char c1; |
Azure.IoT Build | 0:fa2de1b79154 | 156 | unsigned char c2; |
Azure.IoT Build | 0:fa2de1b79154 | 157 | unsigned char c3; |
Azure.IoT Build | 0:fa2de1b79154 | 158 | (void)base64toValue(base64String[indexOfFirstEncodedChar], &c1); |
Azure.IoT Build | 0:fa2de1b79154 | 159 | (void)base64toValue(base64String[indexOfFirstEncodedChar + 1], &c2); |
Azure.IoT Build | 0:fa2de1b79154 | 160 | (void)base64toValue(base64String[indexOfFirstEncodedChar + 2], &c3); |
Azure.IoT Build | 0:fa2de1b79154 | 161 | decodedString[decodedIndex] = (c1 << 2) | (c2 >> 4); |
Azure.IoT Build | 0:fa2de1b79154 | 162 | decodedIndex++; |
Azure.IoT Build | 0:fa2de1b79154 | 163 | decodedString[decodedIndex] = ((c2 & 0x0f) << 4) | (c3 >> 2); |
Azure.IoT Build | 0:fa2de1b79154 | 164 | } |
Azure.IoT Build | 0:fa2de1b79154 | 165 | } |
Azure.IoT Build | 0:fa2de1b79154 | 166 | |
Azure.IoT Build | 0:fa2de1b79154 | 167 | BUFFER_HANDLE Base64_Decoder(const char* source) |
Azure.IoT Build | 0:fa2de1b79154 | 168 | { |
AzureIoTClient | 5:921351ce6973 | 169 | BUFFER_HANDLE result; |
Azure.IoT Build | 0:fa2de1b79154 | 170 | /*Codes_SRS_BASE64_06_008: [If source is NULL then Base64_Decode shall return NULL.]*/ |
AzureIoTClient | 5:921351ce6973 | 171 | if (source == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 172 | { |
AzureIoTClient | 5:921351ce6973 | 173 | LogError("invalid parameter const char* source=%p", source); |
AzureIoTClient | 5:921351ce6973 | 174 | result = NULL; |
AzureIoTClient | 5:921351ce6973 | 175 | } |
AzureIoTClient | 5:921351ce6973 | 176 | else |
AzureIoTClient | 5:921351ce6973 | 177 | { |
AzureIoTClient | 5:921351ce6973 | 178 | if ((strlen(source) % 4) != 0) |
Azure.IoT Build | 0:fa2de1b79154 | 179 | { |
Azure.IoT Build | 0:fa2de1b79154 | 180 | /*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 | 181 | LogError("Invalid length Base64 string!"); |
AzureIoTClient | 5:921351ce6973 | 182 | result = NULL; |
Azure.IoT Build | 0:fa2de1b79154 | 183 | } |
Azure.IoT Build | 0:fa2de1b79154 | 184 | else |
Azure.IoT Build | 0:fa2de1b79154 | 185 | { |
AzureIoTClient | 5:921351ce6973 | 186 | size_t lengthOfSource = numberOfBase64Characters(source); |
Azure.IoT Build | 0:fa2de1b79154 | 187 | if ((result = BUFFER_new()) == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 188 | { |
Azure.IoT Build | 0:fa2de1b79154 | 189 | /*Codes_SRS_BASE64_06_010: [If there is any memory allocation failure during the decode then Base64_Decode shall return NULL.]*/ |
AzureIoTClient | 1:9190c0f4d23a | 190 | LogError("Could not create a buffer to decoding."); |
Azure.IoT Build | 0:fa2de1b79154 | 191 | } |
Azure.IoT Build | 0:fa2de1b79154 | 192 | else |
Azure.IoT Build | 0:fa2de1b79154 | 193 | { |
Azure.IoT Build | 0:fa2de1b79154 | 194 | size_t sizeOfOutputBuffer = Base64decode_len(source); |
Azure.IoT Build | 0:fa2de1b79154 | 195 | /*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 | 196 | if (sizeOfOutputBuffer > 0) |
Azure.IoT Build | 0:fa2de1b79154 | 197 | { |
Azure.IoT Build | 0:fa2de1b79154 | 198 | if (BUFFER_pre_build(result, sizeOfOutputBuffer) != 0) |
Azure.IoT Build | 0:fa2de1b79154 | 199 | { |
Azure.IoT Build | 0:fa2de1b79154 | 200 | /*Codes_SRS_BASE64_06_010: [If there is any memory allocation failure during the decode then Base64_Decode shall return NULL.]*/ |
AzureIoTClient | 1:9190c0f4d23a | 201 | LogError("Could not prebuild a buffer for base 64 decoding."); |
Azure.IoT Build | 0:fa2de1b79154 | 202 | BUFFER_delete(result); |
Azure.IoT Build | 0:fa2de1b79154 | 203 | result = NULL; |
Azure.IoT Build | 0:fa2de1b79154 | 204 | } |
Azure.IoT Build | 0:fa2de1b79154 | 205 | else |
Azure.IoT Build | 0:fa2de1b79154 | 206 | { |
Azure.IoT Build | 0:fa2de1b79154 | 207 | Base64decode(BUFFER_u_char(result), source); |
Azure.IoT Build | 0:fa2de1b79154 | 208 | } |
Azure.IoT Build | 0:fa2de1b79154 | 209 | } |
Azure.IoT Build | 0:fa2de1b79154 | 210 | } |
Azure.IoT Build | 0:fa2de1b79154 | 211 | } |
Azure.IoT Build | 0:fa2de1b79154 | 212 | } |
Azure.IoT Build | 0:fa2de1b79154 | 213 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 214 | } |
Azure.IoT Build | 0:fa2de1b79154 | 215 | |
Azure.IoT Build | 0:fa2de1b79154 | 216 | |
Azure.IoT Build | 0:fa2de1b79154 | 217 | static STRING_HANDLE Base64_Encode_Internal(const unsigned char* source, size_t size) |
Azure.IoT Build | 0:fa2de1b79154 | 218 | { |
Azure.IoT Build | 0:fa2de1b79154 | 219 | STRING_HANDLE result; |
Azure.IoT Build | 0:fa2de1b79154 | 220 | size_t neededSize = 0; |
Azure.IoT Build | 0:fa2de1b79154 | 221 | char* encoded; |
Azure.IoT Build | 0:fa2de1b79154 | 222 | size_t currentPosition = 0; |
Azure.IoT Build | 0:fa2de1b79154 | 223 | neededSize += (size == 0) ? (0) : ((((size - 1) / 3) + 1) * 4); |
Azure.IoT Build | 0:fa2de1b79154 | 224 | neededSize += 1; /*+1 because \0 at the end of the string*/ |
Azure.IoT Build | 0:fa2de1b79154 | 225 | /*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 | 226 | encoded = (char*)malloc(neededSize); |
Azure.IoT Build | 0:fa2de1b79154 | 227 | if (encoded == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 228 | { |
Azure.IoT Build | 0:fa2de1b79154 | 229 | result = NULL; |
AzureIoTClient | 1:9190c0f4d23a | 230 | LogError("Base64_Encode:: Allocation failed."); |
Azure.IoT Build | 0:fa2de1b79154 | 231 | } |
Azure.IoT Build | 0:fa2de1b79154 | 232 | else |
Azure.IoT Build | 0:fa2de1b79154 | 233 | { |
Azure.IoT Build | 0:fa2de1b79154 | 234 | /*b0 b1(+1) b2(+2) |
Azure.IoT Build | 0:fa2de1b79154 | 235 | 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 | 236 | |----c1---| |----c2---| |----c3---| |----c4---| |
Azure.IoT Build | 0:fa2de1b79154 | 237 | */ |
Azure.IoT Build | 0:fa2de1b79154 | 238 | |
Azure.IoT Build | 0:fa2de1b79154 | 239 | size_t destinationPosition = 0; |
Azure.IoT Build | 0:fa2de1b79154 | 240 | while (size - currentPosition >= 3) |
Azure.IoT Build | 0:fa2de1b79154 | 241 | { |
Azure.IoT Build | 0:fa2de1b79154 | 242 | char c1 = base64char[source[currentPosition] >> 2]; |
Azure.IoT Build | 0:fa2de1b79154 | 243 | char c2 = base64char[ |
Azure.IoT Build | 0:fa2de1b79154 | 244 | ((source[currentPosition] & 3) << 4) | |
Azure.IoT Build | 0:fa2de1b79154 | 245 | (source[currentPosition + 1] >> 4) |
Azure.IoT Build | 0:fa2de1b79154 | 246 | ]; |
Azure.IoT Build | 0:fa2de1b79154 | 247 | char c3 = base64char[ |
Azure.IoT Build | 0:fa2de1b79154 | 248 | ((source[currentPosition + 1] & 0x0F) << 2) | |
Azure.IoT Build | 0:fa2de1b79154 | 249 | ((source[currentPosition + 2] >> 6) & 3) |
Azure.IoT Build | 0:fa2de1b79154 | 250 | ]; |
Azure.IoT Build | 0:fa2de1b79154 | 251 | char c4 = base64char[ |
Azure.IoT Build | 0:fa2de1b79154 | 252 | source[currentPosition + 2] & 0x3F |
Azure.IoT Build | 0:fa2de1b79154 | 253 | ]; |
Azure.IoT Build | 0:fa2de1b79154 | 254 | currentPosition += 3; |
Azure.IoT Build | 0:fa2de1b79154 | 255 | encoded[destinationPosition++] = c1; |
Azure.IoT Build | 0:fa2de1b79154 | 256 | encoded[destinationPosition++] = c2; |
Azure.IoT Build | 0:fa2de1b79154 | 257 | encoded[destinationPosition++] = c3; |
Azure.IoT Build | 0:fa2de1b79154 | 258 | encoded[destinationPosition++] = c4; |
Azure.IoT Build | 0:fa2de1b79154 | 259 | |
Azure.IoT Build | 0:fa2de1b79154 | 260 | } |
Azure.IoT Build | 0:fa2de1b79154 | 261 | if (size - currentPosition == 2) |
Azure.IoT Build | 0:fa2de1b79154 | 262 | { |
Azure.IoT Build | 0:fa2de1b79154 | 263 | char c1 = base64char[source[currentPosition] >> 2]; |
Azure.IoT Build | 0:fa2de1b79154 | 264 | char c2 = base64char[ |
Azure.IoT Build | 0:fa2de1b79154 | 265 | ((source[currentPosition] & 0x03) << 4) | |
Azure.IoT Build | 0:fa2de1b79154 | 266 | (source[currentPosition + 1] >> 4) |
Azure.IoT Build | 0:fa2de1b79154 | 267 | ]; |
Azure.IoT Build | 0:fa2de1b79154 | 268 | char c3 = base64b16[source[currentPosition + 1] & 0x0F]; |
Azure.IoT Build | 0:fa2de1b79154 | 269 | encoded[destinationPosition++] = c1; |
Azure.IoT Build | 0:fa2de1b79154 | 270 | encoded[destinationPosition++] = c2; |
Azure.IoT Build | 0:fa2de1b79154 | 271 | encoded[destinationPosition++] = c3; |
Azure.IoT Build | 0:fa2de1b79154 | 272 | encoded[destinationPosition++] = '='; |
Azure.IoT Build | 0:fa2de1b79154 | 273 | } |
Azure.IoT Build | 0:fa2de1b79154 | 274 | else if (size - currentPosition == 1) |
Azure.IoT Build | 0:fa2de1b79154 | 275 | { |
Azure.IoT Build | 0:fa2de1b79154 | 276 | char c1 = base64char[source[currentPosition] >> 2]; |
Azure.IoT Build | 0:fa2de1b79154 | 277 | char c2 = base64b8[source[currentPosition] & 0x03]; |
Azure.IoT Build | 0:fa2de1b79154 | 278 | encoded[destinationPosition++] = c1; |
Azure.IoT Build | 0:fa2de1b79154 | 279 | encoded[destinationPosition++] = c2; |
Azure.IoT Build | 0:fa2de1b79154 | 280 | encoded[destinationPosition++] = '='; |
Azure.IoT Build | 0:fa2de1b79154 | 281 | encoded[destinationPosition++] = '='; |
Azure.IoT Build | 0:fa2de1b79154 | 282 | } |
Azure.IoT Build | 0:fa2de1b79154 | 283 | |
Azure.IoT Build | 0:fa2de1b79154 | 284 | /*null terminating the string*/ |
Azure.IoT Build | 0:fa2de1b79154 | 285 | encoded[destinationPosition] = '\0'; |
Azure.IoT Build | 0:fa2de1b79154 | 286 | /*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 | 287 | result = STRING_new_with_memory(encoded); |
Azure.IoT Build | 0:fa2de1b79154 | 288 | if (result == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 289 | { |
Azure.IoT Build | 0:fa2de1b79154 | 290 | free(encoded); |
AzureIoTClient | 1:9190c0f4d23a | 291 | LogError("Base64_Encode:: Allocation failed for return value."); |
Azure.IoT Build | 0:fa2de1b79154 | 292 | } |
Azure.IoT Build | 0:fa2de1b79154 | 293 | } |
Azure.IoT Build | 0:fa2de1b79154 | 294 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 295 | } |
Azure.IoT Build | 0:fa2de1b79154 | 296 | |
Azure.IoT Build | 0:fa2de1b79154 | 297 | STRING_HANDLE Base64_Encode_Bytes(const unsigned char* source, size_t size) |
Azure.IoT Build | 0:fa2de1b79154 | 298 | { |
Azure.IoT Build | 0:fa2de1b79154 | 299 | STRING_HANDLE result; |
Azure.IoT Build | 0:fa2de1b79154 | 300 | /*Codes_SRS_BASE64_02_001: [If source is NULL then Base64_Encode_Bytes shall return NULL.] */ |
Azure.IoT Build | 0:fa2de1b79154 | 301 | if (source == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 302 | { |
Azure.IoT Build | 0:fa2de1b79154 | 303 | result = NULL; |
Azure.IoT Build | 0:fa2de1b79154 | 304 | } |
Azure.IoT Build | 0:fa2de1b79154 | 305 | /*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 | 306 | else if (size == 0) |
Azure.IoT Build | 0:fa2de1b79154 | 307 | { |
Azure.IoT Build | 0:fa2de1b79154 | 308 | result = STRING_new(); /*empty string*/ |
Azure.IoT Build | 0:fa2de1b79154 | 309 | } |
Azure.IoT Build | 0:fa2de1b79154 | 310 | else |
Azure.IoT Build | 0:fa2de1b79154 | 311 | { |
Azure.IoT Build | 0:fa2de1b79154 | 312 | result = Base64_Encode_Internal(source, size); |
Azure.IoT Build | 0:fa2de1b79154 | 313 | } |
Azure.IoT Build | 0:fa2de1b79154 | 314 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 315 | } |
Azure.IoT Build | 0:fa2de1b79154 | 316 | |
Azure.IoT Build | 0:fa2de1b79154 | 317 | STRING_HANDLE Base64_Encode(BUFFER_HANDLE input) |
Azure.IoT Build | 0:fa2de1b79154 | 318 | { |
Azure.IoT Build | 0:fa2de1b79154 | 319 | STRING_HANDLE result; |
Azure.IoT Build | 0:fa2de1b79154 | 320 | /*the following will happen*/ |
Azure.IoT Build | 0:fa2de1b79154 | 321 | /*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 | 322 | /*2. the remaining characters (1 or 2) shall be encoded.*/ |
Azure.IoT Build | 0:fa2de1b79154 | 323 | /*there's a level of assumption that 'a' corresponds to 0b000000 and that '_' corresponds to 0b111111*/ |
Azure.IoT Build | 0:fa2de1b79154 | 324 | /*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 | 325 | /*these are the bits of the 3 normal bytes to be encoded*/ |
Azure.IoT Build | 0:fa2de1b79154 | 326 | |
Azure.IoT Build | 0:fa2de1b79154 | 327 | /*Codes_SRS_BASE64_06_001: [If input is NULL then Base64_Encode shall return NULL.]*/ |
Azure.IoT Build | 0:fa2de1b79154 | 328 | if (input == NULL) |
Azure.IoT Build | 0:fa2de1b79154 | 329 | { |
Azure.IoT Build | 0:fa2de1b79154 | 330 | result = NULL; |
AzureIoTClient | 1:9190c0f4d23a | 331 | LogError("Base64_Encode:: NULL input"); |
Azure.IoT Build | 0:fa2de1b79154 | 332 | } |
Azure.IoT Build | 0:fa2de1b79154 | 333 | else |
Azure.IoT Build | 0:fa2de1b79154 | 334 | { |
Azure.IoT Build | 0:fa2de1b79154 | 335 | size_t inputSize; |
Azure.IoT Build | 0:fa2de1b79154 | 336 | const unsigned char* inputBinary; |
Azure.IoT Build | 0:fa2de1b79154 | 337 | if ((BUFFER_content(input, &inputBinary) != 0) || |
Azure.IoT Build | 0:fa2de1b79154 | 338 | (BUFFER_size(input, &inputSize) != 0)) |
Azure.IoT Build | 0:fa2de1b79154 | 339 | { |
Azure.IoT Build | 0:fa2de1b79154 | 340 | result = NULL; |
AzureIoTClient | 1:9190c0f4d23a | 341 | LogError("Base64_Encode:: BUFFER_routines failure."); |
Azure.IoT Build | 0:fa2de1b79154 | 342 | } |
Azure.IoT Build | 0:fa2de1b79154 | 343 | else |
Azure.IoT Build | 0:fa2de1b79154 | 344 | { |
Azure.IoT Build | 0:fa2de1b79154 | 345 | result = Base64_Encode_Internal(inputBinary, inputSize); |
Azure.IoT Build | 0:fa2de1b79154 | 346 | } |
Azure.IoT Build | 0:fa2de1b79154 | 347 | } |
Azure.IoT Build | 0:fa2de1b79154 | 348 | return result; |
Azure.IoT Build | 0:fa2de1b79154 | 349 | } |