Einzelnen Beitrag anzeigen

Benutzerbild von maximov
maximov

Registriert seit: 2. Okt 2003
Ort: Hamburg
548 Beiträge
 
Delphi 2005 Professional
 
#19

Re: TCollection und TCollectionItem

  Alt 27. Mai 2004, 23:24
SO:

- 100% DFM konform
- Alle redundanzen beseitigt (fürs binäre streaming).
- DFM-konvertierung -> asBinary = false
- automatische erkennung ob binär oder text beim laden.

Delphi-Quellcode:
unit CollectionExt;
//
// written by Jens Schumann and MaxHub (maximov)
//

interface

Uses SysUtils, Classes;

Type

  TJsCollection = class(TCollection)
  private
    FCollectionname : String;
    FIntValue : Integer;
    function GetFormatSignature: String;
    procedure SetCollectionname(const Value: String);
    procedure SetIntValue(const Value: Integer);
  public
    procedure SaveToFile(const Filename : TFilename);
    procedure SaveToStream(Stream : TStream);
    procedure LoadFromFile(const Filename : TFilename);
    procedure LoadFromStream(Stream : TStream);

  published
    property Collectionname : String read FCollectionname write SetCollectionname;
    property IntValue : Integer read FIntValue write SetIntValue;
  end;

  TmxJsCollection = class(TJsCollection)
    procedure LoadFromStreamEx(aStream: TStream);
    procedure SaveToStreamEx(aStream: TStream; asBinary: Boolean);
    procedure LoadFromFileEx(const Filename: TFilename);
    procedure SaveToFileEx(const Filename: TFilename; asBinary: Boolean);
  end;
      

  TWriterExt = class(TWriter)
  public
    
    procedure WriteCollection(Value: TCollection);
    procedure WriteCollectionProperties(Value : TCollection);
  end;

  TReaderExt = class(TReader)
  public
    procedure ReadCollection(Value: TCollection);
    procedure ReadCollectionProperties(Value: TCollection);
  end;


implementation

uses TypInfo;

const
  iFilerBufferSize = 4096;
  FilerSignatureEx: array[1..4] of Char = 'TPF0';

{ TJsCollection }

function TJsCollection.GetFormatSignature: String;
begin
  Result := ItemClass.ClassName;
end;

procedure TJsCollection.LoadFromFile(const Filename: TFilename);
var
  FileStream : TFileStream;
begin
  Clear;
  FileStream:=TFileStream.Create(Filename,fmOpenRead);
  Try
    LoadFromStream(FileStream);
  Finally
    FileStream.Free;
    end;
end;

procedure TJsCollection.LoadFromStream(Stream: TStream);
var
  Reader : TReaderExt;
begin
  Reader:=TReaderExt.Create(Stream,iFilerBufferSize);
  Try
    Reader.ReadCollection(Self);
  Finally
    Reader.Free;
    end;
end;

procedure TJsCollection.SaveToFile(const Filename: TFilename);
var
  FileStream : TFileStream;
begin
  FileStream:=TFileStream.Create(Filename,fmCreate);
  Try
    SaveToStream(FileStream);
  Finally
    FileStream.Free;
    end;
end;

procedure TJsCollection.SaveToStream(Stream: TStream);
var
  Writer : TWriterExt;
begin
  Writer:=TWriterExt.Create(Stream,iFilerBufferSize);
  Try
    Writer.WriteCollection(Self);
  Finally
    Writer.Free;
    end;
end;

procedure TJsCollection.SetCollectionname(const Value: String);
begin
  FCollectionname := Value;
end;

procedure TJsCollection.SetIntValue(const Value: Integer);
begin
  FIntValue := Value;
end;

{ TWriterExt }

procedure TWriterExt.WriteCollection(Value: TCollection);
begin
  WriteCollectionProperties(Value);
  WriteStr('Items'); // wichtig für DFM-konformität
  inherited WriteCollection(Value);
end;

procedure TWriterExt.WriteCollectionProperties(Value: TCollection);
begin
  WriteProperties(Value);
end;

{ TReaderExt }

