| 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] |  |