Преобразование в строки и из строк

Массивы и структуры можно целиком копировать в строки (это называется «сериализацией»). Можно также копировать из строк в массивы и структуры («десериализация»).

Преобразование в строку уничтожает всю информацию об источнике данных, поэтому можно преобразовывать между несовместимыми типами. Например, можно преобразовать массив в строку, а затем эту строку - в структуру или в массив другого типа.

Массивы в строки и обратно

Для массивов размер принимающего массива может быть меньше или больше объёма данных, подготовленных в строке: 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:

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

«POD» означает «plain old data» (простые старые данные). Строки содержат метаданные, поэтому не являются «plain old data».

Исходный материал Tibbo обновлён 12 сентября 2022Оригинал на docs.tibbo.com · Сообщить об ошибке