capnp-js
Version:
Capnproto run-time decoding and encoding for Node
97 lines (95 loc) • 3.35 kB
JavaScript
var any = require('../reader/layout/any');
var meta = require('../reader/list/meta');
var isNull = require('../reader/isNull');
/*
* Zero a structure's memory, recurring into its pointers.
*
* * arena BuilderArena - The structure's parent arena.
* * layout StructureLayout - Layout of the structure to be zeroed.
*/
var structure = function(arena, layout) {
var blob = {
segment: layout.segment,
position: layout.dataSection
};
var iPointer = {
segment: layout.segment,
position: layout.pointersSection
};
for (;iPointer.position < layout.end; iPointer.position += 8) {
zero(arena, iPointer);
}
arena._zero(blob, layout.end - layout.dataSection);
};
/*
* Zero a list's memory, recurring into its pointers.
*
* * arena BuilderArena - The list's parent arena.
* * layout ListLayout - Layout of the list to be zeroed.
*/
var list = function(arena, layout) {
var bytes = layout.length * (layout.dataBytes + layout.pointersBytes);
var blob = {
segment: layout.segment,
position: layout.begin
};
var iPointer = {
segment: layout.segment,
position: layout.begin + layout.dataBytes
};
// Adjust for the list's tag word.
if (meta(layout).layout === 7) {
bytes += 8;
blob.position -= 8;
}
if (layout.pointersBytes !== 0) {
// Iterate the pointer sections to zero the corresponding blobs.
for (var i = 0; i < layout.length; ++i, iPointer.position += layout.dataBytes) {
var end = iPointer.position + layout.pointersBytes;
for (;iPointer.position < end; iPointer.position += 8) {
zero(arena, iPointer);
}
}
}
arena._zero(blob, bytes);
};
/*
* Zero a far pointer's landing pad. No-op if the provided pointer is not a
* far pointer.
* * arena BuilderArena - The pointer's parent arena.
* * pointer Datum - The far pointer whose landing pad will be zeroed.
*/
var zeroFarLanding = function(arena, pointer) {
// Zero the far pointer landing pad if it exists.
var typeBits = pointer.segment[pointer.position] & 7;
if (typeBits === 2) {
var doubleIncrement = (pointer.segment[pointer.position] & 4) << 1;
arena._zero(far.next(arena, pointer), 8 + doubleIncrement);
}
};
/*
* Zero a pointer's entire branch.
*
* * arena BuilderArena - The pointer's parent arena.
* * pointer Datum - The root of the branch to get zeroed.
*
* * RETURNS: Datum - The root of the branch that was zeroed.
*/
var zero = function(arena, pointer) {
if (isNull(pointer)) return;
var layout = any.unsafe(arena, pointer);
switch (layout.meta) {
case 0:
structure(arena, layout);
break;
case 1:
list(arena, layout);
break;
}
zeroFarLanding(arena, pointer);
arena._zero(pointer, 8);
return pointer;
};
exports.pointer = zero;
exports.structure = structure;
exports.list = list;