⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nmuuencode.pas

📁 DELPHI里面一些常用的控件
💻 PAS
字号:
unit NMUUEncode;

interface
uses
  Classes;

function UUEEncode(const source, destination: TStream): Boolean;

implementation
uses
  NMFileBuffer;

function UUEEncode(const source, destination: TStream): Boolean;

  function EncodeAByte(c: Byte): Byte;
  begin
    if c > 0 then
      Result := (c and $3F) + $20
    else
      Result := Ord('`');
  end;

const
  CRLF = #13#10;
  ENCODELINELENGTH = 45;
  EOB = #0;
  INVALID = $00;
var
  TotalBytes: Integer;
  index: Integer;

  Output: string;
  line_index: Integer;
  LinePtr: PChar;
  Len: Integer;
  Len1: Integer;
  OutputLength: Integer;

  Char1: Byte;
  Char2: Byte;
  Char3: Byte;

  OutChar1: Byte;
  OutChar2: Byte;
  OutChar3: Byte;
  OutChar4: Byte;

  InputPtr: PChar;
  BufferEnd: PChar;
  MemStuff: TNMFileBuffer;

  Process: Boolean;

begin
  Process := True;

  destination.Seek(0, soFromEnd);

  TotalBytes := source.Size;
  index := 0;

  Char1 := 0;
  Char2 := 0;
  Char3 := 0;

  Output := '';
  OutputLength := ENCODELINELENGTH div 3 * 4;

  MemStuff := TNMFileBuffer.Create(source);
  try
    InputPtr := MemStuff.BufPos;
    BufferEnd := MemStuff.BufEnd;
    while Process do
    begin
      line_index := 0;

      if ((TotalBytes - index) >= ENCODELINELENGTH) then
      begin
            // Output the number of bytes in this line
        SetLength(Output, OutputLength + 1);
        LinePtr := PChar(Output);
        OutChar1 := EncodeAByte(ENCODELINELENGTH);
        LinePtr^ := Chr(OutChar1);
        inc(LinePtr);

        while (line_index < ENCODELINELENGTH) do
        begin
          if InputPtr >= BufferEnd then
            if not MemStuff.NextMemoryBuffer(InputPtr, 0) then
              Break
            else
            begin
              InputPtr := MemStuff.BufPos;
              BufferEnd := MemStuff.BufEnd;
            end;
          Char1 := Byte(InputPtr^);
          inc(InputPtr);
          inc(line_index);
          inc(index);

          if InputPtr >= BufferEnd then
            if not MemStuff.NextMemoryBuffer(InputPtr, 0) then
              Break
            else
            begin
              InputPtr := MemStuff.BufPos;
              BufferEnd := MemStuff.BufEnd;
            end;
          Char2 := Byte(InputPtr^);
          inc(InputPtr);
          inc(line_index);
          inc(index);

          if InputPtr >= BufferEnd then
            if not MemStuff.NextMemoryBuffer(InputPtr, 0) then
              Break
            else
            begin
              InputPtr := MemStuff.BufPos;
              BufferEnd := MemStuff.BufEnd;
            end;
          Char3 := Byte(InputPtr^);
          inc(InputPtr);
          inc(line_index);
          inc(index);

          OutChar1 := Char1 shr 2;
          OutChar2 := (((Char1 shl 4) and $30) or ((Char2 shr 4) and $0F));
          OutChar3 := (((Char2 shl 2) and $3C) or ((Char3 shr 6) and $03));
          OutChar4 := Char3 and $3F;

          OutChar1 := EncodeAByte(OutChar1);
          OutChar2 := EncodeAByte(OutChar2);
          OutChar3 := EncodeAByte(OutChar3);
          OutChar4 := EncodeAByte(OutChar4);

          LinePtr^ := Chr(OutChar1);
          inc(LinePtr);
          LinePtr^ := Chr(OutChar2);
          inc(LinePtr);
          LinePtr^ := Chr(OutChar3);
          inc(LinePtr);
          LinePtr^ := Chr(OutChar4);
          inc(LinePtr);
        end;
        if InputPtr >= BufferEnd then
          if not MemStuff.NextMemoryBuffer(InputPtr, 0) then
            Break
          else
          begin
            InputPtr := MemStuff.BufPos;
            BufferEnd := MemStuff.BufEnd;
          end;
      end
      else
      begin
        Len := TotalBytes - index; // get bytes left over
        Len1 := Len div 3;
        if Frac(Len / 3) > 0.0 then // always round up!
          inc(Len1);
        Len1 := Len1 * 4;
        SetLength(Output, Len1 + 1);
        LinePtr := PChar(Output);
        OutChar1 := EncodeAByte(Len);
        LinePtr^ := Chr(OutChar1);
        inc(LinePtr);

        while (index < TotalBytes) do
        begin
          if (index < TotalBytes) then
          begin
            if InputPtr >= BufferEnd then
              if not MemStuff.NextMemoryBuffer(InputPtr, 0) then
                Break
              else
              begin
                InputPtr := MemStuff.BufPos;
                BufferEnd := MemStuff.BufEnd;
              end;
            Char1 := Byte(InputPtr^);
            inc(InputPtr);
          end
          else
          begin
            Char1 := INVALID;
          end;

          inc(index);

          if (index < TotalBytes) then
          begin
            if InputPtr >= BufferEnd then
              if not MemStuff.NextMemoryBuffer(InputPtr, 0) then
                Break
              else
              begin
                InputPtr := MemStuff.BufPos;
                BufferEnd := MemStuff.BufEnd;
              end;
            Char2 := Byte(InputPtr^);
            inc(InputPtr);
          end
          else
          begin
            Char2 := INVALID;
          end;

          inc(index);

          if (index < TotalBytes) then
          begin
            if InputPtr >= BufferEnd then
              if not MemStuff.NextMemoryBuffer(InputPtr, 0) then
                Break
              else
              begin
                InputPtr := MemStuff.BufPos;
                BufferEnd := MemStuff.BufEnd;
              end;
            Char3 := Byte(InputPtr^);
            inc(InputPtr);
          end
          else
          begin
            Char3 := INVALID;
          end;

          inc(index);

          OutChar1 := Char1 shr 2;
          OutChar2 := (((Char1 shl 4) and $30) or ((Char2 shr 4) and $0F));
          OutChar3 := (((Char2 shl 2) and $3C) or ((Char3 shr 6) and $03));
          OutChar4 := Char3 and $3F;

          OutChar1 := EncodeAByte(OutChar1);
          OutChar2 := EncodeAByte(OutChar2);
          OutChar3 := EncodeAByte(OutChar3);
          OutChar4 := EncodeAByte(OutChar4);

          LinePtr^ := Chr(OutChar1);
          inc(LinePtr);
          LinePtr^ := Chr(OutChar2);
          inc(LinePtr);
          LinePtr^ := Chr(OutChar3);
          inc(LinePtr);
          LinePtr^ := Chr(OutChar4);
          inc(LinePtr);
        end;
        Process := False;
      end;

      LinePtr^ := #0;
      destination.Write(PChar(Output)^, Length(Output));
      destination.Write(CRLF, 2);
    end;
  finally
    MemStuff.Free;
  end;
  Result := True; // no errors reported
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -