mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-28 21:40:34 +02:00
Merged revision(s) 32302-32305, 32310 from branches/svenbarth/packages:
+ new stream class TCRangeStream that represents a substream of another stream while being also extendable ........ Extend tentryfile so that it can be opened from a stream in addition to a file entfile.pas, tentryfile: + new method openstream() to open a readable tentryfile based on a stream + new method createstream() to open a writeable tentryfile based on a stream * adjust openfile() to use openstream() * adjust createfile() to use createstream() ........ A few extensions for tentryfile needed for package files entfile.pas, tentryfile: + new property position to retrieve/control the position of the underlying stream (works also with tempclose()/tempopen()) + new method substream() to retrieve a stream that goes from the specified offset with the specified length (-1 create a stream that is extendable, aka for writing) + new property stream to get the underlying stream directly; be careful when using this! ........ Extend tppumodule so that it can be opened from a stream as well. fppu.pas, tppumodule: * rename openppu() to openppufile() + new method openppustream() to open a module based on a stream + put the common part of openppufile() and openppustream() into a new method openppu() ........ Fix compilation. fppu.pas, tppumodule: * openppu: add parameter ppufiletime for printing the time of the file (only if filetime is not -1) * openppufile: pass the retrieve time of the PPU to openppu() * openppustream: pass -1 to openppu() ........ git-svn-id: trunk@33109 -
This commit is contained in:
parent
0226195272
commit
1945bf64b4
@ -132,6 +132,20 @@ var
|
|||||||
CFileStreamClass: TCFileStreamClass = TCFileStream;
|
CFileStreamClass: TCFileStreamClass = TCFileStream;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
TCRangeStream = class(TCStream)
|
||||||
|
private
|
||||||
|
FBase: TCStream;
|
||||||
|
FOffset: LongInt;
|
||||||
|
FMaxOffset: LongInt;
|
||||||
|
FSize: LongInt;
|
||||||
|
FPosition: LongInt;
|
||||||
|
public
|
||||||
|
constructor Create(ABase: TCStream; AOffset, ASize: LongInt);
|
||||||
|
function Read(var Buffer; Count: LongInt): LongInt; override;
|
||||||
|
function Write(const Buffer; Count: LongInt): LongInt; override;
|
||||||
|
function Seek(Offset: LongInt; Origin: Word): LongInt; override;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TCustomMemoryStream abstract class }
|
{ TCustomMemoryStream abstract class }
|
||||||
|
|
||||||
TCCustomMemoryStream = class(TCStream)
|
TCCustomMemoryStream = class(TCStream)
|
||||||
@ -467,6 +481,92 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{****************************************************************************}
|
||||||
|
{* TCRangeStream *}
|
||||||
|
{****************************************************************************}
|
||||||
|
|
||||||
|
|
||||||
|
constructor TCRangeStream.Create(ABase: TCStream; AOffset, ASize: LongInt);
|
||||||
|
begin
|
||||||
|
if not assigned(ABase) then
|
||||||
|
CStreamError:=155
|
||||||
|
else
|
||||||
|
{ we allow to be positioned directly at the end for appending }
|
||||||
|
if (AOffset<0) or (AOffset>ABase.Size) then
|
||||||
|
CStreamError:=156
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
FBase:=ABase;
|
||||||
|
FOffset:=AOffset;
|
||||||
|
if ASize<0 then
|
||||||
|
FSize:=maxLongint-FOffset
|
||||||
|
else
|
||||||
|
FSize:=ASize;
|
||||||
|
FMaxOffset:=FOffset+FSize-1;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TCRangeStream.Read(var Buffer; Count: LongInt): LongInt;
|
||||||
|
begin
|
||||||
|
Count:=Min(Count,FMaxOffset-FPosition+1);
|
||||||
|
if Count>0 then
|
||||||
|
begin
|
||||||
|
FBase.Seek(FOffset+FPosition,soFromBeginning);
|
||||||
|
result:=FBase.Read(Buffer,Count);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
result:=0;
|
||||||
|
FPosition:=FPosition+result;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TCRangeStream.Write(const Buffer; Count: LongInt): LongInt;
|
||||||
|
begin
|
||||||
|
Count:=Min(Count,FMaxOffset-FPosition+1);
|
||||||
|
if Count>0 then
|
||||||
|
begin
|
||||||
|
FBase.Seek(FOffset+FPosition,soFromBeginning);
|
||||||
|
result:=FBase.Write(Buffer,Count);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
result:=0;
|
||||||
|
FPosition:=FPosition+result;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TCRangeStream.Seek(Offset: LongInt; Origin: Word): LongInt;
|
||||||
|
begin
|
||||||
|
case Origin of
|
||||||
|
soFromBeginning:
|
||||||
|
begin
|
||||||
|
if Offset>FMaxOffset then
|
||||||
|
CStreamError:=156
|
||||||
|
else
|
||||||
|
FPosition:=FBase.Seek(FOffset+Offset,soFromBeginning)-FOffset;
|
||||||
|
end;
|
||||||
|
soFromCurrent:
|
||||||
|
begin
|
||||||
|
if Offset>FMaxOffset then
|
||||||
|
CStreamError:=156
|
||||||
|
else
|
||||||
|
FPosition:=FBase.Seek(FOffset+FPosition+Offset,soFromBeginning)-FOffset;
|
||||||
|
end;
|
||||||
|
soFromEnd:
|
||||||
|
begin
|
||||||
|
if Offset>FSize-1 then
|
||||||
|
CStreamError:=156
|
||||||
|
else
|
||||||
|
FPosition:=FBase.Seek(FMaxOffset-Offset,soFromBeginning)-FOffset;
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
CStreamError:=156;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Result:=FPosition;
|
||||||
|
end;
|
||||||
|
|
||||||
{****************************************************************************}
|
{****************************************************************************}
|
||||||
{* TCustomMemoryStream *}
|
{* TCustomMemoryStream *}
|
||||||
{****************************************************************************}
|
{****************************************************************************}
|
||||||
|
@ -192,6 +192,9 @@ type
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
tentryfile=class
|
tentryfile=class
|
||||||
|
private
|
||||||
|
function getposition:longint;
|
||||||
|
procedure setposition(value:longint);
|
||||||
protected
|
protected
|
||||||
buf : pchar;
|
buf : pchar;
|
||||||
bufstart,
|
bufstart,
|
||||||
@ -205,8 +208,9 @@ type
|
|||||||
tempclosed : boolean;
|
tempclosed : boolean;
|
||||||
closepos : integer;
|
closepos : integer;
|
||||||
protected
|
protected
|
||||||
f : TCCustomFileStream;
|
f : TCStream;
|
||||||
mode : byte; {0 - Closed, 1 - Reading, 2 - Writing}
|
mode : byte; {0 - Closed, 1 - Reading, 2 - Writing}
|
||||||
|
fisfile : boolean;
|
||||||
fname : string;
|
fname : string;
|
||||||
fsize : integer;
|
fsize : integer;
|
||||||
procedure newheader;virtual;abstract;
|
procedure newheader;virtual;abstract;
|
||||||
@ -229,8 +233,14 @@ type
|
|||||||
procedure flush;
|
procedure flush;
|
||||||
procedure closefile;virtual;
|
procedure closefile;virtual;
|
||||||
procedure newentry;
|
procedure newentry;
|
||||||
|
property position:longint read getposition write setposition;
|
||||||
|
{ Warning: don't keep the stream open during a tempclose! }
|
||||||
|
function substream(ofs,len:longint):TCStream;
|
||||||
|
{ Warning: don't use the put* or write* functions anymore when writing through this }
|
||||||
|
property stream:TCStream read f;
|
||||||
{read}
|
{read}
|
||||||
function openfile:boolean;
|
function openfile:boolean;
|
||||||
|
function openstream(strm:TCStream):boolean;
|
||||||
procedure reloadbuf;
|
procedure reloadbuf;
|
||||||
procedure readdata(out b;len:integer);
|
procedure readdata(out b;len:integer);
|
||||||
procedure skipdata(len:integer);
|
procedure skipdata(len:integer);
|
||||||
@ -258,6 +268,7 @@ type
|
|||||||
function skipuntilentry(untilb:byte):boolean;
|
function skipuntilentry(untilb:byte):boolean;
|
||||||
{write}
|
{write}
|
||||||
function createfile:boolean;virtual;
|
function createfile:boolean;virtual;
|
||||||
|
function createstream(strm:TCStream):boolean;
|
||||||
procedure writeheader;virtual;abstract;
|
procedure writeheader;virtual;abstract;
|
||||||
procedure writebuf;
|
procedure writebuf;
|
||||||
procedure writedata(const b;len:integer);
|
procedure writedata(const b;len:integer);
|
||||||
@ -310,6 +321,7 @@ end;
|
|||||||
constructor tentryfile.create(const fn:string);
|
constructor tentryfile.create(const fn:string);
|
||||||
begin
|
begin
|
||||||
fname:=fn;
|
fname:=fn;
|
||||||
|
fisfile:=false;
|
||||||
change_endian:=false;
|
change_endian:=false;
|
||||||
mode:=0;
|
mode:=0;
|
||||||
newheader;
|
newheader;
|
||||||
@ -353,6 +365,7 @@ begin
|
|||||||
if mode<>0 then
|
if mode<>0 then
|
||||||
begin
|
begin
|
||||||
flush;
|
flush;
|
||||||
|
if fisfile then
|
||||||
f.Free;
|
f.Free;
|
||||||
mode:=0;
|
mode:=0;
|
||||||
closed:=true;
|
closed:=true;
|
||||||
@ -360,6 +373,36 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tentryfile.setposition(value:longint);
|
||||||
|
begin
|
||||||
|
if assigned(f) then
|
||||||
|
f.Position:=value
|
||||||
|
else
|
||||||
|
if tempclosed then
|
||||||
|
closepos:=value;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tentryfile.getposition:longint;
|
||||||
|
begin
|
||||||
|
if assigned(f) then
|
||||||
|
result:=f.Position
|
||||||
|
else
|
||||||
|
if tempclosed then
|
||||||
|
result:=closepos
|
||||||
|
else
|
||||||
|
result:=0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tentryfile.substream(ofs,len:longint):TCStream;
|
||||||
|
begin
|
||||||
|
result:=nil;
|
||||||
|
if assigned(f) then
|
||||||
|
result:=TCRangeStream.Create(f,ofs,len);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
tentryfile Reading
|
tentryfile Reading
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
@ -367,13 +410,25 @@ end;
|
|||||||
function tentryfile.openfile:boolean;
|
function tentryfile.openfile:boolean;
|
||||||
var
|
var
|
||||||
i : integer;
|
i : integer;
|
||||||
|
strm : TCStream;
|
||||||
begin
|
begin
|
||||||
openfile:=false;
|
openfile:=false;
|
||||||
try
|
try
|
||||||
f:=CFileStreamClass.Create(fname,fmOpenRead)
|
strm:=CFileStreamClass.Create(fname,fmOpenRead)
|
||||||
except
|
except
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
openfile:=openstream(strm);
|
||||||
|
fisfile:=result;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tentryfile.openstream(strm:TCStream):boolean;
|
||||||
|
var
|
||||||
|
i : longint;
|
||||||
|
begin
|
||||||
|
openstream:=false;
|
||||||
|
f:=strm;
|
||||||
closed:=false;
|
closed:=false;
|
||||||
{read ppuheader}
|
{read ppuheader}
|
||||||
fsize:=f.Size;
|
fsize:=f.Size;
|
||||||
@ -390,7 +445,7 @@ begin
|
|||||||
entrystart:=0;
|
entrystart:=0;
|
||||||
entrybufstart:=0;
|
entrybufstart:=0;
|
||||||
error:=false;
|
error:=false;
|
||||||
openfile:=true;
|
openstream:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -890,8 +945,10 @@ end;
|
|||||||
function tentryfile.createfile:boolean;
|
function tentryfile.createfile:boolean;
|
||||||
var
|
var
|
||||||
ok: boolean;
|
ok: boolean;
|
||||||
|
strm : TCStream;
|
||||||
begin
|
begin
|
||||||
createfile:=false;
|
createfile:=false;
|
||||||
|
strm:=nil;
|
||||||
if outputallowed then
|
if outputallowed then
|
||||||
begin
|
begin
|
||||||
{$ifdef MACOS}
|
{$ifdef MACOS}
|
||||||
@ -901,7 +958,7 @@ begin
|
|||||||
{$endif}
|
{$endif}
|
||||||
ok:=false;
|
ok:=false;
|
||||||
try
|
try
|
||||||
f:=CFileStreamClass.Create(fname,fmCreate);
|
strm:=CFileStreamClass.Create(fname,fmCreate);
|
||||||
ok:=true;
|
ok:=true;
|
||||||
except
|
except
|
||||||
end;
|
end;
|
||||||
@ -911,6 +968,17 @@ begin
|
|||||||
{$endif}
|
{$endif}
|
||||||
if not ok then
|
if not ok then
|
||||||
exit;
|
exit;
|
||||||
|
end;
|
||||||
|
createfile:=createstream(strm);
|
||||||
|
fisfile:=result;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function tentryfile.createstream(strm:TCStream):boolean;
|
||||||
|
begin
|
||||||
|
createstream:=false;
|
||||||
|
if outputallowed then
|
||||||
|
begin
|
||||||
|
f:=strm;
|
||||||
mode:=2;
|
mode:=2;
|
||||||
{write header for sure}
|
{write header for sure}
|
||||||
f.Write(getheaderaddr^,getheadersize);
|
f.Write(getheaderaddr^,getheadersize);
|
||||||
@ -925,7 +993,7 @@ begin
|
|||||||
entrytyp:=mainentryid;
|
entrytyp:=mainentryid;
|
||||||
{start}
|
{start}
|
||||||
newentry;
|
newentry;
|
||||||
createfile:=true;
|
createstream:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
cmsgs,verbose,
|
cmsgs,verbose,
|
||||||
cutils,cclasses,
|
cutils,cclasses,cstreams,
|
||||||
globtype,globals,finput,fmodule,
|
globtype,globals,finput,fmodule,
|
||||||
symbase,ppu,symtype;
|
symbase,ppu,symtype;
|
||||||
|
|
||||||
@ -59,7 +59,8 @@ interface
|
|||||||
constructor create(LoadedFrom:TModule;const amodulename: string; const afilename:TPathStr;_is_unit:boolean);
|
constructor create(LoadedFrom:TModule;const amodulename: string; const afilename:TPathStr;_is_unit:boolean);
|
||||||
destructor destroy;override;
|
destructor destroy;override;
|
||||||
procedure reset;override;
|
procedure reset;override;
|
||||||
function openppu:boolean;
|
function openppufile:boolean;
|
||||||
|
function openppustream(strm:TCStream):boolean;
|
||||||
procedure getppucrc;
|
procedure getppucrc;
|
||||||
procedure writeppu;
|
procedure writeppu;
|
||||||
procedure loadppu;
|
procedure loadppu;
|
||||||
@ -75,6 +76,7 @@ interface
|
|||||||
avoid endless resolving loops in case of cyclic dependencies. }
|
avoid endless resolving loops in case of cyclic dependencies. }
|
||||||
defsgeneration : longint;
|
defsgeneration : longint;
|
||||||
|
|
||||||
|
function openppu(ppufiletime:longint):boolean;
|
||||||
function search_unit_files(onlysource:boolean):boolean;
|
function search_unit_files(onlysource:boolean):boolean;
|
||||||
function search_unit(onlysource,shortname:boolean):boolean;
|
function search_unit(onlysource,shortname:boolean):boolean;
|
||||||
procedure load_interface;
|
procedure load_interface;
|
||||||
@ -181,11 +183,11 @@ var
|
|||||||
until false;
|
until false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function tppumodule.openppu:boolean;
|
function tppumodule.openppufile:boolean;
|
||||||
var
|
var
|
||||||
ppufiletime : longint;
|
ppufiletime : longint;
|
||||||
begin
|
begin
|
||||||
openppu:=false;
|
openppufile:=false;
|
||||||
Message1(unit_t_ppu_loading,ppufilename,@queuecomment);
|
Message1(unit_t_ppu_loading,ppufilename,@queuecomment);
|
||||||
{ Get ppufile time (also check if the file exists) }
|
{ Get ppufile time (also check if the file exists) }
|
||||||
ppufiletime:=getnamedfiletime(ppufilename);
|
ppufiletime:=getnamedfiletime(ppufilename);
|
||||||
@ -201,6 +203,29 @@ var
|
|||||||
Message(unit_u_ppu_file_too_short);
|
Message(unit_u_ppu_file_too_short);
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
result:=openppu(ppufiletime);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tppumodule.openppustream(strm:TCStream):boolean;
|
||||||
|
begin
|
||||||
|
{ Open the ppufile }
|
||||||
|
Message1(unit_u_ppu_name,ppufilename);
|
||||||
|
ppufile:=tcompilerppufile.create(ppufilename);
|
||||||
|
if not ppufile.openstream(strm) then
|
||||||
|
begin
|
||||||
|
ppufile.free;
|
||||||
|
ppufile:=nil;
|
||||||
|
Message(unit_u_ppu_file_too_short);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
result:=openppu(-1);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tppumodule.openppu(ppufiletime:longint):boolean;
|
||||||
|
begin
|
||||||
|
openppu:=false;
|
||||||
{ check for a valid PPU file }
|
{ check for a valid PPU file }
|
||||||
if not ppufile.CheckPPUId then
|
if not ppufile.CheckPPUId then
|
||||||
begin
|
begin
|
||||||
@ -287,7 +312,10 @@ var
|
|||||||
interface_crc:=ppufile.header.interface_checksum;
|
interface_crc:=ppufile.header.interface_checksum;
|
||||||
indirect_crc:=ppufile.header.indirect_checksum;
|
indirect_crc:=ppufile.header.indirect_checksum;
|
||||||
{ Show Debug info }
|
{ Show Debug info }
|
||||||
Message1(unit_u_ppu_time,filetimestring(ppufiletime));
|
if ppufiletime<>-1 then
|
||||||
|
Message1(unit_u_ppu_time,filetimestring(ppufiletime))
|
||||||
|
else
|
||||||
|
Message1(unit_u_ppu_time,'unknown');
|
||||||
Message1(unit_u_ppu_flags,tostr(flags));
|
Message1(unit_u_ppu_flags,tostr(flags));
|
||||||
Message1(unit_u_ppu_crc,hexstr(ppufile.header.checksum,8));
|
Message1(unit_u_ppu_crc,hexstr(ppufile.header.checksum,8));
|
||||||
Message1(unit_u_ppu_crc,hexstr(ppufile.header.interface_checksum,8)+' (intfc)');
|
Message1(unit_u_ppu_crc,hexstr(ppufile.header.interface_checksum,8)+' (intfc)');
|
||||||
@ -338,7 +366,7 @@ var
|
|||||||
if Found then
|
if Found then
|
||||||
Begin
|
Begin
|
||||||
SetFileName(hs,false);
|
SetFileName(hs,false);
|
||||||
Found:=OpenPPU;
|
Found:=openppufile;
|
||||||
End;
|
End;
|
||||||
PPUSearchPath:=Found;
|
PPUSearchPath:=Found;
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user