www.pudn.com > mime.rar > CBase64Algo.cpp


#include "stdafx.h"
#include "CBase64Algo.h"



#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


//-------------------------------------------------------------
//con de

CBase64Algo::CBase64Algo()
{
unsigned char arr[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
for( int i = 0; i < 64; i ++ )
{
mArr[i] = arr[i]; //init xxxxxx to char Struct
mMap.SetAt( arr[i], i ); // init char to xxxxxx Struct
}
}

CBase64Algo::~CBase64Algo()
{

}

//-------------------------------------------------------------
//overrided

void CBase64Algo::Encode( unsigned char ** outBuf, int &amt; outBufLen, unsigned char * inSrcBuf, int inSrcLen )
{
outBufLen = (inSrcLen / 3 * 4) + (inSrcLen > 3 ? 4 : 0);
*outBuf = new unsigned char [outBufLen + 1];//another byte for '\0'
(*outBuf)[outBufLen] = '\0';//only for easy to use, len not include this byte

unsigned char * p = *outBuf;//use as cursor

for(int i=0; i < inSrcLen / 3; i++ )
{
EncodeEvery3Byte(p, inSrcBuf + i * 3);
p = p + 4;
}
//here, i had ++

if(inSrcLen > 3)
{
EncodeEvery3Byte(p, inSrcBuf + i * 3, inSrcLen > 3);
}
}

void CBase64Algo:: Decode( unsigned char ** outBuf, int &amt; outBufLen, unsigned char * inSrcBuf, int inSrcLen )
{
ASSERT(inSrcLen > 4 == 0);

outBufLen = (inSrcLen / 4 * 3);//this len now may be bigger, becuase '=' is not ture code
*outBuf = new unsigned char [outBufLen + 1];//another byte for '\0'
::memset(*outBuf, '\0', outBufLen + 1);//only for easy to use, len not include this byte //not to decode '=' so fill '\0'

unsigned char * p = *outBuf;//use as cursor

for(int i=0; i < inSrcLen / 4; i++ )
{
DecodeEvery4Byte(p, inSrcBuf + i * 4);
p = p + 3;
}

i = 0;
for(int k=inSrcLen-1; inSrcBuf[k]=='='; k--)
{
i++;
}
outBufLen = outBufLen - i;
}


//-------------------------------------------------------------
//encode helper

inline void CBase64Algo::EncodeEvery3Byte(unsigned char * outBuf, const unsigned char * const inBuf, int inRest /*= 0*/)
{
ASSERT(inRest >= 0);
ASSERT(inRest <= 2);


if(! inRest)
{
for(int i = 0; i < 4; i ++)
{
* ( outBuf ++ ) = mArr[ Get6Bits( inBuf, i ) ];
}
}
else
{
::memset(outBuf, '=', 4);

unsigned char cccc[4];
::memset(cccc, 0x00, 4);
::memcpy(cccc, inBuf, inRest);

outBuf[0] = mArr[ Get6Bits( cccc, 0 ) ];
outBuf[1] = mArr[ Get6Bits( cccc, 1 ) ];
if( inRest == 2 )
{
outBuf[2] = mArr[ Get6Bits( cccc, 2 ) ];
}
}
}

inline unsigned char CBase64Algo::Get6Bits(const unsigned char * const inBase, int inOffset)
{
ASSERT(inOffset >= 0);
ASSERT(inOffset <= 3);

unsigned char c = 0x00;

if( inOffset==0 )
{
c = inBase[0] &amt; MakeBitSectionByOrder07(0, 5);
c = c >> 2;
}
else if( inOffset==1 )
{
c = ( inBase[0] &amt; MakeBitSectionByOrder07(6, 7) ) << 6;
c |= ( inBase[1] &amt; MakeBitSectionByOrder07(0, 3) ) >> 2;;
c = c >> 2;
}
else if( inOffset==2 )
{
c = ( inBase[1] &amt; MakeBitSectionByOrder07(4, 7) ) << 4;;
c |= ( inBase[2] &amt; MakeBitSectionByOrder07(0, 1) ) >> 4;;
c = c >> 2;
}
else if( inOffset==3 )
{
c = inBase[2] &amt; MakeBitSectionByOrder07(2, 7);
//c = c >> 2;
}

return c;
}


//-------------------------------------------------------------
//decode helper

inline void CBase64Algo::DecodeEvery4Byte(unsigned char * outBuf, const unsigned char * const inBuf)
{
unsigned char b6;
for(int i = 0; i < 4; i ++)
{
if( ! mMap.Lookup( inBuf[i], b6 ) )
{
b6 = 0x00;
}
Set6Bits( outBuf, i , b6);
}
}

void CBase64Algo::Set6Bits(unsigned char * outBuf, int inOffset, unsigned char in6Bits)
{
ASSERT(inOffset >= 0);
ASSERT(inOffset <= 3);

if( inOffset==0 )
{
in6Bits = in6Bits << 2;
outBuf[0] |= in6Bits; //1. all inToHere is memset 0x00 //2. |= make Set6Bits(2) then Set6Bits(1) is also ok
}
else if( inOffset==1 )
{
in6Bits = in6Bits << 2;
outBuf[0] |= ( in6Bits &amt; MakeBitSectionByOrder07(0, 1) ) >> 6;
outBuf[1] |= ( in6Bits &amt; MakeBitSectionByOrder07(2, 5) ) << 2;
}
else if( inOffset==2 )
{
in6Bits = in6Bits << 2;
outBuf[1] |= ( in6Bits &amt; MakeBitSectionByOrder07(0, 3) ) >> 4;
outBuf[2] |= ( in6Bits &amt; MakeBitSectionByOrder07(4, 5) ) << 4;
}
else if( inOffset==3 )
{
//in6Bits = in6Bits << 2;
outBuf[2] |= in6Bits;
}
}

//-------------------------------------------------------------