UNPKG

capnp-js

Version:

Capnproto run-time decoding and encoding for Node

225 lines (224 loc) 8.72 kB
var Reader = require('../reader/AnyPointer'); var isNull = require('../reader/isNull'); var listMeta = require('../reader/list/meta'); var any = require('../reader/layout/any'); var copy = require('./copy/pointer'); var layout = require('./layout/index'); var Blob = require('./AnyPointerBlob'); var fields = require('./fields'); var adoptLayout = function(context, ell) { var meta; if (ell.meta === 1) { meta = listMeta(ell); layout.list.nonpreallocated(context._arena, context._pointer, { segment: ell.segment, position: ell.begin - (meta.layout === 7 ? 8 : 0) }, meta, ell.length); } else { meta = { meta: 0, dataBytes: ell.pointersSection - ell.dataSection, pointersBytes: ell.end - ell.pointersSection }; layout.structure.nonpreallocated(context._arena, context._pointer, { segment: ell.segment, position: ell.dataSection }, meta); } }; var disown = function(context) { var instance = Blob._deref(context._arena, context._pointer); context._arena._zero(context._pointer, 8); instance._isOrphan = true; return instance; }; var disownReadOnly = function(context) { var instance = Blob._READER._deref(context._arena, context._pointer, 0); context._arena._zero(context._pointer, 8); instance._isOrphan = true; return instance; }; var disownAs = function(Type, context) { if (isNull(context._pointer) && Type._CT.meta === 1) throw new ValueError("Cannot disown a null list pointer"); var instance = Type._deref(context._arena, context._pointer); context._arena._zero(context._pointer, 8); instance._isOrphan = true; return instance; }; var disownAsReadOnly = function(Type, context) { if (isNull(context._pointer) && Type._CT.meta === 1) throw new ValueError("Cannot disown a null list pointer"); var instance = Type._READER._deref(context._arena, context._pointer, 0); context._arena._zero(context._pointer, 8); instance._isOrphan = true; return instance; }; var set = function(arena, pointer, value) { if (value._arena.IS_READER) console.log("No read limits have been applied :("); var ell = value._layout(); if (ell.meta === 1) { copy.pointer.setListPointer(value._arena, ell, arena, pointer); } else { copy.pointer.setStructPointer(value._arena, ell, arena, pointer); } }; var t = Reader._TYPE; var UnionAny = function(arena, pointer, discr) { this._arena = arena; this._pointer = pointer; this._isOrphan = false; this._discr = discr; }; UnionAny._READER = Reader; UnionAny._TYPE = t; UnionAny._deref = function(arena, pointer, discr) { return new UnionAny(arena, pointer, discr); }; UnionAny._unionGetField = function(discr, offset, defaultPosition) { return function() { fields.throwOnInactive(this.which(), discr); var pointer = { segment: this._segment, position: this._pointersSection + offset }; return UnionAny._deref(this._arena, pointer, discr); }; }; UnionAny._unionHasField = function(discr, offset) { return function() { fields.throwOnInactive(this.which(), discr); return isNull({ segment: this._segment, position: this._pointersSection + offset }); }; }; UnionAny._unionInitField = function(discr) { return function() { this._setWhich(discr); }; }; UnionAny._unionSetField = function(discr, offset) { return function(value) { if (value._layout === undefined) throw new TypeError(); this._setWhich(discr); set(this._arena, { segment: this._segment, position: this._pointersSection + offset }, value); }; }; UnionAny.prototype = { _TYPE: t, _layout: function() { return any.safe(this._arena, this._pointer); } }; UnionAny.prototype.adopt = function(value) { if (!value._isOrphan) throw new ValueError("Cannot adopt a non-orphan"); if (!value._arena.isEquivTo(context._arena)) throw new ValueError("Cannot adopt from a different arena"); this._setWhich(this._discr); adoptLayout(this, value._layout()); }; UnionAny.prototype.disown = function() { return disown(this); }; UnionAny.prototype.disownAs = function(Type) { return disownAs(Type, this); }; UnionAny.prototype.disownReadOnly = function() { return disownReadOnly(this); }; UnionAny.prototype.disownAsReadOnly = function(Type) { return disownAsReadOnly(Type, this); }; UnionAny.prototype.getAs = function(Derefable) { if (!Derefable._READER) throw new TypeError("Must provide a builder type"); return Derefable._deref(arena, this._pointer); }; UnionAny.prototype.initAs = function(Initable, optionalLength) { if (!Derefable._READER) throw new TypeError("Must provide a builder type"); return Initable._init(this._arena, this._pointer, optionalLength); }; var NonunionAny = function(arena, pointer) { this._arena = arena; this._pointer = pointer; this._isOrphan = false; }; NonunionAny._READER = Reader; NonunionAny._TYPE = t; NonunionAny._deref = function(arena, pointer) { return new NonunionAny(arena, pointer); }; NonunionAny._set = function(arena, pointer, value) { if (value._TYPE === t) { if (value._arena.IS_READER) console.log("No read limits have been applied :("); copy.pointer.setAnyPointer(value._arena, value._pointer, arena, pointer); } else { if (value._arena.IS_READER) console.warn("No read limits have been applied :("); var layout = value._layout(); if (layout.meta === 1) { copy.pointer.setListPointer(value._arena, layout, arena, pointer); } else { copy.pointer.setStructPointer(value._arena, layout, arena, pointer); } } }; NonunionAny._getField = function(offset, defaultPosition) { return function() { var pointer = { segment: this._segment, position: this._pointersSection + offset }; return NonunionAny._deref(this._arena, pointer); }; }; NonunionAny._hasField = function(offset) { return function() { return isNull({ segment: this._segment, position: this._pointersSection + offset }); }; }; NonunionAny._setField = function(offset) { return function(value) { if (value._layout === undefined) throw new TypeError(); set(this._arena, { segment: this._segment, position: this._pointersSection + offset }, value); }; }; NonunionAny.prototype = { _TYPE: t, _layout: function() { return any.safe(this._arena, this._pointer); } }; NonunionAny.prototype.adopt = function(value) { if (!value._isOrphan) throw new ValueError("Cannot adopt a non-orphan"); if (!value._arena.isEquivTo(context._arena)) throw new ValueError("Cannot adopt from a different arena"); adoptLayout(this, value._layout()); }; NonunionAny.prototype.disown = function() { return disown(this); }; NonunionAny.prototype.disownAs = function(Type) { return disownAs(Type, this); }; NonunionAny.prototype.disownReadOnly = function() { return disownReadOnly(this); }; NonunionAny.prototype.disownAsReadOnly = function(Type) { return disownAsReadOnly(Type, this); }; NonunionAny.prototype.getAs = function(Derefable) { if (!Derefable._READER) throw new TypeError("Must provide a builder type"); return Derefable._deref(arena, this._pointer); }; NonunionAny.prototype.initAs = function(Initable, optionalLength) { if (!Derefable._READER) throw new TypeError("Must provide a builder type"); return Initable._init(this._arena, this._pointer, optionalLength); }; exports.Union = UnionAny; exports.Nonunion = NonunionAny;