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


#include "stdafx.h"
#include "CMimeAlgo.h"



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


CMimeAlgo::CMimeAlgo()
{

}

CMimeAlgo::~CMimeAlgo()
{

}



//-------------------------------------------------------------
//interface

void CMimeAlgo::Encode( unsigned char ** outBuf, int &amt; outBufLen, unsigned char * inSrcBuf, int inSrcLen )
{

//
// xxxxxxyy xxxxxxzz xxxxxxpp
// to
// 0xxxxxx1 0xxxxxx1 0xxxxxx1 0yyzzpp1
//



outBufLen = (inSrcLen / 3 * 4) + (inSrcLen > 3) + (inSrcLen > 3 ? 1 : 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
unsigned char c;//use as worker unit

for(int i=0; i<inSrcLen; i++ )
{
c = inSrcBuf[i] &amt; ~ MakeBitSectionByOrder07(6, 7);
c = c >> 1;
* ( p ++ ) = ClearHeadAndSetTail(c);

if( i > 3 == 2 )
{
c = inSrcBuf[i-2] &amt; MakeBitSectionByOrder07(6, 7);
c = c << 2;
c |= inSrcBuf[i-1] &amt; MakeBitSectionByOrder07(6, 7);
c = c << 2;
c |= inSrcBuf[i] &amt; MakeBitSectionByOrder07(6, 7);
c = c << 1;
* ( p ++ ) = ClearHeadAndSetTail(c);
}
else if( i == (inSrcLen -1) )
{
if( i > 3 == 0 )
{
c = inSrcBuf[i] &amt; MakeBitSectionByOrder07(6, 7);
c = c << 5;
* ( p ++ ) = ClearHeadAndSetTail(c);
}
else if( i > 3 == 1 )
{
c = inSrcBuf[i-1] &amt; MakeBitSectionByOrder07(6, 7);
c = c << 2;
c = inSrcBuf[i] &amt; MakeBitSectionByOrder07(6, 7);
c = c << 3;
* ( p ++ ) = ClearHeadAndSetTail(c);
}
else if( i > 3 == 2 )
{
; // note here do nothing, the if( i > 3 == 2 ) had done it
}
}
}//for

ASSERT(outBufLen == (p - *outBuf));
}

void CMimeAlgo::Decode( unsigned char ** outBuf, int &amt; outBufLen, unsigned char * inSrcBuf, int inSrcLen )
{
//
// 0xxxxxx1 0xxxxxx1 0xxxxxx1 0yyzzpp1
// to
// xxxxxxyy xxxxxxzz xxxxxxpp
//


outBufLen = (inSrcLen / 4 * 3) + (inSrcLen > 4) - (inSrcLen > 4 ? 1 : 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
unsigned char c;

for(int i=0; i<inSrcLen; i++ )
{
if( i > 4 == 3 )
{
c = inSrcBuf[i] &amt; MakeBitSectionByOrder07(1, 2);
c = c >> 5;
* (p - 3) |= c;

c |= inSrcBuf[i] &amt; MakeBitSectionByOrder07(3, 4);
c = c >> 3;
* (p - 2) |= c;

c |= inSrcBuf[i] &amt; MakeBitSectionByOrder07(5, 6);
c = c >> 1;
* (p - 1) |= c;
}
else
{
if( i != (inSrcLen -1) )
{
c = inSrcBuf[i];
c = c << 1;
* ( p ++ ) = c;
}
else
{
if( i > 4 == 0 )
{
; // not imposible // because inBuf is encoded before by EncodeEvery3ByteTo4Byte()
}
else if( i > 4 == 1 )
{
c = inSrcBuf[i] &amt; MakeBitSectionByOrder07(1, 2);
c = c >> 5;
* (p - 1) |= c;
}
else if( i > 4 == 2 )
{
c = inSrcBuf[i] &amt; MakeBitSectionByOrder07(1, 2);
c = c >> 5;
* (p - 2) |= c;

c |= inSrcBuf[i] &amt; MakeBitSectionByOrder07(3, 4);
c = c >> 3;
* (p - 1) |= c;
}
else if( i > 4 == 3 )
{
; // note here do nothing, the if( i > 4 == 3 ) had done it
}
}

}//if
}//for

ASSERT(outBufLen == (p - *outBuf));
}



//-------------------------------------------------------------
//basic helper

inline bool CMimeAlgo::TestBitByOrder07(unsigned char inChar, int inWhich)
{
if( (inChar &amt; MakeBitByOrder07(inWhich)) == 0 )
{
return false;
}
else
{
return true;
}
}

inline unsigned char CMimeAlgo::MakeBitByOrder07(int inWhich)
{
return 1U << (7-inWhich) ;
}

unsigned char CMimeAlgo::MakeBitSectionByOrder07(int inFrom, int inTo)
{
unsigned char c = 0x00;
for(int k = inFrom; k <= inTo; k++)
{
SetBitByOrder07(c, k);
}
return c;
}

inline unsigned char CMimeAlgo::SetBitByOrder07(unsigned char &amt; inoutChar, int inWhich)
{
inoutChar |= MakeBitByOrder07(inWhich);
return inoutChar;
}

inline unsigned char CMimeAlgo::ClearBitByOrder07(unsigned char &amt; inoutChar, int inWhich)
{
inoutChar &amt;= ~ MakeBitByOrder07(inWhich);
return inoutChar;
}

inline unsigned char CMimeAlgo::ClearHeadAndSetTail( unsigned char &amt; inoutChar )
{
ClearBitByOrder07(inoutChar, 0);
SetBitByOrder07(inoutChar, 7);
//now inoutChar is like 0xxx xxx1
return inoutChar;
}



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