www.pudn.com > eMule0.42e-Sources.zip > CBase64Coding.cpp


//this file is part of eMule 
//Copyright (C)2002 Merkur ( merkur-@users.sourceforge.net / http://www.emule-project.net ) 
// 
//This program is free software; you can redistribute it and/or 
//modify it under the terms of the GNU General Public License 
//as published by the Free Software Foundation; either 
//version 2 of the License, or (at your option) any later version. 
// 
//This program is distributed in the hope that it will be useful, 
//but WITHOUT ANY WARRANTY; without even the implied warranty of 
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
//GNU General Public License for more details. 
// 
//You should have received a copy of the GNU General Public License 
//along with this program; if not, write to the Free Software 
//Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
#include "stdafx.h" 
#include "CBase64Coding.hpp" 
#pragma hdrstop 
 
#define CARRIAGE_RETURN (13) 
#define LINE_FEED       (10) 
 
/* 
** Author: Samuel R. Blackburn 
** Internet: wfc@pobox.com 
** 
** You can use it any way you like as long as you don't try to sell it. 
** 
** Any attempt to sell WFC in source code form must have the permission 
** of the original author. You can produce commercial executables with 
** WFC but you can't sell WFC. 
** 
** Copyright, 2000, Samuel R. Blackburn 
** 
** $Workfile: CBase64Coding.cpp $ 
** $Revision: 14 $ 
** $Modtime: 5/12/00 3:39p $ 
** $Reuse Tracing Code: 1 $ 
*/ 
 
//Modified for use with CAsyncProxySocket, removed tracing code 
 
#if defined( _DEBUG ) && ! defined( WFC_STL ) 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#define new DEBUG_NEW 
#endif // _DEBUG 
 
#define END_OF_BASE64_ENCODED_DATA           ('=') 
#define BASE64_END_OF_BUFFER                 (0xFD) 
#define BASE64_IGNORABLE_CHARACTER           (0xFE) 
#define BASE64_UNKNOWN_VALUE                 (0xFF) 
#define BASE64_NUMBER_OF_CHARACTERS_PER_LINE (72) 
 
static inline BYTE __get_character( const BYTE * buffer, const BYTE * decoder_table, int& index, int size_of_buffer ) 
{ 
   BYTE return_value = 0; 
 
   do 
   { 
      if ( index >= size_of_buffer ) 
      { 
         return( BASE64_END_OF_BUFFER ); 
      } 
 
      return_value = buffer[ index ]; 
      index++; 
   } 
   while( return_value != END_OF_BASE64_ENCODED_DATA && 
          decoder_table[ return_value ] == BASE64_IGNORABLE_CHARACTER ); 
 
   return( return_value ); 
} 
 
CBase64Coding::CBase64Coding() 
{ 
} 
 
CBase64Coding::~CBase64Coding() 
{ 
} 
 
