www.pudn.com > 《运用设计模式设计MIME编码类》配套代码.zip > 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 & 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> 1; 
		* ( p ++ ) = ClearHeadAndSetTail(c); 
 
		if( i % 3 == 2 ) 
		{ 
			c = inSrcBuf[i-2] & MakeBitSectionByOrder07(6, 7); 
			c = c << 2; 
			c |= inSrcBuf[i-1] & MakeBitSectionByOrder07(6, 7); 
			c = c << 2; 
			c |= inSrcBuf[i] & MakeBitSectionByOrder07(6, 7); 
			c = c << 1; 
			* ( p ++ ) = ClearHeadAndSetTail(c); 
		} 
		else if( i == (inSrcLen -1) ) 
		{ 
			if( i % 3 == 0 ) 
			{ 
				c = inSrcBuf[i] & MakeBitSectionByOrder07(6, 7); 
				c = c << 5; 
				* ( p ++ ) = ClearHeadAndSetTail(c); 
			} 
			else if( i % 3 == 1 ) 
			{ 
				c = inSrcBuf[i-1] & MakeBitSectionByOrder07(6, 7); 
				c = c << 2; 
				c = inSrcBuf[i] & 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 & 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> 5; 
			* (p - 3) |= c; 
 
			c |= inSrcBuf[i] & MakeBitSectionByOrder07(3, 4); 
			c = c >> 3; 
			* (p - 2) |= c; 
 
			c |= inSrcBuf[i] & 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] & MakeBitSectionByOrder07(1, 2); 
					c = c >> 5; 
					* (p - 1) |= c; 
				} 
				else if( i % 4 == 2 ) 
				{ 
					c = inSrcBuf[i] & MakeBitSectionByOrder07(1, 2); 
					c = c >> 5; 
					* (p - 2) |= c; 
 
					c |= inSrcBuf[i] & 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 & MakeBitByOrder07(inWhich)) == 0 ) 
	{ 
		return false; 
	} 
	else 
	{ 
		return true; 
	} 
} 
 
inline unsigned char CMimeAlgo::MakeBitByOrder07(int inWhich) 
{ 
	return 1U << (7-inWhich) ; 
} 
 
inline 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 & inoutChar, int inWhich) 
{ 
	inoutChar |= MakeBitByOrder07(inWhich); 
	return inoutChar; 
} 
 
inline unsigned char CMimeAlgo::ClearBitByOrder07(unsigned char & inoutChar, int inWhich) 
{ 
	inoutChar &= ~ MakeBitByOrder07(inWhich); 
	return inoutChar; 
} 
 
inline unsigned char CMimeAlgo::ClearHeadAndSetTail( unsigned char & inoutChar ) 
{ 
	ClearBitByOrder07(inoutChar, 0); 
	SetBitByOrder07(inoutChar, 7); 
	//now inoutChar is like 0xxx xxx1 
	return inoutChar; 
} 
 
 
 
//-------------------------------------------------------------