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

📄 rm_jclmime.pas

📁 这是一个功能强大
💻 PAS
📖 第 1 页 / 共 3 页
字号:
        B := B shr 6;
        OutPtr.B1 := MIME_ENCODE_TABLE[B];
        OutPtr.B4 := MIME_PAD_CHAR; { Pad remaining byte. }
      end;
  end;
end;
{$ENDIF CLR}

// Decoding Core
function MimeDecode(const InputBuffer {$IFDEF CLR}: TDynByteArray; InputOffset: Cardinal {$ENDIF CLR};
  const InputByteCount: Cardinal; out OutputBuffer {$IFDEF CLR}: TDynByteArray; OutputOffset: Cardinal {$ENDIF CLR}): Cardinal;
var
  ByteBuffer, ByteBufferSpace: Cardinal;
begin
  ByteBuffer := 0;
  ByteBufferSpace := 4;
  {$IFDEF CLR}
  Result := MimeDecodePartial(InputBuffer, InputOffset, InputByteCount, OutputBuffer, OutputOffset, ByteBuffer, ByteBufferSpace);
  Inc(Result, MimeDecodePartialEnd(OutputBuffer, OutputOffset + Result, ByteBuffer, ByteBufferSpace));
  {$ELSE}
  Result := MimeDecodePartial(InputBuffer, InputByteCount, OutputBuffer, ByteBuffer, ByteBufferSpace);
  Inc(Result, MimeDecodePartialEnd(Pointer(Cardinal(@OutputBuffer) + Result)^, ByteBuffer, ByteBufferSpace));
  {$ENDIF CLR}
end;

{$IFDEF CLR}
function MimeDecodePartial(const InputBuffer: TDynByteArray; InputOffset: Cardinal;
  const InputByteCount: Cardinal; out OutputBuffer: TDynByteArray; OutputOffset: Cardinal;
  var ByteBuffer: Cardinal; var ByteBufferSpace: Cardinal): Cardinal;
var
  LByteBuffer, LByteBufferSpace, C: Cardinal;
  InIndex, OuterLimit: Cardinal;
  OutIndex: Cardinal;
begin
  if InputByteCount > 0 then
    begin
      InIndex := InputOffset;
      OuterLimit := InIndex + InputByteCount;
      OutIndex := OutputOffset;
      LByteBuffer := ByteBuffer;
      LByteBufferSpace := ByteBufferSpace;
      while InIndex < OuterLimit do
      begin
        { Read from InputBuffer. }
        C := MIME_DECODE_TABLE[InputBuffer[InIndex]];
        Inc(InIndex);
        if C = $FF then
          Continue;
        LByteBuffer := LByteBuffer shl 6;
        LByteBuffer := LByteBuffer or C;
        Dec(LByteBufferSpace);
        { Have we read 4 bytes from InputBuffer? }
        if LByteBufferSpace <> 0 then
          Continue;

        { Write 3 bytes to OutputBuffer (in reverse order). }
        OutputBuffer[OutIndex + 2] := Byte(LByteBuffer);
        LByteBuffer := LByteBuffer shr 8;
        OutputBuffer[OutIndex + 1] := Byte(LByteBuffer);
        LByteBuffer := LByteBuffer shr 8;
        OutputBuffer[OutIndex + 0] := Byte(LByteBuffer);
        LByteBuffer := 0;
        Inc(OutINdex);
        LByteBufferSpace := 4;
      end;
      ByteBuffer := LByteBuffer;
      ByteBufferSpace := LByteBufferSpace;
      Result := OutIndex - OutputOffset;
    end
  else
    Result := 0;
end;
{$ELSE}
function MimeDecodePartial(const InputBuffer; const InputByteCount: Cardinal; out OutputBuffer;
  var ByteBuffer: Cardinal; var ByteBufferSpace: Cardinal): Cardinal;
var
  LByteBuffer, LByteBufferSpace, C: Cardinal;
  InPtr, OuterLimit: ^Byte;
  OutPtr: PByte3;
begin
  if InputByteCount > 0 then
  begin
    InPtr := @InputBuffer;
    Cardinal(OuterLimit) := Cardinal(InPtr) + InputByteCount;
    OutPtr := @OutputBuffer;
    LByteBuffer := ByteBuffer;
    LByteBufferSpace := ByteBufferSpace;
    while InPtr <> OuterLimit do
    begin
      { Read from InputBuffer. }
      C := MIME_DECODE_TABLE[InPtr^];
      Inc(InPtr);
      if C = $FF then
        Continue;
      LByteBuffer := LByteBuffer shl 6;
      LByteBuffer := LByteBuffer or C;
      Dec(LByteBufferSpace);
      { Have we read 4 bytes from InputBuffer? }
      if LByteBufferSpace <> 0 then
        Continue;

      { Write 3 bytes to OutputBuffer (in reverse order). }
      OutPtr^.B3 := Byte(LByteBuffer);
      LByteBuffer := LByteBuffer shr 8;
      OutPtr^.B2 := Byte(LByteBuffer);
      LByteBuffer := LByteBuffer shr 8;
      OutPtr^.B1 := Byte(LByteBuffer);
      LByteBuffer := 0;
      Inc(OutPtr);
      LByteBufferSpace := 4;
    end;
    ByteBuffer := LByteBuffer;
    ByteBufferSpace := LByteBufferSpace;
    Result := Cardinal(OutPtr) - Cardinal(@OutputBuffer);
  end
  else
    Result := 0;
