readGgufMetadata function

GgufMetadataResult readGgufMetadata({
  1. required Uint8List headerPrefix,
  2. required Set<String> keys,
})

Reads the string values of keys from the GGUF whose first bytes are headerPrefix.

Returns as soon as every requested key has been seen, so a modest prefix (GGUF writers emit general.* keys first) usually suffices; otherwise the whole key/value section must fit in headerPrefix.

Implementation

GgufMetadataResult readGgufMetadata({
  required Uint8List headerPrefix,
  required Set<String> keys,
}) {
  final reader = GgufReader(headerPrefix);
  final values = <String, String>{};
  final numericValues = <String, int>{};
  try {
    if (reader.uint32() != ggufMagic) {
      return const GgufMetadataUnsupported('The file is not a GGUF model.');
    }
    final version = reader.uint32();
    if (version < 2 || version > 3) {
      return GgufMetadataUnsupported(
        'GGUF version $version is not supported (only little-endian v2/v3).',
      );
    }
    reader.uint64(); // tensor count
    final kvCount = reader.uint64();

    var remaining = keys.toSet();
    for (var i = 0; i < kvCount && remaining.isNotEmpty; i++) {
      final key = reader.string();
      final type = reader.uint32();
      if (remaining.remove(key)) {
        if (type == ggufTypeString) {
          values[key] = reader.string();
        } else {
          final value = reader.numericValueOrSkip(type);
          if (value != null) numericValues[key] = value;
        }
      } else {
        reader.skipValue(type);
      }
    }
  } on GgufTruncated {
    return const GgufMetadataNeedsLargerPrefix();
  } on FormatException catch (error) {
    return GgufMetadataUnsupported(error.message);
  }
  return GgufMetadata(values, numericValues);
}