mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 13:20:19 +01:00 
			
		
		
		
	svn+ssh://peter@www.freepascal.org/FPC/svn/fpc/branches/linker/compiler ........ r2669 | peter | 2006-02-23 09:31:21 +0100 (Thu, 23 Feb 2006) | 2 lines * add compiler dir ........ r2673 | peter | 2006-02-23 17:08:56 +0100 (Thu, 23 Feb 2006) | 2 lines * enabled more code ........ r2677 | peter | 2006-02-24 17:46:29 +0100 (Fri, 24 Feb 2006) | 2 lines * pe stub and headers ........ r2683 | peter | 2006-02-25 23:13:24 +0100 (Sat, 25 Feb 2006) | 2 lines * section options cleanup ........ r2696 | peter | 2006-02-26 20:27:41 +0100 (Sun, 26 Feb 2006) | 2 lines * fixed typecasts ........ r2699 | peter | 2006-02-26 23:04:32 +0100 (Sun, 26 Feb 2006) | 2 lines * simple linking works ........ r2700 | peter | 2006-02-27 09:44:50 +0100 (Mon, 27 Feb 2006) | 2 lines * internal linker script ........ r2701 | peter | 2006-02-27 12:05:12 +0100 (Mon, 27 Feb 2006) | 2 lines * make elf working again ........ r2702 | peter | 2006-02-27 14:04:43 +0100 (Mon, 27 Feb 2006) | 3 lines * disable dwarf for smartlinking with .a * fix section start in new .a file ........ r2704 | peter | 2006-02-27 18:30:43 +0100 (Mon, 27 Feb 2006) | 2 lines * stab section fixes ........ r2708 | peter | 2006-02-28 19:29:17 +0100 (Tue, 28 Feb 2006) | 2 lines * basic work to merge stabs sections ........ r2712 | peter | 2006-02-28 23:17:48 +0100 (Tue, 28 Feb 2006) | 2 lines * unload tmodules before linking ........ r2713 | peter | 2006-02-28 23:18:51 +0100 (Tue, 28 Feb 2006) | 2 lines * fixed stabs linking ........ r2714 | peter | 2006-02-28 23:19:19 +0100 (Tue, 28 Feb 2006) | 2 lines * show code and data size ........ r2715 | peter | 2006-02-28 23:25:35 +0100 (Tue, 28 Feb 2006) | 2 lines * unload .stabs from objdata after it is merged ........ r2718 | peter | 2006-03-01 12:24:38 +0100 (Wed, 01 Mar 2006) | 3 lines * memsize/datasize cleanup * check for exports/resources when adding module to linker ........ r2722 | peter | 2006-03-03 09:12:20 +0100 (Fri, 03 Mar 2006) | 2 lines * new TObjSymbol splitted from TAsmSymbol ........ r2723 | peter | 2006-03-03 14:08:55 +0100 (Fri, 03 Mar 2006) | 2 lines * coff fixes after recent objsymbol changes ........ r2728 | peter | 2006-03-03 22:43:04 +0100 (Fri, 03 Mar 2006) | 2 lines * fixed coff writer ........ r2729 | peter | 2006-03-04 01:10:32 +0100 (Sat, 04 Mar 2006) | 2 lines * fix read-only opening ........ r2730 | peter | 2006-03-04 01:11:16 +0100 (Sat, 04 Mar 2006) | 2 lines * Read edata from DLLs, basic work ........ r2740 | peter | 2006-03-04 21:13:43 +0100 (Sat, 04 Mar 2006) | 3 lines * deletedef added * don't remove defs from index when we are already clearing everything ........ r2769 | peter | 2006-03-05 21:42:33 +0100 (Sun, 05 Mar 2006) | 4 lines * moved TObj classes to ogbase * ObjSection.SymbolRefs and SymbolDefines list * DLL importing ........ git-svn-id: trunk@2771 -
		
			
				
	
	
		
			619 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
			
		
		
	
	
			619 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			ObjectPascal
		
	
	
	
	
	
{
 | 
						|
    Copyright (c) 1998-2002 by Florian Klaempfl and Peter Vreman
 | 
						|
 | 
						|
    This module provides stream classes
 | 
						|
 | 
						|
    This program is free software; you can redistribute it and/or modify
 | 
						|
    it under the terms of the GNU General Public License as published by
 | 
						|
    the Free Software Foundation; either version 2 of the License, or
 | 
						|
    (at your option) any later version.
 | 
						|
 | 
						|
    This program is distributed in the hope that it will be useful,
 | 
						|
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
    GNU General Public License for more details.
 | 
						|
 | 
						|
    You should have received a copy of the GNU General Public License
 | 
						|
    along with this program; if not, write to the Free Software
 | 
						|
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
						|
 | 
						|
 ****************************************************************************
 | 
						|
}
 | 
						|
