deserializeParamValue function

({int consumed, ParamValue value}) deserializeParamValue(
  1. Uint8List data, {
  2. int offset = 0,
})

Deserialises a single ParamValue from data starting at offset (mirrors ParamValue::deserialize in the Rust engine). Returns the value and the number of bytes consumed.

Implementation

({ParamValue value, int consumed}) deserializeParamValue(
  Uint8List data, {
  int offset = 0,
}) {
  if (data.length < offset + 5) {
    throw const FormatException('ParamValue buffer too short');
  }
  final tag = data[offset];
  final len = data.buffer.asByteData().getUint32(offset + 1, _littleEndian);
  final consumed = 5 + len;
  if (data.length < offset + consumed) {
    throw const FormatException('ParamValue buffer truncated');
  }
  final start = offset + 5;
  final payload = data.sublist(start, start + len);

  final ParamValue v;
  switch (tag) {
    case _tagNull:
      v = const ParamValueNull();
    case _tagString:
      v = ParamValueString(utf8.decode(payload, allowMalformed: true));
    case _tagInteger:
      if (len != 4) {
        throw const FormatException('ParamValue::Integer expected 4 bytes');
      }
      v = ParamValueInt32(
        ByteData.sublistView(data, start, start + 4).getInt32(0, _littleEndian),
      );
    case _tagBigInt:
      if (len != 8) {
        throw const FormatException('ParamValue::BigInt expected 8 bytes');
      }
      v = ParamValueInt64(
        ByteData.sublistView(data, start, start + 8).getInt64(0, _littleEndian),
      );
    case _tagDecimal:
      v = ParamValueDecimal(utf8.decode(payload, allowMalformed: true));
    case _tagBinary:
      v = ParamValueBinary(payload);
    case _tagRefCursorOut:
      if (len != 0) {
        throw const FormatException(
          'ParamValue::RefCursorOut expected 0 length',
        );
      }
      v = const ParamValueRefCursorOut();
    default:
      throw FormatException('Unknown ParamValue tag: $tag');
  }
  return (value: v, consumed: consumed);
}