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

📄 nmuudecode.pas

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

interface
uses
  Classes;

function UUEDecode(const Source: TStream; var Destination: TStream): Boolean;

implementation


function UUEDecode(const Source: TStream; var Destination: TStream): Boolean;
const
  EOL = #0;
  EOB = #0;
  CR = #13;
  LF = #10;
  Invalid = $FF;

var
  Stream_Ptr: PChar;


  function Decode_Char(c: Char): Byte;
  begin
    Result := ((Byte(c) - $20) and $3F);
  end;

  procedure decode;
  var
    Char1: Byte;
    Char2: Byte;
    Char3: Byte;
    Char4: Byte;

    Line_Ptr: PChar;
    Line_Length: LongInt;
    Line: string;
  begin
    Line_Length := Decode_Char(Stream_Ptr^);
    inc(Stream_Ptr);

    SetLength(Line, Line_Length);
    Line_Ptr := PChar(Line);

    while Line_Length > 0 do
    begin
      if Stream_Ptr^ > EOL then
      begin
        Char1 := Decode_Char(Stream_Ptr^);
        inc(Stream_Ptr);
      end
      else
        Char1 := Invalid;

      if Stream_Ptr^ > EOL then
      begin
        Char2 := Decode_Char(Stream_Ptr^);
        inc(Stream_Ptr);
      end
      else
        Char2 := Invalid;

      if Stream_Ptr^ > EOL then
      begin
        Char3 := Decode_Char(Stream_Ptr^);
        inc(Stream_Ptr);
      end
      else
        Char3 := Invalid;

      if Stream_Ptr^ > EOL then
      begin
        Char4 := Decode_Char(Stream_Ptr^);
        inc(Stream_Ptr);
      end
      else
        Char4 := Invalid;

      Line_Ptr^ := Char((Char1 shl 2) or (Char2 shr 4));
      inc(Line_Ptr);
      Line_Ptr^ := Char((Char2 shl 4) or (Char3 shr 2));
      inc(Line_Ptr);
      Line_Ptr^ := Char((Char3 shl 6) or (Char4));
      inc(Line_Ptr);
      Dec(Line_Length, 3);
    end;
    Destination.Write(Pointer(Line)^, Length(Line));
  end;

const
  MaxBufSize = $FFFE;

var
  Buffer, FillPos, BufPos: PChar;
  Counter, BytesRead: LongInt;
  SourceSize: LongInt;
begin
  Result := TRUE;

  SourceSize := Source.Size;
  Destination.Seek(0, soFromEnd);

  Counter := 0;

  GetMem(Buffer, MaxBufSize + 1);
  FillPos := Buffer;
  inc(FillPos, MaxBufSize + 1);
  FillPos^ := EOB;
  try
    while Source.Position < SourceSize do
    begin
      FillPos := Buffer;
      inc(FillPos, Counter);
      BytesRead := Source.Read(FillPos^, MaxBufSize - Counter);
      inc(Counter, BytesRead);
      BufPos := Buffer;
      inc(FillPos, Counter);
      FillPos^ := EOB;
      Counter := 0;
      while BufPos^ <> EOB do
      begin
        Stream_Ptr := BufPos;

        while not (BufPos^ in [EOB, LF, CR]) do
          inc(BufPos);
        if BufPos^ <> EOB then
        begin
          BufPos^ := EOL;
          decode;
          if BufPos^ = EOB then inc(BufPos);
          if BufPos^ = CR then inc(BufPos);
          if BufPos^ = LF then inc(BufPos);
        end
        else
        begin
          Counter := BufPos - Stream_Ptr;
          System.Move(Stream_Ptr^, Buffer^, Counter + 1);
          Break;
        end;
      end;
    end;
    if Counter > 0 then
    begin
      Stream_Ptr := Buffer;
      decode;
    end;
  finally
    FreeMem(Buffer, MaxBufSize);
  end;
end;

end.

⌨️ 快捷键说明

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