::: nefzger dot at :::
    You are here: Pfeil //nefzger.at/~SoffyT/encoderdecoder.html

~/~SoffyT
Software:
    Pfeil ed
    Pfeil nf
    Pfeil gh
    Pfeil vg

Kontakt:
    Pfeil eMail


~/~MNe
Software:
    Pfeil IPing
    Pfeil IGrep
    Pfeil MaskMove
    Pfeil Puzzle
    Pfeil ZoomIn!

Kontakt:
    Pfeil eMail


~/
Links:
    Pfeil rOOt
    Pfeil Site History
    Pfeil Impressum

Kontakt:
    Pfeil eMail


What Is It?
What Is It?

Link List
Link List


Site Map
Site Map


search ::: nefzger dot at :::

powered by FreeFind
get notified of updates
?
powered by ChangeDetection

TRIANGLE productions
www.triangle.at

Ultima Online Portal
ultima.gatecentral.com

Free Website Promotion & Search Engine Submission
www.addpro.com



Site Stats
Site Stats

-- gh (-G-enerate -H-tml) v1.91 -- Copyright (c) 2002, 2005 SoffyT & MNe --

[ Abstrakt | Über Kodierungen | Das Programm 'ed' | Download | Kontakt ]

^ Abstrakt:

^ Über Kodierungen:

^ Das Programm 'ed':

Der Compilerlauf:

~~
~~ brcc32 ed.verinfo.rc -foed.verinfo.res
~~ dcc32 -B -CC -GD -H -W -$A+ -$B- -$C- -$D- -$L- -$Y- -$H+ 
-$I- -$J- -$O+ -$Q- -$R- -$T- -$U+ -$W- -$X+ -$Z4 ed.dpr
~~
Borland Delphi  Version 13.0  Copyright (c) 1983,99 Inprise Corporation
O:\Marcus\mne_Testverzeichnis\core_utilities\CmdLine_Utilities.pas(182)
O:\Marcus\mne_Testverzeichnis\core_utilities\Misc_Utilities.pas(1054)
O:\Marcus\mne_Testverzeichnis\core_utilities\String_Utilities.pas(121)
O:\Marcus\mne_Testverzeichnis\core_classes\Defs.pas(110)
O:\Marcus\mne_Testverzeichnis\core_classes\EncoderDecoder.pas(1159)
ed.dpr(249)
2881 Zeilen, 0.39 Sekunden, 67648 Bytes Code, 4281 Bytes Daten.

Der Quelltext der Projektdatei ('ed.dpr', 16.960 Byte):

