in src/azure_base64.c [238:314]
static STRING_HANDLE Base64_Encode_Internal(const unsigned char* source, size_t size)
{
STRING_HANDLE result;
char* encoded;
size_t currentPosition = 0;
/*Codes_SRS_BASE64_06_006: [If when allocating memory to produce the encoding a failure occurs then Azure_Base64_Encode shall return NULL.]*/
encoded = malloc_flex(1, (size == 0) ? 0 : (((size - 1) / 3) + 1), 4); /*base==1 because there's a '\0' added at the end of the string, nmemb = (((size - 1) / 3) + 1), each of them having 4 characters*/
if (encoded == NULL)
{
/* Codes_SRS_BASE64_02_004: [ In case of any errors, Azure_Base64_Encode_Bytes shall return NULL. ]*/
result = NULL;
LogError("failure in malloc_flex(1, (size == 0) ? 0 : (((size=%zu - 1) / 3) + 1), 4).", size);
}
else
{
/*b0 b1(+1) b2(+2)
7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|----c1---| |----c2---| |----c3---| |----c4---|
*/
size_t destinationPosition = 0;
while (size - currentPosition >= 3)
{
char c1 = base64char(source[currentPosition] >> 2);
char c2 = base64char(
((source[currentPosition] & 3) << 4) |
(source[currentPosition + 1] >> 4)
);
char c3 = base64char(
((source[currentPosition + 1] & 0x0F) << 2) |
((source[currentPosition + 2] >> 6) & 3)
);
char c4 = base64char(
source[currentPosition + 2] & 0x3F
);
currentPosition += 3;
encoded[destinationPosition++] = c1;
encoded[destinationPosition++] = c2;
encoded[destinationPosition++] = c3;
encoded[destinationPosition++] = c4;
}
if (size - currentPosition == 2)
{
char c1 = base64char(source[currentPosition] >> 2);
char c2 = base64char(
((source[currentPosition] & 0x03) << 4) |
(source[currentPosition + 1] >> 4)
);
char c3 = base64b16(source[currentPosition + 1] & 0x0F);
encoded[destinationPosition++] = c1;
encoded[destinationPosition++] = c2;
encoded[destinationPosition++] = c3;
encoded[destinationPosition++] = '=';
}
else if (size - currentPosition == 1)
{
char c1 = base64char(source[currentPosition] >> 2);
char c2 = base64b8(source[currentPosition] & 0x03);
encoded[destinationPosition++] = c1;
encoded[destinationPosition++] = c2;
encoded[destinationPosition++] = '=';
encoded[destinationPosition++] = '=';
}
/*null terminating the string*/
encoded[destinationPosition] = '\0';
/*Codes_SRS_BASE64_06_007: [Otherwise Azure_Base64_Encode shall return a pointer to STRING, that string contains the base 64 encoding of input.]*/
result = STRING_new_with_memory(encoded);
if (result == NULL)
{
free(encoded);
LogError("Azure_Base64_Encode:: Allocation failed for return value.");
}
}
return result;
}