if fmapname='' then n:=nil else n:=pchar(fmapname); p:=0; p1:=0;
if fprotection=pread then begin p:=page_readonly; p1:=FILE_MAP_READ; end; if preadwrite = fprotection then begin p:=page_readwrite; p1:= FILE_MAP_WRITE ; end; if pcopy = fprotection then begin p:= page_writecopy; p1:= FILE_MAP_COPY; end; if apCommit in fadditionalprotections then p:=p or sec_commit; if apImage in fadditionalprotections then p:=p or sec_image; if apNocache in fadditionalprotections then p:=p or sec_nocache; if apReserve in fadditionalprotections then p:=p or sec_reserve;
fmaphandle:=createfilemapping(ffilehandle,nil,p,0,fsize,n); if (fmaphandle=0) then begin RaiseLastOSError; end else begin self.FAlreadyExists:=getlasterror=ERROR_ALREADY_EXISTS;
FstartPointer:=mapviewoffile(fmaphandle,p1,0,0,0); if fstartpointer=nil then RaiseLastOSError;
fcurrentpointer:=fstartpointer; end; FInitializing:=false; end;destructor TFileMapStream_San.Destroy; begin unmapviewoffile(fstartpointer); closehandle(fmaphandle); //msg; inherited; end;class function TFileMapStream_San.FileMapExists(AMapName: string): boolean; var n:pchar; h:cardinal; begin if amapname='' then n:=nil else n:=pchar(amapname); h:=createfilemapping(c_memhandle,nil,page_readonly,0,1,n); result:=(h<>0)and(getlasterror=ERROR_ALREADY_EXISTS); closehandle(h); end;function TFileMapStream_San.StartPointer(): pointer; begin result:=fstartpointer; end;function TFileMapStream_San.Read(var Buffer; Count: Integer): Longint; var c:cardinal; begin c:=size-position; if c>count then result:=count else result:=c;
copymemory(@buffer,fcurrentpointer,result); position:=position+result; end;function TFileMapStream_San.Write(const Buffer; Count: Integer): Longint; var p:pointer; begin p:=fcurrentpointer; self.setsize(position+count); fcurrentpointer:=p; copymemory(fcurrentpointer,@buffer,count); position:=position+count; result:=count; end;function TFileMapStream_San.Seek(Offset: Integer; Origin: Word): Longint; begin case origin of soFromBeginning: begin result:=offset; end; soFromEnd: begin result:=fsize+offset; end; soFromCurrent: begin result:=cardinal(fcurrentpointer)-cardinal(fstartpointer)+offset; end; end; fcurrentpointer:=pointer(cardinal(fstartpointer)+result); if result<0 then result:=0 else if result>fsize then result:=fsize;end; function TFileMapStream_San.CurrentPointer(): pointer; begin result:=fcurrentpointer; end;function TFileMapStream_San.ToString: string; begin setlength(result,size); copymemory(@result[1],fstartpointer,size); end;end.
uses
windows,classes,sysutils;const
c_memhandle=$FFFFFFFF;
c_msg_cannotsetsize='Cannot set the size of a "%s" object, except for setting the "%s" property to True.';type
TProtection_san=(pREAD,pREADWRITE,pCOPY);
TAdditionalProtection_san=(apCOMMIT,apIMAGE,apNOCACHE,apRESERVE);
TAdditionalProtections_San=set of tadditionalprotection_san;
TFileMapStream_San=class(TStream)
private
FFileHandle:cardinal;
FMapHandle:cardinal;
FStartPointer:pointer;
FCurrentPointer:pointer;
FMapName:string;
FSize:cardinal;
FProtection:TProtection_San;
fAdditionalProtections:TAdditionalProtections_san;
FAlreadyExists:boolean;
//////////
FInitializing:boolean;
protected
procedure SetSize(NewSize: Longint); overload; override;
function StartPointer():pointer;
function CurrentPointer():pointer;
public
AutoSize:boolean;
////////////////////
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const Buffer; Count: Longint): Longint; override;
function Seek(Offset: Longint; Origin: Word): Longint; override; constructor Create(const AMapName:string='';ASize: cardinal=0;AHandle: cardinal=c_memhandle;
AProtection:TProtection_San=pREADWRITE;AAdditionalProtections:TAdditionalProtections_San=[]);
destructor Destroy;override; class function FileMapExists(AMapName:string):boolean;
function ToString:string; published
property FileHandle:cardinal read ffilehandle;
property MapHandle:cardinal read fmaphandle;
property MapName:string read fmapname;
property Protection:tprotection_san read fprotection;
property AdditionalProtection:Tadditionalprotections_san read fadditionalprotections;
property AlreadyExists:boolean read falreadyexists;
end;implementation{ TFileMapStream_San }constructor TFileMapStream_San.create(const AMapName:string;ASize: cardinal;AHandle: cardinal;
AProtection:TProtection_San;AAdditionalProtections:TAdditionalProtections_San);
var
n:pchar;
p,p1:cardinal;
begin
FInitializing:=true; ffilehandle:=ahandle;
fmapname:=amapname; fprotection:=aprotection;
fadditionalprotections:=aadditionalprotections;
autosize:=asize<=0;
self.setsize(asize);end;procedure TFileMapStream_San.SetSize(NewSize: Integer);
var
n:pchar;
p1,p:cardinal;
begin
if (not autosize)and(not FInitializing) then
raise exception.Create(format(c_msg_cannotsetsize,[classname,'AutoSize']));
if newsize<0 then newsize:=0;
if (newsize=size) and (newsize<>0) then exit;
fsize:=newsize;
unmapviewoffile(fstartpointer);
closehandle(fmaphandle);
if fmapname='' then
n:=nil
else
n:=pchar(fmapname); p:=0;
p1:=0;
if fprotection=pread then
begin
p:=page_readonly;
p1:=FILE_MAP_READ; end;
if preadwrite = fprotection then
begin
p:=page_readwrite;
p1:= FILE_MAP_WRITE ;
end;
if pcopy = fprotection then
begin
p:= page_writecopy;
p1:= FILE_MAP_COPY;
end;
if apCommit in fadditionalprotections then p:=p or sec_commit;
if apImage in fadditionalprotections then p:=p or sec_image;
if apNocache in fadditionalprotections then p:=p or sec_nocache;
if apReserve in fadditionalprotections then p:=p or sec_reserve;
fmaphandle:=createfilemapping(ffilehandle,nil,p,0,fsize,n); if (fmaphandle=0) then
begin
RaiseLastOSError;
end else
begin
self.FAlreadyExists:=getlasterror=ERROR_ALREADY_EXISTS;
FstartPointer:=mapviewoffile(fmaphandle,p1,0,0,0);
if fstartpointer=nil then RaiseLastOSError;
fcurrentpointer:=fstartpointer;
end;
FInitializing:=false;
end;destructor TFileMapStream_San.Destroy;
begin
unmapviewoffile(fstartpointer);
closehandle(fmaphandle);
//msg;
inherited;
end;class function TFileMapStream_San.FileMapExists(AMapName: string): boolean;
var
n:pchar;
h:cardinal;
begin
if amapname='' then
n:=nil
else
n:=pchar(amapname);
h:=createfilemapping(c_memhandle,nil,page_readonly,0,1,n);
result:=(h<>0)and(getlasterror=ERROR_ALREADY_EXISTS);
closehandle(h);
end;function TFileMapStream_San.StartPointer(): pointer;
begin
result:=fstartpointer;
end;function TFileMapStream_San.Read(var Buffer; Count: Integer): Longint;
var
c:cardinal;
begin
c:=size-position;
if c>count then
result:=count
else
result:=c;
copymemory(@buffer,fcurrentpointer,result);
position:=position+result;
end;function TFileMapStream_San.Write(const Buffer; Count: Integer): Longint;
var
p:pointer;
begin
p:=fcurrentpointer;
self.setsize(position+count); fcurrentpointer:=p;
copymemory(fcurrentpointer,@buffer,count);
position:=position+count;
result:=count;
end;function TFileMapStream_San.Seek(Offset: Integer; Origin: Word): Longint;
begin case origin of
soFromBeginning:
begin
result:=offset;
end;
soFromEnd:
begin
result:=fsize+offset;
end;
soFromCurrent:
begin
result:=cardinal(fcurrentpointer)-cardinal(fstartpointer)+offset;
end;
end;
fcurrentpointer:=pointer(cardinal(fstartpointer)+result);
if result<0 then
result:=0
else if result>fsize then result:=fsize;end;
function TFileMapStream_San.CurrentPointer(): pointer;
begin
result:=fcurrentpointer;
end;function TFileMapStream_San.ToString: string;
begin
setlength(result,size);
copymemory(@result[1],fstartpointer,size);
end;end.