2018-05-16 16:25:05 +00:00
/**
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
2019-07-09 12:23:59 +01:00
import Operation from "../Operation.mjs" ;
import Utils from "../Utils.mjs" ;
import OperationError from "../errors/OperationError.mjs" ;
import { ENCODING_SCHEME , ENCODING_LOOKUP , FORMAT } from "../lib/BCD.mjs" ;
2018-05-16 16:25:05 +00:00
import BigNumber from "bignumber.js" ;
/**
* From BCD operation
*/
class FromBCD extends Operation {
/**
* FromBCD constructor
*/
constructor () {
super ();
this . name = "From BCD" ;
this . module = "Default" ;
this . description = "Binary-Coded Decimal (BCD) is a class of binary encodings of decimal numbers where each decimal digit is represented by a fixed number of bits, usually four or eight. Special bit patterns are sometimes used for a sign." ;
2018-08-21 19:07:13 +01:00
this . infoURL = "https://wikipedia.org/wiki/Binary-coded_decimal" ;
2018-05-16 16:25:05 +00:00
this . inputType = "string" ;
this . outputType = "BigNumber" ;
this . args = [
{
"name" : "Scheme" ,
"type" : "option" ,
"value" : ENCODING_SCHEME
},
{
"name" : "Packed" ,
"type" : "boolean" ,
"value" : true
},
{
"name" : "Signed" ,
"type" : "boolean" ,
"value" : false
},
{
"name" : "Input format" ,
"type" : "option" ,
"value" : FORMAT
}
];
2020-03-24 11:06:37 +00:00
this . checks = [
{
pattern : "^(?:\\d{4} ){3,}\\d{4}$" ,
flags : "" ,
args : [ "8 4 2 1" , true , false , "Nibbles" ]
},
];
2018-05-16 16:25:05 +00:00
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {BigNumber}
*/
run ( input , args ) {
const encoding = ENCODING_LOOKUP [ args [ 0 ]],
packed = args [ 1 ],
signed = args [ 2 ],
inputFormat = args [ 3 ],
nibbles = [];
let output = "" ,
byteArray ;
// Normalise the input
switch ( inputFormat ) {
case "Nibbles" :
case "Bytes" :
input = input . replace ( /\s/g , "" );
for ( let i = 0 ; i < input . length ; i += 4 ) {
nibbles . push ( parseInt ( input . substr ( i , 4 ), 2 ));
}
break ;
case "Raw" :
default :
2023-02-03 17:10:33 +00:00
byteArray = new Uint8Array ( Utils . strToArrayBuffer ( input ));
2018-05-16 16:25:05 +00:00
byteArray . forEach ( b => {
nibbles . push ( b >>> 4 );
nibbles . push ( b & 15 );
});
break ;
}
if ( ! packed ) {
// Discard each high nibble
for ( let i = 0 ; i < nibbles . length ; i ++ ) {
2021-02-10 13:13:19 +00:00
nibbles . splice ( i , 1 ); // lgtm [js/loop-iteration-skipped-due-to-shifting]
2018-05-16 16:25:05 +00:00
}
}
if ( signed ) {
const sign = nibbles . pop ();
if ( sign === 13 ||
sign === 11 ) {
// Negative
output += "-" ;
}
}
nibbles . forEach ( n => {
if ( isNaN ( n )) throw new OperationError ( "Invalid input" );
const val = encoding . indexOf ( n );
if ( val < 0 ) throw new OperationError ( `Value ${ Utils . bin ( n , 4 ) } is not in the encoding scheme` );
output += val . toString ();
});
return new BigNumber ( output );
}
}
export default FromBCD ;