www.pudn.com > 《运用设计模式设计MIME编码类》配套代码.zip > 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 & 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 & 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] & MakeBitSectionByOrder07(0, 5); 
		c = c >> 2; 
	} 
	else if( inOffset==1 ) 
	{ 
		c = ( inBase[0] & MakeBitSectionByOrder07(6, 7) ) << 6; 
		c |= ( inBase[1] & MakeBitSectionByOrder07(0, 3) ) >> 2;; 
		c = c >> 2; 
	} 
	else if( inOffset==2 ) 
	{ 
		c = ( inBase[1] & MakeBitSectionByOrder07(4, 7) ) << 4;; 
		c |= ( inBase[2] & MakeBitSectionByOrder07(0, 1) ) >> 4;; 
		c = c >> 2; 
	} 
	else if( inOffset==3 ) 
	{ 
		c = inBase[2] & 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 & MakeBitSectionByOrder07(0, 1) ) >> 6; 
		outBuf[1] |= ( in6Bits & MakeBitSectionByOrder07(2, 5) ) << 2; 
	} 
	else if( inOffset==2 ) 
	{ 
		in6Bits = in6Bits << 2; 
		outBuf[1] |= ( in6Bits & MakeBitSectionByOrder07(0, 3) ) >> 4; 
		outBuf[2] |= ( in6Bits & MakeBitSectionByOrder07(4, 5) ) << 4; 
	} 
	else if( inOffset==3 ) 
	{ 
		//in6Bits = in6Bits << 2; 
		outBuf[2] |= in6Bits; 
	} 
} 
 
//-------------------------------------------------------------