Skip to content

Commit 8c17a17

Browse files
committed
Refactor: Remove all sync generators
1 parent bd6265a commit 8c17a17

File tree

13 files changed

+126
-99
lines changed

13 files changed

+126
-99
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
# 2.4.1
2+
3+
- Refactor: Remove all sync generator to improve runtime.
4+
15
# 2.4.0
26

37
- **Breaking Changes**: Uses string for salt and hash in `CryptData`

lib/src/codecs/base16.dart

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright (c) 2023, Sudipto Chandra
22
// All rights reserved. Check LICENSE file for details.
33

4+
import 'dart:typed_data';
5+
46
import 'package:hashlib_codecs/src/core/byte.dart';
57
import 'package:hashlib_codecs/src/core/codec.dart';
68

@@ -21,28 +23,33 @@ class _Base16Encoder extends ByteEncoder {
2123
static const lower = _Base16Encoder._(_smallA - 10);
2224

2325
@override
24-
Iterable<int> convert(Iterable<int> input) sync* {
25-
int a, b;
26-
for (int x in input) {
26+
Iterable<int> convert(Iterable<int> input) {
27+
int i, p, x, a, b;
28+
List<int> list = input is List<int> ? input : input.toList();
29+
var result = Uint8List(list.length << 1);
30+
for (i = p = 0; p < list.length; p++, i += 2) {
31+
x = list[p];
2732
a = (x >>> 4) & 0xF;
2833
b = x & 0xF;
2934
a += a < 10 ? _zero : startCode;
3035
b += b < 10 ? _zero : startCode;
31-
yield a;
32-
yield b;
36+
result[i] = a;
37+
result[i + 1] = b;
3338
}
39+
return result;
3440
}
3541
}
3642

3743
class _Base16Decoder extends ByteDecoder {
3844
const _Base16Decoder() : super(bits: 4);
3945

4046
@override
41-
Iterable<int> convert(Iterable<int> input) sync* {
47+
Iterable<int> convert(Iterable<int> input) {
4248
bool t;
4349
int p, x, y;
4450
p = 0;
4551
t = false;
52+
List<int> out = <int>[];
4653
for (y in input) {
4754
if (y >= _smallA) {
4855
x = y - _smallA + 10;
@@ -57,7 +64,7 @@ class _Base16Decoder extends ByteDecoder {
5764
throw FormatException('Invalid character $y');
5865
}
5966
if (t) {
60-
yield ((p << 4) | x);
67+
out.add((p << 4) | x);
6168
p = 0;
6269
t = false;
6370
} else {
@@ -66,8 +73,9 @@ class _Base16Decoder extends ByteDecoder {
6673
}
6774
}
6875
if (t) {
69-
yield p;
76+
out.add(p);
7077
}
78+
return out;
7179
}
7280
}
7381

lib/src/codecs/base2.dart

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright (c) 2023, Sudipto Chandra
22
// All rights reserved. Check LICENSE file for details.
33

4+
import 'dart:typed_data';
5+
46
import 'package:hashlib_codecs/src/core/byte.dart';
57
import 'package:hashlib_codecs/src/core/codec.dart';
68

@@ -14,25 +16,31 @@ class _Base2Encoder extends ByteEncoder {
1416
const _Base2Encoder() : super(bits: 2);
1517

1618
@override
17-
Iterable<int> convert(Iterable<int> input) sync* {
18-
for (int x in input) {
19-
yield _zero + ((x >>> 7) & 1);
20-
yield _zero + ((x >>> 6) & 1);
21-
yield _zero + ((x >>> 5) & 1);
22-
yield _zero + ((x >>> 4) & 1);
23-
yield _zero + ((x >>> 3) & 1);
24-
yield _zero + ((x >>> 2) & 1);
25-
yield _zero + ((x >>> 1) & 1);
26-
yield _zero + ((x) & 1);
19+
Iterable<int> convert(Iterable<int> input) {
20+
int i, p, x;
21+
List<int> list = input is List<int> ? input : input.toList();
22+
var result = Uint8List(list.length << 3);
23+
for (i = p = 0; p < list.length; p++, i += 8) {
24+
x = list[p];
25+
result[i] = _zero + ((x >>> 7) & 1);
26+
result[i + 1] = _zero + ((x >>> 6) & 1);
27+
result[i + 2] = _zero + ((x >>> 5) & 1);
28+
result[i + 3] = _zero + ((x >>> 4) & 1);
29+
result[i + 4] = _zero + ((x >>> 3) & 1);
30+
result[i + 5] = _zero + ((x >>> 2) & 1);
31+
result[i + 6] = _zero + ((x >>> 1) & 1);
32+
result[i + 7] = _zero + ((x) & 1);
2733
}
34+
return result;
2835
}
2936
}
3037

3138
class _Base2Decoder extends ByteDecoder {
3239
const _Base2Decoder() : super(bits: 2);
3340

3441
@override
35-
Iterable<int> convert(Iterable<int> input) sync* {
42+
Iterable<int> convert(Iterable<int> input) {
43+
List<int> out = <int>[];
3644
int p, n, x, y;
3745
p = n = 0;
3846
for (y in input) {
@@ -44,14 +52,15 @@ class _Base2Decoder extends ByteDecoder {
4452
p = (p << 1) | x;
4553
n++;
4654
} else {
47-
yield p;
55+
out.add(p);
4856
n = 1;
4957
p = x;
5058
}
5159
}
5260
if (n > 0) {
53-
yield p;
61+
out.add(p);
5462
}
63+
return out;
5564
}
5665
}
5766

lib/src/codecs/bigint.dart

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class _BigIntLSBFirstEncoder extends BigIntEncoder {
1919
@override
2020
BigInt convert(Iterable<int> input) {
2121
int a, b, i, j;
22-
var out = <int>[];
22+
List<int> out = <int>[];
2323
for (int x in input) {
2424
a = (x >>> 4) & 0xF;
2525
b = x & 0xF;
@@ -48,28 +48,29 @@ class _BigIntLSBFirstDecoder extends BigIntDecoder {
4848
const _BigIntLSBFirstDecoder();
4949

5050
@override
51-
Iterable<int> convert(BigInt input) sync* {
51+
Iterable<int> convert(BigInt input) {
5252
if (input.isNegative) {
5353
throw FormatException('Negative numbers are not supported');
5454
}
5555
if (input == BigInt.zero) {
56-
yield 0;
57-
return;
56+
return [0];
5857
}
5958
int i, a, b;
59+
List<int> out = <int>[];
6060
var bytes = input.toRadixString(16).codeUnits;
6161
for (i = bytes.length - 2; i >= 0; i -= 2) {
6262
a = bytes[i];
6363
b = bytes[i + 1];
6464
a -= a < _smallA ? _zero : _smallA - 10;
6565
b -= b < _smallA ? _zero : _smallA - 10;
66-
yield (a << 4) | b;
66+
out.add((a << 4) | b);
6767
}
6868
if (i == -1) {
6969
a = bytes[0];
7070
a -= a < _smallA ? _zero : _smallA - 10;
71-
yield a;
71+
out.add(a);
7272
}
73+
return out;
7374
}
7475
}
7576

@@ -83,7 +84,7 @@ class _BigIntMSBFirstEncoder extends BigIntEncoder {
8384
@override
8485
BigInt convert(Iterable<int> input) {
8586
int a, b;
86-
var out = <int>[];
87+
List<int> out = <int>[];
8788
for (int x in input) {
8889
a = (x >>> 4) & 0xF;
8990
b = x & 0xF;
@@ -103,31 +104,32 @@ class _BigIntMSBFirstDecoder extends BigIntDecoder {
103104
const _BigIntMSBFirstDecoder();
104105

105106
@override
106-
Iterable<int> convert(BigInt input) sync* {
107+
Iterable<int> convert(BigInt input) {
107108
if (input.isNegative) {
108109
throw FormatException('Negative numbers are not supported');
109110
}
110111
if (input == BigInt.zero) {
111-
yield 0;
112-
return;
112+
return [0];
113113
}
114114
int i, a, b, n;
115+
List<int> out = <int>[];
115116
var bytes = input.toRadixString(16).codeUnits;
116117
n = bytes.length;
117118
i = 1;
118119
if (n & 1 == 1) {
119120
a = bytes[0];
120121
a -= a < _smallA ? _zero : _smallA - 10;
121-
yield a;
122+
out.add(a);
122123
i++;
123124
}
124125
for (; i < n; i += 2) {
125126
a = bytes[i - 1];
126127
b = bytes[i];
127128
a -= a < _smallA ? _zero : _smallA - 10;
128129
b -= b < _smallA ? _zero : _smallA - 10;
129-
yield (a << 4) | b;
130+
out.add((a << 4) | b);
130131
}
132+
return out;
131133
}
132134
}
133135

lib/src/core/alphabet.dart

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,15 @@ class AlphabetEncoder extends BitEncoder {
3434
int get target => bits;
3535

3636
@override
37-
Iterable<int> convert(Iterable<int> input) sync* {
38-
int l = 0;
39-
for (final x in super.convert(input)) {
40-
yield alphabet[x];
41-
l += target;
42-
}
37+
Iterable<int> convert(Iterable<int> input) {
38+
var out = super.convert(input).map((x) => alphabet[x]).toList();
39+
int l = out.length * target;
4340
if (padding != null) {
4441
for (; (l & 7) != 0; l += target) {
45-
yield padding!;
42+
out.add(padding!);
4643
}
4744
}
45+
return out;
4846
}
4947
}
5048

lib/src/core/byte.dart

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ import 'encoder.dart';
77
class ByteEncoder extends BitEncoder {
88
final int bits;
99

10-
@override
11-
final int source = 8;
12-
1310
/// Creates a new [ByteEncoder] instance.
1411
///
1512
/// Parameters:
@@ -18,16 +15,16 @@ class ByteEncoder extends BitEncoder {
1815
required this.bits,
1916
});
2017

18+
@override
19+
final int source = 8;
20+
2121
@override
2222
int get target => bits;
2323
}
2424

2525
class ByteDecoder extends BitDecoder {
2626
final int bits;
2727

28-
@override
29-
final int target = 8;
30-
3128
/// Creates a new [ByteDecoder] instance.
3229
///
3330
/// Parameters:
@@ -38,4 +35,7 @@ class ByteDecoder extends BitDecoder {
3835

3936
@override
4037
int get source => bits;
38+
39+
@override
40+
final int target = 8;
4141
}

lib/src/core/decoder.dart

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright (c) 2023, Sudipto Chandra
22
// All rights reserved. Check LICENSE file for details.
33

4+
import 'dart:typed_data';
5+
46
import 'codec.dart';
57

68
abstract class BitDecoder extends HashlibConverter {
@@ -16,30 +18,36 @@ abstract class BitDecoder extends HashlibConverter {
1618
///
1719
/// After consuming all of input sequence, if there are some non-zero partial
1820
/// word remains, it will throw [FormatException].
21+
// TODO: sync is slow. use typed list
1922
@override
20-
Iterable<int> convert(Iterable<int> encoded) sync* {
21-
if (source < 2 || source > 64) {
23+
Iterable<int> convert(Iterable<int> encoded) {
24+
int x, p, s, t, l, n, sb, tb;
25+
sb = source;
26+
tb = target;
27+
if (sb < 2 || sb > 64) {
2228
throw ArgumentError('The source bit length should be between 2 to 64');
2329
}
24-
if (target < 2 || target > 64) {
30+
if (tb < 2 || tb > 64) {
2531
throw ArgumentError('The target bit length should be between 2 to 64');
2632
}
2733

28-
int x, p, n, s, t;
29-
p = n = t = 0;
30-
s = 1 << (source - 1);
31-
s = s ^ (s - 1);
34+
List<int> list = encoded is List<int> ? encoded : List<int>.of(encoded);
35+
l = list.length * sb;
36+
var out = Uint8List(l ~/ tb);
3237

3338
// generate words from the input bits
34-
for (x in encoded) {
39+
p = n = t = l = 0;
40+
s = 1 << (sb - 1);
41+
s = s ^ (s - 1);
42+
for (x in list) {
3543
if (x < 0 || x > s) break;
36-
p = (p << source) ^ x;
37-
t = (t << source) ^ s;
38-
n += source;
39-
while (n >= target) {
40-
n -= target;
41-
yield p >>> n;
42-
t >>>= target;
44+
p = (p << sb) ^ x;
45+
t = (t << sb) ^ s;
46+
n += sb;
47+
while (n >= tb) {
48+
n -= tb;
49+
out[l++] = p >>> n;
50+
t >>>= tb;
4351
p &= t;
4452
}
4553
}
@@ -48,5 +56,7 @@ abstract class BitDecoder extends HashlibConverter {
4856
if (p > 0) {
4957
throw FormatException('Invalid length');
5058
}
59+
60+
return Uint8List.view(out.buffer, 0, l);
5161
}
5262
}

0 commit comments

Comments
 (0)