Преобразование в строки и из строк
Массивы и структуры можно целиком копировать в строки (это называется «сериализацией»). Можно также копировать из строк в массивы и структуры («десериализация»).
Преобразование в строку уничтожает всю информацию об источнике данных, поэтому можно преобразовывать между несовместимыми типами. Например, можно преобразовать массив в строку, а затем эту строку - в структуру или в массив другого типа.
Массивы в строки и обратно
Для массивов размер принимающего массива может быть меньше или больше объёма данных, подготовленных в строке: TiOS скопирует только то, что помещается в приёмник или что есть в источнике, в зависимости от того, что меньше.
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: структуры в строки и обратно
В Tibbo BASIC у преобразований структуры в строку и строки в структуру есть ограничение, связанное со строками.
Если структура прямо или косвенно включает строковые члены, то в процессе сериализации информация о длинах этих строковых членов теряется. При сериализации строковых членов структур используется ёмкость строки, а не её размер. То есть если у строкового члена ёмкость равна восьми, а текущий размер - пяти, то в сериализованных данных для этого члена будет выделено 8 символов. Пять символов будут содержать данные строки, а остальные три - ASCII-коды 0. Метаинформация о строке (то есть текущий размер и ёмкость) НЕ сериализуется.
При десериализации TiOS ожидает, что исходная строка содержит для каждого строкового члена структуры-приёмника столько символов, какова его ёмкость. В результате десериализации все строковые члены структуры получат максимальный размер (то есть их размеры станут равны ёмкостям). Иначе говоря, если у строкового члена структуры-приёмника ёмкость равна восьми, то в исходной строке для этого члена должно быть подготовлено восемь символов.
Потеря фактической длины строки при сериализации - серьёзное ограничение, универсального способа обойти которое нет.
Можно придумать собственные обходные пути. Например, если вы знаете, что ваши строки никогда не содержат символов с ASCII-кодом 0, то по этому признаку можно определить фактический размер строки:
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: структуры и объединения в строки и обратно
В Tibbo C у преобразований структуры в строку, строки в структуру, объединения в строку и строки в объединение тоже есть ограничения, связанные со строками.
Если структура или объединение прямо или косвенно включает строковые члены, то в процессе сериализации информация о длинах этих строковых членов теряется. При сериализации строковых членов структур и объединений используется ёмкость строки, а не её размер. То есть если у строкового члена ёмкость равна восьми, а текущий размер - пяти, то в сериализованных данных для этого члена будет выделено 10 символов. Первый символ содержит текущий размер строки, второй - ёмкость строки, следующие пять символов - данные строки, а остальные три - ASCII-коды 0.
Таким образом, в отличие от Tibbo BASIC, метаинформация о строке (то есть текущий размер и ёмкость) СЕРИАЛИЗУЕТСЯ.
Десериализация в структуры или объединения, прямо или косвенно включающие строковые члены, не допускается. Причина ограничения в том, что строковые переменные включают метаданные (текущую длину и ёмкость), которые могут стать недопустимыми в результате десериализации (например, можно было бы установить текущую длину > ёмкости).
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")
Соответствующая ошибка компилятора выглядит так в панели Output:
«POD» означает «plain old data» (простые старые данные). Строки содержат метаданные, поэтому не являются «plain old data».