Einzelnen Beitrag anzeigen

Benutzerbild von Wusel
Wusel

Registriert seit: 27. Sep 2003
Ort: Riesa
54 Beiträge
 
Delphi 6 Personal
 
#6

Re: Untypisierte Daten wieder auslesen

  Alt 25. Jan 2004, 09:47
Klar
Hier mal die ganze Unit und das untere ist das, was ich eigentlich wissen wollte:

Delphi-Quellcode:
unit HanoiList;

interface

uses
  Classes, SysUtils;

const
  cSg = 'HANOI1';

type
  EHanoiList = class(Exception);

  THanoiListHeader = packed record
    cSg : array [0..5] of char;
    dwDiscs,
    dwClusterFill,
    dwClusterSize,
    dwClusterCount : Cardinal;
  end;

  THanoiList = class(TList)
  private
    dwClusterSize, // Größe eines Blockes in Byte
    dwDiscs, // Anzahl der bearbeiteten Scheiben
    dwClusterFill : Cardinal; // Zeigt auf neuen DS in letzten Block
      // (log. Einheiten)

    procedure AddCluster;
      // fügt neuen Datenblock in die Liste ein

  // -- properties --
    function GetMoveCount : Int64;
  protected
    procedure Notify(Ptr: Pointer; Action : TListNotification); override;
  public
    constructor Create(adwClusterSize, adwDiscs : Cardinal);
      // adwClusterSize: siehe dwClusterSize
    constructor LoadFromStream(astm : TStream);
    constructor LoadFromFile(const asFileName : String);

    procedure SaveToStream(astm : TStream);
    procedure SaveToFile(const asFileName : String);

    procedure AddMove(aiFrom, aiTo : Integer);
      // Fügt neuen DS an das Ende an
      // aiFrom, aiTo: Stab-bewegung (0..2 nur sinnvoll)
    procedure GetMove(aiIndex : Int64; var iFrom, iTo : Integer);
      // Holt einen DS
      // aiIndex: log. Position

    property MoveCount : Int64 read GetMoveCount;
  end;

implementation

constructor THanoiList.Create(adwClusterSize, adwDiscs : Cardinal);
begin
  inherited Create;
  dwClusterSize := adwClusterSize;
  dwDiscs := adwDiscs;
  AddCluster;
end;

constructor THanoiList.LoadFromStream(astm : TStream);
Var fHead : THanoiListHeader;
    i : Integer;
    pTmp : Pointer;
begin
  inherited Create;

  astm.Read(fHead, SizeOf(fHead));
  if not CompareMem(@fHead.cSg, PChar(cSg), 6) then
     raise EHanoiList.Create('LoadFromStream - Datei ist ungültig (Signatur)!');

  dwClusterSize := fHead.dwClusterSize;
  dwDiscs := fHead.dwDiscs;
  dwClusterFill := fHead.dwClusterFill;

  for i := 0 to fHead.dwClusterCount - 1 do
      begin
        GetMem(pTmp, dwClusterSize);
        astm.Read(pTmp^, dwClusterSize);
        Add(pTmp);
      end;
end;

constructor THanoiList.LoadFromFile(const asFileName : String);
Var stm : TFileStream;
begin
  stm := TFileStream.Create(asFileName, fmOpenRead);
  try
    LoadFromStream(stm);
  finally
    stm.Free;
  end;
end;

procedure THanoiList.AddCluster;
Var pTemp : Pointer;
begin
  dwClusterFill := 0;
  GetMem(pTemp, dwClusterSize);
  Add(pTemp);
end;

procedure THanoiList.AddMove(aiFrom, aiTo : Integer);
Var pCur : PByte;
    bDS : Byte;
begin
  if dwClusterFill >= dwClusterSize shl 1 then
    AddCluster;
  if (aiFrom in [0..2]) and (aiTo in [0..2]) then
     begin
       bDS := aiFrom or (aiTo shl 2);
       pCur := Last;
       Inc(pCur, dwClusterFill shr 1);
       if (dwClusterFill and 1) = 0 then
          pCur^ := bDS
       else
          pCur^ := pCur^ or (bDS shl 4);
       Inc(dwClusterFill);
     end
   else
     raise EHanoiList.Create('AddMove - aiFrom oder aiTo außerhalb des zulässigen Bereichs!!!');
end;

procedure THanoiList.GetMove(aiIndex : Int64; var iFrom, iTo : Integer);
Var pCur : PByte;
    bDS : Byte;
    iCluster,
    iCur : Integer;
begin
  // In welchem Block steht der Datensatz
  iCluster := (aiIndex shr 1) div dwClusterSize;

  if iCluster >= Count then
     raise EHanoiList.Create('GetMove - Index außerhalb des zulässigen Bereiches!');

  pCur := Items[iCluster];

  iCur := aiIndex mod (dwClusterSize shl 1);
  Inc(pCur, iCur shr 1);

  if (iCur and 1) = 0 then
     bDS := pCur^ and $F
  else
     bDS := pCur^ shr 4;

  iTo := bDS shr 2;
  iFrom := bDS and 3;
end;

procedure THanoiList.Notify(Ptr: Pointer; Action : TListNotification);
begin
  if Action = lnDeleted then
    FreeMem(Ptr);
end;

function THanoiList.GetMoveCount : Int64;
begin
  Result := (dwClusterSize shl 1) * (Count - 1) + dwClusterFill;
end;

procedure THanoiList.SaveToStream(astm : TStream);
Var fHead : THanoiListHeader;
    i : Integer;
begin
  StrLCopy(fHead.cSg, PChar(cSg), 6);

  fHead.dwClusterCount := Count;
  fHead.dwDiscs := dwDiscs;
  fHead.dwClusterSize := dwClusterSize;
  fHead.dwClusterFill := dwClusterFill;

  astm.Write(fHead, SizeOf(fHead));

  for i := 0 to Count - 1 do
      astm.Write(Items[i]^, dwClusterSize);
end;

procedure THanoiList.SaveToFile(const asFileName : String);
Var stm : TFileStream;
begin
  stm := TFileStream.Create(asFileName, fmCreate);
  try
    SaveToStream(stm);
  finally
    stm.Free;
  end;
end;

end.
Delphi-Quellcode:
procedure THanoiList.GetMove(aiIndex : Int64; var iFrom, iTo : Integer);
Var pCur : PByte;
    bDS : Byte;
    iCluster,
    iCur : Integer;
begin
  // In welchem Block steht der Datensatz
  iCluster := (aiIndex shr 1) div dwClusterSize;

  if iCluster >= Count then
     raise EHanoiList.Create('GetMove - Index außerhalb des zulässigen Bereiches!');

  pCur := Items[iCluster];

  iCur := aiIndex mod (dwClusterSize shl 1);
  Inc(pCur, iCur shr 1);

  if (iCur and 1) = 0 then
     bDS := pCur^ and $F
  else
     bDS := pCur^ shr 4;

  iTo := bDS shr 2;
  iFrom := bDS and 3;
end;
Vielleicht erkennt ja jemand worums geht
  Mit Zitat antworten Zitat