Conversion to/from Strings

Top  Previous  Next

You can copy entire arrays and structures to strings (this is known as "serialization"). You can also copy from strings into arrays and structures ("deserialization").

Converting to a string destroys all information about the source of data, so you can convert between incompatible types.

For example, you can convert an array to a string, and then convert this string to a structure, or an array of another type.

 

Arrays to strings and back

For arrays, the size of the receiving array may be smaller or larger than the amount of data prepared in the string — TiOS will only copy what fits in the destination or what's available in the source, depending on which is smaller.

 

Tibbo BASIC:

Tibbo C:

dim ar1(10) as dword
dim ar2(11) as word
dim s as string=ar1     'serialization (the resulting string will have 40 characters)
ar2=s           'deserialization into an array of a different type;
          'notice also that this array won't be able to fit all string data,               'but that's OK

unsigned long ar1[10];
unsigned int ar2[11];
string s=ar1;     //serialization (the resulting string will have 40 characters)
ar2=s;         //deserialization into an array of a different type;
          //notice also that this array won't be able to fit all string data,
          //but that's OK

 

Tibbo BASIC: structures to strings and back

In Tibbo BASIC, there is a string-related limitation on structure-to-string and string-to-structure conversions.

If a structure directly or indirectly includes string members then the serialization process will destroy the knowledge about the lengths of these string members. String capacity, rather than the string size, will be used when serializing string members of structures.

That is, if a string member has a capacity of 8 and the current size of 5, then the resulting serialized data will have 8 characters allocated for this string member. 5 characters will contain the string data, and the remaining 3 characters will contain the ASCII codes of 0. String meta-information, i.e. the current size and the capacity are NOT serialized.

During the deserialization TiOS will expect the source string to contain the capacity number of characters for each string member of the destination structure. As a result of deserialization, all string members of a structure will have maximum sizes (i.e. sizes will equal their capacities).

That is, if a string member of the destination structure has a capacity of 8 then the source string should have 8 characters prepared for this member.

The loss of the actual string length as the result of serialization is a significant limitation, and the one that has no universal way around it.

You can devise your own workarounds. For example, if you know that your strings never include characters with ASCII code 0 then you can use this information to figure out the actual string size:

 

Tibbo BASIC:

type mytype
  x as byte
  s as string(8)
end type
 
dim mt as mytype
mt.x=5
mt.s="TIBBO"
 
ss=mt                 'serialization, string length information is lost
                'ss has the following codes now: &h05, `T`, `I`, `B`, `B`, `O`, &h00, &h00, &h00
                'note how the current string length and the string capacity are NOT present in the string data
mt=ss                 'deserialization, mt.s will have the length of 8
 
dim pos as byte=instr(1,mt.s,chr(0),1)   'see if mt.s contains any zero characters
if pos>0 then           '(that is assuming that our "normal" data never includes ASCII code 0)
  mt.s=left(mt.s,pos-1)     'cut out unused portion of the string -- the original string size is now restored
end if

 

Tibbo C: structures and unions to strings and back

In Tibbo BASIC, there are also string-related limitations on structure-to-string, string-to-structure, union-to-string, and string-to-union conversions.

If a structure or a union directly or indirectly includes string members then the serialization process will destroy the knowledge about the lengths of these string members. String capacity, rather than the string size, will be used when serializing string members of structures and unions.

That is, if a string member has a capacity of 8 and the current size of 5, then the resulting serialized data will have 10 characters allocated for this string member. The first character will contain the current string size, the second character will contain the string capacity. The next 5 characters will contain the string data, and the remaining 3 characters will contain the ASCII codes of 0.

So, unlike in Tibbo BASIC, string meta-information, i.e. the current size and the capacity ARE serialized.

Deserialization into structures or unions that directly or indirectly include string members is not allowed. The reason for this limitation is that string variables include metadata (current length and capacity), which could potentially become invalid as a result of deserialization (for example, it would be possible to set current length > capacity).

 

Tibbo C:

struct pod_struct1{
  char x;
  string<8>s;           //this member makes the structure serialization into a string impossible
}ps1;
 
dim mt as mytype
mt.x=0x5A
mt.s="TIBBO"
 
ss=mt                 //serialization, string length information is lost
                //ss has the following codes now: 0x5A, 0x05, 0x08, `T`, `I`, `B`, `B`, `O`, &h00, &h00, &h00
                //note how 0x05 for the current string length and 0x08 for the string capacity are present in the string data
mt=ss                 //this will generate a compiler error ("it's unsafe to assign strings to non-POD types")

 

Related compiler error looks like this:

 

Output pane:

(prj)\c.tc(19) : error C1328: it's unsafe to assign strings to non-POD types

 

"POD" stands for "plain old data". Strings contain metadata, so they are not "plain old data".