📄 dxmimedecode.pas
字号:
unit DXMIMEDecode;
interface
///////////////////////////////////////////////////////////////////////////////
// Unit: DXMIMEDecoder
// Author: G.E. Ozz Nixon Jr. (onixon@dxsock.com)
// ========================================================================
// Source Owner: DX, Inc. 1995-2002
// Copyright: All code is the property of DX, Inc. Licensed for
// resell by Brain Patchwork DX (tm) and part of the
// DX (r) product lines, which are (c) 1999-2002
// DX, Inc. Source may not be distributed without
// written permission from both Brain Patchwork DX,
// and DX, Inc.
// License: (Reminder), None of this code can be added to other
// developer products without permission. This includes
// but not limited to DCU's, DCP's, DLL's, OCX's, or
// any other form of merging our technologies. All of
// your products released to a public consumer be it
// shareware, freeware, commercial, etc. must contain a
// license notification somewhere visible in the
// application.
// Example is Internet Explorer - Help->About screen
// shows the licensed code contained in the application.
// Code Version: (3rd Generation Code)
// ========================================================================
// Description:
// ========================================================================
///////////////////////////////////////////////////////////////////////////////
uses
Classes;
{$I DXAddons.def}
function B64Decode(const Source:TStream; var Destination:TStream):Boolean;
implementation
uses
dxstring,
sysutils;
const
EOD='=';
EOB=$FE;
INVALID=$FF;
CR=#13;
LF=#10;
EOL=#0;
MaxBufSize=$FFFE;
var
B64_Table:array[0..255] of Byte;
procedure InitTable;
begin
FillChar2(B64_Table, sizeof(B64_Table), char(INVALID));
B64_Table[43]:=62;
B64_Table[47]:=63;
B64_Table[48]:=52;
B64_Table[49]:=53;
B64_Table[50]:=54;
B64_Table[51]:=55;
B64_Table[52]:=56;
B64_Table[53]:=57;
B64_Table[54]:=58;
B64_Table[55]:=59;
B64_Table[56]:=60;
B64_Table[57]:=61;
B64_Table[65]:=0;
B64_Table[66]:=1;
B64_Table[67]:=2;
B64_Table[68]:=3;
B64_Table[69]:=4;
B64_Table[70]:=5;
B64_Table[71]:=6;
B64_Table[72]:=7;
B64_Table[73]:=8;
B64_Table[74]:=9;
B64_Table[75]:=10;
B64_Table[76]:=11;
B64_Table[77]:=12;
B64_Table[78]:=13;
B64_Table[79]:=14;
B64_Table[80]:=15;
B64_Table[81]:=16;
B64_Table[82]:=17;
B64_Table[83]:=18;
B64_Table[84]:=19;
B64_Table[85]:=20;
B64_Table[86]:=21;
B64_Table[87]:=22;
B64_Table[88]:=23;
B64_Table[89]:=24;
B64_Table[90]:=25;
B64_Table[97]:=26;
B64_Table[98]:=27;
B64_Table[99]:=28;
B64_Table[100]:=29;
B64_Table[101]:=30;
B64_Table[102]:=31;
B64_Table[103]:=32;
B64_Table[104]:=33;
B64_Table[105]:=34;
B64_Table[106]:=35;
B64_Table[107]:=36;
B64_Table[108]:=37;
B64_Table[109]:=38;
B64_Table[110]:=39;
B64_Table[111]:=40;
B64_Table[112]:=41;
B64_Table[113]:=42;
B64_Table[114]:=43;
B64_Table[115]:=44;
B64_Table[116]:=45;
B64_Table[117]:=46;
B64_Table[118]:=47;
B64_Table[119]:=48;
B64_Table[120]:=49;
B64_Table[121]:=50;
B64_Table[122]:=51;
end;
function B64Decode(const Source:TStream; var Destination:TStream):Boolean;
var
Stream_Ptr:PChar;
procedure Decode;
var
Char1:Byte;
Char2:Byte;
Char3:Byte;
Char4:Byte;
Count:Integer;
Line_Ptr:PChar;
Line_Length:LongInt;
Line:string;
begin
Line_Length:=StrLen(Stream_Ptr)*3 div 4;
SetLength(Line, Line_Length);
Line_Ptr:=PChar(Line);
while Line_Length>0 do begin
Count:=0;
if Stream_Ptr^>EOL then begin
Char1:=B64_Table[Byte(Stream_Ptr^)];
Inc(Stream_Ptr);
end
else
Char1:=INVALID;
if Stream_Ptr^>EOL then begin
Char2:=B64_Table[Byte(Stream_Ptr^)];
Inc(Stream_Ptr);
end
else
Char2:=INVALID;
if Stream_Ptr^>EOL then begin
Char3:=B64_Table[Byte(Stream_Ptr^)];
Inc(Stream_Ptr);
end
else
Char3:=INVALID;
if Stream_Ptr^>EOL then begin
Char4:=B64_Table[Byte(Stream_Ptr^)];
Inc(Stream_Ptr);
end
else
Char4:=INVALID;
if (Char1=INVALID)or(Char2=INVALID) then begin
Result:=False;
Exit;
end
else begin
Line_Ptr^:=Char((Char1 shl 2)or((Char2 and $30)shr 4));
inc(Line_Ptr);
inc(Count);
if (Char3<>INVALID) then begin
Line_Ptr^:=Char(((Char2 and $0F)shl 4)or((Char3 and $3C)shr 2));
inc(Line_Ptr);
inc(Count);
if (Char4<>INVALID) then begin
Line_Ptr^:=Char(((Char3 and $03)shl 6)or(Char4));
inc(Line_Ptr);
inc(Count);
end;
end;
end;
dec(Line_Length, Count);
end;
Destination.Write(Pointer(Line)^, Line_Ptr-PChar(Line));
end;
var
Buffer, FillPos, BufPos:PChar;
Counter, BytesRead:LongInt;
SourceSize:LongInt;
begin
Result:=TRUE;
InitTable;
SourceSize:=Source.Size;
destination.Seek(0, soFromEnd);
Counter:=0;
GetMem(Buffer, MaxBufSize+1);
FillPos:=Buffer;
BufPos:=Buffer;
inc(FillPos, MaxBufSize+1);
FillPos^:=EOL;
try
while (Source.Position<SourceSize)and(BufPos^<>EOD) do begin
FillPos:=Buffer;
inc(FillPos, Counter);
BytesRead:=Source.Read(FillPos^, MaxBufSize-Counter);
inc(counter, BytesRead);
BufPos:=Buffer;
inc(FillPos, Counter);
FillPos^:=EOL;
Counter:=0;
while (BufPos^<>EOL) do begin
Stream_Ptr:=BufPos;
while not(BufPos^in [EOL, LF, CR, EOD]) do
Inc(BufPos);
if (BufPos^<>EOL)or(BufPos^=EOD) then begin
BufPos^:=EOL;
Decode;
if BufPos^=EOL then Inc(BufPos);
if BufPos^=CR then Inc(BufPos);
if BufPos^=LF then Inc(BufPos);
end
else begin
Counter:=BufPos-Stream_Ptr;
FastMove(Stream_Ptr^, Buffer^, Counter);
Break;
end;
end;
end;
if Counter>0 then begin
Stream_Ptr:=Buffer;
Decode;
end;
finally
FreeMem(Buffer, MaxBufSize);
end;
end;
initialization
InitTable;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -