-
-
Notifications
You must be signed in to change notification settings - Fork 13
/
car_decoder.dart
86 lines (64 loc) · 1.62 KB
/
car_decoder.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// Copyright 2023 Shinya Kato. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided the conditions.
// 🎯 Dart imports:
import 'dart:typed_data';
// 📦 Package imports:
import 'package:multiformats/multiformats.dart';
// 🌎 Project imports:
import 'progress_status.dart';
const _cidV1BytesLength = 36;
Map<CID, List<int>> decodeCar(
final Uint8List bytes, [
ProgressStatus? progress,
]) {
final blocks = <CID, List<int>>{};
final bytesLength = bytes.length;
final header = _decodeReader(bytes);
int start = header.length + header.value;
while (start < bytesLength) {
final body = _decodeReader(bytes.sublist(start));
start += body.length;
final cid = CID.fromList(bytes.sublist(
start,
start + _cidV1BytesLength,
));
start += _cidV1BytesLength;
blocks[cid] = bytes.sublist(
start,
start + body.value - _cidV1BytesLength,
);
start += body.value - _cidV1BytesLength;
progress?.call(ProgressStatusEvent(
bytesLength,
start,
));
}
return blocks;
}
_DecodedBlock _decodeReader(Uint8List bytes) {
final a = <int>[];
int i = 0;
while (true) {
final b = bytes[i];
i++;
a.add(b);
if ((b & 0x80) == 0) {
break;
}
}
return _DecodedBlock(_decode(a), a.length);
}
final class _DecodedBlock {
const _DecodedBlock(this.value, this.length);
final int value;
final int length;
}
int _decode(List<int> b) {
int r = 0;
for (int i = 0; i < b.length; i++) {
int e = b[i];
r = r + ((e & 0x7F) << (i * 7));
}
return r;
}