procedure TReaderExt.ReadCollection(Value: TCollection);
begin
  ReadCollectionProperties(Value);
  ReadStr; // wichtig für DFM-konformität
  ReadValue;
  inherited ReadCollection(Value);
end;

procedure TReaderExt.ReadCollectionProperties(Value: TCollection);
var
  PropList : TPropList;
  PropCount : Integer;
  iCnt : Integer;
begin
  PropCount:=GetPropList(Value.ClassInfo,tkProperties,@PropList);
  For iCnt:=0 to PropCount-1 do
    ReadProperty(Value);
end;


{ TmxJsCollection }

procedure TmxJsCollection.LoadFromStreamEx(aStream: TStream);
var Reader : TReaderExt;
    StreamInner : TStream;
    format : TStreamOriginalFormat;
    oldPos : Int64;
    SigBuffer : array[1..4] of Char;
    isBinary : boolean;
begin
  // automatisch feststellen ob binär oder text
  oldPos := aStream.Position;
  aStream.ReadBuffer(SigBuffer[1],sizeOf(SigBuffer));
  isBinary := SigBuffer = FilerSignatureEx;
  aStream.Position := oldPos;
  
  if isBinary
  then StreamInner := aStream
  else StreamInner := TMemoryStream.Create;
              
  try
    // DFM-text parsen
    if not isBinary then
    begin
      format := sofBinary;
      ObjectTextToBinary(aStream,StreamInner,format);
      StreamInner.Position := 0;
    end;
                          
    Reader := TReaderExt.Create(StreamInner,iFilerBufferSize);
    try
      Reader.ReadSignature;
      Reader.ReadStr; // ClassName
      Reader.ReadStr; // Collectionname

      Reader.ReadCollection(self);

      Reader.ReadListEnd;
      Reader.ReadListEnd;
    finally
      Reader.Free;
    end;
  finally
    if not isBinary then StreamInner.Free;
  end;
end;

procedure TmxJsCollection.SaveToStreamEx(aStream: TStream; asBinary: Boolean);
var Writer : TWriterExt;
    StreamInner : TStream;
    format : TStreamOriginalFormat;
begin
  if asBinary
  then StreamInner := aStream
  else StreamInner := TMemoryStream.Create;
                
  try
    Writer := TWriterExt.Create(StreamInner,iFilerBufferSize);
    try
      Writer.WriteSignature;
      Writer.WriteStr(ClassName);
      Writer.WriteStr(Collectionname);
               
      Writer.WriteCollection(Self);

      Writer.WriteListEnd;
      Writer.WriteListEnd;
    finally
      Writer.Free;
    end;
    // DFM-text konversion
    if not asBinary then
    begin
      StreamInner.Position := 0;
      format := sofText;
      ObjectBinaryToText(StreamInner,aStream,format);
    end;
  finally
    if not asBinary then StreamInner.Free;
  end;
end;


procedure TmxJsCollection.LoadFromFileEx(const Filename: TFilename);
var
  FileStream : TFileStream;
begin
  Clear;
  FileStream:=TFileStream.Create(Filename,fmOpenRead);
  Try
    LoadFromStreamEx(FileStream);
  Finally
    FileStream.Free;
  end;
end;


procedure TmxJsCollection.SaveToFileEx(const Filename: TFilename; asBinary: Boolean);
var
  FileStream : TFileStream;
begin
  FileStream:=TFileStream.Create(Filename,fmCreate);
  Try
    SaveToStreamEx(FileStream, asBinary);
  Finally
    FileStream.Free;
  end;
end;

end.
Wenn willst kannst du das jetzt zu einer klasse zusammenfügen...auf jeden fall ein schönes teil, was der ein oder andere sicher gut gebrauchen kann.

Das einzige das man noch hinzufügen könnte wäre ein format-signatur-abfrage, um besser auf verschiedene datenformate zu reagieren.

auf die gute team-arbeit.


PS: Mein vorschlag für den unit namen wäre: 'dpCollection'
mâxîmôv.

{KDT}
  Mit Zitat antworten Zitat