winamp/Src/Wasabi/bfc/util/base64.cpp
2024-09-24 14:54:57 +02:00

316 lines
7.4 KiB
C++

/* Based on code from Dave Winer (http://www.scripting.com/midas/base64/) */
#include "precomp_wasabi_bfc.h"
#include "base64.h"
char Base64::encodingTable [64] = {
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
};
int Base64::encode(MemBlock<char> &htext, MemBlock<char> &h64, int linelength) {
/*
encode the handle. some funny stuff about linelength -- it only makes
sense to make it a multiple of 4. if it's not a multiple of 4, we make it
so (by only checking it every 4 characters.
further, if it's 0, we don't add any line breaks at all.
*/
unsigned long ixtext;
unsigned long lentext;
unsigned long origsize;
long ctremaining;
unsigned char inbuf [3] = {0}, outbuf [4] = {0};
short i;
short charsonline = 0, ctcopy;
ixtext = 0;
lentext = htext.getSize();
while (1) {
ctremaining = lentext - ixtext;
if (ctremaining <= 0)
break;
for (i = 0; i < 3; i++) {
unsigned long ix = ixtext + i;
if (ix < lentext)
inbuf [i] = *htext.getMemory(ix);
else
inbuf [i] = 0;
}
outbuf [0] = (inbuf [0] & 0xFC) >> 2;
outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4);
outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6);
outbuf [3] = inbuf [2] & 0x3F;
origsize = h64.getSize();
h64.setSize(origsize + 4);
ctcopy = 4;
switch (ctremaining) {
case 1:
ctcopy = 2;
break;
case 2:
ctcopy = 3;
break;
}
for (i = 0; i < ctcopy; i++)
*h64.getMemory(origsize + i) = encodingTable[outbuf[i]];
for (i = ctcopy; i < 4; i++)
*h64.getMemory(origsize + i) = '=';
ixtext += 3;
charsonline += 4;
if (linelength > 0) { /*DW 4/8/97 -- 0 means no line breaks*/
if (charsonline >= linelength) {
charsonline = 0;
origsize = h64.getSize();
h64.setSize(origsize + 1);
*h64.getMemory() = '\n';
}
}
}
return 1;
}
int Base64::encode(MemBlock<char> &htext, MemBlock<wchar_t> &h64, int linelength) {
/*
encode the handle. some funny stuff about linelength -- it only makes
sense to make it a multiple of 4. if it's not a multiple of 4, we make it
so (by only checking it every 4 characters.
further, if it's 0, we don't add any line breaks at all.
*/
unsigned long ixtext;
unsigned long lentext;
unsigned long origsize;
long ctremaining;
unsigned char inbuf [3] = {0}, outbuf [4] = {0};
short i;
short charsonline = 0, ctcopy;
ixtext = 0;
lentext = htext.getSize();
while (1) {
ctremaining = lentext - ixtext;
if (ctremaining <= 0)
break;
for (i = 0; i < 3; i++) {
unsigned long ix = ixtext + i;
if (ix < lentext)
inbuf [i] = *htext.getMemory(ix);
else
inbuf [i] = 0;
}
outbuf [0] = (inbuf [0] & 0xFC) >> 2;
outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4);
outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6);
outbuf [3] = inbuf [2] & 0x3F;
origsize = h64.getSize();
h64.setSize(origsize + 4);
ctcopy = 4;
switch (ctremaining) {
case 1:
ctcopy = 2;
break;
case 2:
ctcopy = 3;
break;
}
for (i = 0; i < ctcopy; i++)
*h64.getMemory(origsize + i) = encodingTable[outbuf[i]];
for (i = ctcopy; i < 4; i++)
*h64.getMemory(origsize + i) = '=';
ixtext += 3;
charsonline += 4;
if (linelength > 0) { /*DW 4/8/97 -- 0 means no line breaks*/
if (charsonline >= linelength) {
charsonline = 0;
origsize = h64.getSize();
h64.setSize(origsize + 1);
*h64.getMemory() = '\n';
}
}
}
return 1;
}
int Base64::decode(MemBlock<char> &h64, MemBlock<char> &htext) {
unsigned long ixtext;
unsigned long lentext;
unsigned long origsize;
unsigned char ch;
unsigned char inbuf [4] = {0}, outbuf [4] = {0};
short i, ixinbuf;
boolean flignore;
boolean flendtext = false;
ixtext = 0;
lentext = h64.getSize();
ixinbuf = 0;
while (true) {
if (ixtext >= lentext)
break;
ch = *h64.getMemory(ixtext++);
flignore = 0;
if ((ch >= 'A') && (ch <= 'Z'))
ch = ch - 'A';
else if ((ch >= 'a') && (ch <= 'z'))
ch = ch - 'a' + 26;
else if ((ch >= '0') && (ch <= '9'))
ch = ch - '0' + 52;
else if (ch == '+')
ch = 62;
else if (ch == '=') /*no op -- can't ignore this one*/
flendtext = true;
else if (ch == '/')
ch = 63;
else
flignore = true;
if (!flignore) {
short ctcharsinbuf = 3;
boolean flbreak = false;
if (flendtext) {
if (ixinbuf == 0)
break;
if ((ixinbuf == 1) || (ixinbuf == 2))
ctcharsinbuf = 1;
else
ctcharsinbuf = 2;
ixinbuf = 3;
flbreak = 1;
}
inbuf [ixinbuf++] = ch;
if (ixinbuf == 4) {
ixinbuf = 0;
outbuf [0] = (inbuf [0] << 2) | ((inbuf [1] & 0x30) >> 4);
outbuf [1] = ((inbuf [1] & 0x0F) << 4) | ((inbuf [2] & 0x3C) >> 2);
outbuf [2] = ((inbuf [2] & 0x03) << 6) | (inbuf [3] & 0x3F);
origsize = htext.getSize();
htext.setSize(origsize + ctcharsinbuf);
for (i = 0; i < ctcharsinbuf; i++)
*htext.getMemory(origsize + i) = outbuf[i];
}
if (flbreak)
break;
}
}
return 1;
}
int Base64::decode(MemBlock<wchar_t> &h64, MemBlock<char> &htext) {
unsigned long ixtext;
unsigned long lentext;
unsigned long origsize;
unsigned char ch;
unsigned char inbuf [4] = {0}, outbuf [4] = {0};
short i, ixinbuf;
boolean flignore;
boolean flendtext = false;
ixtext = 0;
lentext = h64.getSize();
ixinbuf = 0;
while (true) {
if (ixtext >= lentext)
break;
ch = (unsigned char)*h64.getMemory(ixtext++);
flignore = 0;
if ((ch >= 'A') && (ch <= 'Z'))
ch = ch - 'A';
else if ((ch >= 'a') && (ch <= 'z'))
ch = ch - 'a' + 26;
else if ((ch >= '0') && (ch <= '9'))
ch = ch - '0' + 52;
else if (ch == '+')
ch = 62;
else if (ch == '=') /*no op -- can't ignore this one*/
flendtext = true;
else if (ch == '/')
ch = 63;
else
flignore = true;
if (!flignore) {
short ctcharsinbuf = 3;
boolean flbreak = false;
if (flendtext) {
if (ixinbuf == 0)
break;
if ((ixinbuf == 1) || (ixinbuf == 2))
ctcharsinbuf = 1;
else
ctcharsinbuf = 2;
ixinbuf = 3;
flbreak = 1;
}
inbuf [ixinbuf++] = ch;
if (ixinbuf == 4) {
ixinbuf = 0;
outbuf [0] = (inbuf [0] << 2) | ((inbuf [1] & 0x30) >> 4);
outbuf [1] = ((inbuf [1] & 0x0F) << 4) | ((inbuf [2] & 0x3C) >> 2);
outbuf [2] = ((inbuf [2] & 0x03) << 6) | (inbuf [3] & 0x3F);
origsize = htext.getSize();
htext.setSize(origsize + ctcharsinbuf);
for (i = 0; i < ctcharsinbuf; i++)
*htext.getMemory(origsize + i) = outbuf[i];
}
if (flbreak)
break;
}
}
return 1;
}