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

Delphi控件源码

开发平台:

Delphi

  1. unit NMUUEncode;
  2. interface
  3. uses
  4.   Classes;
  5. function UUEEncode(const source, destination: TStream): Boolean;
  6. implementation
  7. uses
  8.   NMFileBuffer;
  9. function UUEEncode(const source, destination: TStream): Boolean;
  10.   function EncodeAByte(c: Byte): Byte;
  11.   begin
  12.     if c > 0 then
  13.       Result := (c and $3F) + $20
  14.     else
  15.       Result := Ord('`');
  16.   end;
  17. const
  18.   CRLF = #13#10;
  19.   ENCODELINELENGTH = 45;
  20.   EOB = #0;
  21.   INVALID = $00;
  22. var
  23.   TotalBytes: Integer;
  24.   index: Integer;
  25.   Output: string;
  26.   line_index: Integer;
  27.   LinePtr: PChar;
  28.   Len: Integer;
  29.   Len1: Integer;
  30.   OutputLength: Integer;
  31.   Char1: Byte;
  32.   Char2: Byte;
  33.   Char3: Byte;
  34.   OutChar1: Byte;
  35.   OutChar2: Byte;
  36.   OutChar3: Byte;
  37.   OutChar4: Byte;
  38.   InputPtr: PChar;
  39.   BufferEnd: PChar;
  40.   MemStuff: TNMFileBuffer;
  41.   Process: Boolean;
  42. begin
  43.   Process := True;
  44.   destination.Seek(0, soFromEnd);
  45.   TotalBytes := source.Size;
  46.   index := 0;
  47.   Char1 := 0;
  48.   Char2 := 0;
  49.   Char3 := 0;
  50.   Output := '';
  51.   OutputLength := ENCODELINELENGTH div 3 * 4;
  52.   MemStuff := TNMFileBuffer.Create(source);
  53.   try
  54.     InputPtr := MemStuff.BufPos;
  55.     BufferEnd := MemStuff.BufEnd;
  56.     while Process do
  57.     begin
  58.       line_index := 0;
  59.       if ((TotalBytes - index) >= ENCODELINELENGTH) then
  60.       begin
  61.             // Output the number of bytes in this line
  62.         SetLength(Output, OutputLength + 1);
  63.         LinePtr := PChar(Output);
  64.         OutChar1 := EncodeAByte(ENCODELINELENGTH);
  65.         LinePtr^ := Chr(OutChar1);
  66.         inc(LinePtr);
  67.         while (line_index < ENCODELINELENGTH) do
  68.         begin
  69.           if InputPtr >= BufferEnd then
  70.             if not MemStuff.NextMemoryBuffer(InputPtr, 0) then
  71.               Break
  72.             else
  73.             begin
  74.               InputPtr := MemStuff.BufPos;
  75.               BufferEnd := MemStuff.BufEnd;
  76.             end;
  77.           Char1 := Byte(InputPtr^);
  78.           inc(InputPtr);
  79.           inc(line_index);
  80.           inc(index);
  81.           if InputPtr >= BufferEnd then
  82.             if not MemStuff.NextMemoryBuffer(InputPtr, 0) then
  83.               Break
  84.             else
  85.             begin
  86.               InputPtr := MemStuff.BufPos;
  87.               BufferEnd := MemStuff.BufEnd;
  88.             end;
  89.           Char2 := Byte(InputPtr^);
  90.           inc(InputPtr);
  91.           inc(line_index);
  92.           inc(index);
  93.           if InputPtr >= BufferEnd then
  94.             if not MemStuff.NextMemoryBuffer(InputPtr, 0) then
  95.               Break
  96.             else
  97.             begin
  98.               InputPtr := MemStuff.BufPos;
  99.               BufferEnd := MemStuff.BufEnd;
  100.             end;
  101.           Char3 := Byte(InputPtr^);
  102.           inc(InputPtr);
  103.           inc(line_index);
  104.           inc(index);
  105.           OutChar1 := Char1 shr 2;
  106.           OutChar2 := (((Char1 shl 4) and $30) or ((Char2 shr 4) and $0F));
  107.           OutChar3 := (((Char2 shl 2) and $3C) or ((Char3 shr 6) and $03));
  108.           OutChar4 := Char3 and $3F;
  109.           OutChar1 := EncodeAByte(OutChar1);
  110.           OutChar2 := EncodeAByte(OutChar2);
  111.           OutChar3 := EncodeAByte(OutChar3);
  112.           OutChar4 := EncodeAByte(OutChar4);
  113.           LinePtr^ := Chr(OutChar1);
  114.           inc(LinePtr);
  115.           LinePtr^ := Chr(OutChar2);
  116.           inc(LinePtr);
  117.           LinePtr^ := Chr(OutChar3);
  118.           inc(LinePtr);
  119.           LinePtr^ := Chr(OutChar4);
  120.           inc(LinePtr);
  121.         end;
  122.         if InputPtr >= BufferEnd then
  123.           if not MemStuff.NextMemoryBuffer(InputPtr, 0) then
  124.             Break
  125.           else
  126.           begin
  127.             InputPtr := MemStuff.BufPos;
  128.             BufferEnd := MemStuff.BufEnd;
  129.           end;
  130.       end
  131.       else
  132.       begin
  133.         Len := TotalBytes - index; // get bytes left over
  134.         Len1 := Len div 3;
  135.         if Frac(Len / 3) > 0.0 then // always round up!
  136.           inc(Len1);
  137.         Len1 := Len1 * 4;
  138.         SetLength(Output, Len1 + 1);
  139.         LinePtr := PChar(Output);
  140.         OutChar1 := EncodeAByte(Len);
  141.         LinePtr^ := Chr(OutChar1);
  142.         inc(LinePtr);
  143.         while (index < TotalBytes) do
  144.         begin
  145.           if (index < TotalBytes) then
  146.           begin
  147.             if InputPtr >= BufferEnd then
  148.               if not MemStuff.NextMemoryBuffer(InputPtr, 0) then
  149.                 Break
  150.               else
  151.               begin
  152.                 InputPtr := MemStuff.BufPos;
  153.                 BufferEnd := MemStuff.BufEnd;
  154.               end;
  155.             Char1 := Byte(InputPtr^);
  156.             inc(InputPtr);
  157.           end
  158.           else
  159.           begin
  160.             Char1 := INVALID;
  161.           end;
  162.           inc(index);
  163.           if (index < TotalBytes) then
  164.           begin
  165.             if InputPtr >= BufferEnd then
  166.               if not MemStuff.NextMemoryBuffer(InputPtr, 0) then
  167.                 Break
  168.               else
  169.               begin
  170.                 InputPtr := MemStuff.BufPos;
  171.                 BufferEnd := MemStuff.BufEnd;
  172.               end;
  173.             Char2 := Byte(InputPtr^);
  174.             inc(InputPtr);
  175.           end
  176.           else
  177.           begin
  178.             Char2 := INVALID;
  179.           end;
  180.           inc(index);
  181.           if (index < TotalBytes) then
  182.           begin
  183.             if InputPtr >= BufferEnd then
  184.               if not MemStuff.NextMemoryBuffer(InputPtr, 0) then
  185.                 Break
  186.               else
  187.               begin
  188.                 InputPtr := MemStuff.BufPos;
  189.                 BufferEnd := MemStuff.BufEnd;
  190.               end;
  191.             Char3 := Byte(InputPtr^);
  192.             inc(InputPtr);
  193.           end
  194.           else
  195.           begin
  196.             Char3 := INVALID;
  197.           end;
  198.           inc(index);
  199.           OutChar1 := Char1 shr 2;
  200.           OutChar2 := (((Char1 shl 4) and $30) or ((Char2 shr 4) and $0F));
  201.           OutChar3 := (((Char2 shl 2) and $3C) or ((Char3 shr 6) and $03));
  202.           OutChar4 := Char3 and $3F;
  203.           OutChar1 := EncodeAByte(OutChar1);
  204.           OutChar2 := EncodeAByte(OutChar2);
  205.           OutChar3 := EncodeAByte(OutChar3);
  206.           OutChar4 := EncodeAByte(OutChar4);
  207.           LinePtr^ := Chr(OutChar1);
  208.           inc(LinePtr);
  209.           LinePtr^ := Chr(OutChar2);
  210.           inc(LinePtr);
  211.           LinePtr^ := Chr(OutChar3);
  212.           inc(LinePtr);
  213.           LinePtr^ := Chr(OutChar4);
  214.           inc(LinePtr);
  215.         end;
  216.         Process := False;
  217.       end;
  218.       LinePtr^ := #0;
  219.       destination.Write(PChar(Output)^, Length(Output));
  220.       destination.Write(CRLF, 2);
  221.     end;
  222.   finally
  223.     MemStuff.Free;
  224.   end;
  225.   Result := True; // no errors reported
  226. end;
  227. end.