Skip to content

Commit

Permalink
Int decoder
Browse files Browse the repository at this point in the history
  • Loading branch information
dincho committed Mar 13, 2020
1 parent 8a4ffd8 commit 2be1005
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 6 deletions.
30 changes: 30 additions & 0 deletions src/Serializers/IntSerializer.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
const RLP = require('rlp')
const FateTag = require('../FateTag.js')
const RLPInt = require('../utils/RLPInt.js')
const FateInt = require('../types/FateInt.js')
const {ByteArray2Int} = require('../utils/Int2ByteArray.js')

const abs = (val) => val > 0 ? val : val * -1n

const SMALL_INT_MASK = 0b00000001

IntSerializer = function () {}

IntSerializer.prototype = {
Expand Down Expand Up @@ -35,6 +39,32 @@ IntSerializer.prototype = {
FateTag.POS_BIG_INT,
...RLPInt(absVal - 64n)
]
},
deserialize: function (data) {
data = new Uint8Array(data)
const prefix = data[0]

//small int
if ((prefix & SMALL_INT_MASK) === 0) {
// positive
if ((prefix & 0b10000000) === 0) {
return new FateInt(prefix >> 1)
}

// negative
const i = (prefix & 0b01111110) >> 1
return new FateInt(-i)
}

if (prefix === FateTag.POS_BIG_INT || prefix === FateTag.NEG_BIG_INT) {
const sign = prefix === FateTag.POS_BIG_INT ? 1n : -1n
const i = ByteArray2Int(RLP.decode(data.slice(1)))

return new FateInt((i + 64n) * sign)

}

throw new Error('Unsupported byte sequence for ' + prefix.toString(2))
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/types/FateBytes.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const FateData = require('./FateData.js')
const Int2ByteArray = require('../utils/Int2ByteArray.js')
const {Int2ByteArray} = require('../utils/Int2ByteArray.js')
const HexStringToByteArray = require('../utils/HexStringToByteArray.js')

const toByteArray = (value) => {
Expand Down
23 changes: 21 additions & 2 deletions src/utils/Int2ByteArray.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const Int2ByteArray = function (value) {
const Int2ByteArray = (value) => {
if (value < 256) {
return new Uint8Array([Number(value)])
}
Expand All @@ -16,4 +16,23 @@ const Int2ByteArray = function (value) {
])
}

module.exports = Int2ByteArray
const ByteArray2Int = (data) => {
var hex = [];

data.forEach(i => {
var h = i.toString(16)

if (h.length % 2) {
h = '0' + h;
}

hex.push(h)
})

return BigInt('0x' + hex.join(''))
}

module.exports = {
Int2ByteArray,
ByteArray2Int
}
2 changes: 1 addition & 1 deletion src/utils/RLPInt.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const RLP = require('rlp')
const Int2ByteArray = require('./Int2ByteArray.js')
const {Int2ByteArray} = require('./Int2ByteArray.js')

module.exports = function RLPInt(value) {
return new Uint8Array(RLP.encode(Int2ByteArray(value)))
Expand Down
10 changes: 9 additions & 1 deletion tests/Decoder.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,17 @@ test.before(async t => {
t.context.encoder = encoder
});

test('Encode boolean return', t => {
test('Decode boolean return', t => {
t.is(
t.context.encoder.decode(CONTRACT, 'test_bool', 'cb_/8CwV/U='),
true
)
});

test('Decode int return', t => {
t.is(
t.context.encoder.decode(CONTRACT, 'test_single_int', 'cb_b4MC7W/bKkpn'),
191919n,
'test_single_int(191919)'
)
});
14 changes: 14 additions & 0 deletions tests/Serializers/IntSerializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,17 @@ test('Serialize', t => {
[111,136,254,220,186,152,118,84,49,208]
)
});

test('Deserialize', t => {
t.deepEqual(s.deserialize([0]), new FateInt(0))
t.deepEqual(s.deserialize([126]), new FateInt(63))
t.deepEqual(s.deserialize([254]), new FateInt(-63))
t.deepEqual(s.deserialize([111, 0]), new FateInt(64))
t.deepEqual(s.deserialize([239, 0]), new FateInt(-64))
t.deepEqual(s.deserialize([111, 131, 1, 134, 96]), new FateInt(100000))
t.deepEqual(s.deserialize([239, 131, 1, 134, 96]), new FateInt(-100000))
t.deepEqual(
s.deserialize([111,136,254,220,186,152,118,84,49,208]),
new FateInt("0xfedcba9876543210")
)
});
18 changes: 17 additions & 1 deletion tests/utils/Int2ByteArray.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const test = require('ava')
const Int2ByteArray = require('../../src/utils/Int2ByteArray.js')
const {Int2ByteArray, ByteArray2Int} = require('../../src/utils/Int2ByteArray.js')

const b = (value) => new Uint8Array(value)

Expand All @@ -18,3 +18,19 @@ test('Int2ByteArray', t => {
b([2,30,25,224,201,186,178,216,150,127])
)
});

test('ByteArray2Int', t => {
t.deepEqual(ByteArray2Int([0]), 0n)
t.deepEqual(ByteArray2Int([1]), 1n)
t.deepEqual(ByteArray2Int([255]), 255n)
t.deepEqual(ByteArray2Int([1, 0]), 256n)
t.deepEqual(ByteArray2Int([1, 44]), 300n)
t.deepEqual(ByteArray2Int([1, 255]), 511n)
t.deepEqual(ByteArray2Int([2, 0]), 512n)
t.deepEqual(ByteArray2Int([2, 40]), 552n)
t.deepEqual(ByteArray2Int([1, 134, 160]), 100000n)
t.deepEqual(
ByteArray2Int([2,30,25,224,201,186,178,216,150,127]),
10000000000000009999999n
)
});

0 comments on commit 2be1005

Please sign in to comment.