Content of this webpage:
What is the "-General Data Format-" ?
|
[top]
|
The -General Data Format- (GDF) is a way to create data files for
applications that are version independent (and even platform
independent ;-) which means fully up- and downwards compatible.
If you are furthermore looking for a way to save your application's
data to a file and protect it with a checksum against corruption (and
misuse) this article might be interesting for you.
Basic functionality
|
[top]
|
The first thing you have to do is to create two procedures
(functions) for your application.
The first procedure is to export (any) data to a file. The incoming
parameters are name of the file (or handle), type of data, an identifier
and the data itself (all this is explained more detailed in the
Specification chapter).
The return parameter is a (boolean) value whether the export was
successful or not (you can alternatively return some kind of
error-code).
The second procedure is to import and validate (any) data from a file.
The incoming parameters is the name (or handle) of the file. The return
parameters are the data-type that has been imported, the identifier,
the data itself as well as an information whether the data has been
validated and another information if the import was successful
(error-code).
All data is im- and exported as "String". How and where to handle the
conversion is up to the developer. After importing a data-set, the
"data-type" specifies how to treat (convert) the imported data-string.
The export procedure has as special feature to calculate a checksum
over the data. Then it exports (writes) all data (including the checksum
and a terminator-value of the data-set) to the data-file.
The import procedure reads such data-sets and validates the checksum.
Reading the string of the data field can be done in some kind of do...
until loop, whereas a detection of the terminator is defined as
"until".
Please note: Since the terminator is the last byte of the data-set, the
last character of the imported data-string is the checksum and needs to
be extracted separately (cut off from the data-string) by the
import-procedure. Then it can be used to validate the rest of the
string.
Both procedures read (write) exactly ONE data entry from (to) the
data-file.
Having created these two procedures, your main application has to take
care of creating (opening) a file, reading (writing) (multiple)
data-sets using the im(ex)port-procedure and handling (possible) errors
or non-validated imported data.
Each data-set (data entry) in the file has a quite simple structure
as following:
[DataType] |
[LowID] |
[HighID] |
[Data...] |
[CRC] |
[Terminator] |
The specification of all the data fields is as following:
Fieldname |
Type |
Description |
[DataType] |
[Byte] |
Type definition for data. This is to specifiy for the import
process how to treat the data. Since it is generally saved as a
string this field holds therefore the information how to convert it
back to it's original data type (e.g. use "10" for real, "20" for
integer and so on).
|
[LowID] |
[Byte] |
Low identifier - in combination with the high identifier this
field represents what data has been imported (data number). Using 2
fields for identification this gives you up to about 60000
possibilities to separate data entries.
|
[HighID] |
[Byte] |
This is the hight identifier (sub index).
|
[Data...] |
[String] |
This is the data itself. It is always exported as a string with
variable length (depending on the data itself). You could add the
code to convert any data to string to the export procedure.
However, any data (real- integer-...) values need to be converted
to string before writing them to the data file.
|
[CRC] |
[Byte] |
Checksum - the checksum is build over the data field to detect
data corruption or unwanted changes. In -Mortens HostAlive- I use
a quite simple, but effective way. Depending on the kind of data
it's up to the developer which method he will use. (E.g. you might
need an algorithm to even detect bit-changes successfully...)
|
[Terminator] |
[Byte] |
Terminator that identicates the end of the string. I suggest
using characters here, that can't appear in a string - e.g. ASCii
values 01-20.
|
Please note: You need to take care, that the CRC value never gets
zero or the value that you have defined as terminator. I simply add +1
if that happens.
In -Mortens HostAlive- configuration file the first two data-entries
are a general identifier named "HostAlive" that validates the file as
"valid configuration file" and a version information that can be used
to e.g. detect updates and/or handle older files.
As next general program data follows that has the LowID-value 10 as
identifier. These are settings like width, height etc. of the formular.
The HighID-value separates and clearly identifies them.
As next all settings of the "general configuration"-formular are
following, having a new LowID-value of 20 and so on...
Due to interlaced "Select Case" statements the order of how the data is
imported is not important (Visual Basic syntax):
' {begin loop}
' {import ("new data-set")}
Select Case LowID
Case LowID = 10
Select Case HighID
Case HighID = 10
' (things to do for identifier 10-10)
Case HighID = 20
' (things to do for identifier 10-20)
End Select
Case LowID = 20
Select Case HighID
Case HighID = 10
' (things to do for identifier 20-10)
Case HighID = 20
' (things to do for identifier 20-20)
End Select
End Select
' {end loop}
Before importing data all fields that are to be imported will be
initialised with their standard-values. If now a field is missing (e.g.
the configuration file is too old) or the checksum does not validate
this entry I simply do not overtake this value. That's why after the end
of the import procedure I have collected ALL data that is needed to
fully initialize -Mortens HostAlive- correctly.
Contact information (bug report)...
|
[top]
|
|