binary-data
Version:
Declarative binary data encoder / decoder.
107 lines (84 loc) • 2.36 kB
JavaScript
const { isType, isFunction, isUserType } = require('lib/util');
const symbols = require('internal/symbols');
const { decodeCommon } = require('lib/decode');
const { encodeCommon } = require('lib/encode');
const { encodingLengthCommon } = require('lib/encoding-length');
const Metadata = require('internal/meta');
module.exports = when;
/**
* Type for conditions.
* @param {Function|bool} condition
* @param {Object} type Any builtin type or schema.
* @returns {Object}
*/
function when(condition, type) {
if (!isType(type) && !isUserType(type)) {
throw new TypeError('Argument #2 should be a valid type.');
}
const result = {
encode,
decode,
encodingLength,
[symbols.skip]: false,
};
return result;
/**
* Encode value if condition is truthy.
* @param {any} value
* @param {EncodeStream} wstream
*/
function encode(value, wstream) {
const context = Metadata.clone(this);
encode.bytes = 0;
const status = isFunction(condition)
? Boolean(condition(context))
: Boolean(condition);
result[symbols.skip] = !status;
if (!status) {
Metadata.clean(context);
return;
}
encodeCommon(value, wstream, type, context);
encode.bytes = context.bytes;
Metadata.clean(context);
}
/**
* Decode value if condition is truthy.
* @param {DecodeStream} rstream
* @returns {any}
*/
function decode(rstream) {
const context = Metadata.clone(this);
decode.bytes = 0;
const status = isFunction(condition)
? Boolean(condition(context))
: Boolean(condition);
result[symbols.skip] = !status;
if (!status) {
Metadata.clean(context);
return;
}
const value = decodeCommon(rstream, type, context);
decode.bytes = context.bytes;
Metadata.clean(context);
return value; // eslint-disable-line consistent-return
}
/**
* Get the number bytes of an encoded value
* when condition is truthy or 0.
* @param {any} value
* @returns {number}
*/
function encodingLength(value) {
const context = Metadata.clone(this);
const status = isFunction(condition)
? Boolean(condition(context))
: Boolean(condition);
if (status) {
encodingLengthCommon(value, type, context);
}
Metadata.clean(context);
return context.bytes;
}
}
;