I needed also this feature. In fact the char is not a problem here. The problem is that output is threated as a ascii string.
Here is a modified, stand alone decode funtion + unchanged hex table.
I decided also to dump some of pointers (I dont like using raw pointers too much) and added stl::string instead.
This is how I call this funtion to decode QP binnary attachment from mine message and write it to disk file:
char* pPointerToQPData;
std::string sOutput;
long lFileSize = QuotedPrintable_DecodeEx(pPointerToQPData, sOutput);
CFile file;
file.Open("C:\\file.bin", CFile::modeCreate|CFile::modeReadWrite);
file.Write(sOutput.c_str(), lFileSize);
file.Close();
----
the code:
#include <string>
#define SKIP '\202'
const char hexmap[] = {
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 ,
8 , 9 , SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, 10, 11, 12, 13, 14, 15, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP,
SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP
};
/*
Return value: length of binary data
*/
int QuotedPrintable_DecodeEx(const char *input, std::string& a_sOutput)
{
BOOL bError = FALSE;
int iFileLen = 0;
a_sOutput.resize(strlen(input)+1);
while (*input != '\0') //loop through the entire string...
{
if (*input == '=') //woops, needs to be decoded...
{
for (int i = 0; i < 3; i++) //is s more than 3 chars long...
{
if (input[i] == '\0')
{
//error in the decoding...
bError = TRUE;
return iFileLen;
}
}
char mid[3];
input++; //move past the "="
//let's put the hex part into mid...
bool ok = true;
for (i = 0; i < 2; i++)
{
if (hexmap[input[i]] == SKIP)
{
//we have an error, or a linebreak, in the encoding...
ok = false;
if (input[i] == '\r' && input[i + 1] == '\n')
{
input += 2;
//*(result++) = '\r';
//*(result++) = '\n';
break;
}
else
{
//we have an error in the encoding...
bError = TRUE;
//s--;
}
}
mid[i] = input[i];
}
//now we just have to convert the hex string to an char...
if (ok)
{
input += 2;
int m = hexmap[mid[0]];
m <<= 4;
m |= hexmap[mid[1]];
a_sOutput[iFileLen++] = m;
}
}
else
{
if (*input != '\0')
{
a_sOutput[iFileLen++] = *(input++);
}
}
}
return iFileLen;
}
Check out my software at: http://www.ireksoftware.com
|