Storing+structures+containing+strings

//by Jon Ripley, July 2006//

The technique described in the storing structures in files article does **not** work for structures containing strings or string arrays. In most cases it is easier simply to write the individual structure members to file one at a time using **PRINT#** and read them back again using **INPUT#** or **READ#**. This alternative method is required to load and save structures containing strings using and.

Why? //BBC BASIC for Windows// does not store the strings themselves inside the structure, instead strings are represented as a string descriptor - a pointer to the string data and the length of the string. This means that the strings must be written to and read from the file separately from the structure block. Due to how string allocation works in //BBC BASIC// each string must be cleared before writing to the file, if strings were left intact then you may crash //BBC BASIC// when you later load the structure and copy the strings back into the structure. Temporary variables are used to contain the strings whilst the structure is being saved.

Writing the structure
To copy the strings into temporary variables, which should be made **LOCAL** inside your save routine, and clear the strings use code similar to the following:

code format="bb4w" temp1$ = struct.string1$ temp2$ = struct.string2$ etc... struct.string1$ = "" struct.string2$ = "" etc... code

Here each string in the structure is copied into a temporary string and each string in the structure is set to a NULL string (**""**). It is now safe to write the structure and the string data to the file:

code format="bb4w" PTR#file% = temp% SYS "WriteFile", @hfile%(file%), struct{}, !!^struct{}, ^temp%, 0 PRINT#file%, temp1$, temp2$... code

Here the file buffers are flushed, the structure is written to the file and the temporary copy of each string is written to the file.

To copy the strings back into the structure use code similar to the following:

code format="bb4w" struct.string1$ = temp1$ struct.string2$ = temp2$ etc... code

Reading the structure
To load the structure from the file use code similar to the following:

code format="bb4w" PTR#file% = PTR#file% SYS "ReadFile", @hfile%(file%), struct{}, !!^struct{}, ^temp%, 0 INPUT#file%, struct.string1$, struct.string2$... code

Here we flush BASIC's file buffers, call to read the structure from the file and use **INPUT#** to load the strings from the file.