home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 September / Chip_2002-09_cd1.bin / zkuste / vbasic / Data / Utils / XZipComp.exe / XceedEncoding.Cab / F112911_Decode.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-05-11  |  12.1 KB  |  350 lines

  1. /* Xceed Binary Encoding Library - Decode Sample Application
  2.  * Copyright (c) 2001 Xceed Software Inc.
  3.  *
  4.  * [Decode.cpp]
  5.  *
  6.  * This console application shows how to decode a file, encoded using
  7.  * different methods. It specifically demonstrates:
  8.  *  - The ReadFile and ProcessFile methods.
  9.  *  - The ContinueOnInvalidData, DataFormating and EncodingFormat properties.
  10.  *
  11.  * This file is part of the Xceed Binary Encoding Library sample 
  12.  * applications. The source code in this file is only intended as 
  13.  * a supplement to Xceed Binary Encoding Library's documentation, 
  14.  * and is provided "as is", without warranty of any kind, either 
  15.  * expressed or implied. 
  16.  */
  17.  
  18. #include "stdafx.h"
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <limits.h>
  22. #include "Decode.h"
  23.  
  24. //
  25. // Mapping between command-line and enumeration values
  26. //
  27.  
  28. static SEncodingMethod g_pxEncodingMethods[] = 
  29. {
  30.   { "=UU",      emUUEncode },    //Default
  31.   { "=XX",      emXXEncode },
  32.   { "=Base64",  emBase64 },
  33.   { "=Hex",     emHexadecimal },
  34.   { "=QP",      emQuotedPrintable },
  35.   { "=BHex",    emBinHex },
  36. };
  37.  
  38.  
  39. //--------------------------------------------------------------------------
  40. // Entry point of the application
  41. //--------------------------------------------------------------------------
  42. int main(int argc, char* argv[])
  43. {
  44.   // Initializes the COM library on the current thread following the STA model
  45.   CoInitialize( NULL );
  46.  
  47.   try
  48.   {
  49.     // Create an instance of the XceedBinaryEncoding coclass, and
  50.     // use the "I" interface which manipulates Byte array instead of
  51.     // Variants as the "D" interface does.
  52.     IXceedBinaryEncodingPtr piEncoding;
  53.     piEncoding.CreateInstance( CLSID_XceedBinaryEncoding );
  54.  
  55.     // Two BSTR variables that will contain the Input and Output file names.
  56.     _bstr_t bstrInputFileName;
  57.     _bstr_t bstrOutputFileName;
  58.   
  59.     // Extract the command line parameters and initialize the Encoding 
  60.     // instance according to the user specification. After this call
  61.     // the Encoding instance piEncoding is ready to decode.
  62.     if( !ExtractParameters( argc, argv, 
  63.                             piEncoding, 
  64.                             bstrInputFileName, 
  65.                             bstrOutputFileName ) )
  66.     {
  67.       ShowHelp();
  68.       return 1;
  69.     }
  70.  
  71.     if( bstrOutputFileName.length() == 0 )
  72.     {
  73.       // An output file name was not provided by the user.
  74.       // Output the result to the console
  75.  
  76.       BYTE* pcDecoded     = NULL;
  77.       DWORD dwDecodedSize = 0;
  78.       DWORD dwBytesRead   = 0;
  79.  
  80.       // Decode by reading a file and sending the output to a buffer.
  81.       // We specify :
  82.       //  - The Source filename, without an offset or size, since we want
  83.       //    to decode all the source file.
  84.       //  - The processing we want to perform, in this case bfpDecode.
  85.       //  - The bEndOfData parameter set to TRUE, since we do all the
  86.       //    processing in a single block.
  87.       //  - The address of a DWORD that will receive the number of bytes 
  88.       //    actually read from the file.
  89.       //  - The address of a BYTE* and a DWORD that will receive the 
  90.       //    decoded data and its size.
  91.       piEncoding->ReadFile( bstrInputFileName, 0, 0, 
  92.                             bfpDecode, TRUE, 
  93.                             &dwBytesRead, &pcDecoded, &dwDecodedSize );
  94.  
  95.       if( pcDecoded )
  96.       {
  97.         // We simply output the decoded data to the console.
  98.         fwrite( pcDecoded, sizeof( BYTE ), dwDecodedSize, stdout );
  99.  
  100.         // Always free the resulting data using the CoTaskMemFree COM API 
  101.         // function.
  102.         CoTaskMemFree( pcDecoded );
  103.       }
  104.     }
  105.     else
  106.     {
  107.       // An output file name was provided by the user.
  108.       // Output the result to the specified file
  109.  
  110.       DWORD dwBytesWritten  = 0;
  111.       DWORD dwBytesRead     = 0;
  112.  
  113.       // Decode by reading a file and sending the output to another file.
  114.       // We specify :
  115.       //  - The source filename, without any offset or size, since we want
  116.       //    to decode all the source file.
  117.       //  - The processing we want to perform, in this case bfpDecode.
  118.       //  - The bEndOfData parameter set to TRUE, since we do all the
  119.       //    processing in a single block.
  120.       //  - The destination filename, with the bAppend parameter set to FALSE
  121.       //    since we want to overwrite any existing file.
  122.       //  - The address of two DWORD that will receive the number of bytes
  123.       //    actually read from the source, and written to the destination.
  124.       piEncoding->ProcessFile( bstrInputFileName, 0, 0, 
  125.                                bfpDecode, TRUE, 
  126.                                bstrOutputFileName, FALSE, 
  127.                                &dwBytesRead, &dwBytesWritten );
  128.  
  129.       printf( "Successfully decoded file %s to file %s\n", 
  130.               ( const char* )bstrInputFileName, ( const char* )bstrOutputFileName );
  131.     }
  132.   }
  133.   catch( const _com_error& err )
  134.   {
  135.     // When using the "#import" directive, the compiler generates wrapper classes
  136.     // around all interface types. These wrapper classes throw exceptions when
  137.     // a method call returns an HRESULT which is a failure code.
  138.     printf( "Error %08x: %s\n", err.Error(), ( const char* )err.Description() );
  139.   }
  140.   catch( ... )
  141.   {
  142.     // Catch any other exceptions
  143.     printf( "An unknown error occured.\n" );
  144.   }
  145.  
  146.   // Close the COM library for the current thread
  147.   CoUninitialize();
  148.  
  149.   return 0;
  150. }
  151.  
  152. //--------------------------------------------------------------------------
  153. // Display usage information
  154. //--------------------------------------------------------------------------
  155. void ShowHelp()
  156. {
  157.   //      "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
  158.   printf( "Usage: Decode [options] input_file [output_file]\n\n"
  159.           "  input_file: the file to be decoded\n"
  160.           "  output_file: the destination file\n\n"
  161.           "  options: /m=[UU | XX | Base64 | Hex : Encoding method\n"
  162.           "               QP | BHex]               if omited, default to UU\n"
  163.           "           /i : Continue on invalid data\n"
  164.           "                if omitted, will stop at the first invalid data\n"
  165.           "           /h or /? : Show this help\n" );
  166. }
  167.  
  168. //--------------------------------------------------------------------------
  169. // Extract commands from the parameters
  170. // In this function, we call the piEncode interface and let exceptions
  171. // be caught by the caller.
  172. // This function returns false if an error occured parsing the command
  173. // line parameters or if the user requested help.
  174. //--------------------------------------------------------------------------
  175. bool ExtractParameters( int argc, char* argv[],
  176.                         IXceedBinaryEncodingPtr piDecode, 
  177.                         _bstr_t& bstrInputFileName,
  178.                         _bstr_t& bstrOutputFileName )
  179. {
  180.   // These variables used to initialize the Encoding format property
  181.   // are set, here, to their default values.
  182.   SEncodingMethod*  pxMethod = g_pxEncodingMethods;
  183.   bool              bContinueOnInvalidData = false;
  184.  
  185.   bool bFound;
  186.  
  187.   int i = 0;
  188.  
  189.   // We parse each command line parameter
  190.   while( ++i < argc )
  191.   {
  192.     if( argv[ i ][ 0 ] == '/' )
  193.     {
  194.       // The parameter starts with a /
  195.       // Meaning it's an option parameter
  196.       switch( argv[ i ][ 1 ] )
  197.       {
  198.         case 'm':
  199.         case 'M':
  200.           // The user wants to set the encoding method
  201.           bFound = false;
  202.  
  203.           // We go through all the encoding methods in the 
  204.           // correspondence table, stopping when we find a 
  205.           // match.
  206.           for( pxMethod = g_pxEncodingMethods;
  207.                pxMethod->pszCommandLine != NULL;
  208.                pxMethod++ )
  209.           {
  210.             if( lstrcmpi( argv[ i ] + 2, pxMethod->pszCommandLine ) == 0 )
  211.             {
  212.               bFound = true;
  213.               break;
  214.             }
  215.           }
  216.  
  217.           if( !bFound )
  218.           {
  219.             printf( "Invalid encoding method '%s'\n\n", argv[ i ] );
  220.             return false;
  221.           }
  222.  
  223.           break;
  224.  
  225.         case 'i':
  226.         case 'I':
  227.           // The user wants to continue decoding if invalid data are found
  228.           bContinueOnInvalidData = true;
  229.           break;
  230.  
  231.         default:
  232.           printf( "Unknown command '%s'\n\n", argv[ i ] );
  233.           // Continue
  234.         case 'h':
  235.         case 'H':
  236.         case '?':
  237.           return false;
  238.       }
  239.     }
  240.   }
  241.  
  242.   // Check if the user provided an input file name
  243.   if( argc < 2 || argv[ argc - 1 ][ 0 ] == '/' )
  244.   {
  245.     printf( "You did not specify an input filename\n\n" );
  246.     return false;
  247.   }
  248.   else if( argc < 3 || argv[ argc - 2 ][ 0 ] == '/' )
  249.   {
  250.     // Only an input file was specified
  251.     bstrInputFileName = argv[ argc - 1 ];
  252.   }
  253.   else
  254.   {
  255.     // Both input and output file were specified
  256.     bstrInputFileName   = argv[ argc - 2 ];
  257.     bstrOutputFileName  = argv[ argc - 1 ];
  258.   }
  259.  
  260.   // According the Encoding method chosen by the user, we set the various 
  261.   // properties of an encoding format and prepare the 
  262.   // Encoding interface (piDecode).
  263.  
  264.   // The properties common to all encoding format are:
  265.   // ContinueOnInvalidData
  266.  
  267.   // For each encoding method, we begin by creating a temporary instance 
  268.   // of the appropriate Encoding format. The properties of this instance
  269.   // are then set and the instance is assign to the EncodingFormat property
  270.   // of the XceedBinaryEncoding instance. This adds a reference to the 
  271.   // Encoding format instance so that the instance will not be freed
  272.   // when it will fall out of scope.
  273.  
  274.   switch( pxMethod->eMethod )
  275.   {
  276.     case emUUEncode :
  277.       {
  278.         IXceedUUEncodingFormatPtr piUUFormat;
  279.         
  280.         piUUFormat.CreateInstance( CLSID_XceedUUEncodingFormat );
  281.         piUUFormat->ContinueOnInvalidData = bContinueOnInvalidData ? TRUE : FALSE;
  282.         // The input file has header and footer
  283.         piUUFormat->IncludeHeaderFooter = TRUE;
  284.         piDecode->EncodingFormat = IXceedEncodeDataPtr( piUUFormat );
  285.       }
  286.       break;
  287.  
  288.     case emXXEncode :
  289.       {
  290.         IXceedXXEncodingFormatPtr piXXFormat;
  291.         
  292.         piXXFormat.CreateInstance( CLSID_XceedXXEncodingFormat );
  293.         piXXFormat->ContinueOnInvalidData = bContinueOnInvalidData ? TRUE : FALSE;
  294.         // The input file has header and footer
  295.         piXXFormat->IncludeHeaderFooter = TRUE;
  296.         piDecode->EncodingFormat = IXceedEncodeDataPtr( piXXFormat );
  297.       }
  298.       break;
  299.  
  300.     case emBase64 :
  301.       {
  302.         IXceedBase64EncodingFormatPtr piBase64Format;
  303.         
  304.         piBase64Format.CreateInstance( CLSID_XceedBase64EncodingFormat );
  305.         piBase64Format->ContinueOnInvalidData = bContinueOnInvalidData ? TRUE : FALSE;
  306.         piDecode->EncodingFormat = IXceedEncodeDataPtr( piBase64Format );
  307.       }
  308.       break;
  309.  
  310.     case emHexadecimal :
  311.       {
  312.         IXceedHexaEncodingFormatPtr piHexaFormat;
  313.         
  314.         piHexaFormat.CreateInstance( CLSID_XceedHexaEncodingFormat );
  315.         piHexaFormat->ContinueOnInvalidData = bContinueOnInvalidData ? TRUE : FALSE;
  316.         piDecode->EncodingFormat = IXceedEncodeDataPtr( piHexaFormat );
  317.       }
  318.       break;
  319.  
  320.     case emQuotedPrintable :
  321.       {
  322.         IXceedQuotedPrintableEncodingFormatPtr piQuotedPrintableFormat;
  323.         
  324.         piQuotedPrintableFormat.CreateInstance( CLSID_XceedQuotedPrintableEncodingFormat );
  325.         piQuotedPrintableFormat->ContinueOnInvalidData = bContinueOnInvalidData ? TRUE : FALSE;
  326.         piDecode->EncodingFormat = IXceedEncodeDataPtr( piQuotedPrintableFormat );
  327.       }
  328.       break;
  329.  
  330.     case emBinHex :
  331.       {
  332.         IXceedBinHexEncodingFormatPtr piBinHexFormat;
  333.  
  334.         piBinHexFormat.CreateInstance( CLSID_XceedBinHexEncodingFormat );
  335.         piBinHexFormat->ContinueOnInvalidData = bContinueOnInvalidData ? TRUE : FALSE;
  336.         // The input file has header and footer
  337.         piBinHexFormat->IncludeHeaderFooter = TRUE;
  338.         piDecode->EncodingFormat = IXceedEncodeDataPtr( piBinHexFormat );
  339.       }
  340.       break;
  341.   }
  342.  
  343.   return true;
  344. }
  345.  
  346.  
  347. //
  348. // END_OF_FILE
  349. //
  350.