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

📄 rm_jclmime.pas

📁 这是一个功能强大
💻 PAS
📖 第 1 页 / 共 3 页
字号:
  Index := LBasic;

  SetLength(Decoded, MimeDecodedSize(L));
  L := MimeDecode(BytesOf(BasicCredentials), Index, L, Decoded, 0);

  { Look for colon (':'). }
  I := 0;
  while (L > 0) and (Char(Decoded[I]) <> ':') do
  begin
    Inc(I);
    Dec(L);
  end;

  { Store UserId and Password. }
  UserId := Copy(Decoded, 0, I);
  if L > 1 then
    PassWord := Copy(Decoded, I + 1, L - 1)
  else
    PassWord := '';
end;
{$ELSE}
var
  DecodedPtr, P: PAnsiChar;
  I, L: Cardinal;
begin
  UserId := '';
  PassWord := '';

  P := Pointer(BasicCredentials);
  if P = nil then
    Exit;

  L := Cardinal(Pointer(P - 4)^);
  if L <= LBasic then
    Exit;

  Dec(L, LBasic);
  Inc(P, LBasic);

  GetMem(DecodedPtr, MimeDecodedSize(L));
  L := MimeDecode(P^, L, DecodedPtr^);

  { Look for colon (':'). }
  I := 0;
  P := DecodedPtr;
  while (L > 0) and (P[I] <> ':') do
  begin
    Inc(I);
    Dec(L);
  end;

  { Store UserId and Password. }
  SetString(UserId, DecodedPtr, I);
  if L > 1 then
    SetString(PassWord, DecodedPtr + I + 1, L - 1)
  else
    PassWord := '';

  FreeMem(DecodedPtr);
end;
{$ENDIF CLR}

// Helper functions
function MimeEncodedSize(const InputSize: Cardinal): Cardinal;
begin
  if InputSize > 0 then
    Result := (InputSize + 2) div 3 * 4 + (InputSize - 1) div MIME_DECODED_LINE_BREAK * 2
  else
    Result := InputSize;
end;

function MimeEncodedSizeNoCRLF(const InputSize: Cardinal): Cardinal;
begin
  Result := (InputSize + 2) div 3 * 4;
end;

function MimeDecodedSize(const InputSize: Cardinal): Cardinal;
begin
  Result := (InputSize + 3) div 4 * 3;
end;


// Primary functions & procedures
procedure MimeEncode(const InputBuffer {$IFDEF CLR}: TDynByteArray; InputOffset: Cardinal {$ENDIF CLR};
  const InputByteCount: Cardinal;
  out OutputBuffer {$IFDEF CLR}: TDynByteArray; OutputOffset: Cardinal {$ENDIF CLR});
var
  IDelta, ODelta: Cardinal;
begin
  {$IFDEF CLR}
  MimeEncodeFullLines(InputBuffer, InputOffset, InputByteCount, OutputBuffer, OutputOffset);
  {$ELSE}
  MimeEncodeFullLines(InputBuffer, InputByteCount, OutputBuffer);
  {$ENDIF CLR}
  IDelta := InputByteCount div MIME_DECODED_LINE_BREAK; // Number of lines processed so far.
  ODelta := IDelta * (MIME_ENCODED_LINE_BREAK + 2);
  IDelta := IDelta * MIME_DECODED_LINE_BREAK;
  {$IFDEF CLR}
  MimeEncodeNoCRLF(InputBuffer, InputOffset + IDelta, InputByteCount - IDelta, OutputBuffer, OutputOffset + ODelta);
  {$ELSE}
  MimeEncodeNoCRLF(Pointer(Cardinal(@InputBuffer) + IDelta)^, InputByteCount - IDelta, Pointer(Cardinal(@OutputBuffer) + ODelta)^);
  {$ENDIF CLR}
end;

{$IFDEF CLR}
procedure MimeEncodeFullLines(const InputBuffer: TDynByteArray; InputOffset: Cardinal;
  const InputByteCount: Cardinal; out OutputBuffer: TDynByteArray; OutputOffset: Cardinal);
var
  B, InnerLimit, OuterLimit: Cardinal;
  InIndex: Cardinal;
  OutIndex: Cardinal;