end;
{$ENDIF CLR}

function MimeDecodePartialEnd(out OutputBuffer {$IFDEF CLR}: TDynByteArray; OutputOffset: Cardinal {$ENDIF CLR};
  const ByteBuffer: Cardinal; const ByteBufferSpace: Cardinal): Cardinal;
var
  LByteBuffer: Cardinal;
begin
  case ByteBufferSpace of
    1:
      begin
        LByteBuffer := ByteBuffer shr 2;
        {$IFDEF CLR}
        OutputBuffer[OutputOffset + 1] := Byte(LByteBuffer);
        LByteBuffer := LByteBuffer shr 8;
        OutputBuffer[OutputOffset + 0] := Byte(LByteBuffer);
        {$ELSE}
        PByte3(@OutputBuffer)^.B2 := Byte(LByteBuffer);
        LByteBuffer := LByteBuffer shr 8;
        PByte3(@OutputBuffer)^.B1 := Byte(LByteBuffer);
        {$ENDIF CLR}
        Result := 2;
      end;
    2:
      begin
        LByteBuffer := ByteBuffer shr 4;
        {$IFDEF CLR}
        OutputBuffer[OutputOffset + 0] := Byte(LByteBuffer);
        {$ELSE}
        PByte3(@OutputBuffer)^.B1 := Byte(LByteBuffer);
        {$ENDIF CLR}
        Result := 1;
      end;
  else
    Result := 0;
  end;
end;

// File Encoding & Decoding
procedure MimeEncodeFile(const InputFileName, OutputFileName: AnsiString);
var
  InputStream, OutputStream: TFileStream;
begin
  InputStream := TFileStream.Create(InputFileName, fmOpenRead or fmShareDenyWrite);
  try
    OutputStream := TFileStream.Create(OutputFileName, fmCreate);
    try
      MimeEncodeStream(InputStream, OutputStream);
    finally
      OutputStream.Free;
    end;
  finally
    InputStream.Free;
  end;
end;

procedure MimeEncodeFileNoCRLF(const InputFileName, OutputFileName: AnsiString);
var
  InputStream, OutputStream: TFileStream;
begin
  InputStream := TFileStream.Create(InputFileName, fmOpenRead or fmShareDenyWrite);
  try
    OutputStream := TFileStream.Create(OutputFileName, fmCreate);
    try
      MimeEncodeStreamNoCRLF(InputStream, OutputStream);
    finally
      OutputStream.Free;
    end;
  finally
    InputStream.Free;
  end;
end;

procedure MimeDecodeFile(const InputFileName, OutputFileName: AnsiString);
var
  InputStream, OutputStream: TFileStream;
begin
  InputStream := TFileStream.Create(InputFileName, fmOpenRead or fmShareDenyWrite);
  try
    OutputStream := TFileStream.Create(OutputFileName, fmCreate);
    try
      MimeDecodeStream(InputStream, OutputStream);
    finally
      OutputStream.Free;
    end;
  finally
    InputStream.Free;
  end;
end;

// Stream Encoding & Decoding
procedure MimeEncodeStream(const InputStream: TStream; const OutputStream: TStream);
var
  InputBuffer: array [0..MIME_BUFFER_SIZE - 1] of Byte;
  {$IFDEF CLR}
  OutputBuffer: array of Byte;
  {$ELSE}
  OutputBuffer: array [0..(MIME_BUFFER_SIZE + 2) div 3 * 4 + MIME_BUFFER_SIZE div MIME_DECODED_LINE_BREAK * 2 - 1] of Byte;
  {$ENDIF CLR}
  BytesRead: Cardinal;
  IDelta, ODelta: Cardinal;
