Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Untypisierte Daten wieder auslesen (https://www.delphipraxis.net/14891-untypisierte-daten-wieder-auslesen.html)

Wusel 17. Jan 2004 14:50


Untypisierte Daten wieder auslesen
 
Hi Leute
Ich hab da ein kleines Problem beim auslesen untypisierte Daten aus einer TList.
hier erstmal der Code:
Delphi-Quellcode:
type
  THanoiList = class(TList)
  ...
  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);
    end
end;

procedure THanoiList.GetMove(aiIndex : Int64; var iFrom, iTo : Integer);
Var
  pCur : PByte;
  bDS : Byte;
begin
  if Count = 1 then
    begin
      pCur := Last;
      Inc(pCur, aiIndex shr 1);
      if (aiIndex and 1) = 0 then
          bDS := pCur^
      else
        bDS := pCur^ shr 4;
    end;
  iTo := bDS shr 2;
  iFrom := bDS and (iTo shl 2);
end;
Bei GetMove hab ich irgendeinen Fehler gemacht, den ich leider nicht finde. Nach meiner Logik funktioniert es eigentlich :-D aber nicht nach Delphis Logik :(

Kann mir vielleicht einer von euch sagen wo der Fehler steckt?

Schonmal vielen Dank an euch

SirThornberry 17. Jan 2004 15:59

Re: Untypisierte Daten wieder auslesen
 
Ähm, irgendwie versteh ich gar nicht was du hier machst. Was sollen die funktionen machen? Ich benutz bei TList immer nur Add und solche grundlegenen funktionen um die pointer zu speichern

Wusel 17. Jan 2004 17:41

Re: Untypisierte Daten wieder auslesen
 
Die Items der TList dienen nur als Cluster, in die ich die Daten speichere. Aber die TList spielt bei meinem jetzigen Problem eigentlich garkeine Rolle, weil ich erstmal nur davon ausgehe dass die Daten nur im 1. Element der Liste stehen.
Hilfe zur Verständniss:
aiIndex gibt dann an, die wievielte Information (bei meinem Beispiel die wievielte Bewegung) es ausgeben soll. Diese Information (2 Integer Werte) soll es in bDS speichern und dann voneinander trennen und getrennt ausgeben.
Nur leider funktioniert das bei mir mit dem richtigen und getrennten ausgeben noch nicht richtig.

Wusel 18. Jan 2004 19:56

Re: Untypisierte Daten wieder auslesen
 
Zitat:

Zitat von Wusel
Kann mir vielleicht einer von euch sagen wo der Fehler steckt?

Keiner? :cry:

neolithos 23. Jan 2004 17:36

Re: Untypisierte Daten wieder auslesen
 
Zitat:

Zitat von SirThornberry
Ähm, irgendwie versteh ich gar nicht was du hier machst. Was sollen die funktionen machen? Ich benutz bei TList immer nur Add und solche grundlegenen funktionen um die pointer zu speichern

Er sollte 4 Bit Datensätze im Speicher ablegen!

Übrigens, man Klassen ableiten und für was neues Modifizieren!
Vielleicht ist Wusel so liebt und Posted noch mal die Lösung!

Wusel 25. Jan 2004 08:47

Re: Untypisierte Daten wieder auslesen
 
Klar :-D
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 :wink:

CalganX 25. Jan 2004 09:43

Re: Untypisierte Daten wieder auslesen
 
Hi,
könntest du bitte solche langen Sourcecodes als Anhang anhängen!? Danke.

Chris

Wusel 26. Jan 2004 16:15

Re: Untypisierte Daten wieder auslesen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Kann den Beitrag oben leider nichtmehr editieren. Trotzdem hier nochmal als Anhang.
Das nächste mal mache ich es gleich richtig :oops:


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:24 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz