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

📄 rm_jclmime.pas

📁 这是一个功能强大
💻 PAS
📖 第 1 页 / 共 3 页
字号:
{**************************************************************************************************}
{                                                                                                  }
{ Project JEDI Code Library (JCL)                                                                  }
{                                                                                                  }
{ The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); }
{ you may not use this file except in compliance with the License. You may obtain a copy of the    }
{ License at http://www.mozilla.org/MPL/                                                           }
{                                                                                                  }
{ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF   }
{ ANY KIND, either express or implied. See the License for the specific language governing rights  }
{ and limitations under the License.                                                               }
{                                                                                                  }
{ The Original Code is JclMime.pas.                                                                }
{                                                                                                  }
{ The Initial Developer of the Original Code is Ralf Junker.                                       }
{ Portions created by Ralf Junker are Copyright (C) Ralf Junker. All rights reserved.              }
{                                                                                                  }
{ Contributors:                                                                                    }
{   Marcel van Brakel                                                                              }
{   Ralf Junker                                                                                    }
{   Robert Marquardt (marquardt)                                                                   }
{   Robert Rossmair (rrossmair)                                                                    }
{   Matthias Thoma (mthoma)                                                                        }
{   Petr Vones (pvones)                                                                            }
{                                                                                                  }
{**************************************************************************************************}
{                                                                                                  }
{ Lightning fast Mime (Base64) Encoding and Decoding routines. Coded by Ralf Junker                }
{ (ralfjunker att gmx dott de).                                                                    }
{                                                                                                  }
{**************************************************************************************************}
{ Migration Guide from JCL 1.90 and older:                                                         }
{                                                                                                  }
{ These new functions now support line breaks (CRLF) as required by RFC 2045.                      }
{ Inserting line breaks is the default behaviour in RFC 2045 therefor the encoding functions now   }
{ encode with line breaks.                                                                         }
{                                                                                                  }
{ This may require changes to your code:                                                           }
{ Encoding without inserting line breaks is possible using the corresponding NoCRLF procedures:    }
{                                                                                                  }
{ MimeEncode => MimeEncodeNoCRLF                                                                   }
{ MimeEncodeString => MimeEncodeStringNoCRLF                                                       }
{ MimeEncodeStream => MimeEncodeStreamNoCRLF                                                       }
{ MimeEncodedSize => MimeEncodedSizeNoCRLF                                                         }
{                                                                                                  }
{**************************************************************************************************}

// Last modified: $Date: 2005-05-05 13:08:48 -0700 (Thu, 05 May 2005) $
// For history see end of file

unit rm_JclMime;

{$I rm_jcl.inc}

interface

uses
  {$IFDEF CLR}
  System.Text,
  {$ENDIF CLR}
  SysUtils, Classes,
  rm_JclBase;

function MimeEncodeString(const S: AnsiString): AnsiString;
function MimeEncodeStringNoCRLF(const S: AnsiString): AnsiString;
function MimeDecodeString(const S: AnsiString): AnsiString;
function MimeEncodedSize(const InputSize: Cardinal): Cardinal;
function MimeEncodedSizeNoCRLF(const InputSize: Cardinal): Cardinal;
function MimeDecodedSize(const InputSize: Cardinal): Cardinal;
procedure DecodeHttpBasicAuthentication(const BasicCredentials: string;
  out UserId, PassWord: string);
{$IFDEF CLR}
procedure MimeEncode(const InputBuffer: TDynByteArray; InputOffset: Cardinal;
  const InputByteCount: Cardinal; out OutputBuffer: TDynByteArray; OutputOffset: Cardinal = 0); overload;
procedure MimeEncodeNoCRLF(const InputBuffer: TDynByteArray; InputOffset: Cardinal;
  const InputByteCount: Cardinal; out OutputBuffer: TDynByteArray; OutputOffset: Cardinal = 0); overload;
procedure MimeEncodeFullLines(const InputBuffer: TDynByteArray; InputOffset: Cardinal;
  const InputByteCount: Cardinal; out OutputBuffer: TDynByteArray; OutputOffset: Cardinal = 0); overload;
function MimeDecode(const InputBuffer: TDynByteArray; InputOffset: Cardinal;
  const InputByteCount: Cardinal; out OutputBuffer: TDynByteArray; OutputOffset: Cardinal = 0): Cardinal; overload;
function MimeDecodePartial(const InputBuffer: TDynByteArray; InputOffset: Cardinal;
  const InputByteCount: Cardinal; out OutputBuffer: TDynByteArray; OutputOffset: Cardinal;
  var ByteBuffer: Cardinal; var ByteBufferSpace: Cardinal): Cardinal; overload;
function MimeDecodePartialEnd(out OutputBuffer: TDynByteArray; OutputOffset: Cardinal;
  const ByteBuffer: Cardinal; const ByteBufferSpace: Cardinal): Cardinal; overload;

procedure MimeEncode(const InputBuffer: TDynByteArray; const InputByteCount: Cardinal;
  out OutputBuffer: TDynByteArray); overload;
procedure MimeEncodeNoCRLF(const InputBuffer: TDynByteArray; const InputByteCount: Cardinal;
  out OutputBuffer: TDynByteArray); overload;
procedure MimeEncodeFullLines(const InputBuffer: TDynByteArray; const InputByteCount: Cardinal;
  out OutputBuffer: TDynByteArray); overload;
function MimeDecode(const InputBuffer: TDynByteArray; const InputByteCount: Cardinal;
  out OutputBuffer: TDynByteArray): Cardinal; overload;
function MimeDecodePartial(const InputBuffer: TDynByteArray; const InputByteCount: Cardinal;
  out OutputBuffer: TDynByteArray; var ByteBuffer: Cardinal; var ByteBufferSpace: Cardinal): Cardinal; overload;
function MimeDecodePartialEnd(out OutputBuffer: TDynByteArray; const ByteBuffer: Cardinal;
  const ByteBufferSpace: Cardinal): Cardinal; overload;

{$ELSE}
procedure MimeEncode(const InputBuffer; const InputByteCount: Cardinal; out OutputBuffer);
procedure MimeEncodeNoCRLF(const InputBuffer; const InputByteCount: Cardinal; out OutputBuffer);
procedure MimeEncodeFullLines(const InputBuffer; const InputByteCount: Cardinal; out OutputBuffer);
function MimeDecode(const InputBuffer; const InputByteCount: Cardinal; out OutputBuffer): Cardinal;
function MimeDecodePartial(const InputBuffer; const InputByteCount: Cardinal; out OutputBuffer;
  var ByteBuffer: Cardinal; var ByteBufferSpace: Cardinal): Cardinal;
function MimeDecodePartialEnd(out OutputBuffer; const ByteBuffer: Cardinal;
  const ByteBufferSpace: Cardinal): Cardinal;
{$ENDIF CLR}
procedure MimeEncodeFile(const InputFileName, OutputFileName: AnsiString);
procedure MimeEncodeFileNoCRLF(const InputFileName, OutputFileName: AnsiString);
procedure MimeDecodeFile(const InputFileName, OutputFileName: AnsiString);
procedure MimeEncodeStream(const InputStream: TStream; const OutputStream: TStream);
procedure MimeEncodeStreamNoCRLF(const InputStream: TStream; const OutputStream: TStream);
procedure MimeDecodeStream(const InputStream: TStream; const OutputStream: TStream);

const
  MIME_ENCODED_LINE_BREAK = 76;
  MIME_DECODED_LINE_BREAK = MIME_ENCODED_LINE_BREAK div 4 * 3;
  MIME_BUFFER_SIZE = MIME_DECODED_LINE_BREAK * 3 * 4 * 4;

implementation

// Caution: For MimeEncodeStream and all other kinds of multi-buffered
// Mime encodings (i.e. Files etc.), BufferSize must be set to a multiple of 3.
// Even though the implementation of the Mime decoding routines below
// do not require a particular buffer size, they work fastest with sizes of
// multiples of four. The chosen size is a multiple of 3 and of 4 as well.
// The following numbers are, in addition, also divisible by 1024:
// $2400, $3000, $3C00, $4800, $5400, $6000, $6C00.

const
  BUFFER_SIZE = $3000;
  EqualSign = Byte('=');

const
  { The mime encoding table. Do not alter. }
  MIME_ENCODE_TABLE: array [0..63] of Byte = (
    065, 066, 067, 068, 069, 070, 071, 072, //  00 - 07
    073, 074, 075, 076, 077, 078, 079, 080, //  08 - 15
    081, 082, 083, 084, 085, 086, 087, 088, //  16 - 23
    089, 090, 097, 098, 099, 100, 101, 102, //  24 - 31
    103, 104, 105, 106, 107, 108, 109, 110, //  32 - 39
    111, 112, 113, 114, 115, 116, 117, 118, //  40 - 47
    119, 120, 121, 122, 048, 049, 050, 051, //  48 - 55
    052, 053, 054, 055, 056, 057, 043, 047); // 56 - 63

  MIME_PAD_CHAR = Byte('=');

  MIME_DECODE_TABLE: array [Byte] of Cardinal = (
    255, 255, 255, 255, 255, 255, 255, 255, //   0 -   7
    255, 255, 255, 255, 255, 255, 255, 255, //   8 -  15
    255, 255, 255, 255, 255, 255, 255, 255, //  16 -  23
    255, 255, 255, 255, 255, 255, 255, 255, //  24 -  31
    255, 255, 255, 255, 255, 255, 255, 255, //  32 -  39
    255, 255, 255, 062, 255, 255, 255, 063, //  40 -  47
    052, 053, 054, 055, 056, 057, 058, 059, //  48 -  55
    060, 061, 255, 255, 255, 255, 255, 255, //  56 -  63
    255, 000, 001, 002, 003, 004, 005, 006, //  64 -  71
    007, 008, 009, 010, 011, 012, 013, 014, //  72 -  79
    015, 016, 017, 018, 019, 020, 021, 022, //  80 -  87
    023, 024, 025, 255, 255, 255, 255, 255, //  88 -  95
    255, 026, 027, 028, 029, 030, 031, 032, //  96 - 103
    033, 034, 035, 036, 037, 038, 039, 040, // 104 - 111
    041, 042, 043, 044, 045, 046, 047, 048, // 112 - 119
    049, 050, 051, 255, 255, 255, 255, 255, // 120 - 127
    255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 255, 255, 255, 255, 255, 255);

{$IFDEF CLR}
procedure MimeEncode(const InputBuffer: TDynByteArray; const InputByteCount: Cardinal;
  out OutputBuffer: TDynByteArray);
begin
  MimeEncode(InputBuffer, 0, InputByteCount, OutputBuffer, 0);
end;

procedure MimeEncodeNoCRLF(const InputBuffer: TDynByteArray; const InputByteCount: Cardinal;
  out OutputBuffer: TDynByteArray);
begin
  MimeEncodeNoCRLF(InputBuffer, 0, InputByteCount, OutputBuffer, 0);
end;

procedure MimeEncodeFullLines(const InputBuffer: TDynByteArray; const InputByteCount: Cardinal;
  out OutputBuffer: TDynByteArray);
begin
  MimeEncodeFullLines(InputBuffer, 0, InputByteCount, OutputBuffer, 0);
end;

function MimeDecode(const InputBuffer: TDynByteArray; const InputByteCount: Cardinal;
  out OutputBuffer: TDynByteArray): Cardinal;
begin
  Result := MimeDecode(InputBuffer, 0, InputByteCount, OutputBuffer, 0);
end;

function MimeDecodePartial(const InputBuffer: TDynByteArray; const InputByteCount: Cardinal;
  out OutputBuffer: TDynByteArray; var ByteBuffer: Cardinal; var ByteBufferSpace: Cardinal): Cardinal;
begin
  Result := MimeDecodePartial(InputBuffer, 0, InputByteCount, OutputBuffer, 0, ByteBuffer, ByteBufferSpace);
end;

function MimeDecodePartialEnd(out OutputBuffer: TDynByteArray; const ByteBuffer: Cardinal;
  const ByteBufferSpace: Cardinal): Cardinal;
begin
  Result := MimeDecodePartialEnd(OutputBuffer, 0, ByteBuffer, ByteBufferSpace);
end;
{$ELSE}
type
  PByte4 = ^TByte4;
  TByte4 = packed record
    B1: Byte;
    B2: Byte;
    B3: Byte;
    B4: Byte;
  end;

  PByte3 = ^TByte3;
  TByte3 = packed record
    B1: Byte;
    B2: Byte;
    B3: Byte;
  end;
{$ENDIF CLR}

// Wrapper functions & procedures
function MimeEncodeString(const S: AnsiString): AnsiString;
var
  L: Cardinal;
  {$IFDEF CLR}
  Bytes: TDynByteArray;
  {$ENDIF CLR}
begin
  if S <> '' then
  begin
    {$IFDEF CLR}
    L := Length(S);
    SetLength(Bytes, MimeEncodedSize(L));
    MimeEncode(BytesOf(S), 0, L, Bytes, 0);
    Result := Bytes;
    {$ELSE}
    L := PCardinal(Cardinal(S) - 4)^;
    SetLength(Result, MimeEncodedSize(L));
    MimeEncode(Pointer(S)^, L, Pointer(Result)^);
    {$ENDIF CLR}
  end
  else
    Result := '';
end;

function MimeEncodeStringNoCRLF(const S: AnsiString): AnsiString;
var
  L: Cardinal;
  {$IFDEF CLR}
  Bytes: TDynByteArray;
  {$ENDIF CLR}
begin
  if S <> '' then
  begin
    {$IFDEF CLR}
    L := Length(S);
    SetLength(Bytes, MimeEncodedSizeNoCRLF(L));
    MimeEncodeNoCRLF(BytesOf(S), 0, L, Bytes, 0);
    Result := Bytes;
    {$ELSE}
    L := PCardinal(Cardinal(S) - 4)^;
    SetLength(Result, MimeEncodedSizeNoCRLF(L));
    MimeEncodeNoCRLF(Pointer(S)^, L, Pointer(Result)^);
    {$ENDIF CLR}
  end
  else
    Result := '';
end;

function MimeDecodeString(const S: AnsiString): AnsiString;
var
  ByteBuffer, ByteBufferSpace: Cardinal;
  L: Cardinal;
  {$IFDEF CLR}
  Bytes: TDynByteArray;
  {$ENDIF CLR}
begin
  if S <> '' then
  begin
    {$IFDEF CLR}
    L := Length(S);
    SetLength(Bytes, MimeEncodedSize(L));
    ByteBuffer := 0;
    ByteBufferSpace := 4;
    L := MimeDecodePartial(BytesOf(S), 0, L, Bytes, 0, ByteBuffer, ByteBufferSpace);
    Inc(L, MimeDecodePartialEnd(Bytes, 0 + L, ByteBuffer, ByteBufferSpace));
    SetLength(Bytes, L);
    Result := Bytes;
    {$ELSE}
    L := PCardinal(Cardinal(S) - 4)^;
    SetLength(Result, MimeDecodedSize(L));
    ByteBuffer := 0;
    ByteBufferSpace := 4;
    L := MimeDecodePartial(Pointer(S)^, L, Pointer(Result)^, ByteBuffer, ByteBufferSpace);
    Inc(L, MimeDecodePartialEnd(Pointer(Cardinal(Result) + L)^, ByteBuffer, ByteBufferSpace));
    SetLength(Result, L);
    {$ENDIF CLR}
  end
  else
    Result := '';
end;

procedure DecodeHttpBasicAuthentication(const BasicCredentials: string; out UserId, PassWord: string);
const
  LBasic = 6; { Length ('Basic ') }
{$IFDEF CLR}
var
  Index: Cardinal;
  Decoded: TDynByteArray;
  I, L: Cardinal;
begin
  UserId := '';
  PassWord := '';
  L := Length(BasicCredentials);
  if L < LBasic then // includes "L = 0"
    Exit;
  Dec(L, LBasic);

⌨️ 快捷键说明

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