unit cstreams;
 | 
						|
 | 
						|
{$i fpcdefs.inc}
 | 
						|
 | 
						|
interface
 | 
						|
 | 
						|
   uses
 | 
						|
     cutils;
 | 
						|
 | 
						|
 | 
						|
{****************************************************************************
 | 
						|
                                  TCStream
 | 
						|
****************************************************************************}
 | 
						|
 | 
						|
    {
 | 
						|
      TCStream is copied directly from classesh.inc from the FCL so
 | 
						|
      it's compatible with the normal Classes.TStream.
 | 
						|
 | 
						|
      TCFileStream is a merge of THandleStream and TFileStream and updated
 | 
						|
      to have a 'file' type instead of Handle.
 | 
						|
 | 
						|
      TCCustomMemoryStream and TCMemoryStream are direct copies.
 | 
						|
    }
 | 
						|
    const
 | 
						|
       { TCStream seek origins }
 | 
						|
       soFromBeginning = 0;
 | 
						|
       soFromCurrent = 1;
 | 
						|
       soFromEnd = 2;
 | 
						|
 | 
						|
       { TCFileStream create mode }
 | 
						|
       fmCreate        = $FFFF;
 | 
						|
       fmOpenRead      = 0;
 | 
						|
       fmOpenWrite     = 1;
 | 
						|
       fmOpenReadWrite = 2;
 | 
						|
 | 
						|
var
 | 
						|
{ Used for Error reporting instead of exceptions }
 | 
						|
  CStreamError : longint;
 | 
						|
 | 
						|
