unit Unit2;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TExtendedStream =
class(TStream)
Constructor Create(OpenFromFilename:
string);
function write(
Const Buffer;Count:integer):integer;
function read(
var Buffer;Count:integer):integer;
private
{ Private-Deklarationen }
aStream:TStream;
ChangeSave:TExtendedStream;
protect:boolean;
inMemory:boolean;
swapsize:integer;
public
Size:int64;
Position:int64;
{ Public-Deklarationen }
end;
implementation
function GetTempFileName(TempDirectory:
String):
string;
var filename:
string;
i:integer;
begin
i:=0;
filename:=inttostr(i)+'
.part';
while fileexists(TempDirectory+filename)
do
begin
inc(i);
filename:=inttostr(i)+'
.part';
end;
result:=TempDirectory+filename;
end;
function GetFileSize(szFile: PChar): Int64;
var
fFile : THandle;
wfd : TWIN32FINDDATA;
begin
result := 0;
if not FileExists(szFile)
then exit;
fFile := FindFirstfile(pchar(szFile), wfd);
if fFile = INVALID_HANDLE_VALUE
then exit;
result := (wfd.nFileSizeHigh * (Int64(MAXDWORD) + 1)) + wfd.nFileSizeLow;
windows.FindClose(fFile);
end;
constructor TExtendedStream.Create(OpenFromFilename:
string);
begin
swapsize:=5242880;
ChangeSave:=nil;
if OpenFromFilename='
'
then
begin
aStream:=TMemoryStream.Create;
inMemory:=True;
Position:=0;
Size:=0;
protect:=False;
end
else
if fileexists(OpenFromFilename)
then
if GetFileSize(pChar(OpenFromFilename))<swapsize
then
begin
aStream:=TMemoryStream.Create;
TMemoryStream(aStream).LoadFromFile(OpenFromFilename);
inMemory:=True;
protect:=False;
Position:=0;
Size:=0;
end
else
begin
aStream:=TFilestream.Create(OpenFromFilename,fmOpenRead);
inMemory:=False;
protect:=true;
Position:=0;
Size:=astream.Size;
end;
end;
function TExtendedStream.
write(
Const Buffer;Count:integer):integer;
var dummystream:TMemorystream;
len:integer;
begin
if inMemory=true
then
if sizeof(Buffer)+TMemorystream(aStream).size<swapsize
then
begin
TMemorystream(aStream).Position:=self.Position;
TMemorystream(aStream).
Write(Buffer,count);
size:=TMemorystream(aStream).Size;
position:=TMemorystream(aStream).position;
end
else
begin //swapen
dummystream:=TMemorystream(aStream);
aStream:=TFilestream.Create(GetTempFileName('
C:\'),fmcreate);
dummystream.Position:=0;
Tfilestream(aStream).CopyFrom(dummystream,dummystream.size);
freeandnil(dummystream);
inMemory:=False;
protect:=false;
Tfilestream(aStream).Position:=self.Position;
Tfilestream(aStream).
Write(Buffer,count);
size:=Tfilestream(aStream).Size;
position:=Tfilestream(aStream).position;
end
else //inMemory=false
if not protect
then
begin
TFileStream(aStream).position:=position;
TFileStream(aStream).
Write(Buffer,count);
size:=Tfilestream(aStream).Size;
position:=Tfilestream(aStream).position;
end
else
begin //in Memory=false protect=true
if ChangeSave=nil
then
begin
ChangeSave:=TExtendedStream.create('
');
ChangeSave.Position:=0;
end;
ChangeSave.Position:=ChangeSave.Size;
ChangeSave.
write(self.Position,sizeof(self.Position));
len:=sizeof(buffer);
ChangeSave.
write(len,sizeof(len));
ChangeSave.
write(Buffer,Count);
end;
end;
function TExtendedStream.
read(
var Buffer;Count:integer):integer;
var dummystream:TMemorystream;
pos,len:integer;
rel_start,rel_end:integer;
begin
if inMemory=true
then
begin
TMemorystream(aStream).Position:=self.Position;
TMemorystream(aStream).
read(Buffer,count);
position:=TMemorystream(aStream).position;
end
else //inMemory=false
if not protect
then
begin
TFileStream(aStream).position:=position;
TFileStream(aStream).
Read(Buffer,count);
position:=Tfilestream(aStream).position;
end
else
begin //in Memory=false protect=true
if ChangeSave<>
nil then
begin
ChangeSave.Position:=0;
ChangeSave.
read(pos,sizeof(pos));
ChangeSave.
read(len,sizeof(len));
rel_start:=position-pos;
rel_end:=(position+count)-(pos+len);
if rel_start>=0
then
if rel_end>=0
then //readstream komplett in Changestream
begin
ChangeSave.Position:=ChangeSave.Position+rel_start;
ChangeSave.
read(Buffer,count);
ChangeSave.Position:=ChangeSave.Position+rel_end;
end
else
begin //Readstream Ende liegt außerhalb von Changestream
ChangeSave.Position:=ChangeSave.Position+rel_start;
ChangeSave.
read(Buffer,count+rel_end);
{hier hänge ich grade etwas}
end;
end;
end;
end;
end.