MemStuff := TNMFileBuffer.Create(source); try InputPtr := MemStuff.BufPos; BufferEnd := MemStuff.BufEnd; while True do begin if InputPtr >= BufferEnd then if not MemStuff.NextMemoryBuffer(InputPtr, 0) then Break else begin InputPtr := MemStuff.BufPos; BufferEnd := MemStuff.BufEnd; end; Char1 := InputPtr^; inc(InputPtr); B64Char := B64Table[Byte(Char1) shr 2]; OutputPtr^ := B64Char; inc(OutputPtr); inc(Counter);
if Counter >= TotalBytes then begin Char2 := #0; B64Char := B64Table[(((Byte(Char1) and $03) shl 4) or ((Byte(Char2) and $F0) shr 4))]; OutputPtr^ := B64Char; inc(OutputPtr); OutputPtr^ := EOD; inc(OutputPtr); OutputPtr^ := EOD; inc(OutputPtr); end else begin if InputPtr >= BufferEnd then if not MemStuff.NextMemoryBuffer(InputPtr, 0) then Break else begin InputPtr := MemStuff.BufPos; BufferEnd := MemStuff.BufEnd; end; Char2 := InputPtr^; inc(InputPtr); B64Char := B64Table[(((Byte(Char1) and $03) shl 4) or ((Byte(Char2) and $F0) shr 4))]; OutputPtr^ := B64Char; inc(OutputPtr); inc(Counter);
if Counter >= TotalBytes then begin Char3 := #0; B64Char := B64Table[(((Byte(Char2) and $0F) shl 2) or ((Byte(Char3) and $C0) shr 6))]; OutputPtr^ := B64Char; inc(OutputPtr); OutputPtr^ := EOD; inc(OutputPtr); end else begin if InputPtr >= BufferEnd then if not MemStuff.NextMemoryBuffer(InputPtr, 0) then Break else begin InputPtr := MemStuff.BufPos; BufferEnd := MemStuff.BufEnd; end; Char3 := InputPtr^; inc(InputPtr); B64Char := B64Table[(((Byte(Char2) and $0F) shl 2) or ((Byte(Char3) and $C0) shr 6))]; OutputPtr^ := B64Char; inc(OutputPtr); inc(Counter); B64Char := B64Table[(Byte(Char3) and $3F)]; OutputPtr^ := B64Char; inc(OutputPtr); end; end;
if (Counter mod 45 = 0) or ((OutputPtr - 1)^ = EOD) then begin if ((OutputPtr - 1)^ <> EOD) then begin OutputPtr^ := #13; inc(OutputPtr); OutputPtr^ := #10; inc(OutputPtr); OutputPtr^ := #0; end else begin Len := LongInt(OutputPtr) - LongInt(Output); SetLength(Output, Len); end; destination.Write(PChar(Output)^, Len); OutputPtr := PChar(Output); end; end; finally MemStuff.Free; end;
Len := LongInt(OutputPtr) - LongInt(Output); if Len > 0 then begin SetLength(Output, Len); destination.Write(PChar(Output)^, Len); end;
destination.Write(EOD, 1); result := True; end;
end. [/Quote]
[Quote title="NM64Decode.pas"]unit NM64Decode;
interface uses Classes;
function B64Decode(const Source: TStream; var Destination: TStream): Boolean;
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 raise Exception.Create('Invalid data encountered within stream') 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;
const MaxBufSize = $FFFE;
var Buffer, FillPos, BufPos: PChar; Counter, BytesRead: LongInt; SourceSize: LongInt; begin Result := TRUE;