build static method

Uint8List build(
  1. Iterable<MapEntry<List<int>, List<int>>> entries, {
  2. Endian? endian,
  3. List<int>? customData,
  4. bool? keepEntryOrder,
  5. bool? skipOffsetIndex,
  6. bool? usePadding,
})

Implementation

static Uint8List build(
  Iterable<MapEntry<List<int>, List<int>>> entries, {
  Endian? endian,
  List<int>? customData,
  bool? keepEntryOrder,
  bool? skipOffsetIndex,
  bool? usePadding,
}) {
  assert(_internalVersion < 0x80);
  endian ??= Endian.host;
  keepEntryOrder ??= false;
  skipOffsetIndex ??= keepEntryOrder;
  usePadding ??= false;

  final writer = BytesWriter(endian);
  writer.write(_magicBytes);
  writer.writeUint8((endian == Endian.little ? 0 : 0x80) | _internalVersion);

  final entriesList = entries
      .map((e) => MapEntry(e.key.toUint8List(), e.value.toUint8List()))
      .toList();
  if (!keepEntryOrder) {
    entriesList.sort((a, b) => a.key.compareTo(b.key));
  }

  // TODO: implement compression
  final prefixBytes = emptyBytes;
  final postfixBytes = emptyBytes;

  final hasCompression = prefixBytes.isNotEmpty | postfixBytes.isNotEmpty;
  final hasCustomData = customData != null && customData.isNotEmpty;
  final firstByte = (hasCustomData ? 0x01 : 0) |
      (keepEntryOrder ? 0 : 0x02) |
      (hasCompression ? 0x04 : 0) |
      (skipOffsetIndex ? 0 : 0x08);
  writer.writeUint8(firstByte);

  writer.writeVarint(entriesList.length);
  if (hasCustomData) {
    writer.writeVarint(customData.length);
    writer.write(customData);
  }

  if (hasCompression) {
    writer.writeVarint(prefixBytes.length);
    writer.write(prefixBytes);
    writer.writeVarint(postfixBytes.length);
    writer.write(postfixBytes);
  }

  final keyLengthPrefixBuilder = LengthEncoding3bitV1Builder.fromValues(
      entriesList.map((e) => e.key.length));
  final valueLengthPrefixBuilder = LengthEncoding3bitV1Builder.fromValues(
      entriesList.map((e) => e.value.length));

  final kvWriter = BytesWriter(endian);
  final offsets = skipOffsetIndex ? null : <int>[];
  for (final e in entriesList) {
    offsets?.add(kvWriter.length);
    keyLengthPrefixBuilder.writeLength(kvWriter, e.key.length);
    kvWriter.write(e.key);
    valueLengthPrefixBuilder.writeLength(kvWriter, e.value.length);
    kvWriter.write(e.value);
  }
  final kvBytes = kvWriter.toBytes();

  if (!skipOffsetIndex) {
    writeOffsetIndex(
      writer,
      offsets!,
      entriesCount: entriesList.length,
      isPadded: usePadding,
    );
  }

  final kvCode = keyLengthPrefixBuilder.code |
      (valueLengthPrefixBuilder.code << 3) |
      (usePadding ? 0x40 : 0);
  writer.writeUint8(kvCode);
  writer.write(keyLengthPrefixBuilder.bytes);
  writer.write(valueLengthPrefixBuilder.bytes);
  writer.writeVarint(kvBytes.length);
  if (usePadding) {
    writer.writePadding8();
  }
  writer.write(kvBytes);
  return writer.toBytes();
}