UNPKG

@thi.ng/transducers-binary

Version:

Binary data related transducers & reducers

63 lines (62 loc) 1.63 kB
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 };