BOOL CBase64Coding::Encode( const char * source, int len, char * destination_string ) 
{ 
 
   const char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 
 
   int loop_index                = 0; 
   int number_of_bytes_to_encode = len; 
 
   BYTE byte_to_add = 0; 
   BYTE byte_1      = 0; 
   BYTE byte_2      = 0; 
   BYTE byte_3      = 0; 
 
   DWORD number_of_bytes_encoded = (DWORD) ( (double) number_of_bytes_to_encode / (double) 0.75 ) + 1; 
 
   // Now add in the CR/LF pairs, each line is truncated at 72 characters 
 
   // 2000-05-12 
   // Thanks go to Ilia Golubev (ilia@varicom.co.il) for finding a bug here. 
   // I was using number_of_bytes_to_encode rather than number_of_bytes_encoded. 
 
   number_of_bytes_encoded += (DWORD)( ( ( number_of_bytes_encoded / BASE64_NUMBER_OF_CHARACTERS_PER_LINE ) + 1 ) * 2 ); 
 
   char * destination = destination_string; 
 
   number_of_bytes_encoded = 0; 
 
   while( loop_index < number_of_bytes_to_encode ) 
   { 
      // Output the first byte 
 
      byte_1 = source[ loop_index ]; 
      byte_to_add = alphabet[ ( byte_1 >> 2 ) ]; 
 
      destination[ number_of_bytes_encoded ] = static_cast< TCHAR >( byte_to_add ); 
      number_of_bytes_encoded++; 
 
      loop_index++; 
 
      if ( loop_index >= number_of_bytes_to_encode ) 
      { 
         // We're at the end of the data to encode 
 
         byte_2 = 0; 
         byte_to_add = alphabet[ ( ( ( byte_1 & 0x03 ) << 4 ) | ( ( byte_2 & 0xF0 ) >> 4 ) ) ]; 
 
         destination[ number_of_bytes_encoded ] = byte_to_add; 
         number_of_bytes_encoded++; 
 
         destination[ number_of_bytes_encoded ] =  END_OF_BASE64_ENCODED_DATA; 
         number_of_bytes_encoded++; 
 
         destination[ number_of_bytes_encoded ] =  END_OF_BASE64_ENCODED_DATA; 
 
         // 1999-09-01 
         // Thanks go to Yurong Lin (ylin@dial.pipex.com) for finding a bug here. 
         // We must NULL terminate the string before letting CString have the buffer back. 
 
         destination[ number_of_bytes_encoded + 1 ] = 0; 
 
         return( TRUE ); 
      } 
      else 
      { 
         byte_2 = source[ loop_index ]; 
      } 
 
      byte_to_add = alphabet[ ( ( ( byte_1 & 0x03 ) << 4 ) | ( ( byte_2 & 0xF0 ) >> 4 ) ) ]; 
 
      destination[ number_of_bytes_encoded ] = byte_to_add; 
      number_of_bytes_encoded++; 
 
      loop_index++; 
 
      if ( loop_index >= number_of_bytes_to_encode ) 
      { 
         // We ran out of bytes, we need to add the last half of byte_2 and pad 
         byte_3 = 0; 
 
         byte_to_add = alphabet[ ( ( ( byte_2 & 0x0F ) << 2 ) | ( ( byte_3 & 0xC0 ) >> 6 ) ) ]; 
 
         destination[ number_of_bytes_encoded ] = byte_to_add; 
         number_of_bytes_encoded++; 
 
         destination[ number_of_bytes_encoded ] = END_OF_BASE64_ENCODED_DATA; 
 
         // 1999-09-01 
         // Thanks go to Yurong Lin (ylin@dial.pipex.com) for finding a bug here. 
         // We must NULL terminate the string before letting CString have the buffer back. 
 
         destination[ number_of_bytes_encoded + 1 ] = 0; 
 
         return( TRUE ); 
      } 
      else 
      { 
         byte_3 = source[ loop_index ]; 
      } 
 
      loop_index++; 
 
      byte_to_add = alphabet[ ( ( ( byte_2 & 0x0F ) << 2 ) | ( ( byte_3 & 0xC0 ) >> 6 ) ) ]; 
 
      destination[ number_of_bytes_encoded ] = byte_to_add; 
      number_of_bytes_encoded++; 
 
      byte_to_add = alphabet[ ( byte_3 & 0x3F ) ]; 
 
      destination[ number_of_bytes_encoded ] = byte_to_add; 
      number_of_bytes_encoded++; 
 
      if ( ( number_of_bytes_encoded % BASE64_NUMBER_OF_CHARACTERS_PER_LINE ) == 0 ) 
      { 
         destination[ number_of_bytes_encoded ] = CARRIAGE_RETURN; 
         number_of_bytes_encoded++; 
 
         destination[ number_of_bytes_encoded ] = LINE_FEED; 
         number_of_bytes_encoded++; 
      } 
   } 
 
   destination[ number_of_bytes_encoded ] = END_OF_BASE64_ENCODED_DATA; 
 
   // 1999-09-01 
   // Thanks go to Yurong Lin (ylin@dial.pipex.com) for finding a bug here. 
   // We must NULL terminate the string before letting CString have the buffer back. 
 
   destination[ number_of_bytes_encoded + 1 ] = 0; 
 
   return( TRUE ); 
} 
 
// End of source 
 
#if 0 
 
 
 
WFC - CBase64Coding 
 
 
 
 
 
 

CBase64Coding

$Revision: 14 $

Description

This class gives you the ability to encode/decode data using base64.

Constructors

CBase64Coding()
Constructs this object.

Methods

BOOL Decode( const CByteArray& source, CByteArray& destination ) 
BOOL Decode( const CString&    source, CByteArray& destination )
This method takes base64 encoded text and produces the bytes. It decodes the base64 encoding.
BOOL Encode( const CByteArray& source, CByteArray& destination ) 
BOOL Encode( const CByteArray& source, CString&    destination )
This method takes bytes and turns them into base64 text.

Example

#include <wfc.h> 
 
int _tmain( int number_of_command_line_arguments, LPCTSTR command_line_arguments[] ) 
{ 
   WFCTRACEINIT( TEXT( "_tmain()" ) ); 
 
   CByteArray bytes; 
 
   get_file_contents( command_line_arguments[ 0 ], bytes ); 
 
   CBase64Coding encoder; 
 
   CString encoded_data; 
 
   if ( encoder.Encode( bytes, encoded_data ) != FALSE ) 
   { 
      _tprintf( TEXT( "%s\n", (LPCTSTR) encoded_data ); 
   } 
}

Copyright, 2000, Samuel R. Blackburn
$Workfile: CBase64Coding.cpp $
$Modtime: 5/12/00 3:39p $ #endif