type
 | 
						|
{ Fake TComponent class, it isn't used any futher }
 | 
						|
  TCComponent = class(TObject)
 | 
						|
  end;
 | 
						|
 | 
						|
{ TCStream abstract class }
 | 
						|
 | 
						|
  TCStream = class(TObject)
 | 
						|
  private
 | 
						|
    function GetPosition: Longint;
 | 
						|
    procedure SetPosition(Pos: Longint);
 | 
						|
    function GetSize: Longint;
 | 
						|
  protected
 | 
						|
    procedure SetSize(NewSize: Longint); virtual;
 | 
						|
  public
 | 
						|
    function Read(var Buffer; Count: Longint): Longint; virtual; abstract;
 | 
						|
    function Write(const Buffer; Count: Longint): Longint; virtual; abstract;
 | 
						|
    function Seek(Offset: Longint; Origin: Word): Longint; virtual; abstract;
 | 
						|
    procedure ReadBuffer(var Buffer; Count: Longint);
 | 
						|
    procedure WriteBuffer(const Buffer; Count: Longint);
 | 
						|
    function CopyFrom(Source: TCStream; Count: Longint): Longint;
 | 
						|
    function ReadComponent(Instance: TCComponent): TCComponent;
 | 
						|
    function ReadComponentRes(Instance: TCComponent): TCComponent;
 | 
						|
    procedure WriteComponent(Instance: TCComponent);
 | 
						|
    procedure WriteComponentRes(const ResName: string; Instance: TCComponent);
 | 
						|
    procedure WriteDescendent(Instance, Ancestor: TCComponent);
 | 
						|
    procedure WriteDescendentRes(const ResName: string; Instance, Ancestor: TCComponent);
 | 
						|
    procedure WriteResourceHeader(const ResName: string; {!!!:out} var FixupInfo: Integer);
 | 
						|
    procedure FixupResourceHeader(FixupInfo: Integer);
 | 
						|
    procedure ReadResHeader;
 | 
						|
    function ReadByte : Byte;
 | 
						|
    function ReadWord : Word;
 | 
						|
    function ReadDWord : Cardinal;
 | 
						|
    function ReadAnsiString : AnsiString;
 | 
						|
    procedure WriteByte(b : Byte);
 | 
						|
    procedure WriteWord(w : Word);
 | 
						|
    procedure WriteDWord(d : Cardinal);
 | 
						|
    Procedure WriteAnsiString (S : AnsiString);
 | 
						|
    property Position: Longint read GetPosition write SetPosition;
 | 
						|
    property Size: Longint read GetSize write SetSize;
 | 
						|
  end;
 | 
						|
 | 
						|
{ TFileStream class }
 | 
						|
 | 
						|
  TCFileStream = class(TCStream)
 | 
						|
  Private
 | 
						|
    FFileName : String;
 | 
						|
    FHandle: File;
 | 
						|
  protected
 | 
						|
    procedure SetSize(NewSize: Longint); override;
 | 
						|
  public
 | 
						|
    constructor Create(const AFileName: string; Mode: Word);
 | 
						|
    destructor Destroy; override;
 | 
						|
    function Read(var Buffer; Count: Longint): Longint; override;
 | 
						|
    function Write(const Buffer; Count: Longint): Longint; override;
 | 
						|
    function Seek(Offset: Longint; Origin: Word): Longint; override;
 | 
						|
    property FileName : String Read FFilename;
 | 
						|
  end;
 | 
						|
 | 
						|
{ TCustomMemoryStream abstract class }
 | 
						|
 | 
						|
  TCCustomMemoryStream = class(TCStream)
 | 
						|
  private
 | 
						|
    FMemory: Pointer;
 | 
						|
    FSize, FPosition: Longint;
 | 
						|
  protected
 | 
						|
    procedure SetPointer(Ptr: Pointer; ASize: Longint);
 | 
						|
  public
 | 
						|
    function Read(var Buffer; Count: Longint): Longint; override;
 | 
						|
    function Seek(Offset: Longint; Origin: Word): Longint; override;
 | 
						|
    procedure SaveToStream(Stream: TCStream);
 | 
						|
    procedure SaveToFile(const FileName: string);
 | 
						|
    property Memory: Pointer read FMemory;
 | 
						|
  end;
 | 
						|
 | 
						|
{ TCMemoryStream }
 | 
						|
 | 
						|
  TCMemoryStream = class(TCCustomMemoryStream)
 | 
						|
  private
 | 
						|
    FCapacity: Longint;
 | 
						|
    procedure SetCapacity(NewCapacity: Longint);
 | 
						|
  protected
 | 
						|
    function Realloc(var NewCapacity: Longint): Pointer; virtual;
 | 
						|
    property Capacity: Longint read FCapacity write SetCapacity;
 | 
						|
  public
 | 
						|
    destructor Destroy; override;
 | 
						|
    procedure Clear;
 | 
						|
    procedure LoadFromStream(Stream: TCStream);
 | 
						|
    procedure LoadFromFile(const FileName: string);
 | 
						|
    procedure SetSize(NewSize: Longint); override;
 | 
						|
    function Write(const Buffer; Count: Longint): Longint; override;
 | 
						|
  end;
 | 
						|
 | 
						|
 | 
						|
implementation
 | 
						|
 | 
						|
  Type
 | 
						|
    PByte = ^Byte;
 | 
						|
 | 
						|
{*****************************************************************************
 | 
						|
                                   TCStream
 | 
						|
*****************************************************************************}
 | 
						|
 | 
						|
  function TCStream.GetPosition: Longint;
 | 
						|
 | 
						|
    begin
 | 
						|
       Result:=Seek(0,soFromCurrent);
 | 
						|
    end;
 | 
						|
 | 
						|
  procedure TCStream.SetPosition(Pos: Longint);
 | 
						|
 | 
						|
    begin
 | 
						|
       Seek(pos,soFromBeginning);
 | 
						|
    end;
 | 
						|
 | 
						|
  function TCStream.GetSize: Longint;
 | 
						|
 | 
						|
    var
 | 
						|
       p : longint;
 | 
						|
 | 
						|
    begin
 | 
						|
       p:=GetPosition;
 | 
						|
       GetSize:=Seek(0,soFromEnd);
 | 
						|
       Seek(p,soFromBeginning);
 | 
						|
    end;
 | 
						|
 | 
						|
  procedure TCStream.SetSize(NewSize: Longint);
 | 
						|
 | 
						|
    begin
 | 
						|
    // We do nothing. Pipe streams don't support this
 | 
						|
    // As wel as possible read-ony streams !!
 | 
						|
    end;
 | 
						|
 | 
						|
  procedure TCStream.ReadBuffer(var Buffer; Count: Longint);
 | 
						|
 | 
						|
    begin
 | 
						|
       CStreamError:=0;
 | 
						|
       if Read(Buffer,Count)<Count then
 | 
						|
         CStreamError:=102;
 | 
						|
    end;
 | 
						|
 | 
						|
  procedure TCStream.WriteBuffer(const Buffer; Count: Longint);
 | 
						|
 | 
						|
    begin
 | 
						|
       CStreamError:=0;
 | 
						|
       if Write(Buffer,Count)<Count then
 | 
						|
         CStreamError:=103;
 | 
						|
    end;
 | 
						|
 | 
						|
  function TCStream.CopyFrom(Source: TCStream; Count: Longint): Longint;
 | 
						|
 | 
						|
    var
 | 
						|
       i : longint;
 | 
						|
       buffer : array[0..1023] of byte;
 | 
						|
 | 
						|
    begin
 | 
						|
       CStreamError:=0;
 | 
						|
       Result:=0;
 | 
						|
       while Count>0 do
 | 
						|
         begin
 | 
						|
            if (Count>sizeof(buffer)) then
 | 
						|
              i:=sizeof(Buffer)
 | 
						|
            else
 | 
						|
              i:=Count;
 | 
						|
            i:=Source.Read(buffer,i);
 | 
						|
            i:=Write(buffer,i);
 | 
						|
            dec(count,i);
 | 
						|
            inc(Result,i);
 | 
						|
            if i=0 then
 | 
						|
              exit;
 | 
						|
         end;
 | 
						|
    end;
 | 
						|
 | 
						|
  function TCStream.ReadComponent(Instance: TCComponent): TCComponent;
 | 
						|
    begin
 | 
						|
      Result:=nil;
 | 
						|
    end;
 | 
						|
 | 
						|
  function TCStream.ReadComponentRes(Instance: TCComponent): TCComponent;
 | 
						|
    begin
 | 
						|
      Result:=nil;
 | 
						|
    end;
 | 
						|
 | 
						|
  procedure TCStream.WriteComponent(Instance: TCComponent);
 | 
						|
    begin
 | 
						|
    end;
 | 
						|
 | 
						|
  procedure TCStream.WriteComponentRes(const ResName: string; Instance: TCComponent);
 | 
						|
    begin
 | 
						|
    end;
 | 
						|
 | 
						|
  procedure TCStream.WriteDescendent(Instance, Ancestor: TCComponent);
 | 
						|
    begin
 | 
						|
    end;
 | 
						|
 | 
						|
  procedure TCStream.WriteDescendentRes(const ResName: string; Instance, Ancestor: TCComponent);
 | 
						|
    begin
 | 
						|
    end;
 | 
						|
 | 
						|
  procedure TCStream.WriteResourceHeader(const ResName: string; {!!!: out} var FixupInfo: Integer);
 | 
						|
    begin
 | 
						|
    end;
 | 
						|
 | 
						|
  procedure TCStream.FixupResourceHeader(FixupInfo: Integer);
 | 
						|
    begin
 | 
						|
    end;
 | 
						|
 | 
						|
  procedure TCStream.ReadResHeader;
 | 
						|
    begin
 | 
						|
    end;
 | 
						|
 | 
						|
  function TCStream.ReadByte : Byte;
 | 
						|
 | 
						|
    var
 | 
						|
       b : Byte;
 | 
						|
 | 
						|
    begin
 | 
						|
       ReadBuffer(b,1);
 | 
						|
       ReadByte:=b;
 | 
						|
    end;
 | 
						|
 | 
						|
  function TCStream.ReadWord : Word;
 | 
						|
 | 
						|
    var
 | 
						|
       w : Word;
 | 
						|
 | 
						|
    begin
 | 
						|
       ReadBuffer(w,2);
 | 
						|
       ReadWord:=w;
 | 
						|
    end;
 | 
						|
 | 
						|
  function TCStream.ReadDWord : Cardinal;
 | 
						|
 | 
						|
    var
 | 
						|
       d : Cardinal;
 | 
						|
 | 
						|
    begin
 | 
						|
       ReadBuffer(d,4);
 | 
						|
       ReadDWord:=d;
 | 
						|
    end;
 | 
						|
 | 
						|
  Function TCStream.ReadAnsiString : AnsiString;
 | 
						|
  Var
 | 
						|
    TheSize : Longint;
 | 
						|
    P : PByte ;
 | 
						|
  begin
 | 
						|
    ReadBuffer (TheSize,SizeOf(TheSize));
 | 
						|
    SetLength(Result,TheSize);
 | 
						|
    // Illegal typecast if no AnsiStrings defined.
 | 
						|
    if TheSize>0 then
 | 
						|
     begin
 | 
						|
       ReadBuffer (Pointer(Result)^,TheSize);
 | 
						|
       P:=PByte(PtrInt(Result)+TheSize);
 | 
						|
       p^:=0;
 | 
						|
     end;
 | 
						|
   end;
 | 
						|
 | 
						|
  Procedure TCStream.WriteAnsiString (S : AnsiString);
 | 
						|
 | 
						|
  Var L : Longint;
 | 
						|
 | 
						|
  begin
 | 
						|
    L:=Length(S);
 | 
						|
    WriteBuffer (L,SizeOf(L));
 | 
						|
    WriteBuffer (Pointer(S)^,L);
 | 
						|
  end;
 | 
						|
 | 
						|
  procedure TCStream.WriteByte(b : Byte);
 | 
						|
 | 
						|
    begin
 | 
						|
       WriteBuffer(b,1);
 | 
						|
    end;
 | 
						|
 | 
						|
  procedure TCStream.WriteWord(w : Word);
 | 
						|
 | 
						|
    begin
 | 
						|
       WriteBuffer(w,2);
 | 
						|
    end;
 | 
						|
 | 
						|
  procedure TCStream.WriteDWord(d : Cardinal);
 | 
						|
 | 
						|
    begin
 | 
						|
       WriteBuffer(d,4);
 | 
						|
    end;
 | 
						|
 | 
						|
 | 
						|
{****************************************************************************}
 | 
						|
{*                             TCFileStream                                  *}
 | 
						|
{****************************************************************************}
 | 
						|
 | 
						|
constructor TCFileStream.Create(const AFileName: string; Mode: Word);
 | 
						|
var
 | 
						|
  oldfilemode : byte;
 | 
						|
begin
 | 
						|
  FFileName:=AFileName;
 | 
						|
  If Mode=fmcreate then
 | 
						|
    begin
 | 
						|
      system.assign(FHandle,AFileName);
 | 
						|
      {$I-}
 | 
						|
       system.rewrite(FHandle,1);
 | 
						|
      {$I+}
 | 
						|
      CStreamError:=IOResult;
 | 
						|
    end
 | 
						|
  else
 | 
						|
    begin
 | 
						|
      oldfilemode:=filemode;
 | 
						|
      filemode:=$40 or Mode;
 | 
						|
      system.assign(FHandle,AFileName);
 | 
						|
      {$I-}
 | 
						|
       system.reset(FHandle,1);
 | 
						|
      {$I+}
 | 
						|
      CStreamError:=IOResult;
 | 
						|
      filemode:=oldfilemode;
 | 
						|
    end;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
destructor TCFileStream.Destroy;
 | 
						|
begin
 | 
						|
  {$I-}
 | 
						|
   System.Close(FHandle);
 | 
						|
  {$I+}
 | 
						|
  CStreamError:=IOResult;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
function TCFileStream.Read(var Buffer; Count: Longint): Longint;
 | 
						|
begin
 | 
						|
  CStreamError:=0;
 | 
						|
  BlockRead(FHandle,Buffer,Count,Result);
 | 
						|
  If Result=-1 then Result:=0;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
function TCFileStream.Write(const Buffer; Count: Longint): Longint;
 | 
						|
begin
 | 
						|
  CStreamError:=0;
 | 
						|
  BlockWrite (FHandle,(@Buffer)^,Count,Result);
 | 
						|
  If Result=-1 then Result:=0;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
Procedure TCFileStream.SetSize(NewSize: Longint);
 | 
						|
begin
 | 
						|
  {$I-}
 | 
						|
   System.Seek(FHandle,NewSize);
 | 
						|
   System.Truncate(FHandle);
 | 
						|
  {$I+}
 | 
						|
  CStreamError:=IOResult;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
function TCFileStream.Seek(Offset: Longint; Origin: Word): Longint;
 | 
						|
var
 | 
						|
  l : longint;
 | 
						|
begin
 | 
						|
  {$I-}
 | 
						|
   case Origin of
 | 
						|
     soFromBeginning :
 | 
						|
       System.Seek(FHandle,Offset);
 | 
						|
     soFromCurrent :
 | 
						|
       begin
 | 
						|
         l:=System.FilePos(FHandle);
 | 
						|
         inc(l,Offset);
 | 
						|
         System.Seek(FHandle,l);
 | 
						|
       end;
 | 
						|
     soFromEnd :
 | 
						|
       begin
 | 
						|
         l:=System.FileSize(FHandle);
 | 
						|
         dec(l,Offset);
 | 
						|
         if l<0 then
 | 
						|
          l:=0;
 | 
						|
         System.Seek(FHandle,l);
 | 
						|
       end;
 | 
						|
   end;
 | 
						|
  {$I+}
 | 
						|
  CStreamError:=IOResult;
 | 
						|
  Result:=CStreamError;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
{****************************************************************************}
 | 
						|
{*                             TCustomMemoryStream                          *}
 | 
						|
{****************************************************************************}
 | 
						|
 | 
						|
procedure TCCustomMemoryStream.SetPointer(Ptr: Pointer; ASize: Longint);
 | 
						|
 | 
						|
begin
 | 
						|
  FMemory:=Ptr;
 | 
						|
  FSize:=ASize;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
function TCCustomMemoryStream.Read(var Buffer; Count: Longint): Longint;
 | 
						|
 | 
						|
begin
 | 
						|
  Result:=0;
 | 
						|
  If (FSize>0) and (FPosition<Fsize) then
 | 
						|
    begin
 | 
						|
    Result:=FSize-FPosition;
 | 
						|
    If Result>Count then Result:=Count;
 | 
						|
    Move (Pointer(PtrInt(FMemory)+FPosition)^,Buffer,Result);
 | 
						|
    FPosition:=Fposition+Result;
 | 
						|
    end;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
function TCCustomMemoryStream.Seek(Offset: Longint; Origin: Word): Longint;
 | 
						|
 | 
						|
begin
 | 
						|
  Case Origin of
 | 
						|
    soFromBeginning : FPosition:=Offset;
 | 
						|
    soFromEnd       : FPosition:=FSize+Offset;
 | 
						|
    soFromCurrent   : FpoSition:=FPosition+Offset;
 | 
						|
  end;
 | 
						|
  Result:=FPosition;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure TCCustomMemoryStream.SaveToStream(Stream: TCStream);
 | 
						|
 | 
						|
begin
 | 
						|
  if FSize>0 then Stream.WriteBuffer (FMemory^,FSize);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure TCCustomMemoryStream.SaveToFile(const FileName: string);
 | 
						|
 | 
						|
Var S : TCFileStream;
 | 
						|
 | 
						|
begin
 | 
						|
  Try
 | 
						|
    S:=TCFileStream.Create (FileName,fmCreate);
 | 
						|
    SaveToStream(S);
 | 
						|
  finally
 | 
						|
    S.free;
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
{****************************************************************************}
 | 
						|
{*                             TCMemoryStream                                *}
 | 
						|
{****************************************************************************}
 | 
						|
 | 
						|
 | 
						|
Const TMSGrow = 4096; { Use 4k blocks. }
 | 
						|
 | 
						|
procedure TCMemoryStream.SetCapacity(NewCapacity: Longint);
 | 
						|
 | 
						|
begin
 | 
						|
  SetPointer (Realloc(NewCapacity),Fsize);
 | 
						|
  FCapacity:=NewCapacity;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
function TCMemoryStream.Realloc(var NewCapacity: Longint): Pointer;
 | 
						|
 | 
						|
Var MoveSize : Longint;
 | 
						|
 | 
						|
begin
 | 
						|
  CStreamError:=0;
 | 
						|
  If NewCapacity>0 Then // round off to block size.
 | 
						|
    NewCapacity := (NewCapacity + (TMSGrow-1)) and not (TMSGROW-1);
 | 
						|
  // Only now check !
 | 
						|
  If NewCapacity=FCapacity then
 | 
						|
    Result:=FMemory
 | 
						|
  else
 | 
						|
    If NewCapacity=0 then
 | 
						|
      FreeMem (FMemory,Fcapacity)
 | 
						|
    else
 | 
						|
      begin
 | 
						|
      GetMem (Result,NewCapacity);
 | 
						|
      If Result=Nil then
 | 
						|
        CStreamError:=204;
 | 
						|
      If FCapacity>0 then
 | 
						|
        begin
 | 
						|
        MoveSize:=FSize;
 | 
						|
        If MoveSize>NewCapacity then MoveSize:=NewCapacity;
 | 
						|
        Move (Fmemory^,Result^,MoveSize);
 | 
						|
        FreeMem (FMemory,FCapacity);
 | 
						|
        end;
 | 
						|
      end;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
destructor TCMemoryStream.Destroy;
 | 
						|
 | 
						|
begin
 | 
						|
  Clear;
 | 
						|
  Inherited Destroy;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure TCMemoryStream.Clear;
 | 
						|
 | 
						|
begin
 | 
						|
  FSize:=0;
 | 
						|
  FPosition:=0;
 | 
						|
  SetCapacity (0);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure TCMemoryStream.LoadFromStream(Stream: TCStream);
 | 
						|
 | 
						|
begin
 | 
						|
  Stream.Position:=0;
 | 
						|
  SetSize(Stream.Size);
 | 
						|
  If FSize>0 then Stream.ReadBuffer(FMemory^,FSize);
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure TCMemoryStream.LoadFromFile(const FileName: string);
 | 
						|
 | 
						|
Var S : TCFileStream;
 | 
						|
 | 
						|
begin
 | 
						|
  Try
 | 
						|
    S:=TCFileStream.Create (FileName,fmOpenRead);
 | 
						|
    LoadFromStream(S);
 | 
						|
  finally
 | 
						|
    S.free;
 | 
						|
  end;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
procedure TCMemoryStream.SetSize(NewSize: Longint);
 | 
						|
 | 
						|
begin
 | 
						|
  SetCapacity (NewSize);
 | 
						|
  FSize:=NewSize;
 | 
						|
  IF FPosition>FSize then
 | 
						|
    FPosition:=FSize;
 | 
						|
end;
 | 
						|
 | 
						|
 | 
						|
function TCMemoryStream.Write(const Buffer; Count: Longint): Longint;
 | 
						|
 | 
						|
Var NewPos : Longint;
 | 
						|
 | 
						|
begin
 | 
						|
  If Count=0 then
 | 
						|
   begin
 | 
						|
     Result:=0;
 | 
						|
     exit;
 | 
						|
   end;
 | 
						|
  NewPos:=FPosition+Count;
 | 
						|
  If NewPos>Fsize then
 | 
						|
    begin
 | 
						|
    IF NewPos>FCapacity then
 | 
						|
      SetCapacity (NewPos);
 | 
						|
    FSize:=Newpos;
 | 
						|
    end;
 | 
						|
  System.Move (Buffer,Pointer(Ptrint(FMemory)+FPosition)^,Count);
 | 
						|
  FPosition:=NewPos;
 | 
						|
  Result:=Count;
 | 
						|
end;
 | 
						|
 | 
						|
end.
 |