<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: persistent code</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Sat, 06 Sep 2008 09:58:59 GMT</pubDate>
    <description>DZone Snippets: persistent code</description>
    <item>
      <title>Just #@$% do it!</title>
      <link>http://snippets.dzone.com/posts/show/3076</link>
      <description>If you have an unreliable network feed and want to run something like rsync, scp, etc. without having to babysit it a simple function can be used to prefix a command.  The function looks like this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;# Function to force a command to try until it works.&lt;br /&gt;# Name means "JUST #@$% DO IT!"&lt;br /&gt;JFDI () {&lt;br /&gt;  COMMAND=$*&lt;br /&gt;  while ! $COMMAND ; do echo "Retrying..." ; done&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Using it is simplicity itself:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;# command that can fail and annoy&lt;br /&gt;rsync -avz /my/local/directory/ myuser@host:~/my/remote/directory/&lt;br /&gt;&lt;br /&gt;# command that won't give up ever&lt;br /&gt;JFDI rsync -avz /my/local/directory/ myuser@host:~/my/remote/directory/&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Mon, 04 Dec 2006 17:32:15 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/3076</guid>
      <author>ttmrichter (Michael T. Richter)</author>
    </item>
    <item>
      <title>a binary tree structure "PersistentTree"</title>
      <link>http://snippets.dzone.com/posts/show/436</link>
      <description>unit StreamAdapter.pas&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;//+ Jonas Raoni Soares Silva&lt;br /&gt;//@ http://jsfromhell.com&lt;br /&gt;&lt;br /&gt;unit StreamAdapter;&lt;br /&gt;&lt;br /&gt;interface&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  Classes;&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;  IStream = interface( IInterface )&lt;br /&gt;    ['{FBEF199A-09BC-4B61-89EA-1EF8B22C93A5}']&lt;br /&gt;    function Read(var Buffer; const Count: Longint): Longint;&lt;br /&gt;    function Write(const Buffer; const Count: Longint): Longint;&lt;br /&gt;    function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;&lt;br /&gt;    procedure ReadBuffer(var Buffer; const Count: Longint);&lt;br /&gt;    procedure WriteBuffer(const Buffer; const Count: Longint);&lt;br /&gt;    function CopyFrom(Source: TStream; const Count: Int64): Int64;&lt;br /&gt;    function WriteTo(Dest: TStream; const Count: Int64): Int64;&lt;br /&gt;&lt;br /&gt;    procedure SetPosition( const Value: Int64 );&lt;br /&gt;    procedure SetSize( const Value: Int64 );&lt;br /&gt;    function GetPosition: Int64;&lt;br /&gt;    function GetSize: Int64;&lt;br /&gt;&lt;br /&gt;    property Position: Int64 read GetPosition write SetPosition;&lt;br /&gt;    property Size: Int64 read GetSize write SetSize;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  TStreamAdapter = class( TInterfacedObject, IStream )&lt;br /&gt;  private&lt;br /&gt;    FStream: TStream;&lt;br /&gt;    procedure SetPosition( const Value: Int64 );&lt;br /&gt;    procedure SetSize( const Value: Int64 );&lt;br /&gt;    function GetPosition: Int64;&lt;br /&gt;    function GetSize: Int64;&lt;br /&gt;&lt;br /&gt;  public&lt;br /&gt;    constructor Create( Stream: TStream );&lt;br /&gt;    destructor Destroy; override;&lt;br /&gt;&lt;br /&gt;    function Read(var Buffer; const Count: Longint): Longint;&lt;br /&gt;    function Write(const Buffer; const Count: Longint): Longint;&lt;br /&gt;&lt;br /&gt;    procedure ReadBuffer(var Buffer; const Count: Longint);&lt;br /&gt;    procedure WriteBuffer(const Buffer; const Count: Longint);&lt;br /&gt;&lt;br /&gt;    function CopyFrom(Source: TStream; const Count: Int64): Int64;&lt;br /&gt;    function WriteTo(Dest: TStream; const Count: Int64): Int64;&lt;br /&gt;&lt;br /&gt;    function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;&lt;br /&gt;&lt;br /&gt;    property Position: Int64 read GetPosition write SetPosition;&lt;br /&gt;    property Size: Int64 read GetSize write SetSize;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;&lt;br /&gt;{ TStreamAdapter }&lt;br /&gt;&lt;br /&gt;function TStreamAdapter.CopyFrom(Source: TStream; const Count: Int64): Int64;&lt;br /&gt;begin&lt;br /&gt;  Result := FStream.CopyFrom( Source, Count );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;constructor TStreamAdapter.Create(Stream: TStream);&lt;br /&gt;begin&lt;br /&gt;  FStream := Stream;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;destructor TStreamAdapter.Destroy;&lt;br /&gt;begin&lt;br /&gt;  FStream.Free;&lt;br /&gt;  inherited;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TStreamAdapter.GetPosition: Int64;&lt;br /&gt;begin&lt;br /&gt;  Result := FStream.Position;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TStreamAdapter.GetSize: Int64;&lt;br /&gt;begin&lt;br /&gt;  Result := FStream.Size;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TStreamAdapter.Read(var Buffer; const Count: Integer): Longint;&lt;br /&gt;begin&lt;br /&gt;  Result := FStream.Read( Buffer, Count );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TStreamAdapter.ReadBuffer(var Buffer; const Count: Integer);&lt;br /&gt;begin&lt;br /&gt;  FStream.ReadBuffer( Buffer, Count );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TStreamAdapter.Seek(const Offset: Int64;&lt;br /&gt;  Origin: TSeekOrigin): Int64;&lt;br /&gt;begin&lt;br /&gt;  Result := FStream.Seek( Offset, Origin );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TStreamAdapter.SetPosition(const Value: Int64);&lt;br /&gt;begin&lt;br /&gt;  FStream.Position := Value;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TStreamAdapter.SetSize(const Value: Int64);&lt;br /&gt;begin&lt;br /&gt;  FStream.Size := Value;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TStreamAdapter.Write(const Buffer; const Count: Integer): Longint;&lt;br /&gt;begin&lt;br /&gt;  Result := FStream.Write( Buffer, Count );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TStreamAdapter.WriteBuffer(const Buffer; const Count: Integer);&lt;br /&gt;begin&lt;br /&gt;  FStream.WriteBuffer( Buffer, Count );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TStreamAdapter.WriteTo(Dest: TStream; const Count: Int64): Int64;&lt;br /&gt;begin&lt;br /&gt;  Result := Dest.CopyFrom( FStream, Count );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;end.&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;unit PersistentTree.pas&lt;br /&gt;&lt;code&gt;&lt;br /&gt;//+ Jonas Raoni Soares Silva&lt;br /&gt;//@ http://jsfromhell.com&lt;br /&gt;&lt;br /&gt;unit PersistentTree;&lt;br /&gt;&lt;br /&gt;interface&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  Windows, Classes, SysUtils, StreamAdapter;&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;  EPersistentTree = class( Exception );&lt;br /&gt;&lt;br /&gt;  TPersistentTree = class;&lt;br /&gt;&lt;br /&gt;  TPersistentTreeClass = class of TPersistentTree;&lt;br /&gt;&lt;br /&gt;  TPersistentTree = class( TStream )&lt;br /&gt;  private&lt;br /&gt;    FStream: IStream;&lt;br /&gt;    FList: TList;&lt;br /&gt;    FBaseClass: TPersistentTreeClass;&lt;br /&gt;    FOwner, FParent: TPersistentTree;&lt;br /&gt;    FOwnStream: Boolean;&lt;br /&gt;    FDataFilename, FFilename: string;&lt;br /&gt;    FLastPosition, FDataBegin, FDataLength: Int64;&lt;br /&gt;&lt;br /&gt;    function GetItem(const Index: Integer): TPersistentTree;&lt;br /&gt;    function GetCount: Integer;&lt;br /&gt;    function GetStream: TStream;&lt;br /&gt;    function Import( Item: TPersistentTree ): Boolean;&lt;br /&gt;    procedure ClearData;&lt;br /&gt;    procedure RecreateStream( const Pos: Int64; const Deep: Boolean = False );&lt;br /&gt;    procedure Synchronize;&lt;br /&gt;&lt;br /&gt;  protected&lt;br /&gt;    //override to provide writing/reading notifications&lt;br /&gt;    procedure Loaded; virtual;&lt;br /&gt;    procedure Saving; virtual;&lt;br /&gt;&lt;br /&gt;    //derived from TStream&lt;br /&gt;    function GetSize: Int64; override;&lt;br /&gt;    procedure SetSize(NewSize: Longint); override;&lt;br /&gt;    procedure SetSize(const NewSize: Int64); override;&lt;br /&gt;&lt;br /&gt;  public&lt;br /&gt;    constructor Create; virtual;&lt;br /&gt;    destructor Destroy; override;&lt;br /&gt;&lt;br /&gt;    //derived from TStream&lt;br /&gt;    function Read( var Buffer; Count: Longint ): Longint; override;&lt;br /&gt;    function Write( const Buffer; Count: Longint ): Longint; override;&lt;br /&gt;    function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;&lt;br /&gt;&lt;br /&gt;    function Truncate: Int64;&lt;br /&gt;    function ReadString: string;&lt;br /&gt;    procedure WriteString( const Data: string );&lt;br /&gt;&lt;br /&gt;    procedure Save( const AFilename: string ); overload;&lt;br /&gt;    procedure Save( Stream: TStream ); overload;&lt;br /&gt;    procedure Load( const AFilename: string ); overload;&lt;br /&gt;    procedure Load( Stream: IStream ); overload;&lt;br /&gt;    procedure Load( Stream: TStream ); overload;&lt;br /&gt;&lt;br /&gt;    function Add: TPersistentTree; overload;&lt;br /&gt;    function Add( Item: TPersistentTree ): Integer; overload;&lt;br /&gt;    procedure Insert( const Index: Integer; Item: TPersistentTree);&lt;br /&gt;    function IndexOf( Item: TPersistentTree ): Integer;&lt;br /&gt;    function Remove( Item: TPersistentTree ): Integer;&lt;br /&gt;    procedure Delete( const Index: Integer);&lt;br /&gt;    function Extract( Item: TPersistentTree ): TPersistentTree;&lt;br /&gt;    procedure Exchange( const IndexA, IndexB: Integer );&lt;br /&gt;    procedure Move(const CurIndex, NewIndex: Integer);&lt;br /&gt;    procedure Clear;&lt;br /&gt;&lt;br /&gt;    property Items[ const Index: Integer ]: TPersistentTree read GetItem; default;&lt;br /&gt;    property Count: Integer read GetCount;&lt;br /&gt;    property Owner: TPersistentTree read FOwner;&lt;br /&gt;    property Parent: TPersistentTree read FParent;&lt;br /&gt;    property Filename: string read FFilename;&lt;br /&gt;    property BaseClass: TPersistentTreeClass read FBaseClass write FBaseClass;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  TPersistentTreeHeader = packed record&lt;br /&gt;    Sig: array[0..4] of Char;&lt;br /&gt;    Ver: Word;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;const&lt;br /&gt;  PERSISTENT_TREE_HEADER: TPersistentTreeHeader = ( Sig: 'PTREE'; Ver: 1 );&lt;br /&gt;&lt;br /&gt;function GetTempFile: string;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;&lt;br /&gt;function GetTempFile: string;&lt;br /&gt;var&lt;br /&gt;  Path: array[0..MAX_PATH-1] of Char;&lt;br /&gt;begin&lt;br /&gt;  GetTempPath( MAX_PATH, Path );&lt;br /&gt;  GetTempFileName( Path, 'BUF', 0, Path );&lt;br /&gt;  Result := Path;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;{ TPersistentTree }&lt;br /&gt;&lt;br /&gt;procedure TPersistentTree.Clear;&lt;br /&gt;var&lt;br /&gt;  I: Integer;&lt;br /&gt;begin&lt;br /&gt;  for I := FList.Count - 1 downto 0 do&lt;br /&gt;  begin&lt;br /&gt;    TPersistentTree( FList[I] ).Free;&lt;br /&gt;    FList.Delete( I );&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;constructor TPersistentTree.Create;&lt;br /&gt;begin&lt;br /&gt;  FBaseClass := TPersistentTreeClass( Self.ClassType );&lt;br /&gt;  FList := TList.Create;&lt;br /&gt;  FStream := TStreamAdapter.Create( GetStream );&lt;br /&gt;  FOwnStream := True;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;destructor TPersistentTree.Destroy;&lt;br /&gt;begin&lt;br /&gt;  ClearData;&lt;br /&gt;  FList.Free;&lt;br /&gt;  inherited;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TPersistentTree.Exchange(const IndexA, IndexB: Integer);&lt;br /&gt;begin&lt;br /&gt;  FList.Exchange( IndexA, IndexB );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TPersistentTree.GetCount: Integer;&lt;br /&gt;begin&lt;br /&gt;  Result := FList.Count;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TPersistentTree.GetItem(const Index: Integer): TPersistentTree;&lt;br /&gt;begin&lt;br /&gt;  Result := FList[ Index ];&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TPersistentTree.IndexOf(&lt;br /&gt;  Item: TPersistentTree): Integer;&lt;br /&gt;begin&lt;br /&gt;  Result := FList.IndexOf( Item );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TPersistentTree.Load(const AFilename: string);&lt;br /&gt;var&lt;br /&gt;  FS: TFileStream;&lt;br /&gt;  //Header: TPersistentTreeHeader;&lt;br /&gt;begin&lt;br /&gt;  FS := TFileStream.Create( AFilename, fmOpenRead or fmShareDenyWrite );&lt;br /&gt;  try&lt;br /&gt;    //FS.Read( Header, SizeOf( TPersistentTreeHeader ) );&lt;br /&gt;    //if not CompareMem( @Header, @PERSISTENT_TREE_HEADER, SizeOf( TPersistentTreeHeader ) ) then&lt;br /&gt;    //  raise EPersistentTree.CreateFmt( '%s.LoadFromFile :: "%s" Not Recognized', [ClassName, AFilename] );&lt;br /&gt;    Load( FS );&lt;br /&gt;    FFilename := AFilename;&lt;br /&gt;  except&lt;br /&gt;    FS.Free;&lt;br /&gt;    raise;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TPersistentTree.Load(Stream: TStream);&lt;br /&gt;begin&lt;br /&gt;  Load( TStreamAdapter.Create( Stream ) );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TPersistentTree.Remove(Item: TPersistentTree): Integer;&lt;br /&gt;begin&lt;br /&gt;  Result := FList.Remove( Item );&lt;br /&gt;  if Result &gt;= 0 then&lt;br /&gt;    Item.Free;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TPersistentTree.Save( const AFilename: string );&lt;br /&gt;var&lt;br /&gt;  FS: TFileStream;&lt;br /&gt;begin&lt;br /&gt;  FS := TFileStream.Create( AFilename, fmCreate or fmShareDenyWrite );&lt;br /&gt;  try&lt;br /&gt;    //FS.Write( PERSISTENT_TREE_HEADER, SizeOf( TPersistentTreeHeader ) );&lt;br /&gt;    Save( FS );&lt;br /&gt;  finally&lt;br /&gt;    FS.Free;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TPersistentTree.Save(Stream: TStream);&lt;br /&gt;var&lt;br /&gt;  I: LongInt;&lt;br /&gt;begin&lt;br /&gt;  Seek( 0, soBeginning );&lt;br /&gt;  Saving;&lt;br /&gt;&lt;br /&gt;  FDataLength := Size;&lt;br /&gt;  Stream.Write( FDataLength, SizeOf( FDataLength ) );&lt;br /&gt;  Stream.CopyFrom( Self, 0 );&lt;br /&gt;&lt;br /&gt;  I := FList.Count;&lt;br /&gt;  Stream.Write( I, SizeOf( I ) );&lt;br /&gt;  for I := 0 to FList.Count-1 do&lt;br /&gt;    Self[I].Save( Stream );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TPersistentTree.Write( const Buffer; Count: Longint ): Longint;&lt;br /&gt;begin&lt;br /&gt;  if FOwnStream then&lt;br /&gt;    Result := FStream.Write( Buffer, Count )&lt;br /&gt;  else&lt;br /&gt;  begin&lt;br /&gt;    Synchronize;&lt;br /&gt;    if Position + Count &gt; Size then&lt;br /&gt;      RecreateStream( Position );&lt;br /&gt;    Result := FStream.Write( Buffer, Count );&lt;br /&gt;    FLastPosition := FStream.Position;          &lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TPersistentTree.Read( var Buffer; Count: Longint): Longint;&lt;br /&gt;begin&lt;br /&gt;  if FOwnStream then&lt;br /&gt;    Result := FStream.Read( Buffer, Count )&lt;br /&gt;  else&lt;br /&gt;  begin&lt;br /&gt;    Synchronize;&lt;br /&gt;    if Count &lt; 0 then&lt;br /&gt;      Count := 0&lt;br /&gt;    else if Count &gt; Size - Position then&lt;br /&gt;      Count := Size - Position;&lt;br /&gt;    Result := FStream.Read( Buffer, Count );&lt;br /&gt;    FLastPosition := FStream.Position;&lt;br /&gt;  end&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TPersistentTree.Seek(const Offset: Int64;&lt;br /&gt;  Origin: TSeekOrigin): Int64;&lt;br /&gt;begin&lt;br /&gt;  if FOwnStream then&lt;br /&gt;    Result := FStream.Seek( Offset, Origin )&lt;br /&gt;  else&lt;br /&gt;  begin&lt;br /&gt;    Synchronize;&lt;br /&gt;    case Origin of&lt;br /&gt;      soBeginning: Result := FDataBegin + Offset;&lt;br /&gt;      soCurrent: Result := FStream.Position + Offset;&lt;br /&gt;      soEnd: Result := FDataBegin + Size - Offset;&lt;br /&gt;    else&lt;br /&gt;      Result := 0;&lt;br /&gt;    end;&lt;br /&gt;    if Result &gt; -1 then&lt;br /&gt;      if Result &lt;= FDataBegin + Size then&lt;br /&gt;        Result := FStream.Seek( Result, soBeginning ) - FDataBegin&lt;br /&gt;      else&lt;br /&gt;      begin&lt;br /&gt;        RecreateStream( Size );&lt;br /&gt;        Result := FStream.Seek( Result, soBeginning );&lt;br /&gt;      end;&lt;br /&gt;    FLastPosition := FStream.Position;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TPersistentTree.SetSize(const NewSize: Int64);&lt;br /&gt;begin&lt;br /&gt;  if FOwnStream then&lt;br /&gt;    FStream.Size := NewSize&lt;br /&gt;  else begin&lt;br /&gt;    if NewSize &lt;= 0 then&lt;br /&gt;      RecreateStream( 0 )&lt;br /&gt;    else if NewSize &gt; Size then&lt;br /&gt;      RecreateStream( Size )&lt;br /&gt;    else&lt;br /&gt;    begin&lt;br /&gt;      FDataLength := NewSize;&lt;br /&gt;      Seek( 0, soEnd );&lt;br /&gt;    end;&lt;br /&gt;    FLastPosition := FStream.Position;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TPersistentTree.Synchronize;&lt;br /&gt;begin&lt;br /&gt;  if not FOwnStream and ( ( FStream.Position &lt; FDataBegin ) or ( FStream.Position - FDataBegin &gt; FDataLength ) ) then&lt;br /&gt;    FStream.Seek( FLastPosition, soBeginning );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TPersistentTree.Load( Stream: IStream);&lt;br /&gt;var&lt;br /&gt;  I: LongInt;&lt;br /&gt;begin&lt;br /&gt;  ClearData;&lt;br /&gt;&lt;br /&gt;  FStream := Stream;&lt;br /&gt;  FOwnStream := False;&lt;br /&gt;&lt;br /&gt;  Stream.Read( FDataLength, SizeOf( FDataLength ) );&lt;br /&gt;  FDataBegin := FStream.Position;&lt;br /&gt;  FLastPosition := FDataBegin;&lt;br /&gt;&lt;br /&gt;  Stream.Seek( FDataLength, soCurrent );&lt;br /&gt;&lt;br /&gt;  Stream.Read( I, SizeOf( I ) );&lt;br /&gt;  for I := I - 1 downto 0 do&lt;br /&gt;    Add.Load( FStream );&lt;br /&gt;&lt;br /&gt;  //Seek( 0, soBeginning ); it isnt needed since synchonize will do it anyway&lt;br /&gt;  Loaded;&lt;br /&gt;  FStream.Seek( FDataBegin + FDataLength + SizeOf( I ), soBeginning );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TPersistentTree.Extract( Item: TPersistentTree): TPersistentTree;&lt;br /&gt;begin&lt;br /&gt;  Result := FList.Extract( Item );&lt;br /&gt;  if Assigned( Result ) then begin&lt;br /&gt;    Result.FParent := nil;&lt;br /&gt;    Result.FOwner := nil;&lt;br /&gt;    Result.RecreateStream( Size, True );&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;function TPersistentTree.GetSize: Int64;&lt;br /&gt;begin&lt;br /&gt;  if FOwnStream then&lt;br /&gt;    Result := FStream.Size&lt;br /&gt;  else&lt;br /&gt;    Result := FDataLength;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TPersistentTree.WriteString(const Data: string);&lt;br /&gt;var&lt;br /&gt;  I: LongWord;&lt;br /&gt;begin&lt;br /&gt;  I := Length( Data );&lt;br /&gt;  Write( I, SizeOf( I ) );&lt;br /&gt;  Write( Pointer( Data )^, I );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TPersistentTree.ReadString: string;&lt;br /&gt;var&lt;br /&gt;  I: LongWord;&lt;br /&gt;begin&lt;br /&gt;  Read( I, SizeOf( I ) );&lt;br /&gt;  SetLength( Result, I );&lt;br /&gt;  Read( Pointer( Result )^, I );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TPersistentTree.SetSize(NewSize: Integer);&lt;br /&gt;begin&lt;br /&gt;  SetSize( Int64( NewSize ) );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TPersistentTree.RecreateStream( const Pos: Int64; const Deep: Boolean );&lt;br /&gt;var&lt;br /&gt;  FS: TStream;&lt;br /&gt;  I: Integer;&lt;br /&gt;begin&lt;br /&gt;  if not FOwnStream then&lt;br /&gt;  begin&lt;br /&gt;    FS := GetStream;&lt;br /&gt;    if Pos &gt; 0 then&lt;br /&gt;    begin&lt;br /&gt;      Seek( 0, soBeginning );&lt;br /&gt;      FS.CopyFrom( Self, Pos );&lt;br /&gt;    end;&lt;br /&gt;    FStream := TStreamAdapter.Create( FS );&lt;br /&gt;    FOwnStream := True;&lt;br /&gt;  end;&lt;br /&gt;  if Deep then&lt;br /&gt;    for I := 0 to FList.Count - 1 do&lt;br /&gt;      Self[I].RecreateStream( Self[I].Size, True );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TPersistentTree.ClearData;&lt;br /&gt;begin&lt;br /&gt;  FStream := nil;&lt;br /&gt;  if FOwnStream then&lt;br /&gt;    DeleteFile( FDataFilename );&lt;br /&gt;  Clear;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TPersistentTree.GetStream: TStream;&lt;br /&gt;begin&lt;br /&gt;  FDataFilename := GetTempFile;&lt;br /&gt;  Result := TFileStream.Create( FDataFilename, fmCreate or fmShareDenyWrite );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TPersistentTree.Add: TPersistentTree;&lt;br /&gt;begin&lt;br /&gt;  Result := TPersistentTreeClass( FBaseClass ).Create;&lt;br /&gt;  Add( Result );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TPersistentTree.Add( Item: TPersistentTree): Integer;&lt;br /&gt;begin&lt;br /&gt;  if Import( Item ) then&lt;br /&gt;    Result := FList.Add( Item )&lt;br /&gt;  else&lt;br /&gt;    Result := FList.IndexOf( Item );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TPersistentTree.Delete(const Index: Integer);&lt;br /&gt;begin&lt;br /&gt;  TPersistentTree( FList[Index] ).Free;&lt;br /&gt;  FList.Delete( Index );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TPersistentTree.Insert(const Index: Integer; Item: TPersistentTree);&lt;br /&gt;begin&lt;br /&gt;  if Import( Item ) then&lt;br /&gt;    FList.Insert( Index, Item )&lt;br /&gt;  else&lt;br /&gt;    FList.Move( FList.IndexOf( Item ), Index );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TPersistentTree.Move(const CurIndex, NewIndex: Integer);&lt;br /&gt;begin&lt;br /&gt;  FList.Move( CurIndex, NewIndex );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TPersistentTree.Truncate: Int64;&lt;br /&gt;begin&lt;br /&gt;  Result := Position;&lt;br /&gt;  Size := Result;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TPersistentTree.Import(Item: TPersistentTree): Boolean;&lt;br /&gt;begin&lt;br /&gt;  Result := not Assigned( Item.FParent ) or ( ( Item.FParent &lt;&gt; Self ) and Assigned( Item.FParent.Extract( Item ) ) );&lt;br /&gt;  if Result then&lt;br /&gt;  begin&lt;br /&gt;    Item.FParent := Self;&lt;br /&gt;    if FOwner &lt;&gt; nil then&lt;br /&gt;      Item.FOwner := FOwner&lt;br /&gt;    else&lt;br /&gt;      Item.FOwner := Self;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TPersistentTree.Saving;&lt;br /&gt;begin&lt;br /&gt;//override to provide extra save features&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TPersistentTree.Loaded;&lt;br /&gt;begin&lt;br /&gt;//override to provide extra load features&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;end.&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Sat, 02 Jul 2005 03:50:02 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/436</guid>
      <author>jonasraoni (Jonas Raoni Soares Silva)</author>
    </item>
  </channel>
</rss>