begin
  { Do we have enough input to encode a full line? }
  if InputByteCount < MIME_DECODED_LINE_BREAK then
    Exit;

  InIndex := InputOffset;
  OutIndex := OutputOffset;

  InnerLimit := InIndex;
  Inc(InnerLimit, MIME_DECODED_LINE_BREAK);

  OuterLimit := InIndex;
  Inc(OuterLimit, InputByteCount);

  { Multiple line loop. }
  repeat
    { Single line loop. }
    repeat
      { Read 3 bytes from InputBuffer. }
      B := InputBuffer[InIndex + 0];
      B := B shl 8;
      B := B or InputBuffer[InIndex + 1];
      B := B shl 8;
      B := B or InputBuffer[InIndex + 2];
      Inc(InIndex);
      { Write 4 bytes to OutputBuffer (in reverse order). }
      OutputBuffer[OutIndex + 3] := MIME_ENCODE_TABLE[B and $3F];
      B := B shr 6;
      OutputBuffer[OutIndex + 2] := MIME_ENCODE_TABLE[B and $3F];
      B := B shr 6;
      OutputBuffer[OutIndex + 1] := MIME_ENCODE_TABLE[B and $3F];
      B := B shr 6;
      OutputBuffer[OutIndex + 0] := MIME_ENCODE_TABLE[B];
      Inc(OutIndex);
    until InIndex >= InnerLimit;

    { Write line break (CRLF). }
    OutputBuffer[OutIndex + 0] := 13;
    OutputBuffer[OutIndex + 1] := 10;
    Inc(OutIndex, 2);

    Inc(InnerLimit, MIME_DECODED_LINE_BREAK);
  until InnerLimit > OuterLimit;
end;
{$ELSE}
procedure MimeEncodeFullLines(const InputBuffer; const InputByteCount: Cardinal; out OutputBuffer);
var
  B, InnerLimit, OuterLimit: Cardinal;
  InPtr: PByte3;
  OutPtr: PByte4;
begin
  { Do we have enough input to encode a full line? }
  if InputByteCount < MIME_DECODED_LINE_BREAK then
    Exit;

  InPtr := @InputBuffer;
  OutPtr := @OutputBuffer;

  InnerLimit := Cardinal(InPtr);
  Inc(InnerLimit, MIME_DECODED_LINE_BREAK);

  OuterLimit := Cardinal(InPtr);
  Inc(OuterLimit, InputByteCount);

  { Multiple line loop. }
  repeat
    { Single line loop. }
    repeat
      { Read 3 bytes from InputBuffer. }
      B := InPtr^.B1;
      B := B shl 8;
      B := B or InPtr^.B2;
      B := B shl 8;
      B := B or InPtr^.B3;
      Inc(InPtr);
      { Write 4 bytes to OutputBuffer (in reverse order). }
      OutPtr^.B4 := MIME_ENCODE_TABLE[B and $3F];
      B := B shr 6;
      OutPtr^.B3 := MIME_ENCODE_TABLE[B and $3F];
      B := B shr 6;
      OutPtr^.B2 := MIME_ENCODE_TABLE[B and $3F];
      B := B shr 6;
      OutPtr^.B1 := MIME_ENCODE_TABLE[B];
      Inc(OutPtr);
    until Cardinal(InPtr) >= InnerLimit;

    { Write line break (CRLF). }
    OutPtr^.B1 := 13;
    OutPtr^.B2 := 10;
    Inc(Cardinal(OutPtr), 2);

    Inc(InnerLimit, MIME_DECODED_LINE_BREAK);
  until InnerLimit > OuterLimit;
end;
{$ENDIF CLR}

{$IFDEF CLR}
procedure MimeEncodeNoCRLF(const InputBuffer: TDynByteArray; InputOffset: Cardinal;
  const InputByteCount: Cardinal; out OutputBuffer: TDynByteArray; OutputOffset: Cardinal);
var
  B, InnerLimit, OuterLimit: Cardinal;
  InIndex: Cardinal;
  OutIndex: Cardinal;
