Here's a very simple example - it generates a relative record file, then reads it back.
type Record_t
Caption as string ` Limit to 30 chars (+1 for size)
Colour as dword ` 4 bytes
Size as integer ` 4 bytes
endtype
global Record as Record_t
Filename as string = "RecordEditor.dat"
if open datafile to update( 1, Filename ) = 0
if open datafile to write( 1, Filename ) = 0
report error "Unable to open datafile " + Filename
endif
endif
datafile string type 1, 4
Record.Caption = "This is a test string"
Record.Colour = rgb(255, 255, 255)
Record.Size = 30
WriteRecord(0)
Record.Caption = "Followed by another"
Record.Colour = rgb(255, 0, 0)
Record.Size = 15
WriteRecord(1)
` Not writing record 2, so it doesn't exist and will leave a blank in the file
Record.Caption = "And yet another, but limited to 30 characters"
Record.Colour = rgb(0, 255, 255)
Record.Size = 20
WriteRecord(3)
Record.Caption = "Oops, that last one was ..."
Record.Colour = rgb(0, 255, 0)
Record.Size = 15
WriteRecord(7)
Record.Caption = "...truncated"
WriteRecord(8)
Top = LastRecord()
for i = 0 to Top
if ReadRecord(i)
set text size Record.Size
ink Record.Colour, 0
print Record.Caption
else
set text size 10
ink rgb(255, 255, 255), 0
print "<empty record>"
endif
next
close datafile 1
wait key
end
function WriteRecord(Id as integer)
set datafile position 1, Id * 38 ` The 38 comes from ...
write datafile boolean 1, 1 ` 1 byte, if set then the record is availabe, otherwise, not.
write datafile string 1, left$(Record.Caption, 30) ` 31 bytes (30 chars, plus 1 byte for size)
write datafile dword 1, Record.Colour ` 4 bytes
write datafile dword 1, Record.Size ` 4 bytes
endfunction
function ReadRecord(Id as integer)
set datafile position 1, Id * 38
` If the record is marked as deleted, return a fail
if datafile boolean(1) = 0 then exitfunction 0
Record.Caption = datafile string$(1)
Record.Colour = datafile dword(1)
Record.Size = datafile dword(1)
endfunction 1
function DeleteRecord(Id as integer)
set datafile position 1, Id * 38
write datafile boolean 1, 0
endfunction
function LastRecord()
local Count as integer
Count = datafile size(1) / 38
endfunction Count
One thing to note is that I have NOT padded the string to 30 characters, because in this case it's not necessary - it's only necessary when you wish to read a particular field from within a record, without reading the whole record.