📄 rm_jclmime.pas
字号:
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 + -