begin
  if InputByteCount = 0 then
    Exit;

  InIndex := InputOffset;
  OutIndex := OutputOffset;

  OuterLimit := InputByteCount div 3 * 3;

  InnerLimit := InIndex;
  Inc(InnerLimit, OuterLimit);

  { Last line loop. }
  while InIndex < InnerLimit do
  begin
    { Read 3 bytes from InputBuffer. }
    B := InputBuffer[InIndex + 0];
    B := B shl 8;
    B := B or InputBuffer[InIndex + 1];
    B := B shl 8;
    B := B or InputBuffer[InIndex + 2];
    Inc(InIndex);
    { Write 4 bytes to OutputBuffer (in reverse order). }
    OutputBuffer[OutIndex + 3] := MIME_ENCODE_TABLE[B and $3F];
    B := B shr 6;
    OutputBuffer[OutIndex + 2] := MIME_ENCODE_TABLE[B and $3F];
    B := B shr 6;
    OutputBuffer[OutIndex + 1] := MIME_ENCODE_TABLE[B and $3F];
    B := B shr 6;
    OutputBuffer[OutIndex + 0] := MIME_ENCODE_TABLE[B];
    Inc(OutIndex);
  end;

  { End of data & padding. }
  case InputByteCount - OuterLimit of
    1:
      begin
        B := InputBuffer[InIndex + 0];
        B := B shl 4;
        OutputBuffer[OutIndex + 1] := MIME_ENCODE_TABLE[B and $3F];
        B := B shr 6;
        OutputBuffer[OutIndex + 0] := MIME_ENCODE_TABLE[B];
        OutputBuffer[OutIndex + 2] := MIME_PAD_CHAR; { Pad remaining 2 bytes. }
        OutputBuffer[OutIndex + 3] := MIME_PAD_CHAR;
      end;
    2:
      begin
        B := InputBuffer[InIndex + 0];
        B := B shl 8;
        B := B or InputBuffer[InIndex + 1];
        B := B shl 2;
        OutputBuffer[OutIndex + 2] := MIME_ENCODE_TABLE[B and $3F];
        B := B shr 6;
        OutputBuffer[OutIndex + 1] := MIME_ENCODE_TABLE[B and $3F];
        B := B shr 6;
        OutputBuffer[OutIndex + 0] := MIME_ENCODE_TABLE[B];
        OutputBuffer[OutIndex + 3] := MIME_PAD_CHAR; { Pad remaining byte. }
      end;
  end;
end;
{$ELSE}
procedure MimeEncodeNoCRLF(const InputBuffer; const InputByteCount: Cardinal; out OutputBuffer);
var
  B, InnerLimit, OuterLimit: Cardinal;
  InPtr: PByte3;
  OutPtr: PByte4;
begin
  if InputByteCount = 0 then
    Exit;

  InPtr := @InputBuffer;
  OutPtr := @OutputBuffer;

  OuterLimit := InputByteCount div 3 * 3;

  InnerLimit := Cardinal(InPtr);
  Inc(InnerLimit, OuterLimit);

  { Last line loop. }
  while Cardinal(InPtr) < InnerLimit do
  begin
    { Read 3 bytes from InputBuffer. }
    B := InPtr^.B1;
    B := B shl 8;
    B := B or InPtr^.B2;
    B := B shl 8;
    B := B or InPtr^.B3;
    Inc(InPtr);
    { Write 4 bytes to OutputBuffer (in reverse order). }
    OutPtr^.B4 := MIME_ENCODE_TABLE[B and $3F];
    B := B shr 6;
    OutPtr^.B3 := MIME_ENCODE_TABLE[B and $3F];
    B := B shr 6;
    OutPtr^.B2 := MIME_ENCODE_TABLE[B and $3F];
    B := B shr 6;
    OutPtr^.B1 := MIME_ENCODE_TABLE[B];
    Inc(OutPtr);
  end;

  { End of data & padding. }
  case InputByteCount - OuterLimit of
    1:
      begin
        B := InPtr^.B1;
        B := B shl 4;
        OutPtr.B2 := MIME_ENCODE_TABLE[B and $3F];
        B := B shr 6;
        OutPtr.B1 := MIME_ENCODE_TABLE[B];
        OutPtr.B3 := MIME_PAD_CHAR; { Pad remaining 2 bytes. }
        OutPtr.B4 := MIME_PAD_CHAR;
      end;
    2:
      begin
        B := InPtr^.B1;
        B := B shl 8;
        B := B or InPtr^.B2;
        B := B shl 2;
        OutPtr.B3 := MIME_ENCODE_TABLE[B and $3F];
        B := B shr 6;
        OutPtr.B2 := MIME_ENCODE_TABLE[B and $3F];

⌨️ 快捷键说明

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