NMUUDecode.pas
上传用户:szzdds
上传日期:2013-09-18
资源大小:293k
文件大小:3k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. unit NMUUDecode;
  2. interface
  3. uses
  4.   Classes;
  5. function UUEDecode(const Source: TStream; var Destination: TStream): Boolean;
  6. implementation
  7. function UUEDecode(const Source: TStream; var Destination: TStream): Boolean;
  8. const
  9.   EOL = #0;
  10.   EOB = #0;
  11.   CR = #13;
  12.   LF = #10;
  13.   Invalid = $FF;
  14. var
  15.   Stream_Ptr: PChar;
  16.   function Decode_Char(c: Char): Byte;
  17.   begin
  18.     Result := ((Byte(c) - $20) and $3F);
  19.   end;
  20.   procedure decode;
  21.   var
  22.     Char1: Byte;
  23.     Char2: Byte;
  24.     Char3: Byte;
  25.     Char4: Byte;
  26.     Line_Ptr: PChar;
  27.     Line_Length: LongInt;
  28.     Line: string;
  29.   begin
  30.     Line_Length := Decode_Char(Stream_Ptr^);
  31.     inc(Stream_Ptr);
  32.     SetLength(Line, Line_Length);
  33.     Line_Ptr := PChar(Line);
  34.     while Line_Length > 0 do
  35.     begin
  36.       if Stream_Ptr^ > EOL then
  37.       begin
  38.         Char1 := Decode_Char(Stream_Ptr^);
  39.         inc(Stream_Ptr);
  40.       end
  41.       else
  42.         Char1 := Invalid;
  43.       if Stream_Ptr^ > EOL then
  44.       begin
  45.         Char2 := Decode_Char(Stream_Ptr^);
  46.         inc(Stream_Ptr);
  47.       end
  48.       else
  49.         Char2 := Invalid;
  50.       if Stream_Ptr^ > EOL then
  51.       begin
  52.         Char3 := Decode_Char(Stream_Ptr^);
  53.         inc(Stream_Ptr);
  54.       end
  55.       else
  56.         Char3 := Invalid;
  57.       if Stream_Ptr^ > EOL then
  58.       begin
  59.         Char4 := Decode_Char(Stream_Ptr^);
  60.         inc(Stream_Ptr);
  61.       end
  62.       else
  63.         Char4 := Invalid;
  64.       Line_Ptr^ := Char((Char1 shl 2) or (Char2 shr 4));
  65.       inc(Line_Ptr);
  66.       Line_Ptr^ := Char((Char2 shl 4) or (Char3 shr 2));
  67.       inc(Line_Ptr);
  68.       Line_Ptr^ := Char((Char3 shl 6) or (Char4));
  69.       inc(Line_Ptr);
  70.       Dec(Line_Length, 3);
  71.     end;
  72.     Destination.Write(Pointer(Line)^, Length(Line));
  73.   end;
  74. const
  75.   MaxBufSize = $FFFE;
  76. var
  77.   Buffer, FillPos, BufPos: PChar;
  78.   Counter, BytesRead: LongInt;
  79.   SourceSize: LongInt;
  80. begin
  81.   Result := TRUE;
  82.   SourceSize := Source.Size;
  83.   Destination.Seek(0, soFromEnd);
  84.   Counter := 0;
  85.   GetMem(Buffer, MaxBufSize + 1);
  86.   FillPos := Buffer;
  87.   inc(FillPos, MaxBufSize + 1);
  88.   FillPos^ := EOB;
  89.   try
  90.     while Source.Position < SourceSize do
  91.     begin
  92.       FillPos := Buffer;
  93.       inc(FillPos, Counter);
  94.       BytesRead := Source.Read(FillPos^, MaxBufSize - Counter);
  95.       inc(Counter, BytesRead);
  96.       BufPos := Buffer;
  97.       inc(FillPos, Counter);
  98.       FillPos^ := EOB;
  99.       Counter := 0;
  100.       while BufPos^ <> EOB do
  101.       begin
  102.         Stream_Ptr := BufPos;
  103.         while not (BufPos^ in [EOB, LF, CR]) do
  104.           inc(BufPos);
  105.         if BufPos^ <> EOB then
  106.         begin
  107.           BufPos^ := EOL;
  108.           decode;
  109.           if BufPos^ = EOB then inc(BufPos);
  110.           if BufPos^ = CR then inc(BufPos);
  111.           if BufPos^ = LF then inc(BufPos);
  112.         end
  113.         else
  114.         begin
  115.           Counter := BufPos - Stream_Ptr;
  116.           System.Move(Stream_Ptr^, Buffer^, Counter + 1);
  117.           Break;
  118.         end;
  119.       end;
  120.     end;
  121.     if Counter > 0 then
  122.     begin
  123.       Stream_Ptr := Buffer;
  124.       decode;
  125.     end;
  126.   finally
  127.     FreeMem(Buffer, MaxBufSize);
  128.   end;
  129. end;
  130. end.