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