home *** CD-ROM | disk | FTP | other *** search
- /* Xceed Binary Encoding Library - Encode Sample Application
- * Copyright (c) 2001 Xceed Software Inc.
- *
- * [Encode.cpp]
- *
- * This console application shows how to encode a file, using
- * different encoding methods. It specifically demonstrates:
- * - The ReadFile and ProcessFile methods.
- * - The EndOfLineType, MaxLineLength, EncodingFormat,
- * DataFormating, HeaderDataForkLen and HeaderResourceForkLen properties
- * from the various Encoding format interfaces.
- *
- * This file is part of the Xceed Binary Encoding Library sample
- * applications. The source code in this file is only intended as
- * a supplement to Xceed Binary Encoding Library's documentation,
- * and is provided "as is", without warranty of any kind, either
- * expressed or implied.
- */
-
- #include "stdafx.h"
- #include <stdio.h>
- #include <string.h>
- #include <limits.h>
- #include "Encode.h"
-
- //
- // Mapping between command-line and enumeration values
- //
-
- static SEncodingMethod g_pxEncodingMethods[] =
- {
- { "=UU", emUUEncode }, //Default
- { "=XX", emXXEncode },
- { "=Base64", emBase64 },
- { "=Hex", emHexadecimal },
- { "=QP", emQuotedPrintable },
- { "=BHex", emBinHex },
- };
-
-
- //--------------------------------------------------------------------------
- // Entry point of the application
- //--------------------------------------------------------------------------
- int main(int argc, char* argv[])
- {
- // Initializes the COM library on the current thread following the STA model
- CoInitialize( NULL );
-
- try
- {
- // Create an instance of the XceedBinaryEncoding coclass, and
- // use the "I" interface which manipulates byte arrays instead of
- // Variants as the "D" interface does.
- IXceedBinaryEncodingPtr piEncoding;
- piEncoding.CreateInstance( CLSID_XceedBinaryEncoding );
-
- // Two BSTR variables that will contain the Input and Output file names.
- _bstr_t bstrInputFileName;
- _bstr_t bstrOutputFileName;
-
- // Extract the command line parameters and initialize the Encoding
- // instance according to the user specification. After this call
- // the Encoding instance piEncoding is ready to encode.
- if( !ExtractParameters( argc, argv,
- piEncoding,
- bstrInputFileName,
- bstrOutputFileName ) )
- {
- ShowHelp();
- return 1;
- }
-
- if( bstrOutputFileName.length() == 0 )
- {
- // An output file name was not provided by the user.
- // Output the result to the console.
-
- BYTE* pcEncoded = NULL;
- DWORD dwEncodedSize = 0;
- DWORD dwBytesRead = 0;
-
- // Encode by reading a file and sending the output to a buffer.
- // We specify :
- // - The Source filename, without an offset or size, since we want
- // to encode all the source file.
- // - The processing we want to perform, in this case bfpEncode.
- // - The bEndOfData parameter set to TRUE, since we do all the
- // processing in a single block.
- // - The address of a DWORD that will receive the number of bytes
- // actually read from the file.
- // - The address of a BYTE* and a DWORD that will receive the
- // encoded data and its size.
- piEncoding->ReadFile( bstrInputFileName, 0, 0,
- bfpEncode, TRUE,
- &dwBytesRead, &pcEncoded, &dwEncodedSize );
-
- if( pcEncoded )
- {
- // We simply output the encoded data to the console.
- fwrite( pcEncoded, sizeof( BYTE ), dwEncodedSize, stdout );
-
- // Always free the resulting data using the CoTaskMemFree COM API
- // function.
- CoTaskMemFree( pcEncoded );
- }
- }
- else
- {
- // An output file name was provided by the user.
- // Output the result to the specified file
-
- DWORD dwBytesRead = 0;
- DWORD dwBytesWritten = 0;
-
- // Encode by reading a file and sending the output to another file.
- // We specify :
- // - The source filename, without any offset or size, since we want
- // to encode all the source file.
- // - The processing we want to perform, in this case bfpEncode.
- // - The bEndOfData parameter set to TRUE, since we do all the
- // processing in a single block.
- // - The destination filename, with the bAppend parameter set to FALSE
- // since we want to overwrite any existing file.
- // - The address of two DWORD that will receive the number of bytes
- // actually read from the source, and written to the destination.
- piEncoding->ProcessFile( bstrInputFileName, 0, 0,
- bfpEncode, TRUE,
- bstrOutputFileName, FALSE,
- &dwBytesRead, &dwBytesWritten );
-
- printf( "Successfully encoded file %s to file %s\n",
- ( const char* )bstrInputFileName, ( const char* )bstrOutputFileName );
- }
- }
- catch( const _com_error& err )
- {
- // When using the "#import" directive, the compiler generates wrapper classes
- // around all interface types. These wrapper classes throw exceptions when
- // a method call returns an HRESULT which is a failure code.
- printf( "Error %08x: %s\n", err.Error(), ( const char* )err.Description() );
- }
- catch( ... )
- {
- // Catch any other exceptions
- printf( "An unknown error occured.\n" );
- }
-
- // Close the COM library for the current thread
- CoUninitialize();
-
- return 0;
- }
-
- //--------------------------------------------------------------------------
- // Display usage information
- //--------------------------------------------------------------------------
- void ShowHelp()
- {
- // "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
- printf( "Usage: Encode [options] input_file [output_file]\n\n"
- " input_file: the file to be encoded\n"
- " output_file: the destination file\n\n"
- " options: /m=[UU | XX | Base64 | Hex : Encoding method\n"
- " QP | BHex] if omited, default to UU\n"
- " /t=[CrLf | Lf] : End of line type\n"
- " if omited, default to CrLf\n"
- " /l=######### : Maximum line length between ends of line delimiter\n"
- " Can be from 1 to 999999999\n"
- " if omited, default to 78\n"
- " /h or /? : Show this help\n" );
- }
-
- //--------------------------------------------------------------------------
- // Extract commands from the parameters
- //
- // In this function, we call the piEncode interface and let exceptions
- // be caught by the caller.
- // This function returns false if an error occured parsing the command
- // line parameters or if the user requested help.
- //--------------------------------------------------------------------------
- bool ExtractParameters( int argc, char* argv[],
- IXceedBinaryEncodingPtr piEncode,
- _bstr_t& bstrInputFileName,
- _bstr_t& bstrOutputFileName )
- {
- // These variables used to initialize the Encoding format property
- // are set, here, to their default values.
- SEncodingMethod* pxMethod = g_pxEncodingMethods;
- EXBEndOfLineType eEOLType = bltCrLf;
- DWORD dwMaxLineLength = 78;
-
- bool bFound;
-
- // We parse each command line parameter
- int i = 0;
- while( ++i < argc )
- {
- if( argv[ i ][ 0 ] == '/' )
- {
- // The parameter starts with a /
- // Meaning it's an option parameter
- switch( argv[ i ][ 1 ] )
- {
- case 'm':
- case 'M':
- {
- // The user wants to set the encoding method
- bFound = false;
-
- // We go through all the encoding methods in the
- // correspondence table, stopping when we find a
- // match.
- for( pxMethod = g_pxEncodingMethods;
- pxMethod->pszCommandLine != NULL;
- pxMethod++ )
- {
- if( lstrcmpi( argv[ i ] + 2, pxMethod->pszCommandLine ) == 0 )
- {
- bFound = true;
- break;
- }
- }
-
- if( !bFound )
- {
- printf( "Invalid encoding method '%s'\n\n", argv[ i ] );
- return false;
- }
- }
- break;
-
- case 't':
- case 'T':
- // The user wants to set the End of line type
- if( lstrcmpi( argv[ i ] + 2, "=CrLf" ) == 0 )
- {
- eEOLType = bltCrLf;
- }
- else if( lstrcmpi( argv[ i ] + 2, "=Lf" ) == 0 )
- {
- eEOLType = bltLf;
- }
- else
- {
- printf( "Invalid end-of-line type '%s'\n\n", argv[ i ] );
- return false;
- }
-
- break;
-
- case 'l':
- case 'L':
- // The user wants to set the MaxLineLength
- bFound = false;
-
- if( argv[ i ][ 2 ] == '=' )
- {
- char* pcStop;
- DWORD dwLength = strtoul( argv[ i ] + 3, &pcStop, 10 );
-
- if( dwLength != ULONG_MAX )
- {
- dwMaxLineLength = dwLength;
- bFound = true;
- }
- }
-
- if( !bFound )
- {
- printf( "Invalid maximum line length '%s'\n\n", argv[ i ] );
- return false;
- }
-
- break;
-
- default:
- printf( "Unknown command '%s'\n\n", argv[ i ] );
- // Continue
- case 'h':
- case 'H':
- case '?':
- return false;
- }
- }
- }
-
- // Check if the user provided an input file name
- if( argc < 2 || argv[ argc - 1 ][ 0 ] == '/' )
- {
- printf( "You did not specify an input filename\n\n" );
- return false;
- }
- else if( argc < 3 || argv[ argc - 2 ][ 0 ] == '/' )
- {
- // Only an input file was specified
- bstrInputFileName = argv[ argc - 1 ];
- }
- else
- {
- // Both input and output file were specified
- bstrInputFileName = argv[ argc - 2 ];
- bstrOutputFileName = argv[ argc - 1 ];
- }
-
- // According the Encoding method chosen by the user, we set the various
- // properties of an encoding format and prepare the
- // Encoding interface (piEncode).
-
- // The properties common to all encoding format are:
- // EndOfLineType and MaxLineLength
-
- // For each encoding method, we begin by creating a temporary instance
- // of the appropriate Encoding format. The properties of this instance
- // are then set and the instance is assign to the EncodingFormat property
- // of the XceedBinaryEncoding instance. This adds a reference to the
- // Encoding format instance so that the instance will not be freed
- // when it will fall out of scope.
-
- switch( pxMethod->eMethod )
- {
- case emUUEncode :
- {
- IXceedUUEncodingFormatPtr piUUFormat;
-
- piUUFormat.CreateInstance( CLSID_XceedUUEncodingFormat );
- // Set the type of End of line chosen by the user (or the default value).
- piUUFormat->EndOfLineType = eEOLType;
- // Set the maximum line length specified by the user (or the default value).
- piUUFormat->MaxLineLength = dwMaxLineLength;
- // We want the output file to have header and footer
- piUUFormat->IncludeHeaderFooter = TRUE;
- piEncode->EncodingFormat = IXceedEncodeDataPtr( piUUFormat );
- }
- break;
-
- case emXXEncode :
- {
- IXceedXXEncodingFormatPtr piXXFormat;
-
- piXXFormat.CreateInstance( CLSID_XceedXXEncodingFormat );
- piXXFormat->EndOfLineType = eEOLType;
- piXXFormat->MaxLineLength = dwMaxLineLength;
- // We want the output file to have header and footer
- piXXFormat->IncludeHeaderFooter = TRUE;
- piEncode->EncodingFormat = IXceedEncodeDataPtr( piXXFormat );
- }
- break;
-
- case emBase64 :
- {
- IXceedBase64EncodingFormatPtr piBase64Format;
-
- piBase64Format.CreateInstance( CLSID_XceedBase64EncodingFormat );
- piBase64Format->EndOfLineType = eEOLType;
- piBase64Format->MaxLineLength = dwMaxLineLength;
- piEncode->EncodingFormat = IXceedEncodeDataPtr( piBase64Format );
- }
- break;
-
- case emHexadecimal :
- {
- IXceedHexaEncodingFormatPtr piHexaFormat;
-
- piHexaFormat.CreateInstance( CLSID_XceedHexaEncodingFormat );
- piHexaFormat->EndOfLineType = eEOLType;
- piHexaFormat->MaxLineLength = dwMaxLineLength;
- piEncode->EncodingFormat = IXceedEncodeDataPtr( piHexaFormat );
- }
- break;
-
- case emQuotedPrintable :
- {
- IXceedQuotedPrintableEncodingFormatPtr piQuotedPrintableFormat;
-
- piQuotedPrintableFormat.CreateInstance( CLSID_XceedQuotedPrintableEncodingFormat );
- piQuotedPrintableFormat->EndOfLineType = eEOLType;
- piQuotedPrintableFormat->MaxLineLength = dwMaxLineLength;
- piEncode->EncodingFormat = IXceedEncodeDataPtr( piQuotedPrintableFormat );
- }
- break;
-
- case emBinHex :
- {
- // We open a handle on the input file which will be used
- // to get the file's size.
- HANDLE hFic = CreateFile( bstrInputFileName, GENERIC_READ, FILE_SHARE_WRITE & FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL );
-
- if( hFic != INVALID_HANDLE_VALUE )
- {
- IXceedBinHexEncodingFormatPtr piBinHexFormat;
-
- piBinHexFormat.CreateInstance( CLSID_XceedBinHexEncodingFormat );
- piBinHexFormat->EndOfLineType = eEOLType;
- piBinHexFormat->MaxLineLength = dwMaxLineLength;
- // We want the output file to have BinHex formating
- piBinHexFormat->IncludeHeaderFooter = TRUE;
- // The DataForkLen is mandatory and must be set to the size
- // of the data that will be encoded.
- piBinHexFormat->HeaderDataForkLength = GetFileSize( hFic, NULL );
- // The ResourceForkLen, used by MAC system, is not relevant
- // under a PC system. We set it to 0.
- piBinHexFormat->HeaderResourceForkLength = 0;
- piEncode->EncodingFormat = IXceedEncodeDataPtr( piBinHexFormat );
-
- CloseHandle( hFic );
- }
- else
- {
- printf( "Error opening the input filename\n\n" );
- return false;
- }
- }
- break;
- }
-
- return true;
- }
-
-
- //
- // END_OF_FILE
- //
-