encode method
Encode values with ABI rules based on the ABI type schemes @return byte[] of ABI encoding @throws IllegalArgumentException if encoder cannot infer the type from obj
Implementation
@override
Uint8List encode(dynamic obj) {
if (obj is! List) {
throw ArgumentError(
'cannot infer type for unify array/list-like object to object array');
}
if (obj.length != childTypes.length) {
throw ArgumentError(
'abi tuple child type size != abi tuple element value size');
}
final tupleValues = obj;
final tupleTypes = List<AbiType>.from(childTypes);
final heads =
List<Uint8List>.filled(tupleTypes.length, Uint8List.fromList([]));
final tails =
List<Uint8List>.filled(tupleTypes.length, Uint8List.fromList([]));
final dynamicIndex = <int>{};
for (var i = 0; i < tupleTypes.length; i++) {
var currType = tupleTypes[i];
var currValue = tupleValues[i];
Uint8List currHead, currTail;
if (currType.isDynamic()) {
currHead = Uint8List.fromList([0x00, 0x00]);
currTail = currType.encode(currValue);
dynamicIndex.add(i);
} else if (currType is TypeBool) {
var before = AbiType.findBoolLR(tupleTypes, i, -1);
var after = AbiType.findBoolLR(tupleTypes, i, 1);
if (before % 8 != 0) {
throw ArgumentError('expected before has number of bool mod 8 == 0');
}
after = min(after, 7);
var compressed = 0;
for (var boolIndex = 0; boolIndex <= after; boolIndex++) {
final result = tupleValues[i + boolIndex] as bool;
if (result) {
compressed |= 1 << (7 - boolIndex);
}
}
currHead = Uint8List.fromList([compressed]);
currTail = Uint8List.fromList([]);
i += after;
} else {
currHead = currType.encode(currValue);
currTail = Uint8List.fromList([]);
}
heads[i] = currHead;
tails[i] = currTail;
}
var headLength = 0;
for (var h in heads) {
headLength += h.length;
}
var tailCurrLength = 0;
for (var i = 0; i < heads.length; i++) {
if (dynamicIndex.contains(i)) {
var headValue = headLength + tailCurrLength;
if (headValue >= (1 << 16)) {
throw ArgumentError('encoding error: byte length >= 2^16');
}
heads[i] = BigIntEncoder.encodeUintToBytes(
BigInt.from(headValue), AbiType.ABI_DYNAMIC_HEAD_BYTE_LEN);
}
tailCurrLength += tails[i].length;
}
final buffer = <int>[];
for (var h in heads) {
buffer.addAll(h);
}
for (var t in tails) {
buffer.addAll(t);
}
return Uint8List.fromList(buffer);
}