@kotevode/ffjavascript
Version:
Finite Field Library in Javascript
89 lines (69 loc) • 2.49 kB
JavaScript
const PAGE_SIZE = 1<<30;
export default class BigBuffer {
constructor(size) {
this.buffers = [];
this.byteLength = size;
for (let i=0; i<size; i+= PAGE_SIZE) {
const n = Math.min(size-i, PAGE_SIZE);
this.buffers.push(new Uint8Array(n));
}
}
slice(fr, to) {
if ( to === undefined ) to = this.byteLength;
if ( fr === undefined ) fr = 0;
const len = to-fr;
const firstPage = Math.floor(fr / PAGE_SIZE);
const lastPage = Math.floor((fr+len-1) / PAGE_SIZE);
if ((firstPage == lastPage)||(len==0))
return this.buffers[firstPage].slice(fr%PAGE_SIZE, fr%PAGE_SIZE + len);
let buff;
let p = firstPage;
let o = fr % PAGE_SIZE;
// Remaining bytes to read
let r = len;
while (r>0) {
// bytes to copy from this page
const l = (o+r > PAGE_SIZE) ? (PAGE_SIZE -o) : r;
const srcView = new Uint8Array(this.buffers[p].buffer, this.buffers[p].byteOffset+o, l);
if (l == len) return srcView.slice();
if (!buff) {
if (len <= PAGE_SIZE) {
buff = new Uint8Array(len);
} else {
buff = new BigBuffer(len);
}
}
buff.set(srcView, len-r);
r = r-l;
p ++;
o = 0;
}
return buff;
}
set(buff, offset) {
if (offset === undefined) offset = 0;
const len = buff.byteLength;
if (len==0) return;
const firstPage = Math.floor(offset / PAGE_SIZE);
const lastPage = Math.floor((offset+len-1) / PAGE_SIZE);
if (firstPage == lastPage) {
if ((buff instanceof BigBuffer)&&(buff.buffers.length==1)) {
return this.buffers[firstPage].set(buff.buffers[0], offset % PAGE_SIZE);
} else {
return this.buffers[firstPage].set(buff, offset % PAGE_SIZE);
}
}
let p = firstPage;
let o = offset % PAGE_SIZE;
let r = len;
while (r>0) {
const l = (o+r > PAGE_SIZE) ? (PAGE_SIZE -o) : r;
const srcView = buff.slice( len -r, len -r+l);
const dstView = new Uint8Array(this.buffers[p].buffer, this.buffers[p].byteOffset + o, l);
dstView.set(srcView);
r = r-l;
p ++;
o = 0;
}
}
}