• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 166
  • Last Modified:

Need to write this data structure to a file..

OK, I need help desperately !!!

I have a (VERY VERY) complex data structure.

I need to be able to write this data stucture to a file, and I also need to read this structure from a file.

The data structure ("MACRO") is as follows.

(****************** BEGIN ********)
Type
  Rec = Record
     Name1, Name2: String;
     X,Y:Integer;
  end;

  LineRec = Record
     statement: Char;
     Action:Integer;
     ObjectCount:Integer;//Number of elements in the variable ObjectInfo array below.
     ObjectInfo : Array of Rec;
  End;

  Macro=Record   //Structure that needs to be written to a file.
    Name: String;
    LinesCount:Integer; //Number of elements in the variable Line array below.
    Line: array of LineRec;
  End;

(****************** END ********)

Ok, I need to have a file of "Macro" objects, so that I can write many "Macro" objects to the file, and then read the "Macro" objects(from the file) into an array of Macro Objects

Help please....

Im using Delphi 5 - if that helps in any way...

Thanx
0
CyberKnight
Asked:
CyberKnight
1 Solution
 
cubudCommented:
You are making a nightmare for yourself.

You should really use descendents of TPersistent (objects) and use collections for the arrays.

That way you can do

Writer := TWriter.Create(MyFileStream, 4096);
try
  Writer.WriteComponent(MyBaseComponent);
finally
  Writer.Free;
end;

You can probably guess TReader :)

Look at my 2 articles on component writing.
http://www.howtodothings.com/showarticle.asp?article=310
http://www.howtodothings.com/showarticle.asp?article=320

Part 1 is about the basics, part 2 is about Collections etc.

Pete
====
http://www.HowToDoThings.com (Programming articles)
http://www.StuckIndoors.com/delphi (Open source)
0
 
bugrogerCommented:
Hi,

i hope you can need it!

(****************** BEGIN ********)
Type
 TRec = Record
         Name1, Name2: String;
         X,Y:Integer;
        end;

 TLineRec = Record
             statement  : Char;
             Action     :Integer;
             ObjectCount:Integer; //Number of elements in the variable ObjectInfo array below.
             ObjectInfo : Array of TRec;
            End;

 TMacro = Record               //Structure that needs to be written to a file.
           Name      : String;
           LinesCount:Integer; //Number of elements in the variable Line array below.
           Line      : array of TLineRec;
          End;

 TMacroMain = array of TMacro;


Function Write_MacroStruct(MacroFileName : String; VAR M : TMacroMain) : Boolean;
VAR
 MacroFile : Cardinal; //File handle
 Written   : Cardinal; //for WriteFile()
 Main      : Integer;
 z1, z2    : Integer;
 b         : byte;

 Procedure WriteString(s : string);
 Begin
  WriteFile(MacroFile, Pchar(s)[0], Length(s) +1, Written, NIL);
 End;
 Procedure WriteInteger(i : integer);
 Begin
  WriteFile(MacroFile, i, 4, Written, NIL);
 End;

Begin
 Result := TRUE;

 //Create Macro File
 MacroFile := CreateFile(PChar(MacroFileName), GENERIC_WRITE, FILE_SHARE_WRITE,
                         NIL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
 IF MacroFile = INVALID_HANDLE_VALUE then
 Begin
  Result := FALSE;
  Exit;
 End;

 TRY
  b := 0;
  For Main := 0 to High(M) do
  Begin
   With M[Main] do
   Begin
    //TMacro
    WriteString(Name);
    WriteInteger(LinesCount);
    For z1 := 0 to LinesCount -1 do
    Begin
     //TLineRec
     WriteFile(MacroFile, Line[z1].statement, 1, Written, NIL);
     WriteInteger(Line[z1].Action);
     WriteInteger(Line[z1].ObjectCount);
     For z2 := 0 to Line[z1].ObjectCount-1 do
     Begin
      //TRec
      WriteString(Line[z1].ObjectInfo[z2].Name1);
      WriteString(Line[z1].ObjectInfo[z2].Name2);
      WriteInteger(Line[z1].ObjectInfo[z2].X);
      WriteInteger(Line[z1].ObjectInfo[z2].Y);
     End;
    End;
   End;
   IF Main = High(M) then b := 1;
   WriteFile(MacroFile, b, 1, Written, NIL);
  End;

 EXCEPT
  Result := FALSE;
 END;

 //Close Macro File
 CloseHandle(MacroFile);
End;


Function Read_MacroStruct(MacroFileName : String; VAR M : TMacroMain) : Boolean;
VAR
 MacroFile : Cardinal; //File handle
 Read      : Cardinal; //for ReadFile()
 Main      : Integer;
 z1, z2    : Integer;
 b         : byte;


 Function ReadString : String;
 VAR
  CharByte : Char;
 Begin
  Result := '';
  Repeat
   ReadFile(MacroFile, CharByte, 1, Read, NIL);
   IF (CharByte <> #0)and(Read <> 0) then Result := Result + CharByte
                                     else Exit;
  Until False;
 End;

 Function ReadInteger : Integer;
 Begin
  ReadFile(MacroFile, Result, 4, Read, NIL);
 End;

Begin
 Result := TRUE;

 //Open Macro File
 MacroFile := CreateFile(PChar(MacroFileName), GENERIC_READ, FILE_SHARE_READ,
                         NIL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
 IF MacroFile = INVALID_HANDLE_VALUE then
 Begin
  Result := FALSE;
  Exit;
 End;

 TRY
  Main := 0;
  Repeat
   SetLength(M, Main +1);
   With M[Main] do
   Begin
    //TMacro
    Name       := ReadString;
    LinesCount := ReadInteger;
    SetLength(Line, LinesCount);
    For z1 := 0 to LinesCount -1 do
    Begin
     //TLineRec
     ReadFile(MacroFile, Line[z1].statement, 1, Read, NIL);
     Line[z1].Action      := ReadInteger;
     Line[z1].ObjectCount := READInteger;
     SetLength(Line[z1].ObjectInfo, Line[z1].ObjectCount);
     For z2 := 0 to Line[z1].ObjectCount-1 do
     Begin
      //TRec

      Line[z1].ObjectInfo[z2].Name1 := ReadString;
      Line[z1].ObjectInfo[z2].Name2 := ReadString;
      Line[z1].ObjectInfo[z2].X     := ReadInteger;
      Line[z1].ObjectInfo[z2].Y     := ReadInteger;
     End;
    End;
   End;
   ReadFile(MacroFile, b, 1, Read, NIL);
   IF b <> 1 then Inc(Main);
  Until (b = 1);
 EXCEPT
  Result := FALSE;
 END;

 //Close Macro File
 CloseHandle(MacroFile);
End;


GL
 Bug
0
 
edeyCommented:
For something like this I would sugest XML - it is very good for storing heriecrical data, there a re existing parsers, and it's easy to troble shoot.  The only real disadvantage is that it's not always a very compact way of representing your data.

GL
Mike
0
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 
rondiCommented:
Nice code bugroger - does the trick.
However, it's not very extensible: one slight change to the
record structure and you've got a problem.

I'd go with cubud's suggestion. I use Delphi's in-built component streaming quite a lot. It's easy to add properties and stuff when you descend from TPersistent.
It's also more generic & flexible - if you need to add
or remove functionality later it'll be a piece of cake.

XML would do fine. But it's still not as elegant.
I use XML storage with VB only coz feeble VB doesn't support object streaming. Ideally, each object oughta know
what it needs to store and be responsible for it.
0
 
CyberKnightAuthor Commented:
Hi...
Bugroger code works well....

but like rondi said - Its not very flexible....if the structure needs changing - then the code has to be changed accordingly.

cubud approach *seems* to be more effecient.

But even though Ive read his articles, Im not able to write the code for the structure... Ive never used Tcollection, and never created my own descendents of TPersistent. Could someone please help with some code to show me how its done (in regards to my structure)..?

Thank you all...
0
 
rondiCommented:
I'll try whip up something tonight...
0
 
rondiCommented:
try
  WhipUpSomethingTonight;
except
  ApologizeTomorrow;
end;
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now