208 lines
6.0 KiB
C++
208 lines
6.0 KiB
C++
|
|
#include "fm_base64.h"
|
|
#if (ENCODE_CFG_BASE64)
|
|
#include <QFile>
|
|
|
|
static const unsigned char base64_table[65] = "0123456789+/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; // Changed Code...
|
|
|
|
#define BASE64_MARK_SIZE 4
|
|
static const unsigned char base64_start_mark[BASE64_MARK_SIZE] = { 0x1B, 0x9B, 0x1B, 0x9C };
|
|
static const unsigned char base64_end_mark[BASE64_MARK_SIZE] = { 0x1B, 0x9C, 0x1B, 0x9D };
|
|
|
|
/* base64_encode - Base64 encode */
|
|
uint8_t* FMBase64::mg_base64_encode(const uint8_t *src, uint32_t len, uint32_t *out_len)
|
|
{
|
|
uint8_t *out, *pos;
|
|
const uint8_t *end, *in;
|
|
uint32_t olen;
|
|
int line_len;
|
|
|
|
olen = len * 4 / 3 + 4; /* 3-byte blocks to 4-byte */
|
|
olen += olen / 72; /* line feeds */
|
|
olen++; /* nul termination */
|
|
if (olen < len) return NULL; /* integer overflow */
|
|
out = (uint8_t*)malloc(olen+(BASE64_MARK_SIZE*2));
|
|
memset(out,0,olen+(BASE64_MARK_SIZE*2));
|
|
|
|
if (out == NULL) return NULL;
|
|
|
|
end = src + len;
|
|
in = src;
|
|
pos = out;
|
|
line_len = 0;
|
|
|
|
memcpy((void*)pos, base64_start_mark, BASE64_MARK_SIZE);
|
|
pos += BASE64_MARK_SIZE;
|
|
|
|
while (end - in >= 3) {
|
|
*pos++ = base64_table[in[0] >> 2];
|
|
*pos++ = base64_table[((in[0] & 0x03) << 4) | (in[1] >> 4)];
|
|
*pos++ = base64_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)];
|
|
*pos++ = base64_table[in[2] & 0x3f];
|
|
in += 3;
|
|
line_len += 4;
|
|
if (line_len >= 72) {
|
|
*pos++ = '\n';
|
|
line_len = 0;
|
|
}
|
|
}
|
|
|
|
if (end - in) {
|
|
*pos++ = base64_table[in[0] >> 2];
|
|
if (end - in == 1) {
|
|
*pos++ = base64_table[(in[0] & 0x03) << 4];
|
|
*pos++ = '=';
|
|
} else {
|
|
*pos++ = base64_table[((in[0] & 0x03) << 4) |
|
|
(in[1] >> 4)];
|
|
*pos++ = base64_table[(in[1] & 0x0f) << 2];
|
|
}
|
|
*pos++ = '=';
|
|
line_len += 4;
|
|
}
|
|
|
|
if (line_len) *pos++ = '\n';
|
|
|
|
memcpy((void*)pos, base64_end_mark, BASE64_MARK_SIZE);
|
|
pos += BASE64_MARK_SIZE;
|
|
|
|
*pos = '\0';
|
|
if (out_len) *out_len = pos - out;
|
|
return out;
|
|
}
|
|
|
|
/* base64_decode - Base64 decode */
|
|
uint8_t* FMBase64::mg_base64_decode(uint8_t *src, uint32_t len, uint32_t *out_len)
|
|
{
|
|
uint8_t dtable[256], *out, *pos, block[4], tmp;
|
|
uint32_t i, count, olen;
|
|
int pad = 0;
|
|
|
|
if(src == NULL || len <= BASE64_MARK_SIZE*2) return NULL;
|
|
if(memcmp((void*)&src[0], base64_start_mark, BASE64_MARK_SIZE) ||
|
|
memcmp((void*)&src[len-BASE64_MARK_SIZE], base64_end_mark, BASE64_MARK_SIZE)) {
|
|
return NULL;
|
|
}
|
|
src += BASE64_MARK_SIZE;
|
|
len -= BASE64_MARK_SIZE*2;
|
|
|
|
memset((void*)dtable, 0x80, 256);
|
|
for (i = 0; i < sizeof(base64_table) - 1; i++)
|
|
dtable[base64_table[i]] = (uint8_t) i;
|
|
dtable['='] = 0;
|
|
|
|
count = 0;
|
|
for (i = 0; i < len; i++) {
|
|
if (dtable[src[i]] != 0x80) count++;
|
|
}
|
|
|
|
if (count == 0 || count % 4) return NULL;
|
|
|
|
olen = count / 4 * 3;
|
|
//qInfo() << olen << olen + (olen % 2048) << __FUNCTION__;
|
|
pos = out = (uint8_t*)malloc(qMax(olen,(uint32_t)4096));
|
|
memset(out,0,olen);
|
|
if (out == NULL) return NULL;
|
|
|
|
count = 0;
|
|
for (i = 0; i < len; i++) {
|
|
tmp = dtable[src[i]];
|
|
if (tmp == 0x80) continue;
|
|
|
|
if (src[i] == '=') pad++;
|
|
block[count] = tmp;
|
|
count++;
|
|
if (count == 4) {
|
|
*pos++ = (block[0] << 2) | (block[1] >> 4);
|
|
*pos++ = (block[1] << 4) | (block[2] >> 2);
|
|
*pos++ = (block[2] << 6) | block[3];
|
|
count = 0;
|
|
if (pad) {
|
|
if (pad == 1) pos--;
|
|
else if (pad == 2) pos -= 2;
|
|
else {
|
|
/* Invalid padding */
|
|
free((void*)out);
|
|
return NULL;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
*out_len = pos - out;
|
|
return out;
|
|
}
|
|
|
|
// 파일 확인하여 텍스트 스트림으로 처리
|
|
QStringList FMBase64::load(QString path, bool* isEncoded)
|
|
{
|
|
QFile file(path);
|
|
if(file.exists() && file.open(QIODevice::ReadOnly))
|
|
{
|
|
uint32_t len = (uint32_t)(file.size() + (file.size() % 8));
|
|
uint8_t* buffer = (uint8_t*)malloc(len);
|
|
memset(buffer,0,len);
|
|
file.read((char*)buffer,file.size());
|
|
uint8_t* text = buffer;
|
|
|
|
// MARK 확인 , 0x9C, 0x1B, 0x9D
|
|
if(buffer[0] == base64_start_mark[0] &&
|
|
buffer[1] == base64_start_mark[1] &&
|
|
buffer[2] == base64_start_mark[2] &&
|
|
buffer[3] == base64_start_mark[3] &&
|
|
buffer[file.size()-4] == base64_end_mark[0] &&
|
|
buffer[file.size()-3] == base64_end_mark[1] &&
|
|
buffer[file.size()-2] == base64_end_mark[2] &&
|
|
buffer[file.size()-1] == base64_end_mark[3]) {
|
|
*isEncoded = true;
|
|
uint32_t outlen = 0;
|
|
text = mg_base64_decode(buffer, file.size(),&outlen);
|
|
text[outlen] = 0;
|
|
} else {
|
|
*isEncoded = false;
|
|
}
|
|
QString lines = QString::fromLatin1((char*)text);
|
|
file.close();
|
|
if(buffer != text) {
|
|
free(text);
|
|
}
|
|
free(buffer);
|
|
return lines.split(QRegExp("[\r\n]"),QString::SkipEmptyParts);
|
|
}
|
|
return QStringList();
|
|
}
|
|
void FMBase64::save(QString path, QStringList lines, bool isEncoded)
|
|
{
|
|
|
|
// \r\n
|
|
QString str = QString();
|
|
for(int i=0;i<lines.size();i++) {
|
|
str += lines.at(i);
|
|
str += "\r\n";
|
|
}
|
|
QByteArray ba = str.toLatin1();
|
|
const uint8_t * src = (uint8_t*)ba.data();
|
|
uint8_t* dest = NULL;
|
|
|
|
uint32_t out_len = ba.size();
|
|
if(true) { // isEncoded) {
|
|
dest = mg_base64_encode(src, ba.size(),&out_len);
|
|
} else {
|
|
size_t ss = ba.size() + (ba.size() % 8);
|
|
dest = (uint8_t*)malloc(ss);
|
|
memset(dest,0,ss);
|
|
memcpy(dest,ba.data(),ba.size());
|
|
}
|
|
|
|
QFile file(path);
|
|
if (file.open(QIODevice::WriteOnly)) {
|
|
|
|
file.write((char*)dest,out_len);
|
|
file.close();
|
|
}
|
|
free(dest);
|
|
|
|
}
|
|
#endif // #if (ENCODE_CFG_BASE64)
|