getBaseXEncoder function
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;
},
);
}