2014-01-28 16:38:02 +00:00
|
|
|
/* [MS-XLSB] 2.1.4 Record */
|
2017-02-10 19:23:01 +00:00
|
|
|
function recordhopper(data, cb/*:RecordHopperCB*/, opts/*:?any*/) {
|
|
|
|
if(!data) return;
|
2014-01-29 06:00:09 +00:00
|
|
|
var tmpbyte, cntbyte, length;
|
2014-01-28 16:38:02 +00:00
|
|
|
prep_blob(data, data.l || 0);
|
2017-04-09 04:03:19 +00:00
|
|
|
var L = data.length, RT = 0, tgt = 0;
|
|
|
|
while(data.l < L) {
|
|
|
|
RT = data.read_shift(1);
|
2014-01-28 16:38:02 +00:00
|
|
|
if(RT & 0x80) RT = (RT & 0x7F) + ((data.read_shift(1) & 0x7F)<<7);
|
2015-04-02 20:32:22 +00:00
|
|
|
var R = XLSBRecordEnum[RT] || XLSBRecordEnum[0xFFFF];
|
2014-02-12 06:09:42 +00:00
|
|
|
tmpbyte = data.read_shift(1);
|
|
|
|
length = tmpbyte & 0x7F;
|
2014-01-28 16:38:02 +00:00
|
|
|
for(cntbyte = 1; cntbyte <4 && (tmpbyte & 0x80); ++cntbyte) length += ((tmpbyte = data.read_shift(1)) & 0x7F)<<(7*cntbyte);
|
2017-04-09 04:03:19 +00:00
|
|
|
tgt = data.l + length;
|
2017-09-22 22:18:51 +00:00
|
|
|
var d = (R.f||parsenoop)(data, length, opts);
|
2017-04-02 06:47:25 +00:00
|
|
|
data.l = tgt;
|
2017-04-09 04:03:19 +00:00
|
|
|
if(cb(d, R.n, RT)) return;
|
2014-01-28 16:38:02 +00:00
|
|
|
}
|
2014-06-29 18:29:45 +00:00
|
|
|
}
|
2014-05-16 00:33:34 +00:00
|
|
|
|
|
|
|
/* control buffer usage for fixed-length buffers */
|
2017-02-10 19:23:01 +00:00
|
|
|
function buf_array()/*:BufArray*/ {
|
2014-05-29 22:30:03 +00:00
|
|
|
var bufs = [], blksz = 2048;
|
2014-06-29 18:29:45 +00:00
|
|
|
var newblk = function ba_newblk(sz) {
|
2017-03-12 18:02:43 +00:00
|
|
|
var o/*:Block*/ = (new_buf(sz)/*:any*/);
|
2014-06-29 18:29:45 +00:00
|
|
|
prep_blob(o, 0);
|
2014-05-29 22:30:03 +00:00
|
|
|
return o;
|
|
|
|
};
|
|
|
|
|
2014-06-29 18:29:45 +00:00
|
|
|
var curbuf = newblk(blksz);
|
2014-05-29 22:30:03 +00:00
|
|
|
|
2014-06-29 18:29:45 +00:00
|
|
|
var endbuf = function ba_endbuf() {
|
2017-02-10 19:23:01 +00:00
|
|
|
if(!curbuf) return;
|
2017-02-03 20:50:45 +00:00
|
|
|
if(curbuf.length > curbuf.l) curbuf = curbuf.slice(0, curbuf.l);
|
2014-05-29 22:30:03 +00:00
|
|
|
if(curbuf.length > 0) bufs.push(curbuf);
|
|
|
|
curbuf = null;
|
|
|
|
};
|
|
|
|
|
2014-06-29 18:29:45 +00:00
|
|
|
var next = function ba_next(sz) {
|
2017-02-10 19:23:01 +00:00
|
|
|
if(curbuf && sz < curbuf.length - curbuf.l) return curbuf;
|
2014-05-29 22:30:03 +00:00
|
|
|
endbuf();
|
|
|
|
return (curbuf = newblk(Math.max(sz+1, blksz)));
|
|
|
|
};
|
|
|
|
|
2014-06-29 18:29:45 +00:00
|
|
|
var end = function ba_end() {
|
2014-05-29 22:30:03 +00:00
|
|
|
endbuf();
|
|
|
|
return __toBuffer([bufs]);
|
|
|
|
};
|
|
|
|
|
2014-06-29 18:29:45 +00:00
|
|
|
var push = function ba_push(buf) { endbuf(); curbuf = buf; next(blksz); };
|
2014-05-29 22:30:03 +00:00
|
|
|
|
2017-02-10 19:23:01 +00:00
|
|
|
return ({ next:next, push:push, end:end, _bufs:bufs }/*:any*/);
|
2014-06-29 18:29:45 +00:00
|
|
|
}
|
2014-05-29 22:30:03 +00:00
|
|
|
|
2017-02-03 20:50:45 +00:00
|
|
|
function write_record(ba/*:BufArray*/, type/*:string*/, payload, length/*:?number*/) {
|
2017-09-22 22:18:51 +00:00
|
|
|
var t/*:number*/ = +XLSBRE[type], l;
|
2017-02-10 19:23:01 +00:00
|
|
|
if(isNaN(t)) return; // TODO: throw something here?
|
2015-04-02 20:32:22 +00:00
|
|
|
if(!length) length = XLSBRecordEnum[t].p || (payload||[]).length || 0;
|
2014-05-29 22:30:03 +00:00
|
|
|
l = 1 + (t >= 0x80 ? 1 : 0) + 1 + length;
|
|
|
|
if(length >= 0x80) ++l; if(length >= 0x4000) ++l; if(length >= 0x200000) ++l;
|
|
|
|
var o = ba.next(l);
|
|
|
|
if(t <= 0x7F) o.write_shift(1, t);
|
|
|
|
else {
|
|
|
|
o.write_shift(1, (t & 0x7F) + 0x80);
|
|
|
|
o.write_shift(1, (t >> 7));
|
|
|
|
}
|
|
|
|
for(var i = 0; i != 4; ++i) {
|
|
|
|
if(length >= 0x80) { o.write_shift(1, (length & 0x7F)+0x80); length >>= 7; }
|
|
|
|
else { o.write_shift(1, length); break; }
|
|
|
|
}
|
2017-02-03 20:50:45 +00:00
|
|
|
if(/*:: length != null &&*/length > 0 && is_buf(payload)) ba.push(payload);
|
2014-06-29 18:29:45 +00:00
|
|
|
}
|