(*
 *                                                                                             .
 * Module name: ed.dpr; Module type: Delphi (console) project; Language: Object pascal;        .
 * Original developed with: Delphi 5 Enterprise; Portability: most likely down to Delphi 2;    .
 *                                                                                             .
 * Author: ~SoffyT (web:<http://www.nefzger.at/~SoffyT/>; mailto:<MissyQueen@nefzger.at>)      .
 * File created: Fri., 01.11.2002; Last modified: Thu., 07.10.2004                             .
 *                                                                                             .
 * Bug report: Report all bugs, wishes, suggestions etc. to <BugReport@nefzger.at>.            .
 *                                                                                             .
 *  Purpose:                                                                                   .
 * ----------                                                                                  .
 *    Console wrapper for EncoderDecoder.pas                                                   .
 *                                                                                             .
 *)
{$APPTYPE Console}
program
   EncDec; // AKA 'ed' or 'ed.dpr'                                                             .
uses
   Windows,
   SysUtils,
   CmdLine_Utilities in '..\core_utilities\CmdLine_Utilities.pas',
   Misc_Utilities    in '..\core_utilities\Misc_Utilities.pas',
   String_Utilities  in '..\core_utilities\String_Utilities.pas',
   Defs              in '..\core_classes\Defs.pas',
   EncoderDecoder    in '..\core_classes\EncoderDecoder.pas';
// -- Programm- & Versions-Info -------------------------------                                .
{$R 'ed.verinfo.res'}          // generiert mit VerGen.exe Copyright (c) 2002, 2004 ~MNe :-)   .
var
   Program_name : String;
   CmdLine_ok   : Integer;
// ------------------------------------------------------------                                .
{$I 'ed.clipboard.inc'}
var
   ed_A    : TEncoderDecoder_Action; // Aktion: Encode / Decode ?                              .
   ed_C    : TEncoderDecoder_Coding; // Kodierung: Base64 / UU / XX ?                          .
   F_in    : String;                 // Input Dateiname                                        .
   F_out   : String;                 // Output Dateiname                                       .
   F_dout  : Boolean;                // Output Datei(name) löschen, wenn vorhanden             .
   ed      : TEncoderDecoder;        // Arbeitsklasse                                          .
   ed_erg  : Integer;                // Ergebnis der geforderten Operation                     .
   ed_size : Integer;
// ============================================================================                .
begin try
   // Vorspann                                                                                 .
   Program_name := appGetApplicationFileName();
   CmdLine_ok := GetFirstInvalidSwitch(
      CheckCmdLineSwitches(  // Kommandozeile auswerten #1, "Lang-Form" ..                     .
         ['version','history',
          'quiet',
          'encode','decode',
          'base64','uu','uuspace','xx',
          'input-file','output-file',
          'force'],
         ['-'],
         [False,False,
          False,
          False,False,
          False,False,False,False,
          True,True,
          False],
         True),
      CheckCmdLineSwitches(  // Kommandozeile auswerten #2, "Kurz-Form" ..                     .
         ['v','h',
          'q',
          'e','d',
          'b','u','u2','x',
          'i','o',
          'f'],
         ['-','/'],
         [False,False,
          False,
          False,False,
          False,False,False,False,
          True,True,
          False]
         {,False}));
   WriteLn;
   WriteLn(Program_name,' -- ',resGetXVersionInfo(),', ',resGetXReleaseInfo(),', ',
      resGetXDateTimeInfo());
   Writeln(StringOfChar(' ',Length(Program_name)),' -- ',resGetXCopyrightInfo());
   WriteLn(StringOfChar(' ',Length(Program_name)),' -- ','(dbg) OS: ',
      sysGetWin32Version().w32ComposedName,'; CmdLineCnt: ',ParamCount(),'; CmdLineErg: ',
      CmdLine_ok);
   // Kommandozeile auswerten                                                                  .
   WriteLn;
   // Parameter für 'Aktion' (Enkodieren | Dekodieren) auswerten ...                           .
   if ((CmdLineSwitch('e',['-','/'],False) > 0) or
       (CmdLineSwitch('encode',['-'],False,True) > 0)) then
      ed_A := eda_ENCODE
   else if ((CmdLineSwitch('d',['-','/'],False) > 0) or
            (CmdLineSwitch('decode',['-'],False,True) > 0)) then
      ed_A := eda_DECODE
   else
      ed_A := eda_NONE;
   // Parameter für 'Modus' (Base64 | UU | UUSpace | XX) auswerten ...                         .
   if ((CmdLineSwitch('b',['-','/'],False) > 0) or
       (CmdLineSwitch('base64',['-'],False,True) > 0)) then
      ed_C := edc_BASE64
   else if ((CmdLineSwitch('u',['-','/'],False) > 0) or
            (CmdLineSwitch('uu',['-'],False,True) > 0)) then
      ed_C := edc_UU
   else if ((CmdLineSwitch('u2',['-','/'],False) > 0) or
            (CmdLineSwitch('uuspace',['-'],False,True) > 0)) then
      ed_c := edc_UUSPACE
   else if ((CmdLineSwitch('x',['-','/'],False) > 0) or
            (CmdLineSwitch('xx',['-'],False,True) > 0)) then
      ed_C := edc_XX
   else
      ed_C := edc_NONE;
   // Parameter -i | --input-file: input file name | RESERVED_CLIPBOARD                        .
   F_in := ParamBySwitch('i',['-','/'],True);
   if (F_in = '') then  // Parameter nicht gefunden oder kein Wert; lange Version versuchen    .
      F_in := ParamBySwitch('input-file',['-'],True,True);
   if ((F_in = '') and (ed_A = eda_DECODE)) then // immer noch kein Wert?                      .
      F_in := RESERVED_CLIPBOARD;                // wenn *eda_DECODE* auf 'Clipboard' setzen   .
   // Parameter --o | --output-file: output file name | RESERVED_CLIPBOARD                     .
   F_out := ParamBySwitch('o',['-','/'],True);
   if (F_out = '') then // Parameter nicht gefunden oder kein Wert; lange Version versuchen    .
      F_out := ParamBySwitch('output-file',['-'],True,True);
   if ((F_out = '') and (ed_A = eda_ENCODE)) then // immer noch kein Wert?                     .
      F_out := RESERVED_CLIPBOARD;                // wenn *eda_ENCODE* auf 'Clibboard' setzen  .
   // Flag für 'Ausgabedatei überschreiben, wenn diese existiert'                              .
   F_dout := ((CmdLineSwitch('f',['-','/'],False) > 0) or
              (CmdLineSwitch('force',['-'],False,True) > 0));
   // Parameter prüfen & Programm durchführen ..                                               .
   if (CmdLine_ok = CMDLINE_VALID) and
      ((ParamCount = 1) and ((CmdLineSwitch('v',['-','/'],False) > 0) or
                             (CmdLineSwitch('version',['-'],False,True) > 0))) then begin
      // Parameter '--version': keine weiteren Informationen anzeigen ..                       .
      ;
   end else if (CmdLine_ok = CMDLINE_VALID) and
               ((ParamCount = 1) and ((CmdLineSwitch('h',['-','/'],False) > 0) or
                                      (CmdLineSwitch('history',['-'],False,True) > 0))) then begin
      // Parameter '--history': (als Resource gelinkte) History anzeigen ..                    .
      WriteLn(resGetXHistoryInfo());
   end else if (CmdLine_ok = CMDLINE_VALID) and
               ((ParamCount = 4) or ((ParamCount = 5) and F_dout)) and
               ((ed_A <> eda_NONE) and (ed_C <> edc_NONE) and
                (F_in <> '') and (F_out <> '')) then begin
      // Kommandozeile sieht richtig aus für die "normale" Benutzung ..                        .
      if (FileExists(F_in)) or
         ((ed_A = eda_DECODE) and (LowerCase(F_in) = RESERVED_CLIPBOARD)) then begin
         if (ed_C = edc_BASE64) then
            ed := TBase64EncoderDecoder.Create()    // bei Base64: keine weiteren Optionen     .
         else if ((ed_C = edc_UU) or (ed_C = edc_UUSPACE)) then begin
            TUUEncoderDecoder.SetUUSpaceCoding(ed_C = edc_UUSPACE);
            ed := TUUEncoderDecoder.Create();
            TUUEncoderDecoder(ed).FileMode := 644;  // <- "Just in case": bei Aktion "decode"  .
            TUUEncoderDecoder(ed).FileName := F_in; // werden diese aus der Datei-Info gesetzt .
         end else if (ed_C = edc_XX) then begin
            ed := TXXEncoderDecoder.Create();
            TXXEncoderDecoder(ed).FileMode := 644;  // <- "Just in case": bei Aktion "decode"  .
            TXXEncoderDecoder(ed).FileName := F_in; // werden diese aus der Datei-Info gesetzt .
         end else
            ed := NIL;
         if (ed <> NIL) then begin
            ed_size := 0;
            if (ed_A = eda_ENCODE) then begin
               ed_erg := ed.LoadFileData(F_in);
               if (ed_erg >= ERROR_SUCCESS) then begin
                  WriteLn('Data loaded. Guessing encoded file size: ',
                     fmtFormatNumber((1.0*ed.GuessEncodedSize),0),' octets.');
                  ed_erg := ed.Encode();
                  if (ed_erg >= ERROR_SUCCESS) then begin
                     ed_size := ed.Result; // # Bytes merken                                   .
                     if (LowerCase(F_out) = RESERVED_CLIPBOARD) then
                        ed_erg := ed.SaveTextData() // <- to the clipboard                     .
                     else begin
                        if ((FileExists(F_out)) and (F_dout)) then
                           helperSafeDeleteFile(F_out);
                        ed_erg := ed.SaveTextData(F_out); // <- to file 'F_out'                .
                     end;
                  end;
               end;
               if (ed_erg >= ERROR_SUCCESS) then
                  WriteLn('Success: Encoded ''',F_in,''' to ''',F_out,''', ',
                     fmtFormatNumber((1.0*ed_size),0),' octets written.')
               else
                  WriteLn('Failure: ',TEncoderDecoder.ErrorCodeToStr(ed_erg),'.');
            end else if (ed_A = eda_DECODE) then begin
               if (LowerCase(F_in) = RESERVED_CLIPBOARD) then
                  ed_erg := ed.LoadTextData() // <- from the clipboard                         .
               else
                  ed_erg := ed.LoadTextData(F_in); // <- from file 'F_in'                      .
               if (ed_erg >= ERROR_SUCCESS) then begin
                  WriteLn('Data loaded. Guessing decoded file size: ',
                     fmtFormatNumber((1.0*ed.GuessDecodedSize),0),' bytes.');
                  Write('             Guessing coding type (will *NOT* override switch): ');
                  if (LowerCase(F_in) = RESERVED_CLIPBOARD) then // <- from the clipboard      .
                     WriteLn('Sorry! This function has no clipoard support!')
                  else
                     case ed.GuessEncoding(F_in) of // <- from file 'F_in'                     .
                        edc_BASE64  : WriteLn('base64');
                        edc_UU      : WriteLn('uu');
                        edc_UUSPACE : WriteLn('uuspace');
                        edc_XX      : WriteLn('xx');
                        else          WriteLn('can''t determine.');
                     end;
                  ed_erg := ed.Decode();
                  if (ed_erg >= ERROR_SUCCESS) then begin
                     ed_size := ed.Result; // # Bytes merken                                   .
                     if ((FileExists(F_out)) and (F_dout)) then
                        helperSafeDeleteFile(F_out);
                     ed_erg := ed.SaveFileData(F_out);
                  end;
               end;
               if (ed_erg >= ERROR_SUCCESS) then
                  WriteLn('Success: Decoded ''',F_in,''' to ''',F_out,''', ',
                     fmtFormatNumber((1.0*ed_size),0),' bytes written.')
               else
                  WriteLn('Failure: ',TEncoderDecoder.ErrorCodeToStr(ed_erg),'.');
            end else
               WriteLn('Failure: internal failure.');
            FreeAndNil(ed);
         end else
            WriteLn('Failure: internal failure.');
      end else
         WriteLn('Failure: "',F_in,'" can not be found.');
   end else begin
      // Ungültigen Parameter / Schalter gefunden? -> Ausgabe desjenigen welchen ..            .
      if ((CmdLine_ok <> CMDLINE_VALID) or
          (ParamCount() > 0)) then begin
         if (CmdLine_ok <> CMDLINE_VALID) then
            WriteLn('Sorry! Unknown switch: ','''',ParamStr(CmdLine_ok),'''','.')
         else
            WriteLn('Sorry! Unknown or unsupported parameter: ',
               '''',ParamStr(ParamCount()),'''','.');
         WriteLn;
      end;
      // Angegebene Kommandozeile war wohl niX .. Usage-Meldung ausgeben ..                    .
      WriteLn('Usage: ',Program_name,' [[-e|--encode]|[-d|--decode]] [[-b|--bas' +
         'e64]|[-u|--uu]|[-u2|--uuspace]|[-x|x-xx]] [-i|--input-file[<InputFile' +
         '>]] [-o|--output-file[<OutputFile>]] {-f|--force} | {-h|--history}');
      WriteLn;
      writeln(' e.g.: ',Program_name,' -e -b -iFoo.jpg -oBar.txt');
      writeln('     = ',Program_name,' --encode --base64 --input-fileFoo.jpg --' +
         'output-fileBar.txt');
      WriteLn('          (this will encodcode ''Foo.jpg'' to ''Bar.txt'' using ' +
         'base64 coding)');
      WriteLn;
      writeLn(' e.g.: ',Program_name,' -d -u -iBar.uue -oFoo.bin');
      writeLn('     = ',Program_name,' --decode --uu --input-fileBar.uue --outp' +
         'ut-fileFoo.bin');
      WriteLn('          (this will decode ''Foo.bin'' from ''Bar.uue'' using U' +
         'U coding)');
      WriteLn;
      WriteLn('  -e,  /e,  --encode       Encode input file to output file (tha' +
         't is: bin -> text).');
      WriteLn('  -d,  /d,  --decode       Decode input file to output file (tha' +
         't is: text -> bin).');
      WriteLn('  -b,  /b,  --base64       Use BASE64 for encoding/ decoding (oc' +
         'curence: very common).');
      WriteLn('  -u,  /u,  --uu           Use UU for encoding/ decoding (occure' +
         'nce: rare).');
      WriteLn('  -u2, /u2, --uuspace      Use UU-Space for encoding/ decoding (' +
         'occurence: more rare).');
      WriteLn('  -x,  /x,  --xx           Use XX for encoding/ decoding (occure' +
         'ce: very rare).');
      WriteLn('  -i,  /i,  --input-file   Name of input file.');
      WriteLn('  -o,  /o,  --output-file  Name of output file.');
      WriteLn('  -f,  /f,  --force        Force overwriting output file.');
      WriteLn('  -v,  /v,  --version      Display version number only.');
      WriteLn('  -h,  /h,  --history      Display program & version history.');
      WriteLn('  -q,  /q,  --quiet        Quiet: no additional output. (Unimple' +
         'mented by now.)');
      WriteLn;
      WriteLn('Hint(s): Parameters enclosed in ''[]'' are mandatory; parameters' +
         ' enclosed in ''{}'' are optional; parameters seperated by ''|'' exclu' +
         'de each other; ''<..>'' within a parameter means that *you* have to s' +
         'upply additional information.');
      WriteLn;
      WriteLn('Note(s): If <OutputFile> exists, the program will fail, as it wi' +
         'll *NOT* overwrite existing files. Use {--force} to indicate that you' +
         ' know what you are doing and to override this behavior (e.g. for use ' +
         'in a batch).');
      WriteLn;
      WriteLn('Clipboard support: if mode is --encode, then --output-file may b' +
         'e ''$clpbrd$''; if mode is --decode, then --input-file may be ''$clpb' +
         'rd$''; in either case, the program will write/ read the (text) data t' +
         'o/ from the windows clipboard, respectively.');
      WriteLn;
      WriteLn('Bug report: Pls. report all bug(s) and/ or wishes, suggestions e' +
         'tc. to <BugReport@nefzger.at>, including the module name (which is: ''',
         Program_name,''') and module version (which is: ''',resGetXVersionInfo(),
         '''). Thank you.');
   end;
   Halt(0); // Normales Programmende                                                           .
except
   on e: Exception do begin
      WriteLn(' Fatal: Exception: ','''',e.Message,'''','; pls. contact the pro' +
         'grammer: <BugReport@nefzger.at>.');
      Halt(1); // Abnormales Programmende: irgendwo wurde (intern) eine Exception geworfen ..  .
   end;
end; {try} end. // {begin}                                                                     .

Der Quelltext der Klasse TEncoderDecoder ('encoderdecoder.pas', 74.546 Byte):

(*
 *                                                                                             .
 * Module name: EncoderDecoder.pas; Module type: Delphi unit; Language: Object pascal;         .
 * Original developed with: Delphi 5 Enterprise; Portability: most likely down to Delphi 2;    .
 *                                                                                             .
 * Author: Marcus F. Nefzger AKA MNe (web:<http://www.nefzger.at/>; mailto:<MNe@nefzger.at>)   .
 * File created: Fri., 01.11.2002; Last modified: Thu., 03.07.2003                             .
 *                                                                                             .
 * Bug report: Report all bugs, wishes, suggestions etc. to <BugReport@nefzger.at>.            .
 *                                                                                             .
 *  Purpose:                                                                                   .
 * ----------                                                                                  .
 *    Provides classes for encoding binary data in such a way that they can be transmitted     .
 * savely over a character-only network transmission (e.g. via the mail service) and can be    .
 * decoded to it's original form.                                                              .
 *                                                                                             .
 *  Implemented classes:                                                                       .
 * ----------------------                                                                      .
 *    TEncoderDecoder { = class (TObject) }   .. (abstract basis class ~ do not instance)      .
 *    TEncoderDecoder2 { = class (TObject) }  .. (abstract basis class ~ do not instance)      .
 *    TBase64EncoderDecoder { = class (TEncoderDecoder) }  .. Base64 Encoder/ Decoder          .
 *    TUUEncoderDecoder { = class (TEncoderDecoder2) }     .. UU Encoder/ Decoder              .
 *    TXXEncoderDecoder { = class (TEncoderDecoder2) }     .. XX Encoder/ Decoder              .
 *                                                                                             .
 *)
unit
   EncoderDecoder;
// ----------                                                                                  .
   interface
// ----------                                                                                  .
uses
   Classes,
   Defs;
   (*
    * Die nachfolgenden beiden 'Flags' werden intern nicht verwendet                           .
    * und sind hauptsächlich zur Verwendung in einem Programm gedacht,                         .
    * in welchem die EncoderDecoder-Klassen Verwendung finden.                                 .
    *)
type
   TEncoderDecoder_Action
      = (eda_NONE,         // nicht zugewiesen                                                 .
         eda_ENCODE,       // Kodieren (Binär -> Text)                                         .
         eda_DECODE);      // Dekodieren (Text -> Binär                                        .
   TEncoderDecoder_Coding
      = (edc_NONE,         // nicht zugewiesen                                                 .
         edc_BASE64,       // Base64 Kodierung                                                 .
         edc_UU,           // UU Kodierung                                                     .
         edc_UUSPACE,      // UU-Space Kodierung                                               .
         edc_XX);          // XX Kodierung                                                     .
const
   CODE_BITS        = 6;                     // Abbildung ist (3*8) Bit auf (4*6) Bit          .
   CODE_BYTE_MASK   = ((1 shl CODE_BITS)-1); // die zugehörige Bitmaske                        .
   MAX_CODE_VALUE   = CODE_BYTE_MASK;        // --"-- ditto, nur unter anderem Namen bekannt   .
type
   PByteToCharTable = ^TByteToCharTable;
   TByteToCharTable = packed array [0..MAX_CODE_VALUE] of Char;
   PCharToByteTable = ^TCharToByteTable;
   TCharToByteTable = packed array [Char] of Byte;
type
   PLineSourceTable = ^TLineSourceTable;
   TLineSourceTable = packed array [Byte] of Byte;
   PLineResultTable = ^TLineResultTable;      // Sehen zwar irgenwie alle ziemlich gleich aus, .
   TLineResultTable = packed array [Byte] of Char;  // aber bei DER strengen Typenprüfung :-)  .
type
   TEncoderDecoder = class
   { Private-Deklarationen }
   private
      FResult: Integer;
      FFile: TStream;
      FText: TStrings;
      function EncodeLine (const AFrom: PLineSourceTable; const AFromSize: Integer;
         const ATable: TByteToCharTable; const ATo: PLineResultTable): Integer;
      function DecodeLine (const AFrom: String; const AFromSize: Integer;
         const ATable: TCharToByteTable; const ATo: PLineResultTable): Integer;
      procedure SetFileData (const AFileData: TStream);
      procedure SetTextData (const ATextData: TStrings);
      function GetResultAsStr ({keine Parameter}): String;
   { Protected-Deklarationen }
   protected
   (*
    * Binär -> Text, d.h. FFile -> FText                                                       .
    *)
      function GetEncodedSize ({keine Parameter}): Integer; virtual; abstract;
      function DoEncode ({keine Parameter}): Integer; virtual; abstract;
   (*
    * Text -> Binär, d.h. FText -> FFile                                                       .
    *)
      function GetDecodedSize ({keine Parameter}): Integer; virtual; abstract;
      function DoDecode ({keine Parameter}): Integer; virtual; abstract;
   { Public-Deklarationen }
   public
      constructor Create ({keine Parameter}); overload;
      constructor Create (AFileData: TStream); overload;
      constructor Create (ATextData: TStrings); overload;
      destructor Destroy ({keine Parameter}); override;
      // Encoder-Funktionen                                                                    .
      function LoadFileData (const AFileName: String): Integer;
      function SaveTextData ({keine Parameter}): Integer; overload;
      function SaveTextData (const AFileName: String): Integer; overload;
      function Encode ({keine Parameter}): Integer;
      function EncodeFromFile (const AFileName: String): Integer;
      function EncodeFromStream (const AFileData: TStream): Integer;
      // Decoder-Funktionen                                                                    .
      function LoadTextData ({keine Parameter}): Integer; overload;
      function LoadTextData (const AFileName: String): Integer; overload;
      function SaveFileData (const AFileName: String): Integer;
      function Decode ({keine Parameter}): Integer;
      function DecodeFromFile (const AFileName: String): Integer;
      function DecodeFromStrings (const ATextData: TStrings): Integer;
      // Properties                                                                            .
      property Result: Integer read FResult;
      property ResultAsStr: String read GetResultAsStr;
      property FileData: TStream read FFile write SetFileData;
      property TextData: TStrings read FText write SetTextData;
      property GuessEncodedSize: Integer read GetEncodedSize;
      property GuessDecodedSize: Integer read GetDecodedSize;
      class function ErrorCodeToStr (const AErrorCode: Integer): String;
      class function GuessEncoding (const ATextData: TStrings): TEncoderDecoder_Coding; overload;
      class function GuessEncoding (const AFileName: String): TEncoderDecoder_Coding; overload;
   { Published-Deklarationen }
   published
   end;
type
   TEncoderDecoder2 = class (TEncoderDecoder)
   { Private-Deklarationen }
   private
      FFileMode: Integer;
      FFileName: String;
   { Protected-Deklarationen }
   protected
      function GetEncodedSize ({keine Parameter}): Integer; override; abstract;
      function DoEncode ({keine Parameter}): Integer; override; abstract;
      function GetDecodedSize ({keine Parameter}): Integer; override; abstract;
      function DoDecode ({keine Parameter}): Integer; override; abstract;
   { Public-Deklarationen }
   public
      constructor Create ({keine Parameter});
      property FileMode: Integer read FFileMode write FFileMode;
      property FileName: String read FFileName write FFileName;
   { Published-Deklarationen }
   published
   end;
(*
 *                                                                                             .
 * ============================================================================                .
 * ===  TBase64EncoderDecoder                                               ===                .
 * ============================================================================                .
 *                                                                                             .
 *)
type
   TBase64EncoderDecoder = class (TEncoderDecoder)
   { Private-Deklarationen }
   private
   { Protected-Deklarationen }
   protected
      function GetEncodedSize ({keine Parameter}): Integer; override;
      function DoEncode ({keine Parameter}): Integer; override;
      function GetDecodedSize ({keine Parameter}): Integer; override;
      function DoDecode ({keine Parameter}): Integer; override;
   { Public-Deklarationen }
   public
   { Published-Deklarationen }
   published
   end;
(*
 *                                                                                             .
 * ============================================================================                .
 * ===  TUUEncoderDecoder                                                   ===                .
 * ============================================================================                .
 *                                                                                             .
 *)
type
   TUUEncoderDecoder = class (TEncoderDecoder2)
   { Private-Deklarationen }
   private
   { Protected-Deklarationen }
   protected
      function GetEncodedSize ({keine Parameter}): Integer; override;
      function DoEncode ({keine Parameter}): Integer; override;
      function GetDecodedSize ({keine Parameter}): Integer; override;
      function DoDecode ({keine Parameter}): Integer; override;
   { Public-Deklarationen }
   public
   { Published-Deklarationen }
      class function SetUUSpaceCoding (const ASpaceCoding: Boolean): Boolean;
   published
   end;
(*
 *                                                                                             .
 * ============================================================================                .
 * ===  TXXEncoderDecoder                                                   ===                .
 * ============================================================================                .
 *                                                                                             .
 *)
type
   TXXEncoderDecoder = class (TEncoderDecoder2)
   { Private-Deklarationen }
   private
   { Protected-Deklarationen }
   protected
      function GetEncodedSize ({keine Parameter}): Integer; override;
      function DoEncode ({keine Parameter}): Integer; override;
      function GetDecodedSize ({keine Parameter}): Integer; override;
      function DoDecode ({keine Parameter}): Integer; override;
   { Public-Deklarationen }
   public
   { Published-Deklarationen }
   published
   end;
(*
 * Fehlerbehandlung: Fehler-Nummern & -Erklärungen                                             .
 *)
const                        // Encoder ~ Konstante                                            .
   ERROR_ENC_ENCODELINE_FAILED  = -(ENCODERDECODER_ERROR_BASE + $01);
   ERROR_ENC_FILE_DOES_EXIST    = -(ENCODERDECODER_ERROR_BASE + $02);
   ERROR_ENC_FILE_NOT_FOUND     = -(ENCODERDECODER_ERROR_BASE + $03);
   ERROR_ENC_ILLEGAL_EOF        = -(ENCODERDECODER_ERROR_BASE + $04);
   ERROR_ENC_LOADFILE_FAILED    = -(ENCODERDECODER_ERROR_BASE + $05);
   ERROR_ENC_NO_INPUT           = -(ENCODERDECODER_ERROR_BASE + $06);
   ERROR_ENC_SAVECLPBRD_FAILED  = -(ENCODERDECODER_ERROR_BASE + $07);
   ERROR_ENC_SAVEFILE_FAILED    = -(ENCODERDECODER_ERROR_BASE + $08);
   ERROR_ENC_UNKNOWN_ERROR      = -(ENCODERDECODER_ERROR_BASE + $09);
resourcestring               // Encoder ~ Resourcestrings                                      .
   sERROR_ENC_ENCODELINE_FAILED = 'Fatal: Internal failure in .EncodeLine()';
   sERROR_ENC_FILE_DOES_EXIST   = 'Saving data from encoder output stream <FTex' +
                                     't> failed: File does exist';
   sERROR_ENC_FILE_NOT_FOUND    = 'Loading data to encoder input stream <FFile>' +
                                    ' failed: File does not exist';
   sERROR_ENC_ILLEGAL_EOF       = 'Fatal: Illegal EOF in encoder input stream <' +
                                    'FFile>';
   sERROR_ENC_LOADFILE_FAILED   = 'Loading data to encoder input stream <FFile>' +
                                    ' failed: Internal failure';
   sERROR_ENC_NO_INPUT          = 'The encoder input stream <FFile> is empty';
   sERROR_ENC_SAVECLPBRD_FAILED = 'Saving data from encoder output stream <FTex' +
                                    't> to the clipboard failed: Internal failure';
   sERROR_ENC_SAVEFILE_FAILED   = 'Saving data from encoder output stream <FTex' +
                                    't> failed: Internal failure';
   sERROR_ENC_UNKNOWN_ERROR     = 'Unknown error while encoding stream';
const                        // Decoder ~ Konstante                                            .
   ERROR_DEC_DECODELINE_FAILED  = -(ENCODERDECODER_ERROR_BASE + $11);
   ERROR_DEC_FILE_DOES_EXIST    = -(ENCODERDECODER_ERROR_BASE + $12);
   ERROR_DEC_CLPBRD_EMPTY       = -(ENCODERDECODER_ERROR_BASE + $13);
   ERROR_DEC_FILE_NOT_FOUND     = -(ENCODERDECODER_ERROR_BASE + $14);
   ERROR_DEC_ILLEGAL_CODE       = -(ENCODERDECODER_ERROR_BASE + $15);
   ERROR_DEC_ILLEGAL_EOF        = -(ENCODERDECODER_ERROR_BASE + $16);
   ERROR_DEC_LOADCLPBRD_FAILED  = -(ENCODERDECODER_ERROR_BASE + $17);
   ERROR_DEC_LOADFILE_FAILED    = -(ENCODERDECODER_ERROR_BASE + $18);
   ERROR_DEC_NO_INPUT           = -(ENCODERDECODER_ERROR_BASE + $19);
   ERROR_DEC_SAVEFILE_FAILED    = -(ENCODERDECODER_ERROR_BASE + $1A);
   ERROR_DEC_UNKNOWN_ERROR      = -(ENCODERDECODER_ERROR_BASE + $1B);
resourcestring               // Decoder ~ Resourcestrings                                      .
   sERROR_DEC_DECODELINE_FAILED = 'Fatal: Internal failure in .DecodeLine()';
   sERROR_DEC_FILE_DOES_EXIST   = 'Saving data from decoder output stream <FFil' +
                                    'e> failed: File does exist';
   sERROR_DEC_CLPBRD_EMPTY      = 'Loading data to decoder input stream <FText>' +
                                    ' from the clipboard failed: Clipboard is e' +
                                    'mpty or clipboard content is not CF_TEXT';
   sERROR_DEC_FILE_NOT_FOUND    = 'Loading data to decoder input stream <FText>' +
                                    ' failed: File does not exist';
   sERROR_DEC_ILLEGAL_CODE      = 'Fatal: Illegal code value in decoder input s' +
                                    'tream <FText>';
   sERROR_DEC_ILLEGAL_EOF       = 'Fatal: Illegal EOF in decoder input stream <' +
                                    'FText>';
   sERROR_DEC_LOADCLPBRD_FAILED = 'Loading data to decoder input stream <FText>' +
                                    ' from the clipboard failed: Internal failu' +
                                    're';
   sERROR_DEC_LOADFILE_FAILED   = 'Loading data to decoder input stream <FText>' +
                                    ' failed: Internal failure';
   sERROR_DEC_NO_INPUT          = 'The decoder input stream <FText> is empty';
   sERROR_DEC_SAVEFILE_FAILED   = 'Saving data from decoder output stream <FFil' +
                                    'e> failed: Internal failure';
   sERROR_DEC_UNKNOWN_ERROR     = 'Unknown error while decoding stream';
const
// TResolverMap = packed array [0..0] of TResolverRec;                                         .
   ResolverMap : packed array [0..20] of TResolverRec
      = ((Code: ERROR_ENC_ENCODELINE_FAILED; Desc: @sERROR_ENC_ENCODELINE_FAILED),
         (Code: ERROR_ENC_FILE_DOES_EXIST  ; Desc: @sERROR_ENC_FILE_DOES_EXIST  ),
         (Code: ERROR_ENC_FILE_NOT_FOUND   ; Desc: @sERROR_ENC_FILE_NOT_FOUND   ),
         (Code: ERROR_ENC_ILLEGAL_EOF      ; Desc: @sERROR_ENC_ILLEGAL_EOF      ),
         (Code: ERROR_ENC_LOADFILE_FAILED  ; Desc: @sERROR_ENC_LOADFILE_FAILED  ),
         (Code: ERROR_ENC_NO_INPUT         ; Desc: @sERROR_ENC_NO_INPUT         ),
         (Code: ERROR_ENC_SAVECLPBRD_FAILED; Desc: @sERROR_ENC_SAVECLPBRD_FAILED),
         (Code: ERROR_ENC_SAVEFILE_FAILED  ; Desc: @sERROR_ENC_SAVEFILE_FAILED  ),
         (Code: ERROR_ENC_UNKNOWN_ERROR    ; Desc: @sERROR_ENC_UNKNOWN_ERROR    ),
         (Code: ERROR_DEC_DECODELINE_FAILED; Desc: @sERROR_DEC_DECODELINE_FAILED),
         (Code: ERROR_DEC_FILE_DOES_EXIST  ; Desc: @sERROR_DEC_FILE_DOES_EXIST  ),
         (Code: ERROR_DEC_CLPBRD_EMPTY     ; Desc: @sERROR_DEC_CLPBRD_EMPTY     ),
         (Code: ERROR_DEC_FILE_NOT_FOUND   ; Desc: @sERROR_DEC_FILE_NOT_FOUND   ),
         (Code: ERROR_DEC_ILLEGAL_CODE     ; Desc: @sERROR_DEC_ILLEGAL_CODE     ),
         (Code: ERROR_DEC_ILLEGAL_EOF      ; Desc: @sERROR_DEC_ILLEGAL_EOF      ),
         (Code: ERROR_DEC_LOADCLPBRD_FAILED; Desc: @sERROR_DEC_LOADCLPBRD_FAILED),
         (Code: ERROR_DEC_LOADFILE_FAILED  ; Desc: @sERROR_DEC_LOADFILE_FAILED  ),
         (Code: ERROR_DEC_NO_INPUT         ; Desc: @sERROR_DEC_NO_INPUT         ),
         (Code: ERROR_DEC_SAVEFILE_FAILED  ; Desc: @sERROR_DEC_SAVEFILE_FAILED  ),
         (Code: ERROR_DEC_UNKNOWN_ERROR    ; Desc: @sERROR_DEC_UNKNOWN_ERROR    ),
         (Code: ERROR_UNDEFINED            ; Desc: @sERROR_UNDEFINED            ));
// ---------------                                                                             .
   implementation
// ---------------                                                                             .
uses
   SysUtils,
   Math,
   Misc_Utilities,
   String_Utilities;
(*
 *                                                                                             .
 * ============================================================================                .
 * ===  TEncoderDecoder                                                     ===                .
 * ============================================================================                .
 *                                                                                             .
 *)
// ----------------------------------------------------------------------------                .
// Kodiert eine Datenzeile:                                                                    .
//    <AFrom>     .. Pointer auf Daten.                                                        .
//    <AFromSize> .. Menge der Daten (in Byte), auf die <AFrom> zeigt.                         .
//    <ATable>    .. Code-Tabelle, die für alle Werte 0 .. 63 ein ein-                         .
//                   deutiges ("druckbares") Zeichen definiert.                                .
//    <ATo>       .. Pointer auf Zielbuffer, max. 256 Zeichen.                                 .
// ----------------------------------------------------------------------------                .
function TEncoderDecoder.EncodeLine (const AFrom: PLineSourceTable;
                                     const AFromSize: Integer;
                                     const ATable: TByteToCharTable;
                                     const ATo: PLineResultTable): Integer;
const
   INIT_F3 = $FF;
var
   i, j: Integer;
   field: packed array [0..3] of Byte;    // Slot #3 ist unbenutzt                             .
   tupel: Cardinal absolute field; // <tupel> "überdeckt" sich mit <field>                     .
begin
   Result := 0;
   // Kodierung ist 3 -> 4, d.h. aus 3 Byte zu 8 Bit werden 4 Byte zu 6 Bit                    .
   //                                                                                          .
   // Encoder: Interpretation der "3-Byte-Chunks":                                             .
   // 1 Byte -> 'XX--'; 2 Byte -> 'XXX-'; 3 Byte -> 'XXXX'                                     .
   i := 1;
   field[3] := INIT_F3;
   while (i <= AFromSize) do begin
      tupel := (tupel and $FF000000);
      j := (1 + (AFromSize - i)); // verbleibender Rest                                        .
      if (j < 1) then begin
         Result := ERROR_ENC_ILLEGAL_EOF;
         Break;
      end else if (j = 1) then begin      // 1 Byte Rest?                                      .
         field[2] := AFrom^[i-1];           // dieses 1 Byte lesen                             .
                                          // 1 Byte ergibt 2 Code-Byte                         .
         ATo^[Result  ] := ATable[((tupel shr 18) and CODE_BYTE_MASK)];
         ATo^[Result+1] := ATable[((tupel shr 12) and CODE_BYTE_MASK)];
         Inc(Result,2);                   // 2 Code-Byte mehr                                  .
      end else if (j = 2) then begin      // 2 Byte Rest?                                      .
         field[2] := AFrom^[i-1];           // diese 2 Byte lesen                              .
         field[1] := AFrom^[i  ];           // 2 Byte ergeben 3 Code-Byte                      .
         ATo^[Result  ] := ATable[((tupel shr 18) and CODE_BYTE_MASK)];
         ATo^[Result+1] := ATable[((tupel shr 12) and CODE_BYTE_MASK)];
         ATo^[Result+2] := ATable[((tupel shr  6) and CODE_BYTE_MASK)];
         Inc(Result,3);                   // 3 Code-Byte mehr                                  .
      end else { if (j >= 3) then } begin // 3 (oder mehr) Byte Rest ...                       .
         field[2] := AFrom^[i-1];           // genau 3 Byte lesen                              .
         field[1] := AFrom^[i  ];
         field[0] := AFrom^[i+1];           // 3 Byte ergeben 4 Code-Byte                      .
         ATo^[Result  ] := ATable[((tupel shr 18) and CODE_BYTE_MASK)];
         ATo^[Result+1] := ATable[((tupel shr 12) and CODE_BYTE_MASK)];
         ATo^[Result+2] := ATable[((tupel shr  6) and CODE_BYTE_MASK)];
         ATo^[Result+3] := ATable[( tupel         and CODE_BYTE_MASK)];
         Inc(Result,4);                   // 4 Code-Byte mehr                                  .
      end;
      Inc(i,3); // für (j <= 3) folgt sofortiger Abbruch; sonst weiter                         .
   end;
   if (field[3] <> INIT_F3) then
      Result := ERROR_ENC_ENCODELINE_FAILED;
end;
// ----------------------------------------------------------------------------                .
// De-Kodiert eine Datenzeile:                                                                 .
//    <AFrom>     .. String mit einer kodierten Datenzeile.                                    .
//    <AFromSize> .. Menge der Daten (in Byte), die in <AFrom> enthalten sind.                 .
//    <ATable>    .. Code-Tabelle, die für jedes mögliche ("druckbare")                        .
//                   Zeichen einen eindeutigen Binärwert definiert.                            .
//    <ATo>       .. Pointer auf Zielbuffer, max. 256 Zeichen.                                 .
// ----------------------------------------------------------------------------                .
function TEncoderDecoder.DecodeLine (const AFrom: String;
                                     const AFromSize: Integer;
                                     const ATable: TCharToByteTable;
                                     const ATo: PLineResultTable): Integer;
const
   INIT_F3 = #$FF;
var
   i, j: Integer;
   tupel: Cardinal;
   field: packed array [0..3] of Char absolute tupel; // <field> "überdeckt" sich mit <tupel>; .
                                               // Slot #3 ist unbenutzt                        .
begin
   Result := 0;
   // De-Kodierung ist 4 -> 3, d.h. aus 4 Byte zu 6 Bit werden 3 Byte zu 8 Bit                 .
   //                                                                                          .
   // Decoder: Interpretation der "4-Character-Chunks":                                        .
   // 'XX==' -> 1 Byte; 'XXX=' -> 2 Byte; 'XXXX' -> 3 Byte                                     .
   i := 1;
   while (i <= AFromSize) do begin
      if (ATable[AFrom[i]] > CODE_BYTE_MASK) then begin
         Result := ERROR_DEC_ILLEGAL_CODE;
         Break;
      end;
      Inc(i);
   end;
   if (Result = 0) then begin
      i := 1;
      field[3] := INIT_F3;
      while (i <= AFromSize) do begin
         tupel := (tupel and $FF000000);
         j := (1 + (AFromSize - i));
         if (j < 2) then begin
            Result := ERROR_DEC_ILLEGAL_EOF;
            Break;
         end else if (j = 2) then begin
            tupel :=  tupel                                 or
                     ((Cardinal(ATable[AFrom[i  ]]) shl 18) or
                      (Cardinal(ATable[AFrom[i+1]]) shl 12));
            ATo^[Result  ] := field[2];
            Inc(Result);
         end else if (j = 3) then begin
            tupel :=  tupel                                 or
                     ((Cardinal(ATable[AFrom[i  ]]) shl 18) or
                      (Cardinal(ATable[AFrom[i+1]]) shl 12) or
                      (Cardinal(ATable[AFrom[i+2]]) shl  6));
            ATo^[Result  ] := field[2];
            ATo^[Result+1] := field[1];
            Inc(Result,2);
         end else { if (j >= 4) then } begin
            tupel :=  tupel                                 or
                     ((Cardinal(ATable[AFrom[i  ]]) shl 18) or
                      (Cardinal(ATable[AFrom[i+1]]) shl 12) or
                      (Cardinal(ATable[AFrom[i+2]]) shl  6) or
                       Cardinal(ATable[AFrom[i+3]])        );
            ATo^[Result  ] := field[2];
            ATo^[Result+1] := field[1];
            ATo^[Result+2] := field[0];
            Inc(Result,3);
         end;
         Inc(i,4); // für (j <= 4) folgt sofortiger Abbruch; sonst weiter                      .
      end;
      if (field[3] <> INIT_F3) then
         Result := ERROR_DEC_DECODELINE_FAILED;
   end;
end;
// ----------------------------------------------------------------------------                .
// Binäre Daten werden "as-is" übernommen.                                                     .
// ----------------------------------------------------------------------------                .
procedure TEncoderDecoder.SetFileData (const AFileData: TStream);
begin
   if (AFileData <> NIL) then
      FFile.CopyFrom(AFileData,0);
end;
// ----------------------------------------------------------------------------                .
// Kodierte (Text-) Daten werden _NICHT_ "as-is" übernommen:                                   .
//    .) Zeilenumbruch wird auf Standard-CRLF-Umbruch angepasst                                .
//    .) Leerzeilen werden über den gesamten Text entfernt                                     .
// ----------------------------------------------------------------------------                .
procedure TEncoderDecoder.SetTextData (const ATextData: TStrings);
begin
   if (ATextData <> NIL) then begin
      FText.Text := Trim(AdjustLineBreaks(ATextData.Text));
      while (Pos((CRLF+CRLF),FText.Text) > 0) do
         FText.Text := StringReplace(FText.Text,(CRLF+CRLF),CRLF,[rfReplaceAll]);
   end;
end;
// ----------------------------------------------------------------------------                .
function TEncoderDecoder.GetResultAsStr (): String;
begin
   Result := ErrorCodeToStr(FResult);
end;
// ----------------------------------------------------------------------------                .
constructor TEncoderDecoder.Create ();
begin
   inherited;
   FFile := TMemoryStream.Create();
   FText := TStringList.Create();
end;
// ----------------------------------------------------------------------------                .
constructor TEncoderDecoder.Create (AFileData: TStream);
begin
   Create();
   FResult := EncodeFromStream(AFileData);
end;
// ----------------------------------------------------------------------------                .
constructor TEncoderDecoder.Create (ATextData: TStrings);
begin
   Create();
   FResult := DecodeFromStrings(ATextData);
end;
// ----------------------------------------------------------------------------                .
destructor TEncoderDecoder.Destroy ();
begin
   FreeAndNil(FText);
   FreeAndNil(FFile);
   inherited;
end;
// ----------------------------------------------------------------------------                .
function TEncoderDecoder.LoadFileData (const AFileName: String): Integer;
begin
   if (FileExists(AFileName)) then begin
      try
         (FFile as TMemoryStream).LoadFromFile(AFileName);
         FResult := ERROR_SUCCESS;
      except
         on e: Exception do begin
            FResult := ERROR_ENC_LOADFILE_FAILED;
            sysShowErrMsg(e.Message);
         end;
      end;
   end else
      FResult := ERROR_ENC_FILE_NOT_FOUND;
   Result := FResult;
end;
// ----------------------------------------------------------------------------                .
// <FText>.Text -> Windows Clipboard                                                           .
// ----------------------------------------------------------------------------                .
function TEncoderDecoder.SaveTextData (): Integer;
begin
   if (clpbrdCopyTextToClipboard(FText.Text)) then
      FResult := ERROR_SUCCESS
   else
      FResult := ERROR_ENC_SAVECLPBRD_FAILED;
   Result := FResult;
end;
// ----------------------------------------------------------------------------                .
// <FText.Text> -> File <AFileName>                                                            .
// ----------------------------------------------------------------------------                .
function TEncoderDecoder.SaveTextData (const AFileName: String): Integer;
begin
   if not(FileExists(AFileName)) then begin
      try
         FText.SaveToFile(AFileName);
         FResult := ERROR_SUCCESS;
      except
         on e: Exception do begin
            FResult := ERROR_ENC_SAVEFILE_FAILED;
            sysShowErrMsg(e.Message);
         end;
      end;
   end else
      FResult := ERROR_ENC_FILE_DOES_EXIST;
   Result := FResult;
end;
// ----------------------------------------------------------------------------                .
function TEncoderDecoder.Encode (): Integer;
begin
   FResult := DoEncode();
   Result := FResult;
end;
// ----------------------------------------------------------------------------                .
function TEncoderDecoder.EncodeFromFile (const AFileName: String): Integer;
begin
   FResult := LoadFileData(AFileName);
   if (FResult = ERROR_SUCCESS) then
      FResult := DoEncode();
   Result := FResult;
end;
// ----------------------------------------------------------------------------                .
function TEncoderDecoder.EncodeFromStream (const AFileData: TStream): Integer;
begin
   SetFileData(AFileData);
   FResult := DoEncode();
   Result := FResult;
end;
// ----------------------------------------------------------------------------                .
// Windows Clipboard -> <FText>.Text -- via .SetTextData()                                     .
// ----------------------------------------------------------------------------                .
function TEncoderDecoder.LoadTextData (): Integer;
var
   text: String;
   temp: TStringList;
begin
   text := clpbrdPasteTextFromClipboard();
   if (text <> '') then begin
      try
         temp := TStringList.Create();
         try
            temp.SetText(PChar(text));
            SetTextData(temp);
            FResult := ERROR_SUCCESS;
         finally
            FreeAndNil(temp);
         end;
      except
         on e: Exception do begin
            FResult := ERROR_DEC_LOADCLPBRD_FAILED;
            sysShowErrMsg(e.Message);
         end;
      end;
   end else
      FResult := ERROR_DEC_CLPBRD_EMPTY;
   Result := FResult;
end;
// ----------------------------------------------------------------------------                .
// File <AFileName> -> <FText>.Text -- via .SetTextData()                                      .
// ----------------------------------------------------------------------------                .
function TEncoderDecoder.LoadTextData (const AFileName: String): Integer;
var
   temp: TStringList;
begin
   if (FileExists(AFileName)) then begin
      try
         temp := TStringList.Create();
         try
            temp.LoadFromFile(AFileName);
            SetTextData(temp);
            FResult := ERROR_SUCCESS;
         finally
            FreeAndNil(temp);
         end;
      except
         on e: Exception do begin
            FResult := ERROR_DEC_LOADFILE_FAILED;
            sysShowErrMsg(e.Message);
         end;
      end;
   end else
      FResult := ERROR_DEC_FILE_NOT_FOUND;
   Result := FResult;
end;
// ----------------------------------------------------------------------------                .
function TEncoderDecoder.SaveFileData (const AFileName: String): Integer;
begin
   if not(FileExists(AFileName)) then begin
      try
         (FFile as TMemoryStream).SaveToFile(AFileName);
         FResult := ERROR_SUCCESS;
      except
         on e: Exception do begin
            FResult := ERROR_DEC_SAVEFILE_FAILED;
            sysShowErrMsg(e.Message);
         end;
      end;
   end else
      FResult := ERROR_DEC_FILE_DOES_EXIST;
   Result := FResult;
end;
// ----------------------------------------------------------------------------                .
function TEncoderDecoder.Decode (): Integer;
begin
   FResult := DoDecode();
   Result := FResult;
end;
// ----------------------------------------------------------------------------                .
function TEncoderDecoder.DecodeFromFile (const AFileName: String): Integer;
begin
   FResult := LoadTextData(AFileName);
   if (FResult = 0) then
      FResult := DoDecode();
   Result := FResult;
end;
// ----------------------------------------------------------------------------                .
function TEncoderDecoder.DecodeFromStrings (const ATextData: TStrings): Integer;
begin
   SetTextData(ATextData);
   FResult := DoDecode();
   Result := FResult;
end;
// ----------------------------------------------------------------------------                .
constructor TEncoderDecoder2.Create ();
begin
   inherited;
   FFileMode := 0;
   FFileName := '';
end;
(*
 *                                                                                             .
 * ============================================================================                .
 * ===  TBase64EncoderDecoder                                               ===                .
 * ============================================================================                .
 *                                                                                             .
 *)
const
   Base64_ChunkSize = 57;
   Base64_EncodeTable : TByteToCharTable
      = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
var
   Base64_DecodeTable : TCharToByteTable;
// ----------------------------------------------------------------------------                .
function TBase64EncoderDecoder.GetEncodedSize (): Integer;
var
   ref_size : Integer;
begin
   if (FFile.Size > 0) then begin
      // Prolog                                                                                .
      ;
      // Konvertierte Daten                                                                    .
      if ((FFile.Size mod 3) = 0) then
         ref_size := FFile.Size
      else
         ref_size := (3*((FFile.Size div 3)+1));
      FResult := Round((4/3)*ref_size)+                       // aus 3 Byte werden 4 Code-Byte .
                 (Length(CRLF)*(ref_size div Base64_ChunkSize)); // Anzahl der Zeilenumbrüche  .
      if ((ref_size mod Base64_ChunkSize) <> 0) then
         Inc(FResult,Length(CRLF));
      // Epilog                                                                                .
      ;
   end else
      // Fehler ~ keine Daten verfügbar                                                        .
      FResult := ERROR_ENC_NO_INPUT;
   Result := FResult;
end;
// ----------------------------------------------------------------------------                .
function TBase64EncoderDecoder.DoEncode (): Integer;
var
   pBuf: packed array [1..Base64_ChunkSize] of Byte;
   pBuf_size: Integer;
   pResult: TLineResultTable;
   pResult_size: Integer;
begin
   if (FFile.Size > 0) then begin
      FText.BeginUpdate();
      try
         try
            FResult := 0;
            FFile.Position := 0;
            FText.Clear();
            FillChar(pBuf,Base64_ChunkSize,0);
            repeat
               pBuf_size := FFile.Read(pBuf,Base64_ChunkSize);
               if (pBuf_size > 0) then begin
                  FillChar(pResult,SizeOf(pResult),#0);
                  pResult_size := EncodeLine(@pBuf,pBuf_size,
                     Base64_EncodeTable,@pResult);
                  if (pResult_size > 0) then begin
                     if (pBuf_size < Base64_ChunkSize) then begin
                        case (pBuf_size mod 3) of
                           0:                                  // Codefolge 'XXXX'             .
                              FText.Add(StrPas(pResult));
                           1: begin
                              FText.Add(StrPas(pResult)+'=='); // Codefolge 'XX--'             .
                              Inc(FResult,2);
                           end;
                           2: begin
                              FText.Add(StrPas(pResult)+'=');  // Codefolge 'XXX-'             .
                              Inc(FResult,1);
                           end;
                        end;
                     end else
                        FText.Add(StrPas(pResult));
                     Inc(FResult,(pResult_size+Length(CRLF))); // Code-Folge + Zeilenumbruch   .
                  end else begin
                     if (pResult_size = 0) then                // Das darf nicht passieren :-( .
                        FResult := ERROR_ENC_UNKNOWN_ERROR     // Unbekannter Fehler           .
                     else
                        FResult := pResult_size;               // Definierter Fehler           .
                     Break;
                  end;
               end else
                  // FFile-Stream aufgebraucht, fertig ...                                     .
                  Break;
            until (False);
         except
            on e: Exception do begin
               FResult := ERROR_ENC_UNKNOWN_ERROR;             // Unbekannter Fehler           .
               sysShowErrMsg(e.Message);
            end;
         end;
      finally
         FText.EndUpdate();
      end;
   end else
      FResult := ERROR_ENC_NO_INPUT;
   Result := FResult;
end;
// ----------------------------------------------------------------------------                .
function TBase64EncoderDecoder.GetDecodedSize (): Integer;
var
   i, j: Integer;
begin
   if (FText.Count > 0) then begin
      FResult := 0;
      for i := 0 to (FText.Count-1) do
         FResult := (FResult+Round((3/4)*Length(FText[i])));
      j := Pos('=',FText[(FText.Count-1)]);
      if (j > 0) then
         if (j = Length(FText[(FText.Count-1)])) then
            Dec(FResult)    // 'XXX=' .. 1 Byte weniger                                        .
         else
            Dec(FResult,2); // 'XX==' .. 2 Byte weniger                                        .
   end else
      FResult := ERROR_DEC_NO_INPUT;
   Result := FResult;
end;
// ----------------------------------------------------------------------------                .
function TBase64EncoderDecoder.DoDecode (): Integer;
var
   i, j: Integer;
   s: String;
   pResult: TLineResultTable;
   pResult_size: Integer;
begin
   if (FText.Count > 0) then begin
      FResult := 0;
      (FFile as TMemoryStream).Clear();
      for i := 0 to (FText.Count-1) do begin
         s := FText[i];
         j := Pos('=',s);
         if (j = 0) then
            pResult_size := DecodeLine(s,Length(s),
               Base64_DecodeTable,@pResult)
         else
            pResult_size := DecodeLine(Copy(s,1,(j-1)),(j-1),
               Base64_DecodeTable,@pResult);
         if (pResult_size > 0) then begin
            FFile.Write(pResult,pResult_size);
            Inc(FResult,pResult_size);
         end else begin
            if (pResult_size = 0) then
               FResult := ERROR_DEC_UNKNOWN_ERROR
            else
               FResult := pResult_size;
            Break;
         end;
      end;
   end else
      FResult := ERROR_DEC_NO_INPUT;
   Result := FResult;
end;
(*
 *                                                                                             .
 * ============================================================================                .
 * ===  TUUEncoderDecoder                                                   ===                .
 * ============================================================================                .
 *                                                                                             .
 *)
// Standard-UU-Kodierung                                                                       .
const
   UU_ChunkSize = 45;
   UU_EncodeTable : TByteToCharTable
      = '`!"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_';
var
   UU_DecodeTable : TCharToByteTable;
// "Space"-UU-Kodierung                                                                        .
const
   UUSpace_ChunkSize = 45;
   UUSpace_EncodeTable : TByteToCharTable
      = ' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_';
var
   UUSpace_DecodeTable : TCharToByteTable;
// UU-Koding kennt 2 unterschiedliche Tabellen: UU-Space und UU-`                              .
var
   UU_UseSpaceCoding : Boolean;
const
   UU_EncodeTables : array [Boolean] of PByteToCharTable
      = (@UU_EncodeTable,@UUSpace_EncodeTable);
   UU_DecodeTables : array [Boolean] of PCharToByteTable
      = (@UU_DecodeTable,@UUSpace_DecodeTable);
// ----------------------------------------------------------------------------                .
function TUUEncoderDecoder.GetEncodedSize (): Integer;
var
   s: String;
begin
   if (FFile.Size > 0) then begin
      // Prolog                                                                                .
      s := 'begin';
      if (FFileMode = 0) then
         s := Format('%s %d',[s,644])
      else
         s := Format('%s %d',[s,FFileMode]);
      if (FFileName = '') then
         s := Format('%s %p',[s,(FFile as TMemoryStream).Memory])
      else
         s := Format('%s %s',[s,FFileName]);
      FResult := (Length(s)+Length(CRLF));
      // Konvertierte Daten                                                                    .
                                                              // aus 3 Byte werden 4 Code-Byte .
      Inc(FResult,(Round((4/3)*UU_ChunkSize*(FFile.Size div UU_ChunkSize ))+
                                                   // Anzahl der (Längen-Info + Zeilenumbruch) .
                   ((1+Length(CRLF))*(FFile.Size div UU_ChunkSize))));
      if ((FFile.Size mod 3) <> 0) then
         Inc(FResult,(3-(FFile.Size mod 3)));
      if ((FFile.Size mod UU_ChunkSize) <> 0) then
                                       // zzgl. (Längen-Info + Zeilenumbruch) + Rest der Daten .
         Inc(FResult,(1+Length(CRLF)+Ceil((4/3)*(FFile.Size mod UU_ChunkSize))));
      // Epilog                                                                                .
      s := UU_EncodeTables[UU_UseSpaceCoding]^[0];
      Inc(FResult,(Length(s)+Length(CRLF)));
      s := 'end';
      Inc(FResult,(Length(s)+Length(CRLF)));
   end else
      // Fehler ~ keine Daten verfügbar                                                        .
      FResult := ERROR_ENC_NO_INPUT;
   Result := FResult;
end;
// ----------------------------------------------------------------------------                .
function TUUEncoderDecoder.DoEncode (): Integer;
var
   pBuf: packed array [1..UU_ChunkSize] of Byte;
   pBuf_size: Integer;
   pResult: TLineResultTable;
   pResult_size: Integer;
   s: String;
begin
   if (FFile.Size > 0) then begin
      if (FFileMode = 0) then
         FFileMode := 644;
      if (FFileName = '') then
         FFileName := Format('%p',[(FFile as TMemoryStream).Memory]);
      FText.BeginUpdate();
      try
         try
            FResult := 0;
            FFile.Position := 0;
            FText.Clear();
            s := Format('begin %d %s',[FFileMode,FFileName]);
            FText.Add(s);
            Inc(FResult,(Length(s)+Length(CRLF)));
            repeat
               FillChar(pBuf,UU_ChunkSize,0);
               pBuf_size := FFile.Read(pBuf,UU_ChunkSize);
               if (pBuf_size > 0) then begin
                  FillChar(pResult,SizeOf(pResult),#0);
                  if (pBuf_size < 3) then
                     pResult_size := EncodeLine(@pBuf,3,
                        UU_EncodeTables[UU_UseSpaceCoding]^,@pResult)
                  else
                     pResult_size := EncodeLine(@pBuf,pBuf_size,
                        UU_EncodeTables[UU_UseSpaceCoding]^,@pResult);
                  if (pResult_size > 0) then begin
                     s := (UU_EncodeTables[UU_UseSpaceCoding]^[pBuf_size]+StrPas(pResult));
                     FText.Add(s);
                     Inc(FResult,(Length(s)+Length(CRLF)));
                  end else begin
                     if (pResult_size = 0) then                // Das darf nicht passieren :-( .
                        FResult := ERROR_ENC_UNKNOWN_ERROR     // Unbekannter Fehler           .
                     else
                        FResult := pResult_size;               // Definierter Fehler           .
                     Break;
                  end;
               end else
                  // FFile-Stream aufgebraucht, fertig ...                                     .
                  Break;
            until (False);
            s := UU_EncodeTables[UU_UseSpaceCoding]^[0];
            FText.Add(s);
            Inc(FResult,(Length(s)+Length(CRLF)));
            s := 'end';
            FText.Add(s);
            Inc(FResult,(Length(s)+Length(CRLF)));
         except
            on e: Exception do begin
               FResult := ERROR_ENC_UNKNOWN_ERROR;             // Unbekannter Fehler           .
               sysShowErrMsg(e.Message);
            end;
         end;
      finally
         FText.EndUpdate();
      end;
   end else
      FResult := ERROR_ENC_NO_INPUT;
   Result := FResult;
end;
// ----------------------------------------------------------------------------                .
function TUUEncoderDecoder.GetDecodedSize (): Integer;
var
   i: Integer;
   s: String;
begin
   if (FText.Count > 0) then begin
      FResult := 0;
      for i := 1 to ((FText.Count-1)-1) do begin
         s := FText[i];
         if (UU_DecodeTables[UU_UseSpaceCoding]^[s[1]] = 0) then
            Continue;
         Inc(FResult,UU_DecodeTables[UU_UseSpaceCoding]^[s[1]]);
      end;
   end else
      FResult := ERROR_DEC_NO_INPUT;
   Result := FResult;
end;
// ----------------------------------------------------------------------------                .
function TUUEncoderDecoder.DoDecode (): Integer;
var
   i: Integer;
   s: String;
   pResult: TLineResultTable;
   pResult_size: Integer;
begin
   if (FText.Count > 0) then begin
      FResult := 0;
      (FFile as TMemoryStream).Clear();
      s := FText[0];
      if (AnsiLowerCase(GetNthStringDelimitedBy(1,s,[' '])) <> 'begin') then
         {falscher Prolog};
      FFileMode := StrToIntDef(GetNthStringDelimitedBy(2,FText[0],[' ']),644);
      FFileName := GetNthStringDelimitedBy(3,FText[0],[' ']);
      for i := 1 to ((FText.Count-1)-1) do begin
         s := FText[i];
         if (UU_DecodeTables[UU_UseSpaceCoding]^[s[1]] = 0) then
            Continue;
         pResult_size := DecodeLine(Copy(s,2,(Length(s)-1)),(Length(s)-1),
            UU_DecodeTables[UU_UseSpaceCoding]^,@pResult);
         // <pResult_size> ist bei dieser Kodierung eigentlich nicht mehr als ein Flag;        .
         // (= Ergebnis der Funktion DecodeLine()); die Größe der (nach der Dekodierung        .
         // gültigen) Daten ergibt sich aus s[1].                                              .
         if (pResult_size > 0) then begin
            if (pResult_size <> UU_DecodeTables[UU_UseSpaceCoding]^[s[1]]) then
               {?falsche Größenangabe?};
            FFile.Write(pResult,UU_DecodeTables[UU_UseSpaceCoding]^[s[1]]);
            Inc(FResult,UU_DecodeTables[UU_UseSpaceCoding]^[s[1]]);
         end else begin
            if (pResult_size = 0) then
               FResult := ERROR_DEC_UNKNOWN_ERROR
            else
               FResult := pResult_size;
            Break;
         end;
      end;
      if (AnsiLowerCase(FText[(FText.Count-1)]) <> 'end') then
         {falscher Epilog};
   end else
      FResult := ERROR_DEC_NO_INPUT;
   Result := FResult;
end;
(*
 *                                                                                             .
 * ============================================================================                .
 * ===  TXXEncoderDecoder                                                   ===                .
 * ============================================================================                .
 *                                                                                             .
 *)
const
   XX_ChunkSize = 45;
   XX_EncodeTable : TByteToCharTable
      = '+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
var
   XX_DecodeTable : TCharToByteTable;
// ----------------------------------------------------------------------------                .
function TXXEncoderDecoder.GetEncodedSize (): Integer;
var
   s: String;
begin
   if (FFile.Size > 0) then begin
      // Prolog                                                                                .
      s := 'begin';
      if (FFileMode = 0) then
         s := Format('%s %d',[s,644])
      else
         s := Format('%s %d',[s,FFileMode]);
      if (FFileName = '') then
         s := Format('%s %p',[s,(FFile as TMemoryStream).Memory])
      else
         s := Format('%s %s',[s,FFileName]);
      FResult := (Length(s)+Length(CRLF));
      // Konvertierte Daten                                                                    .
                                                              // aus 3 Byte werden 4 Code-Byte .
      Inc(FResult,(Round((4/3)*XX_ChunkSize*(FFile.Size div XX_ChunkSize ))+
                                                   // Anzahl der (Längen-Info + Zeilenumbruch) .
                   ((1+Length(CRLF))*(FFile.Size div XX_ChunkSize))));
      if ((FFile.Size mod 3) <> 0) then
         Inc(FResult,(3-(FFile.Size mod 3)));
      if ((FFile.Size mod XX_ChunkSize) <> 0) then
                                       // zzgl. (Längen-Info + Zeilenumbruch) + Rest der Daten .
         Inc(FResult,(1+Length(CRLF)+Ceil((4/3)*(FFile.Size mod XX_ChunkSize))));
      // Epilog                                                                                .
      s := XX_EncodeTable[0];
      Inc(FResult,(Length(s)+Length(CRLF)));
      s := 'end';
      Inc(FResult,(Length(s)+Length(CRLF)));
   end else
      // Fehler ~ keine Daten verfügbar                                                        .
      FResult := ERROR_ENC_NO_INPUT;
   Result := FResult;
end;
// ----------------------------------------------------------------------------                .
function TXXEncoderDecoder.DoEncode (): Integer;
var
   pBuf: packed array [1..XX_ChunkSize] of Byte;
   pBuf_size: Integer;
   pResult: TLineResultTable;
   pResult_size: Integer;
   s: String;
begin
   if (FFile.Size > 0) then begin
      if (FFileMode = 0) then
         FFileMode := 644;
      if (FFileName = '') then
         FFileName := Format('%p',[(FFile as TMemoryStream).Memory]);
      FText.BeginUpdate();
      try
         try
            FResult := 0;
            FFile.Position := 0;
            FText.Clear();
            s := Format('begin %d %s',[FFileMode,FFileName]);
            FText.Add(s);
            Inc(FResult,(Length(s)+Length(CRLF)));
            repeat
               FillChar(pBuf,XX_ChunkSize,0);
               pBuf_size := FFile.Read(pBuf,XX_ChunkSize);
               if (pBuf_size > 0) then begin
                  FillChar(pResult,SizeOf(pResult),#0);
                  if (pBuf_size < 3) then
                     pResult_size := EncodeLine(@pBuf,3,
                        XX_EncodeTable,@pResult)
                  else
                     pResult_size := EncodeLine(@pBuf,pBuf_size,
                        XX_EncodeTable,@pResult);
                  if (pResult_size > 0) then begin
                     s := (XX_EncodeTable[pBuf_size]+StrPas(pResult));
                     FText.Add(s);
                     Inc(FResult,(Length(s)+Length(CRLF)));
                  end else begin
                     if (pResult_size = 0) then                // Das darf nicht passieren :-( .
                        FResult := ERROR_ENC_UNKNOWN_ERROR     // Unbekannter Fehler           .
                     else
                        FResult := pResult_size;               // Definierter Fehler           .
                     Break;
                  end;
               end else
                  // FFile-Stream aufgebraucht, fertig ...                                     .
                  Break;
            until (False);
            s := XX_EncodeTable[0];
            FText.Add(s);
            Inc(FResult,(Length(s)+Length(CRLF)));
            s := 'end';
            FText.Add(s);
            Inc(FResult,(Length(s)+Length(CRLF)));
         except
            on e: Exception do begin
               FResult := ERROR_ENC_UNKNOWN_ERROR;             // Unbekannter Fehler           .
               sysShowErrMsg(e.Message);
            end;
         end;
      finally
         FText.EndUpdate();
      end;
   end else
      FResult := ERROR_ENC_NO_INPUT;
   Result := FResult;
end;
// ----------------------------------------------------------------------------                .
function TXXEncoderDecoder.GetDecodedSize (): Integer;
var
   i: Integer;
   s: String;
begin
   if (FText.Count > 0) then begin
      FResult := 0;
      for i := 1 to ((FText.Count-1)-1) do begin
         s := FText[i];
         if (XX_DecodeTable[s[1]] = 0) then
            Continue;
         Inc(FResult,XX_DecodeTable[s[1]]);
      end;
   end else
      FResult := ERROR_DEC_NO_INPUT;
   Result := FResult;
end;
// ----------------------------------------------------------------------------                .
function TXXEncoderDecoder.DoDecode (): Integer;
var
   i: Integer;
   s: String;
   pResult: TLineResultTable;
   pResult_size: Integer;
begin
   if (FText.Count > 0) then begin
      FResult := 0;
      (FFile as TMemoryStream).Clear();
      s := FText[0];
      if (AnsiLowerCase(GetNthStringDelimitedBy(1,s,[' '])) <> 'begin') then
         {falscher Prolog};
      FFileMode := StrToIntDef(GetNthStringDelimitedBy(2,FText[0],[' ']),644);
      FFileName := GetNthStringDelimitedBy(3,FText[0],[' ']);
      for i := 1 to ((FText.Count-1)-1) do begin
         s := FText[i];
         if (XX_DecodeTable[s[1]] = 0) then
            Continue;
         pResult_size := DecodeLine(Copy(s,2,(Length(s)-1)),(Length(s)-1),
            XX_DecodeTable,@pResult);
         // <pResult_size> ist bei dieser Kodierung eigentlich nicht mehr als ein Flag;        .
         // (= Ergebnis der Funktion DecodeLine()); die Größe der (nach der Dekodierung        .
         // gültigen) Daten ergibt sich aus s[1].                                              .
         if (pResult_size > 0) then begin
            if (pResult_size <> XX_DecodeTable[s[1]]) then
               {?falsche Größenangabe?};
            FFile.Write(pResult,XX_DecodeTable[s[1]]);
            Inc(FResult,XX_DecodeTable[s[1]]);
         end else begin
            if (pResult_size = 0) then
               FResult := ERROR_DEC_UNKNOWN_ERROR
            else
               FResult := pResult_size;
            Break;
         end;
      end;
      if (AnsiLowerCase(FText[(FText.Count-1)]) <> 'end') then
         {falscher Epilog};
   end else
      FResult := ERROR_DEC_NO_INPUT;
   Result := FResult;
end;
(*
 *                                                                                             .
 * ============================================================================                .
 * ===  TBinHexEncoderDecoder                                               ===                .
 * ============================================================================                .
 *                                                                                             .
 *)
(*
// "BinHex 4.0" Hqx7 "RFC 1741"
const
   BinHex_ChunkSize = 0;
   BinHex_EncodeTable: TByteToCharTable
      = '!"#$%&''()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr';
*)
(*
 *                                                                                             .
 * ============================================================================                .
 * ===  Klassenfunktionen von TEncoderDecoder                               ===                .
 * ============================================================================                .
 *                                                                                             .
 *)
// ----------------------------------------------------------------------------                .
class function TEncoderDecoder.ErrorCodeToStr (const AErrorCode: Integer): String;
begin
   Result := ResolveErrorCode('EncoderDecoder.pas',ResolverMap,AErrorCode,
      @sENCODERDECODER_ERROR_BASE);
end;
// ----------------------------------------------------------------------------                .
var
   ABS_MIN_CHAR : Char;
   ABS_MAX_CHAR : Char;
{                                                                                 .
base64:                                                                           .
   <base64-coding does not support a header ..>                                   .
   R0lGODdhIANYAvcAAP///+Xl5fr638zMzJkAmf8AAMgAAAAA/wAAyAAAAAAAAAAAAAAAAAAAAAAA   .
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA   .
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA   .
   AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAAAAAALAAAAAAgA1gC   .
   AAj/AAMIHEhQYIKDBwgeWJiw4MCDDiNKnEiR4MEEFS8C2HhR48aPIEOCREASgciTB0+qXAkyJUuQ   .
   BDy+bJlA5MWKOHNO7BiA58ObOncCDZoRY8SFRH0StQhxqcOhBZU6ndqz6U+jBQfIpDmz60uXHwdU   .
   xUp1wACOW23W9Mq2Ldq1KKFSHTv36c2OVnXelVs0b129CAs2FEr2b1C/Ejt+xOv2Y0mTX+E2Vgk2   .
   cuWukhcjNpwUb2GDmzuHnroZKVLAn53yVb15NWeKfvFG1HoZ7WS3l2mPxnn2bWaav28LB5AWeGqq   .
   rlkblZpTaXK7dF/jlHoa9nHpUZ8zlZwyuNeSM2sP/7dt2fvK2tqxEx6dN/1V6a4HD+772j39q9fV   .
   R82+PHFx4uNhlpt9DvVG3H9vBaigeADolh9pu6HG1FLMpTcUgZxdxNB81um3k3KaKdbYY5EpGBKD   .
   IZpH2W8RevjXXqg9SOF11XFoV4szyrieZzq66J9BEukWl4ks5RadTmb5VqSKRFp23nMYgobjfRBe   .
   lxxizPlYFUOdadncajIxNhmJTzZJ3oooonnilF4eJluM8D0oH5cRZWlYlFJKiaeLWLUo5JpMLpiZ   .
   g0im+GSgZsZlnp349bjdnXgymmedx+2JHJs/tXmjZ/6FeOBtZKKU6KeHIsqVcZrGWZWbmBYV1Jw3   .
   8v/Z6qqNptrchBX9Cdyoa4akW04Giqgor7gtCiVEkc4aq2gPZmmnpZc6mmmqPNJKKVyegUrSeaOq   .
   GBOCK6olra0d9iRhfZZyCO2X0mKprI9NuSesZsR6iipFwYILbr1qqURouXuuOym7OkLFKaXkSioU   .
                                                                                  .
uu:                                                                               .
   begin 644 TestFiles\Phorusgasse_6.gif                                          .
   M1TE&.#=A(`-8`O<``/___^7EY?KZW\S,S)D`F?\``,@`````_P``R```````                  .
   M````````````````````````````````````````````````````````````                  .
   M````````````````````````````````````````````````````````````                  .
   M`````````````````````"'Y!```````+``````@`U@"``C_``,('$A08(*#                  .
   M!P@>6)BPX,"##B-*G$B1X,$$%2\"V'A1X\:/($."1$`2@<B3!T^J7`DR)4N0                  .
   M!#R^;)E`Y,6*.'-.[!B`Y\.;.G<"#9H18\2%1'T2M0AQJ<.A!94ZG=JSZ4^C                  .
   M!0?(I#FSZTN7'P=4Q4IUP`".6VW6],JV+=JU**%2'3OWZ<V.5G7>E5LT;UV]                  .
   M"`LV%$KV;U"_$CM^Q.OV8TF37^$V5@DV<N6NDA<C-IP4;V&#FSN'GKH9*5+`                  .
   MGYWR5;UY-6>*?O%&U'H9[62WEVF/QGGV;6::OV\+!Y`6>&JJKED;E9I3:7*[                  .
   M=%_CE'H:]G'I49\SE9PRN->2,VL/_[=MV?O*VMJQ$QZ=-_U5Z:X'#^[[VCW]                  .
   MJ]?51\V^/'%QXN-AEIM]#O5&W']O!:B@>`#HEA]INZ'&U%+,I3<4@9Q=Q-!\                  .
   MUNFWDW*:*=;88Y$I&!*#(9I'V6\1>OC77J@]2.%UU7%H5XLSRKB>9SJZZ)]!                  .
   M$ND6EXDLY1:=3F;Y5J2*1%IVWG,8@H;C?1!>EQQBS/E8%4.=:=G<:C(Q-AF)                  .
   M3S9)WHHHHGGBE%X>)EN,\#TH'Y<196E8E%)*B:>+6+4HY)I,+IB9@TBF^&2@                  .
   M9L9EGIWX];C=G7@RFF>=Q^V)')L_M7FC9_Z%>.!M9**4Z*>'(LJ5<9K&696;                  .
                                                                                  .
uu-space:                                                                         .
   begin 644 TestFiles\Phorusgasse_6.gif                                          .
   M1TE&.#=A( -8 O<  /___^7EY?KZW\S,S)D F?\  ,@     _P  R                         .
   M                                                                              .
   M                                                                              .
   M                     "'Y!       +      @ U@"  C_  ,('$A08(*#                  .
   M!P@>6)BPX,"##B-*G$B1X,$$%2\"V'A1X\:/($."1$ 2@<B3!T^J7 DR)4N0                  .
   M!#R^;)E Y,6*.'-.[!B Y\.;.G<"#9H18\2%1'T2M0AQJ<.A!94ZG=JSZ4^C                  .
   M!0?(I#FSZTN7'P=4Q4IUP ".6VW6],JV+=JU**%2'3OWZ<V.5G7>E5LT;UV]                  .
   M" LV%$KV;U"_$CM^Q.OV8TF37^$V5@DV<N6NDA<C-IP4;V&#FSN'GKH9*5+                   .
   MGYWR5;UY-6>*?O%&U'H9[62WEVF/QGGV;6::OV\+!Y 6>&JJKED;E9I3:7*[                  .
   M=%_CE'H:]G'I49\SE9PRN->2,VL/_[=MV?O*VMJQ$QZ=-_U5Z:X'#^[[VCW]                  .
   MJ]?51\V^/'%QXN-AEIM]#O5&W']O!:B@> #HEA]INZ'&U%+,I3<4@9Q=Q-!\                  .
   MUNFWDW*:*=;88Y$I&!*#(9I'V6\1>OC77J@]2.%UU7%H5XLSRKB>9SJZZ)]!                  .
   M$ND6EXDLY1:=3F;Y5J2*1%IVWG,8@H;C?1!>EQQBS/E8%4.=:=G<:C(Q-AF)                  .
   M3S9)WHHHHGGBE%X>)EN,\#TH'Y<196E8E%)*B:>+6+4HY)I,+IB9@TBF^&2@                  .
   M9L9EGIWX];C=G7@RFF>=Q^V)')L_M7FC9_Z%>.!M9**4Z*>'(LJ5<9K&696;                  .
                                                                                  .
xx:                                                                               .
   begin 644 TestFiles\Phorusgasse_6.gif                                          .
   hFoZ4C1RV6+BM+jQ++DzzzyLZtTfurwnAn7Y+aTw++AU+++++zk++m+++++++                  .
   h++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++                  .
   h++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++                  .
   h+++++++++++++++++++++05t-+++++++9++++++U+pU0++Xz++A652VEM681                  .
   h-kUSK7WksA011WB8b2WFsA223Gw0q5VFswOD62C0F2+GUQWH-oyeL+Ym7IiE                  .
   h-1myP7Z+tAK8C5BCv-W+twCPCbQ01NcFMwG3F5oGhEVleQCV-NIubRenuIyX                  .
   h-ET6d1anuoiL5kRIlIdpk+0CKqrKxAeq9Rep883G5HjruQqCJbLSZJgoPpqx                  .
   h0+gq32fqPp0z2XhylCjqMoaHLy2qJUYqQiKiYVQXBdkIPq41ani5bfcN8J9+                  .
   hbtrmJPptBKS8Tj34p5cNvKGrZqaDlbbqPKOOjqw9-t+KS4eefZYPZNdHOL8v                  .
   hR3zXZ5cOxb5dINwnZNkmiBSGAqgDzvRhqTj8qhel2luRBzpJuOs51yvvqXrx                  .
   hexTJFwqyD53lsiBVZdhx1jJ4r5xj-OWUS+1cZVxdiu54p39AdHQIUNlRlB-w                  .
   hpiarYr8O8RPMMt2d4-816Nd5qKwFSjXLLeUxGC3ppL3cJsgnmfWSNneuu7x-                  .
   h2iYKZsYgtFORHaPtJeG8F3dqrbAMUcPXTF-SZllWnDZM3ICRORbQOX6lBVa7                  .
   hHnN7rccccbbWZ3sS7ZiAw1oc5tQFNKZMZ378WOS9K9Ict7dA9dWNUoWay4GU                  .
   hNgNZbdrsxPXRbLUmaaSRlyq757gzhLaXNzu3SC-hN88Iu8S56geJQNf4KNKP                  .
                                                                                  }
// ----------------------------------------------------------------------------                .
class function TEncoderDecoder.GuessEncoding (const ATextData: TStrings): TEncoderDecoder_Coding;
var
   i: Integer;
   has_header, has_footer: Boolean;          // base64 vs. uu | uuspace | xx                   .
   contains_lowercase,                       // base64 | xx vs. uu | uuspace                   .
   contains_slash, contains_minus,           // base64 vs. xx                                  .
   contains_hyphen, contains_space: Boolean; // uu vs. uuspace                                 .
begin                                                                                          
   // base64  = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';            .
   // xx      = '+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';            .
   // uu      = '`!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_';            .
   // uuspace = ' !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_';            .
   Result := edc_NONE;
   // Header: 'begin' -- uu | uuspace | xx                                                     .
   has_header := False;
   for i := 0 to (ATextData.Count-1) do
      if (AnsiLowerCase(GetNthStringDelimitedBy(1,ATextData[i],[' '])) = 'begin') then begin
         has_header := True;
         ATextData.Delete(i);
         Break;
      end;
   // Footer: 'end' -- uu | uusapce | xx                                                       .
   has_footer := False;
   for i := 0 to (ATextData.Count-1) do
      if (AnsiLowerCase(GetNthStringDelimitedBy(1,ATextData[i],[' '])) = 'end') then begin
         has_footer := True;
         ATextData.Delete(i);
         Break;
      end;
   // Auch Kleinbuchstaben im Stream: base64 | xx                                              .
   contains_lowercase := False;
   for i := 1 to Length(ATextData.Text) do
      if (ATextData.Text[i] in ['a'..'z']) then begin
         contains_lowercase := True;
         Break;
      end;
   // (base64 | xx): wenn '/' vorhanden, dann base64                                           .
   contains_slash := False;
   for i := 1 to Length(ATextData.Text) do
      if (ATextData.Text[i] = '/') then begin
         contains_slash := True;
         Break;
      end;
   // (base64 | xx): wenn '-' vorhanden, dann xx                                               .
   contains_minus := False;
   for i := 1 to Length(ATextData.Text) do
      if (ATextData.Text[i] = '-') then begin
         contains_minus := True;
         Break;
      end;
   // (uu | uuspace): wenn '`' vorhanden, dann uu                                              .
   contains_hyphen := False;
   for i := 1 to Length(ATextData.Text) do
      if (ATextData.Text[i] = '`') then begin
         contains_hyphen := True;
         Break;
      end;
   // (uu | uuspace): wenn ' ' vorhanden, dann uuspace                                         .
   contains_space := False;
   for i := 1 to Length(ATextData.Text) do
      if (ATextData.Text[i] = ' ') then begin
         contains_space := True;
         Break;
      end;
   // Auswertung der festgestellten Flags                                                      .
   if (contains_lowercase) then begin
      // Kann nur mehr base64 | xx sein ..                                                     .
      if ((contains_slash) and (contains_minus)) then
         Result := edc_NONE
      else if (contains_slash) then
         Result := edc_BASE64
      else if (contains_minus) then
         Result := edc_XX
      else if not((has_header) or (has_footer)) then
         Result := edc_BASE64
      else
         Result := edc_XX;
   end else begin
      // Kann nur mehr uu | uuspace sein ..                                                    .
      if ((contains_hyphen) and (contains_space)) then
         Result := edc_NONE
      else if (contains_hyphen) then
         Result := edc_UU
      else if (contains_space) then
         Result := edc_UUSPACE;
   end;
end;
// ----------------------------------------------------------------------------                .
class function TEncoderDecoder.GuessEncoding (const AFileName: String): TEncoderDecoder_Coding;
const
   MAX_GUESSBUFFER_SIZE = (4*1024);
var
   temp: TStringList;
   f: TextFile;
   s: String;
begin
   if (FileExists(AFileName)) then begin
      try
         temp := TStringList.Create();
         try
            AssignFile(f,AFileName);
            Reset(f);
            // So lange Strings (hoffentlich Strings!) lesen, bis entweder EOF oder der           .
            // Buffer mit (mehr oder weniger) ca. 4 kB Daten gefüllt ist.                         .
            //    Base64: 4096/((57*(4/3))+2) == ca. 52 Code-Zeilen                               .
            //    UU/XX : 4096/((45*(4/3))+2) == ca. 66 Code-Zeilen                               .
            //    BinHex: ???                                                                     .
            while (not(Eof(f)) and (Length(temp.Text) <= MAX_GUESSBUFFER_SIZE)) do begin
               ReadLn(f,s);
               if (s <> '') then
                  temp.Add(s);
            end;
            CloseFile(f);
            Result := GuessEncoding(temp);
         finally
            FreeAndNil(temp);
         end;
      except
         on e: Exception do begin
            Result := edc_NONE;
            sysShowErrMsg(e.Message);
         end;
      end;
   end else
      Result := edc_NONE;
end;
// ----------------------------------------------------------------------------                .
class function TUUEncoderDecoder.SetUUSpaceCoding (const ASpaceCoding: Boolean): Boolean;
begin
   Result := UU_UseSpaceCoding;
   UU_UseSpaceCoding := ASpaceCoding;
end;
(*
 *                                                                                             .
 * ============================================================================                .
 * ===  Initialisierung der Unit                                            ===                .
 * ============================================================================                .
 *                                                                                             .
 *)
var
   i : Integer;
// ---------------                                                                             .
   initialization
// ---------------                                                                             .
begin
   // Initialisierung -- Start.                                                                .
   ABS_MIN_CHAR := #255;
   ABS_MAX_CHAR := #0;
   (*
    * Tabelle "Base64_DecodeTable" aus Tabelle "Base64_EncodeTable" aufbauen ...               .
    *)
   FillChar(Base64_DecodeTable,SizeOf(Base64_DecodeTable),$FF); // $FF = Byte(-1)
   for i := 0 to MAX_CODE_VALUE do begin
      Base64_DecodeTable[ Base64_EncodeTable[i] ] := Byte(i);
      if (Base64_EncodeTable[i] < ABS_MIN_CHAR) then
         ABS_MIN_CHAR := Base64_EncodeTable[i];
      if (Base64_EncodeTable[i] > ABS_MAX_CHAR) then
         ABS_MAX_CHAR := Base64_EncodeTable[i];
   end;
   (*
    * Tabelle "UU_DecodeTable" aus Tabelle "UU_EncodeTable" aufbauen ...                       .
    *)
   UU_UseSpaceCoding := False;
   FillChar(UU_DecodeTable,SizeOf(UU_DecodeTable),$FF); // $FF = Byte(-1)
   for i := 0 to MAX_CODE_VALUE do // Standard-UU-Kodierung                                    .
      UU_DecodeTable[ UU_EncodeTable[i] ] := Byte(i);
   FillChar(UUSpace_DecodeTable,SizeOf(UUSpace_DecodeTable),$FF); // $FF = Byte(-1)
   for i := 0 to MAX_CODE_VALUE do // "Space"-UU-Kodierung                                     .
      UUSpace_DecodeTable[ UUSpace_EncodeTable[i] ] := Byte(i);
   (*
    * Tabelle "XX_DecodeTable" aus Tabelle "XX_EncodeTable" aufbauen ...                       .
    *)
   FillChar(XX_DecodeTable,SizeOf(XX_DecodeTable),$FF); // $FF = Byte(-1)
   for i := 0 to MAX_CODE_VALUE do begin
      XX_DecodeTable[ XX_EncodeTable[i] ] := Byte(i);
      if (XX_EncodeTable[i] < ABS_MIN_CHAR) then
         ABS_MIN_CHAR := XX_EncodeTable[i];
      if (XX_EncodeTable[i] > ABS_MAX_CHAR) then
         ABS_MAX_CHAR := XX_EncodeTable[i];
   end;
   // Initialisierung -- Ende.                                                                 .
end;
end.

Die ausführbare Datei -- auf Wunsch inklusive komplettem Quelltext -- steht in der Download-Sektion als ZIP-Archiv zur Verfügung.

^ Download:

Folgende Dateien stehen zum Download zur Verfügung:

Dateiname:Dateigröße:Beschreibung:

ed_ExeOnly.zip51.573 Byte'ed_ExeOnly.zip' für die Konsole, nur ausführbare Datei.
edGUI_ExeOnly.zip257.985 Byte'edGUI_ExeOnly.zip' (GUI wrapper für 'ed.exe' ['ed.exe' ist im Archiv inkludiert]), nur ausführbare Dateien.
ed_ExeAndSource.zip94.444 Byte'ed_ExeAndSource.zip' für die Konsole, ausführbare Datei & Quellcode (für Delphi5).
edGUI_ExeAndSource.zip315.621 Byte'edGUI_ExeAndSource.zip' (GUI wrapper für 'ed.exe' ['ed.exe' ist im Archiv inkludiert]), ausführbare Dateien & Quellcode (für Delphi5).


Zusätzliche Informationen:

  • Aktuelle Version von 'ed' ist /v/1.41.0.0258, Release /r/win32-x86-C-F-04.43.1, vom 18.10.2004, 16:48.
  • Aktuelle Version von 'edGUI' ist /v/1.10.0.0183, Release /r/win32-x86-GUI-F-04.43.1, vom 18.10.2004, 16:48.
  • Die Archive mit Quellcode inkuldieren jeweils alle Source-Dateien (d.h. *.dpr, *.pas, *.dfm [*.dfm als Text-DFM]) und alle Resourcen (d.h. *.rc, *.res, *.ico). Das/ die Projekt(e) ist/ sind daher 'compile-ready' für Delphi 5 (und höher, denke ich :-). Portierung(en) bis hinunter zu Delphi 2 sollte(n) problemlos möglich sein. Das/ die Projekt(e) sind allerdings nicht für 16-Bit OS/ Compiler (d.h. z.B. Win32s, Delphi 1, Pascal ...) gedacht, aber who knows ...

^ Kontakt:

Web- & Mail-Adresse(n):




Valid XHTML! Valid CSS! Erstellt & gewartet von: Marcus F. Nefzger -- [ (2**5) == (18,31,14) ].
Site-Version: v0.83; zul. geändert am: Wed, 23 Feb 2005 09:03:55 GMT.
Generator: gh (-G-enerate -H-tml) v1.91, Copyright (c) 2002, 2005 SoffyT & MNe.