PDA

View Full Version : Record BlockWrite problems



Memphis
23-01-2009, 04:37 PM
hi there, i've been having problems with writing some variant sized records. i have no idea what is going wrong, anyone can confirm my code would be really appreciated.

the type: (there is a reason why it is an array of byte, because i tried many other ways to get it to work and still no luck)


TRule = record
data : array of byte;
end;
PRule = ^TRule;


the writing of the data, first i created a test record.



New(nr);
SetLength(nr.data, 8 + 6);
Integer((@nr.data[0])^) := 1;
Integer((@nr.data[4])^) := 1;
PAnsiChar((@nr.data[8])^) := 'Admin'+#0;
rules.Add(nr); // (cant be bothered to make as a linked list until i get it working)


now writing it



var
datalen: DWord;
i: Integer;
nr: PRule;
f: file of byte;
begin
AssignFile(f, './rules.rul');
ReWrite(f);
for i := rules.Count-1 downto 0 do begin
nr := rules[i];

datalen := Length(nr.data);
BlockWrite(f, datalen, 4);
BlockWrite(f, nr.data, datalen);
end;
CloseFile(f);


and finally reading it



AssignFile(f, './rules.rul');
Reset(f);
while not eof(f) do begin
BlockRead(f, datalen, 4);
GetMem(nr, datalen);
BlockRead(f, nr, datalen);
rules.Add(nr);
end;
CloseFile(f);


thanks in advance for any help.

;MM;

JSoftware
23-01-2009, 05:08 PM
Use
ReWrite(f,1);
and
Reset(f,1);

Memphis
23-01-2009, 05:16 PM
hi thanks for reply, ok you can't use rewrite(f, 1) or reset, when you have a file of

the file of byte referes to 1 byte, however for confirmation sake, i removed of byte, and changed both to ", 1".

however, it does exact same thing, doesnt output and load the data back correctly.

btw it always outputs the right amount of bytes.

;MM;

JSoftware
23-01-2009, 05:41 PM
Try this

var
datalen: DWord;
i: Integer;
nr: PRule;
f: file of byte;
begin
AssignFile(f, './rules.rul');
ReWrite(f);
for i := rules.Count-1 downto 0 do begin
nr := rules[i];

datalen := Length(nr.data);
BlockWrite(f, datalen, 4);
BlockWrite(f, nr.data[0], datalen);
end;
CloseFile(f);



AssignFile(f, './rules.rul');
Reset(f);
while not eof(f) do begin
GetMem(nr, SizeOf(TRule));
BlockRead(f, datalen, 4);
SetLength(nr.data, datalen);
BlockRead(f, nr.data[0], datalen);
rules.Add(nr);
end;
CloseFile(f);

Memphis
23-01-2009, 05:51 PM
hi, the GetMem with SizeOf will not work as the data array is dynamic, i have tried with the nr.data[0] but that does not work neither unfortuanatly.

JSoftware
23-01-2009, 06:26 PM
It should work. nr is a pointer to a record which has a field which is a dynamic array. The record should be 4 bytes because the dynamic array field is a pointer to a compiler defined dynamic array structure. That's why you need the .data[0] to "dereference" the dynamic record.

.data will give you a pointer to the structure of the dynamic array which contains some metainformation

Memphis
23-01-2009, 06:33 PM
It should work. nr is a pointer to a record which has a field which is a dynamic array. The record should be 4 bytes because the dynamic array field is a pointer to a compiler defined dynamic array structure. That's why you need the .data[0] to "dereference" the dynamic record.

.data will give you a pointer to the structure of the dynamic array which contains some metainformation

well anyways i have tried this way and it still causes error on reloading the data, opening the file, again the file length is correct, but the data does not look correct that is written.

edit: i found one of the problems, now just gonna test it all, if it works i will post a working version anyways


New(nr);
SetLength(nr.data, 8 + 6);
Integer((@nr.data[0])^) := 1;
Integer((@nr.data[4])^) := 1;
strLCopy(pChar(@nr.data[8]), 'Admin'+#0, 6);
rules.Add(nr);


this was the problem, the data being written was incorrect to start with lol

edit: ok thanks for all your help, seems that was the problem.

noeska
23-01-2009, 09:50 PM
It is good to have an hex editor available to inspect the file being written. That helped me a great deal while developing nvfs. Once you are sure the file is written correctly try to do a read test.