read method

  1. @override
dynamic read([
  1. int? typeId
])

Read and decode any value.

If typeId is not provided, it is read first.

Implementation

@override
dynamic read([int? typeId]) {
  typeId ??= readTypeId();
  if (TypeRegistryImpl.isInternalTypeId(typeId)) {
    return super.read(typeId);
  }

  final isEnum = readByte() == 1;
  final dataLength = readInt32();

  final type = _types.entries
      .where(
        (e) =>
            TypeRegistryImpl.calculateTypeId(
              e.value.typeId,
              internal: false,
            ) ==
            typeId,
      )
      .firstOrNull;
  if (type == null) {
    if (typeId == 233 && dataLength == 8) {
      // Assume TimeOfDay
      final totalMinutes = readInt();
      final hour = totalMinutes ~/ 60;
      final minute = totalMinutes % 60;
      return '$hour:$minute';
    } else {
      return readBytes(dataLength);
    }
  }

  MapEntry<String, RiftSchemaField>? getField(int index) {
    return type.value.fields.entries
        .where((e) => e.value.index == index)
        .firstOrNull;
  }

  if (isEnum) {
    final index = readByte();
    final field = getField(index);

    if (field == null) {
      throw RiftError('Unknown enum index: ${type.key}[$index]');
    }
    return RawEnum(type.key, field.key);
  } else {
    final length = readByte();
    final fields = List<RawField>.filled(length, RawField('', null));
    for (var i = 0; i < length; i++) {
      final index = readByte();
      final field = getField(index);

      if (field == null) {
        throw RiftError('Unknown field index: ${type.key}[$index]');
      }
      fields[i] = RawField(field.key, read());
    }
    return RawObject(type.key, fields);
  }
}