getBaseXEncoder function

VariableSizeEncoder<String> getBaseXEncoder(
  1. String alphabet
)

Returns an encoder for base-X encoded strings.

This encoder serializes strings using a custom alphabet, treating the length of the alphabet as the base. The encoding process involves converting the input string to a numeric value in base-X, then encoding that value into bytes while preserving leading zeroes.

For more details, see getBaseXCodec.

Implementation

VariableSizeEncoder<String> getBaseXEncoder(String alphabet) {
  return VariableSizeEncoder<String>(
    getSizeFromValue: (value) {
      final (leadingZeroes, tailChars) = _partitionLeadingZeroes(
        value,
        alphabet[0],
      );
      if (tailChars == null || tailChars.isEmpty) return value.length;

      final base10Number = _getBigIntFromBaseX(tailChars, alphabet);
      return leadingZeroes.length +
          (base10Number.toRadixString(16).length / 2).ceil();
    },
    write: (value, bytes, offset) {
      // Check if the value is valid.
      assertValidBaseString(alphabet, value);
      if (value.isEmpty) return offset;

      // Handle leading zeroes.
      final (leadingZeroes, tailChars) = _partitionLeadingZeroes(
        value,
        alphabet[0],
      );
      if (tailChars == null || tailChars.isEmpty) {
        for (var i = 0; i < leadingZeroes.length; i++) {
          bytes[offset + i] = 0;
        }
        return offset + leadingZeroes.length;
      }

      // From baseX to base10.
      var base10Number = _getBigIntFromBaseX(tailChars, alphabet);

      // From base10 to bytes.
      final tailBytes = <int>[];
      while (base10Number > BigInt.zero) {
        tailBytes.insert(0, (base10Number % BigInt.from(256)).toInt());
        base10Number = base10Number ~/ BigInt.from(256);
      }

      final bytesToAdd = [
        ...List<int>.filled(leadingZeroes.length, 0),
        ...tailBytes,
      ];
      bytes.setAll(offset, bytesToAdd);
      return offset + bytesToAdd.length;
    },
  );
}