@aeternity/aepp-calldata
Version:
Aeternity data serialization library
101 lines (100 loc) • 2.94 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _rlp = _interopRequireDefault(require("rlp"));
var _ChainObject = _interopRequireDefault(require("./ChainObject.cjs"));
var _ChainObjectTags = _interopRequireDefault(require("./ChainObjectTags.cjs"));
var _ChainObjectTemplates = _interopRequireDefault(require("./ChainObjectTemplates.cjs"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
class ChainObjectSerializer {
/**
* @param {FieldsEncoder} fieldsEncoder
*/
constructor(fieldsEncoder) {
this.fieldsEncoder = fieldsEncoder;
}
serialize(chainObject) {
const {
name,
tag,
vsn
} = chainObject;
const template = _ChainObjectTemplates.default[name.toUpperCase()][vsn];
if (template === undefined) {
throw new Error(`Unsupported template version "${vsn}" for object type "${name}"`);
}
const serializedFields = this.#serializeFields(tag, vsn, template, chainObject);
return new Uint8Array(serializedFields);
}
deserialize(data) {
const {
tag,
vsn,
rest
} = this.#deserializeHeader(data);
const type = Object.keys(_ChainObjectTags.default).find(key => _ChainObjectTags.default[key] === Number(tag));
if (type === undefined) {
throw new Error(`Unsupported object tag: ${tag}`);
}
if (!_ChainObjectTemplates.default.hasOwnProperty(type)) {
return new _ChainObject.default(type.toLowerCase(), {});
}
if (!_ChainObjectTemplates.default[type].hasOwnProperty(vsn)) {
throw new Error(`Unsupported template version "${vsn}" for object type "${type}"`);
}
const template = _ChainObjectTemplates.default[type][vsn];
const fields = this.fieldsEncoder.decodeFields(rest, template);
return new _ChainObject.default(type.toLowerCase(), {
vsn,
...fields
});
}
#deserializeHeader(data) {
const objData = _rlp.default.decode(data);
const template = {
tag: 'int',
vsn: 'int'
};
const {
tag,
vsn
} = this.fieldsEncoder.decodeFields(objData, template);
const rest = objData.slice(2);
return {
tag,
vsn,
rest
};
}
#serializeFields(tag, vsn, template, fields) {
const allFields = {
tag,
vsn,
...fields
};
const fullTemplate = {
tag: 'int',
vsn: 'int',
...template
};
const data = this.fieldsEncoder.encodeFields(allFields, fullTemplate);
return [..._rlp.default.encode(data)];
}
#deserializeFields(template, data) {
const objData = _rlp.default.decode(data);
const fullTemplate = {
tag: 'int',
vsn: 'int',
...template
};
const {
_tag,
_vsn,
...fields
} = this.fieldsEncoder.decodeFields(objData, fullTemplate);
return fields;
}
}
var _default = exports.default = ChainObjectSerializer;