encode method
Writes data
into the buffer
.
Implementation
@override
void encode(List data, LengthTrackingByteSink buffer) {
// Formal definition of the encoding: https://solidity.readthedocs.io/en/develop/abi-spec.html#formal-specification-of-the-encoding
assert(data.length == types.length);
// first, encode all non-dynamic values. For each dynamic value we
// encounter, encode its position instead. Then, encode all the dynamic
// values.
var currentDynamicOffset = 0;
final dynamicHeaderPositions = List.filled(data.length, -1);
for (var i = 0; i < data.length; i++) {
final payload = data[i];
final type = types[i];
if (type.encodingLength.isDynamic) {
// just write a bunch of zeroes, we later have to encode the relative
// offset here.
dynamicHeaderPositions[i] = buffer.length;
buffer.add(Uint8List(sizeUnitBytes));
currentDynamicOffset += sizeUnitBytes;
} else {
final lengthBefore = buffer.length;
type.encode(payload, buffer);
currentDynamicOffset += buffer.length - lengthBefore;
}
}
// now that the heads are written, write tails for the dynamic values
for (var i = 0; i < data.length; i++) {
if (!types[i].encodingLength.isDynamic) continue;
// replace the 32 zero-bytes with the actual encoded offset
const UintType().encodeReplace(
dynamicHeaderPositions[i],
BigInt.from(currentDynamicOffset),
buffer,
);
final lengthBefore = buffer.length;
types[i].encode(data[i], buffer);
currentDynamicOffset += buffer.length - lengthBefore;
}
}