capnp-js
Version:
Capnproto run-time decoding and encoding for Node
225 lines (224 loc) • 8.72 kB
JavaScript
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;