📄 stmime.pas
字号:
raise;
end;
Progress(csFinished, 100);
end;
{ TStQuotedStream }
constructor TStQuotedStream.Create(Owner : TStMimeConverter);
begin
inherited Create(Owner);
end;
procedure TStQuotedStream.DecodeToStream(InStream, OutStream : TStream);
var
I, O, Count, WS : Byte;
InBuf : array[0..85] of Byte;
OutBuf : array[0..85] of Byte;
Decoding : Boolean;
Keeper : Boolean;
begin
FillChar(InBuf, SizeOf(InBuf), #0);
WS := $FF;
Decoding := True;
Keeper := False;
{ Skip any CR/LF's to get to the encoded stuff }
while True do begin
Count := InStream.Read(InBuf, 1);
{ End of stream -- exit assuming we're done }
if Count <> 1 then Exit;
if ((InBuf[0] <> $0D) and (InBuf[0] <> $0A)) then begin
Keeper := True;
Break;
end;
end;
while Decoding do begin
{ Initialize }
if Keeper then begin
I := 1;
Keeper := False;
end else begin
I := 0;
end;
O := 0;
{ Read in one line at a time - skipping over bad characters }
while True do begin
if InStream.Read(InBuf[I], 1) = 0 then Break;
case InBuf[I] of
$0A : Continue;
$0D : begin
Inc(I);
Break;
end;
{ Test for potential end of data }
{ '--' is probably the next Mime boundary }
$2D : if (I = 1) and (InBuf[0] = $2D) then Exit;
end;
Inc(I);
end;
if I = 0 then Exit;
Count := I;
I := 0;
{ Decode data to output stream }
while I < Count do begin
case InBuf[I] of
9 : begin
if WS = $FF then
WS := O;
OutBuf[O] := InBuf[I];
Inc(O);
Inc(I);
end;
13 : if WS = $FF then begin
OutBuf[O] := 13;
OutBuf[O+1] := 10;
Inc(O, 2);
Inc(I);
end else begin
OutBuf[WS] := 13;
OutBuf[WS+1] := 10;
O := WS+2;
Inc(I);
end;
32 : begin
if WS = $FF then
WS := O;
OutBuf[O] := InBuf[I];
Inc(O);
Inc(I);
end;
33..60 : begin
WS := $FF;
OutBuf[O] := InBuf[I];
Inc(O);
Inc(I);
end;
61 : begin
WS := $FF;
if I+2 >= Count then Break;
case InBuf[I+1] of
48 : OutBuf[O] := 0; {0}
49 : OutBuf[O] := 16; {1}
50 : OutBuf[O] := 32; {2}
51 : OutBuf[O] := 48; {3}
52 : OutBuf[O] := 64; {4}
53 : OutBuf[O] := 80; {5}
54 : OutBuf[O] := 96; {6}
55 : OutBuf[O] := 112; {7}
56 : OutBuf[O] := 128; {8}
57 : OutBuf[O] := 144; {9}
65 : OutBuf[O] := 160; {A}
66 : OutBuf[O] := 176; {B}
67 : OutBuf[O] := 192; {C}
68 : OutBuf[O] := 208; {D}
69 : OutBuf[O] := 224; {E}
70 : OutBuf[O] := 240; {F}
97 : OutBuf[O] := 160; {a}
98 : OutBuf[O] := 176; {b}
99 : OutBuf[O] := 192; {c}
100 : OutBuf[O] := 208; {d}
101 : OutBuf[O] := 224; {e}
102 : OutBuf[O] := 240; {f}
end;
case InBuf[I+2] of
48 : ; {0}
49 : OutBuf[O] := OutBuf[O] + 1; {1}
50 : OutBuf[O] := OutBuf[O] + 2; {2}
51 : OutBuf[O] := OutBuf[O] + 3; {3}
52 : OutBuf[O] := OutBuf[O] + 4; {4}
53 : OutBuf[O] := OutBuf[O] + 5; {5}
54 : OutBuf[O] := OutBuf[O] + 6; {6}
55 : OutBuf[O] := OutBuf[O] + 7; {7}
56 : OutBuf[O] := OutBuf[O] + 8; {8}
57 : OutBuf[O] := OutBuf[O] + 9; {9}
65 : OutBuf[O] := OutBuf[O] + 10; {A}
66 : OutBuf[O] := OutBuf[O] + 11; {B}
67 : OutBuf[O] := OutBuf[O] + 12; {C}
68 : OutBuf[O] := OutBuf[O] + 13; {D}
69 : OutBuf[O] := OutBuf[O] + 14; {E}
70 : OutBuf[O] := OutBuf[O] + 15; {F}
97 : OutBuf[O] := OutBuf[O] + 10; {a}
98 : OutBuf[O] := OutBuf[O] + 11; {b}
99 : OutBuf[O] := OutBuf[O] + 12; {c}
100 : OutBuf[O] := OutBuf[O] + 13; {d}
101 : OutBuf[O] := OutBuf[O] + 14; {e}
102 : OutBuf[O] := OutBuf[O] + 15; {f}
end;
Inc(I, 3);
Inc(O);
end;
62..126 : begin
WS := $FF;
OutBuf[O] := InBuf[I];
Inc(O);
Inc(I);
end;
else
Inc(I);
end;
end;
if O>0 then
OutStream.Write(OutBuf, O)
else
Break; { OutBuf is empty }
end;
end;
procedure TStQuotedStream.EncodeToStream(InStream, OutStream : TStream);
var
O, W : Integer;
WordBuf, OutBuf : array[0..80] of Char;
CurChar : Char;
procedure SendLine;
begin
if (OutBuf[O-1] = #9) or (OutBuf[O-1] = #32) then begin
OutBuf[O] := '=';
Inc(O);
end;
OutBuf[O] := #13;
OutBuf[O+1] := #10;
Inc(O, 2);
OutStream.Write(OutBuf, O);
O := 0;
end;
procedure AddWordToOutBuf;
var
J : Integer;
begin
if (O + W) > 74 then SendLine;
for J := 0 to (W - 1) do begin
OutBuf[O] := WordBuf[J];
Inc(O);
end;
W := 0;
end;
procedure AddHexToWord(B : Byte);
begin
if W > 73 then AddWordToOutBuf;
WordBuf[W] := '=';
WordBuf[W+1] := StHexDigits[B shr 4];
WordBuf[W+2] := StHexDigits[B and $F];
Inc(W, 3)
end;
begin
O := 0;
W := 0;
while InStream.Read(CurChar, 1) <> 0 do begin
if (Ord(CurChar) in [33..60, 62..126]) then begin
WordBuf[W] := CurChar;
Inc(W);
if W > 74 then AddWordToOutBuf;
end else if (CurChar = ' ') or (CurChar = #9) then begin
WordBuf[W] := CurChar;
Inc(W);
AddWordToOutBuf;
end else if (CurChar = #13) then begin
AddWordToOutBuf;
SendLine;
end else if (CurChar = #10) then begin
{ Do nothing }
end else begin
AddHexToWord(Byte(CurChar));
end;
end;
end;
{ TStUUStream }
constructor TStUUStream.Create(Owner : TStMimeConverter);
begin
inherited Create(Owner);
end;
procedure TStUUStream.DecodeToStream(InStream, OutStream : TStream);
var
I, O, Len, Count : Byte;
InBuf : array[0..85] of Byte;
OutBuf : array[0..65] of Byte;
FirstLine : Boolean;
begin
FirstLine := True;
while True do begin
{ Initialize }
I := 0;
O := 0;
{ Skip any CR/LF's to get to the encoded stuff }
while True do begin
Count := InStream.Read(InBuf, 1);
{ End of stream -- bail assuming we're done }
if Count <> 1 then Exit;
if FirstLine then begin
if ((InBuf[0] <> $0D) and (InBuf[0] <> $0A)) then begin
FirstLine := False;
Break;
end;
end else begin
if ((InBuf[0] = $0D) or (InBuf[0] = $0A)) then FirstLine := True;
end;
end;
{ We're done }
if Char(InBuf[0]) = '`' then Exit;
{ Get count for this line }
Len := (((InBuf[0] - $20) and $3F) * 4) div 3;
if (((InBuf[0] - $20) and $3F) * 4) mod 3 <> 0 then
Inc(Len);
Count := InStream.Read(InBuf, Len);
{ Unexpected situation }
if (Count <> Len) or (Count > 63) then
RaiseStError(EStMimeError, stscInStream);
{ Decode buffer }
while (I < Count) do begin
if ((Count - I) >= 4) then begin
{!!.01 -- Changed}
{Note: indexing inverted to avoid compiler problem with D6upd2 and BCB6}
OutBuf[O+2] := (((InBuf[I+2] - $20) and $3F) shl 6) or
(((InBuf[I+3] - $20) and $3F));
OutBuf[O+1] := (((InBuf[I+1] - $20) and $3F) shl 4) or
(((InBuf[I+2] - $20) and $3F) shr 2);
OutBuf[O] := (((InBuf[I] - $20) and $3F) shl 2) or
(((InBuf[I+1] - $20) and $3F) shr 4);
{!!.01 -- End Changed}
Inc(O, 3);
end else begin
if (Count >= 2) then begin
OutBuf[O] := (((InBuf[I] - $20) and $3F) shl 2) or
(((InBuf[I+1] - $20) and $3F) shr 4);
Inc(O);
end;
if (Count >= 3) then begin
OutBuf[O+1] := (((InBuf[I+1] - $20) and $3F) shl 4) or
(((InBuf[I+2] - $20) and $3F) shr 2);
Inc(O);
end;
end;
Inc(I, 4);
end;
OutStream.Write(OutBuf, O);
end;
end;
procedure TStUUStream.EncodeToStream(InStream, OutStream : TStream);
var
I, O, Count, Temp : Byte;
InBuf : array[1..45] of Byte;
OutBuf : array[0..63] of Char;
S : string;
begin
S := Format('begin 600 %s'#13#10, [FCurrentFile]);
OutStream.Write(S[1], Length(S));
{ Encode and stream the attachment }
repeat
Count := InStream.Read(InBuf, SizeOf(InBuf));
if Count <= 0 then Break;
I := 1;
O := 0;
OutBuf[O] := Char(StUUTable[Count and $3F]);
Inc(O);
while I+2 <= Count do begin
{ Encode 1st byte }
Temp := (InBuf[I] shr 2);
OutBuf[O] := Char(StUUTable[Temp and $3F]);
{ Encode 1st/2nd byte }
Temp := (InBuf[I] shl 4) or (InBuf[I+1] shr 4);
OutBuf[O+1] := Char(StUUTable[Temp and $3F]);
{ Encode 2nd/3rd byte }
Temp := (InBuf[I+1] shl 2) or (InBuf[I+2] shr 6);
OutBuf[O+2] := Char(StUUTable[Temp and $3F]);
{ Encode 3rd byte }
Temp := (InBuf[I+2] and $3F);
OutBuf[O+3] := Char(StUUTable[Temp]);
Inc(I, 3);
Inc(O, 4);
end;
{ Are there odd bytes to add? }
if (I <= Count) then begin
Temp := (InBuf[I] shr 2);
OutBuf[O] := Char(StUUTable[Temp and $3F]);
{ One odd byte }
if (I = Count) then begin
Temp := (InBuf[I] shl 4) and $30;
OutBuf[O+1] := Char(StUUTable[Temp and $3F]);
Inc(O, 2);
{ Two odd bytes }
end else begin
Temp := ((InBuf[I] shl 4) and $30) or ((InBuf[I+1] shr 4) and $0F);
OutBuf[O+1] := Char(StUUTable[Temp and $3F]);
Temp := (InBuf[I+1] shl 2) and $3C;
OutBuf[O+2] := Char(StUUTable[Temp and $3F]);
Inc(O, 3);
end;
end;
{ Add CR/LF }
OutBuf[O] := #13;
OutBuf[O+1] := #10;
{ Write line to stream }
OutStream.Write(OutBuf, (O + 2));
until Count < SizeOf(InBuf);
{ Add terminating end }
StrCopy(StrECopy(OutBuf, '`'#13#10), 'end'#13#10);
OutStream.Write(OutBuf, StrLen(OutBuf));
end;
{ TStBase64Stream }
constructor TStBase64Stream.Create(Owner : TStMimeConverter);
begin
inherited Create(Owner);
end;
procedure TStBase64Stream.DecodeToStream(InStream, OutStream : TStream);
var
I, O, Count, c1, c2, c3 : Byte;
InBuf : array[0..85] of Byte;
OutBuf : array[0..65] of Byte;
Decoding : Boolean;
begin
Decoding := True;
while Decoding do begin
{ Initialize }
O := 0;
I := 0;
{ Skip any CR/LF's to get to the encoded stuff }
while True do begin
Count := InStream.Read(InBuf, 1);
{ End of stream -- exit assuming we're done }
if Count <> 1 then Exit;
if ((InBuf[0] <> $0D) and (InBuf[0] <> $0A)) then begin
Inc(I);
Break;
end;
end;
{ Read in a line at a time - skipping over bad characters }
while True do begin
if InStream.Read(InBuf[I], 1) = 0 then Break;
case InBuf[I] of
$00..$09 : Continue;
$0A : Break;
$0B..$0C : Continue;
$0D : Break;
$0E..$2A : Continue;
{ Test for potential end of data }
{ '--' is probably the next Mime boundary }
$2D : begin
if I = 1 then
if (InBuf[0] = $2D) then
Exit;
Continue;
end;
$3D : begin
Inc(I);
Break;
end;
$7B..$FF : Continue;
end;
if (StD64Table[InBuf[I]] = $7F) then Continue;
Inc(I);
end;
{ 'end' can mean end of data for base64 }
if (InBuf[0] = $65) and (InBuf[1] = $6E) and
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -