UNPKG

@kotevode/ffjavascript

Version:

Finite Field Library in Javascript

89 lines (69 loc) 2.49 kB
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; } } }