Trace.decode constructor
Trace.decode(
- Uint8List bytes
Reads a trace written by encode.
Throws a TraceFormatException for bytes that are not a trace, a version newer than formatVersion, or an event or a value this build does not know.
Implementation
factory Trace.decode(Uint8List bytes) {
final data = ByteData.sublistView(bytes);
for (var i = 0; i < _magic.length; i++) {
if (bytes.length <= i || bytes[i] != _magic[i]) {
throw const TraceFormatException(
'not a flutter3d trace: no F3DTRACE magic',
);
}
}
// Every format up to this build's, lifted through [_migrations]; only a
// trace from the future is refused (decision 8 of
// `tasks/1.0-stability.md`). Mutation: put back `!=` and bump the
// constant, and `test/fixtures/v1/frame.f3dtrace` stops opening.
final version = data.getUint32(8, Endian.little);
if (version < 1 || version > formatVersion) {
throw TraceFormatException(
'a trace of format $version; this build reads up to $formatVersion. '
'Update flutter3d to replay it',
);
}
final headerLength = data.getUint32(12, Endian.little);
if (bytes.length < 16 + headerLength) {
throw TraceFormatException(
'a trace whose header says $headerLength bytes, in a file of '
'${bytes.length}',
);
}
try {
final header = _migrations
.skip(version - 1)
.fold(
asMap(
jsonDecode(utf8.decode(bytes.sublist(16, 16 + headerLength))),
),
(Map<String, Object?> json, _TraceMigration lift) => lift(json),
);
final blob = TraceBlobReader(bytes.sublist(16 + headerLength));
return Trace(<TraceEvent>[
for (final e in (header['events']! as List<Object?>).map(asMap))
TraceEvent.fromJson(e, blob),
], metadata: asMap(header['metadata'] ?? <String, Object?>{}));
} on FormatException catch (error) {
// JSON or UTF-8 that does not parse: the file, not this build.
throw TraceFormatException(
'a trace header that does not read',
cause: error,
);
}
}