begin
  BytesRead := InputStream.Read(InputBuffer, SizeOf(InputBuffer));
  {$IFDEF CLR}
  SetLength(OutputBuffer, (MIME_BUFFER_SIZE + 2) div 3 * 4 + MIME_BUFFER_SIZE div MIME_DECODED_LINE_BREAK * 2);
  {$ENDIF CLR}

  while BytesRead = Cardinal(Length(InputBuffer)) do
  begin
    MimeEncodeFullLines(InputBuffer, Length(InputBuffer), OutputBuffer);
    OutputStream.Write(OutputBuffer, Length(OutputBuffer));
    BytesRead := InputStream.Read(InputBuffer, Length(InputBuffer));
  end;

  MimeEncodeFullLines(InputBuffer, BytesRead, OutputBuffer);

  IDelta := BytesRead div MIME_DECODED_LINE_BREAK; // Number of lines processed.
  ODelta := IDelta * (MIME_ENCODED_LINE_BREAK + 2);
  IDelta := IDelta * MIME_DECODED_LINE_BREAK;
  {$IFDEF ClR}
  MimeEncodeNoCRLF(InputBuffer, IDelta, BytesRead - IDelta, OutputBuffer, ODelta);
  {$ELSE}
  MimeEncodeNoCRLF(Pointer(Cardinal(@InputBuffer) + IDelta)^, BytesRead - IDelta, Pointer(Cardinal(@OutputBuffer) + ODelta)^);
  {$ENDIF CLR}

  OutputStream.Write(OutputBuffer, MimeEncodedSize(BytesRead));
end;

procedure MimeEncodeStreamNoCRLF(const InputStream: TStream; const OutputStream: TStream);
var
  InputBuffer: array [0..MIME_BUFFER_SIZE - 1] of Byte;
  {$IFDEF CLR}
  OutputBuffer: array of Byte;
  {$ELSE}
  OutputBuffer: array [0..((MIME_BUFFER_SIZE + 2) div 3) * 4 - 1] of Byte;
  {$ENDIF CLR}
  BytesRead: Cardinal;
begin
  BytesRead := InputStream.Read(InputBuffer, SizeOf(InputBuffer));
  {$IFDEF CLR}
  SetLength(OutputBuffer, ((MIME_BUFFER_SIZE + 2) div 3) * 4);
  {$ENDIF CLR}

  while BytesRead = Cardinal(Length(InputBuffer)) do
  begin
    MimeEncodeNoCRLF(InputBuffer, Length(InputBuffer), OutputBuffer);
    OutputStream.Write(OutputBuffer, Length(OutputBuffer));
    BytesRead := InputStream.Read(InputBuffer, Length(InputBuffer));
  end;

  MimeEncodeNoCRLF(InputBuffer, BytesRead, OutputBuffer);
  OutputStream.Write(OutputBuffer, MimeEncodedSizeNoCRLF(BytesRead));
end;

procedure MimeDecodeStream(const InputStream: TStream; const OutputStream: TStream);
var
  ByteBuffer, ByteBufferSpace: Cardinal;
  InputBuffer: array [0..MIME_BUFFER_SIZE - 1] of Byte;
  {$IFDEF CLR}
  OutputBuffer: array of Byte;
  {$ELSE}
  OutputBuffer: array [0..(MIME_BUFFER_SIZE + 3) div 4 * 3 - 1] of Byte;
  {$ENDIF CLR}
  BytesRead: Cardinal;
begin
  ByteBuffer := 0;
  ByteBufferSpace := 4;
  BytesRead := InputStream.Read(InputBuffer, SizeOf(InputBuffer));
  {$IFDEF CLR}
  SetLength(OutputBuffer, (MIME_BUFFER_SIZE + 3) div 4 * 3);
  {$ENDIF CLR}

  while BytesRead > 0 do
  begin
    OutputStream.Write(OutputBuffer, MimeDecodePartial(InputBuffer, BytesRead, OutputBuffer, ByteBuffer, ByteBufferSpace));
    BytesRead := InputStream.Read(InputBuffer, Length(InputBuffer));
  end;
  OutputStream.Write(OutputBuffer, MimeDecodePartialEnd(OutputBuffer, ByteBuffer, ByteBufferSpace));
end;

// History:

// $Log$
// Revision 1.14  2005/05/05 20:08:43  ahuser
// JCL.NET support
//
// Revision 1.13  2005/02/24 16:34:40  marquardt
// remove divider lines, add section lines (unfinished)
//
// Revision 1.12  2005/02/13 22:24:25  rrossmair
// moved PCardinal declaration from JclMime to JclBase
//
// Revision 1.11  2004/10/13 06:58:19  marquardt
// normal style cleaning
//
// Revision 1.10  2004/10/12 18:29:52  rrossmair
// cleanup
//
// Revision 1.9  2004/07/28 18:00:51  marquardt
// various style cleanings, some minor fixes
//
// Revision 1.8  2004/07/07 22:34:25  mthoma
// Added Ralf MimeStreams and MimeFile utilities...
//
// Revision 1.7  2004/06/14 13:05:18  marquardt
// style cleaning ENDIF, Tabs
//
// Revision 1.6  2004/05/05 00:09:59  mthoma
// Updated headers: Added donors as contributors, adjusted the initial authors, added cvs names when they were not obvious. Changed $data to $date where necessary,
//
// Revision 1.5  2004/04/09 20:21:11  mthoma
// Updated to Ralfs latest release. That also fixed 0000406.
//

end.

⌨️ 快捷键说明

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