// converts a 6 bit value into the Base64 ASCII equivalent
unsigned char ASCIITo_6BitVal(char ch)
{
if((ch >= 'A') && (ch <= 'Z')) return ch - 'A';
else if((ch >= 'a') && (ch <= 'z')) return (ch - 'a') + 26;
else if((ch >= '0') && (ch <= '9')) return (ch - '0') + 52;
else if(ch == '+') return 62;
else if(ch == '/') return 63;
else if(ch == '=') return 64;
else return 65;
}
// converts binary data to Base64, If the data will be used on a platform with a different endianness, the
// data 32 bit integers or the decoder will not be able to switch the endianness automatically
int Base64Binary(const char *in_base64_data, unsigned int in_base64_data_length,
unsigned char *out_binary_data, unsigned int in_binary_buffer_length, unsigned int &out_binary_data_length)
{
out_binary_data_length = 0;
for(unsigned int i = 0; i < in_base64_data_length; i += 4)
{
bool end_found = false;
unsigned char b64_byte1 = ASCIITo_6BitVal(in_base64_data[i]);
if(b64_byte1 > 63) return 1; // stop processing
unsigned char b64_byte2 = ASCIITo_6BitVal(in_base64_data[i+1]);
if(b64_byte2 > 63) return -1;
unsigned char b64_byte3 = ASCIITo_6BitVal(in_base64_data[i+2]);
if(b64_byte3 > 64) return -1; // this could be the end of the stream so it could also be '='
unsigned char b64_byte4 = ASCIITo_6BitVal(in_base64_data[i+3]);
if(b64_byte4 > 64) return -1; // this could be the end of the stream so it could also be '='
int size = 3;
// check for the end
if(b64_byte4 == 64)
{
size = 2;
end_found = true;
b64_byte4 = 0;
}
if(b64_byte3 == 64)
{
size = 1;
end_found = true;
b64_byte3 = 0;
}
if(in_binary_buffer_length < (out_binary_data_length + size))
{
// the buffer is too small
return -2;
}
out_binary_data[out_binary_data_length + 0] = (b64_byte1 << 2) | ((0x30 & b64_byte2) >> 4);
if(size > 1)out_binary_data[out_binary_data_length + 1] = ((0xF & b64_byte2) << 4) | ((0x3C & b64_byte3) >> 2);
if(size > 2)out_binary_data[out_binary_data_length + 2] = ((0x3 & b64_byte3) << 6) | b64_byte4;
out_binary_data_length += size;
if(end_found) break;
}
return 0;
}
Sunday, February 2, 2014
Very Simple Base64 Reader
I've written this very simple Base64 reader. I wrote this as part of my loader for Tiled Map Editor files (see mapeditor.org). The code is very simple, but it works. The out_binary_data parameter is unsigned char * for simplicity as the code works in 8 bit chunks. Tiled actually uses 32 bit int variables so the pointer will need to be cast to int *. If you have anymore questions about the code, just leave a comment.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment