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

Save & Load Sets?

I am trying to save & load a large amount of set data, to and from file using streams.

I have made an example of what I am trying to do.

It seams the writing to file works fine, but it crashes on the loading from file portion

Here is basically what I have:

Type

 TAnimal = (Dog, Cat, Horse, Cow, Squirrel);
 TAnimals = set of TAnimal;


var
 Animals: TAnimals;
 Animal: TAnimal;


//returns the number of items in Set
function GetAnimalCount(AAnimals: TAnimals): Integer;
var
 AAnimal: TAnimal;
begin
  result:= 0;
  for AAnimal:=  Low(AAnimal) to High(AANimal) do
   if AAnimal in AAnimals then  Result:= Result + 1;
end;



Here is where I save to file

 MemStr:= TMemoryStream.Create;

 WriteStreamInt(MemStr, GetAnimalCount(Animals));
 
 for Animal := Low(Animal) to High(Animal) do
  if Animal in Animals then
   WriteStreamStr(MemStr, GetEnumName(TypeInfo(TAnimal), Ord(Animal)));

  MemStr.SaveToFile(fFileName);
  MemStr.Free


here is where I load from file


 MemStr:= TMemoryStream.Create;
 MemStr.LoadFromFile(fFileName);
   
Count:= ReadStreamInt(MemStr);
for I:= 0 to Count - 1 do
 begin
  AnimalStr:= ReadStreamStr(MemStr);
  Include(Animals, TAnimal(GetEnumValue(TypeInfo(TAnimal),AnimalStr)));
 end;
MemStr.Free;

Using a showmessage in teh load from file, i can show the first item read in, but then it crashes.

Shane



0
shaneholmes
Asked:
shaneholmes
  • 4
  • 2
1 Solution
 
shaneholmesAuthor Commented:
Sorry, typo mistake


for Animal := Low(TAnimal) to High(TAnimal) do

Shane
0
 
shaneholmesAuthor Commented:
This is definitly where it crashes  

Include(Animals, TAnimal(GetEnumValue(TypeInfo(TAnimal),AnimalStr)));
 
I have also tried:

Animals:= Animals + TAnimal(GetEnumValue(TypeInfo(TAnimal),AnimalStr));

and

Animals:= Animals + [TAnimal(GetEnumValue(TypeInfo(TAnimal),AnimalStr))];

Shane
0
 
Russell LibbySoftware Engineer, Advisory Commented:

Not sure if this helps, but the following compiles and executes correctly on D5.

// Read/Write functions taken from TReader and TWriter respectively

function GetAnimalCount(AAnimals: TAnimals): Integer;
var  AAnimal:    TAnimal;
begin
  result:=0;
  for AAnimal:=Low(AAnimal) to High(AAnimal) do
     if AAnimal in AAnimals then  Inc(result);
end;

procedure WriteStreamInt(Stream: TStream; Value: Integer);
begin
  Stream.Write(Value, SizeOf(Value));
end;

function ReadStreamInt(Stream: TStream): Integer;
begin
  Stream.Read(result, SizeOf(Integer));
end;

function ReadStreamStr(Stream: TStream): String;
var  dwLength:   Integer;
begin
  Stream.Read(dwLength, SizeOf(Integer));
  SetLength(result, dwLength);
  Stream.Read(Pointer(result)^, dwLength);
end;

procedure WriteStreamStr(Stream: TStream; Value: String);
var  dwLength:   Integer;
begin
  dwLength:=Length(Value);
  Stream.Write(dwLength, SizeOf(Integer));
  Stream.Write(Pointer(Value)^, dwLength);
end;

procedure SetSaveToFile(FileName: String);
var  MemStream:  TMemoryStream;
     AAnimal:    TAnimal;
begin
  MemStream:=TMemoryStream.Create;
  WriteStreamInt(MemStream, GetAnimalCount(Animals));
  for AAnimal:=Low(Animal) to High(Animal) do
     if AAnimal in Animals then
        WriteStreamStr(MemStream, GetEnumName(TypeInfo(TAnimal), Ord(AAnimal)));
  MemStream.SaveToFile(FileName);
  MemStream.Free
end;

procedure SetLoadFromFile(FileName: String);
var  MemStream:  TMemoryStream;
     dwIndex:    Integer;
     dwCount:    Integer;
begin
  MemStream:=TMemoryStream.Create;
  MemStream.LoadFromFile(FileName);
  Animals:=[];
  dwCount:=ReadStreamInt(MemStream);
  for dwIndex:=0 to Pred(dwCount) do
     Include(Animals, TAnimal(GetEnumValue(TypeInfo(TAnimal), ReadStreamStr(MemStream))));
  MemStream.Free
end;

----

begin

  Animals:=[Dog, Horse];
  SetSaveToFile('c:\test.txt');
  Animals:=[];
  SetLoadFromFile('c:\test.txt');
  if Animals = [Dog, Horse] then
     ShowMessage('Correct');

end;


Regards,
Russell

0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
shaneholmesAuthor Commented:
Russel, im in the middle of something right now, but i will get back to this in a bit and test it.

If it compiles and runs on your machine, im sure it will on mine.

Thanks!

Shane

0
 
shaneholmesAuthor Commented:
Hey Russell, after reviewing your code, I found two problems, fixed them and boom - works like a charm.

Sometimes youc an stare at code for ever and never see it. I knew smeone else would be able to right away!

Thanks for the boost!

Shane
0
 
Russell LibbySoftware Engineer, Advisory Commented:
Anytime ;-)

And thank you,
Russell

0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

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