Определить тип по одному только указателю на значение нельзя. Тип и размер придётся где-то хранить явно.
Теоретически, вместо строк и чисел можно было бы использовать указатель на Variant (PVariant), или указатель на запись с полем типа и указателем на реальные данные.
В данном конкретном случае, поскольку требуется сохранение чужих структур, которые менять не желательно, нужно отдельно сохранять типы значений, которые в TSQLiteTable храняться в поле fColTypes. При этом и в момент записи поля в поток, и в момент чтения его из потока нужно проверять тип, так же как это делается в коде библиотеки:
- Код: Выделить всё
if pInteger(fColTypes[i])^ = dtInt then
// и т.д.
В целом алгоритм будет примерно таким:
1) Пишем в поток число элементов fColTypes.
2) В цикле пишем все значения элементов fColTypes (они - pInteger, т.е. в поток должно записаться разыменованное значение указателя, которое будет типа Integer).
3) Пишем число элементов fResults.
4) В цикле пишем сами элементы fResults, каждый элемент в зависимости от типа. С числами всё просто: они Int64 при dtInt или Double при dtNumeric, достаточно разыменовать и записать полученные значения в поток. Строки нужно писать либо через TStream.WriteAnsiString, либо руками, подсмотрев реализацию этого метода. С блобами ещё чуть сложнее, нужно будет разыменовать указатель в TMemoryStream и скопировать его содержимое в наш Stream через TStream.CopyFrom.
Чтение - соответственно.
P.S.
Если непонятно, как определяется тип - см. destructor TSQLiteTable.Destroy:
- Код: Выделить всё
iColNo := (i mod fColCount);
case pInteger(self.fColTypes[iColNo])^ of
dtBlob: // ...
dtStr: // ...
// ...