@thi.ng/transducers-binary
Version:
Binary data related transducers & reducers
63 lines (62 loc) • 1.63 kB
JavaScript
import { iterator, __iter } from "@thi.ng/transducers/iterator";
import { isReduced } from "@thi.ng/transducers/reduced";
function partitionBits(...args) {
return __iter(partitionBits, args, iterator) || ((rfn) => {
const destSize = args[0];
const srcSize = args[1] || 8;
return destSize < srcSize ? __small(rfn, destSize, srcSize) : destSize > srcSize ? __large(rfn, destSize, srcSize) : rfn;
});
}
const __small = ([init, complete, reduce], n, wordSize) => {
const maxb = wordSize - n;
const m1 = (1 << wordSize) - 1;
const m2 = (1 << n) - 1;
let r = 0;
let y = 0;
return [
init,
(acc) => complete(r > 0 ? reduce(acc, y) : acc),
(acc, x) => {
let b = 0;
do {
acc = reduce(acc, y + (x >>> maxb + r & m2));
b += n - r;
x = x << n - r & m1;
y = 0;
r = 0;
} while (b <= maxb && !isReduced(acc));
r = wordSize - b;
y = r > 0 ? x >>> maxb & m2 : 0;
return acc;
}
];
};
const __large = ([init, complete, reduce], n, wordSize) => {
const m1 = (1 << wordSize) - 1;
let r = 0;
let y = 0;
return [
init,
(acc) => complete(r > 0 ? reduce(acc, y) : acc),
(acc, x) => {
if (r + wordSize <= n) {
y |= (x & m1) << n - wordSize - r;
r += wordSize;
if (r === n) {
acc = reduce(acc, y);
y = 0;
r = 0;
}
} else {
const k = n - r;
r = wordSize - k;
acc = reduce(acc, y | x >>> r & (1 << k) - 1);
y = (x & (1 << r) - 1) << n - r;
}
return acc;
}
];
};
export {
partitionBits
};