Skip to content

Commit

Permalink
Split serializers in their own files
Browse files Browse the repository at this point in the history
  • Loading branch information
dincho committed Feb 12, 2020
1 parent 27cb6d6 commit e5364e6
Show file tree
Hide file tree
Showing 32 changed files with 609 additions and 335 deletions.
231 changes: 43 additions & 188 deletions src/Serializer.js
Original file line number Diff line number Diff line change
@@ -1,196 +1,51 @@
const RLP = require('rlp')
const FATE = require('./fate.js')
const Int2ByteArray = require('./utils/Int2ByteArray.js')
const RLPInt = require('./utils/RLPInt.js')

module.exports = {
const AddressSerializer = require('./Serializers/AddressSerializer')
const BitsSerializer = require('./Serializers/BitsSerializer')
const BoolSerializer = require('./Serializers/BoolSerializer')
const ByteArraySerializer = require('./Serializers/ByteArraySerializer')
const BytesSerializer = require('./Serializers/BytesSerializer')
const ChannelSerializer = require('./Serializers/ChannelSerializer')
const ContractSerializer = require('./Serializers/ContractSerializer')
const IntSerializer = require('./Serializers/IntSerializer')
const ListSerializer = require('./Serializers/ListSerializer')
const MapSerializer = require('./Serializers/MapSerializer')
const OracleQuerySerializer = require('./Serializers/OracleQuerySerializer')
const OracleSerializer = require('./Serializers/OracleSerializer')
const StringSerializer = require('./Serializers/StringSerializer')
const TupleSerializer = require('./Serializers/TupleSerializer')
const VariantSerializer = require('./Serializers/VariantSerializer')

Serializer = {
serializers: {},
register: function(type, instance) {
this.serializers[type] = instance
},
serialize: function (data) {
const [type, value] = data

if (!this.serializers.hasOwnProperty(type)) {
throw new Error("Unsupported type: " + type);
throw new Error("Unsupported type, " + type);
}

return this.serializers[type].call(this, value)
},
serializers: {
'bool': function (value) {
return (value === true) ? [FATE.TRUE] : [FATE.FALSE]
},
'int': function (value) {
const absVal = Math.abs(value)

// small integer
if (absVal < 64) {
if (value >= 0) {
return [(value << 1)]
}

// negative
return [(0xff | (absVal << 1)) & 0b11111110]
}

// large negative integer
if (value < 0) {
return [
FATE.NEG_BIG_INT,
...RLPInt(absVal - 64)
]
}

// large positive integer
return [
FATE.POS_BIG_INT,
...RLPInt(absVal - 64)
]

},
'tuple': function (value) {
if (value.length === 0) {
return [FATE.EMPTY_TUPLE]
}

const elements = value.map(e => this.serialize(e)).flat(Infinity)

if (value.length < 16) {
const prefix = (value.length << 4) | FATE.SHORT_TUPLE

return [
prefix,
...elements
]
}

return [
FATE.LONG_TUPLE,
...this.serialize(['int', elements.length - 16]),
...elements
]
},
//TODO: nested lists
'list': function (value) {
const [type, elements] = value
const serializedElements = elements.map(e => this.serialize([type, e])).flat(Infinity)
const len = elements.length

if (len < 16) {
const prefix = (len << 4) | FATE.SHORT_LIST

return [
prefix,
...serializedElements
]
}

return [
FATE.LONG_LIST,
...this.serialize(['int', len - 16]),
...serializedElements
]
},
//TODO: nested maps
'map': function (value) {
const [keyKype, valueType, elements] = value
const len = elements.length

const serializedElements = elements.map(e => {
const [key, value] = e
return [
this.serialize([keyKype, key]),
this.serialize([valueType, value])
]
})

return [
FATE.MAP,
...RLPInt(len),
...serializedElements.flat(Infinity)
]
},
'byte_array': function (byteArray) {
if (byteArray.length === 0) {
return [FATE.EMPTY_STRING]
}

if (byteArray.length < 64) {
const prefix = (byteArray.length << 2) | FATE.SHORT_STRING

return [
prefix,
...byteArray
]
}

return [
FATE.LONG_STRING,
...this.serialize(['int', (byteArray.length - 64)]),
...byteArray
]
},
'string': function (value) {
const encoder = new TextEncoder()
const bytes = encoder.encode(value)

return this.serialize(['byte_array', bytes])
},
'bits': function (value) {
const absVal = Math.abs(value)
const prefix = value >= 0 ? FATE.POS_BITS : FATE.NEG_BITS

return [
prefix,
...RLPInt(absVal)
]
},
'variant': function (data) {
return [
FATE.VARIANT,
...RLP.encode(Uint8Array.from(data.arities)),
data.tag,
...this.serialize(['tuple', data.variantValues])
]
},
'bytes': function (value) {
return [
FATE.OBJECT,
FATE.OTYPE_BYTES,
...this.serialize(['byte_array', Int2ByteArray(value)])
]
},
'address': function (value) {
return [
FATE.OBJECT,
FATE.OTYPE_ADDRESS,
...RLPInt(value)
]
},
'contract': function (value) {
return [
FATE.OBJECT,
FATE.OTYPE_CONTRACT,
...RLPInt(value)
]
},
'oracle': function (value) {
return [
FATE.OBJECT,
FATE.OTYPE_ORACLE,
...RLPInt(value)
]
},
'oracle_query': function (value) {
return [
FATE.OBJECT,
FATE.OTYPE_ORACLE_QUERY,
...RLPInt(value)
]
},
'channel': function (value) {
return [
FATE.OBJECT,
FATE.OTYPE_CHANNEL,
...RLPInt(value)
]
},
return this.serializers[type].serialize(value)
}
}

Serializer.register('bool', new BoolSerializer())
Serializer.register('int', new IntSerializer())
Serializer.register('tuple', new TupleSerializer(Serializer))
//TODO, nested list
Serializer.register('list', new ListSerializer())
//TODO, nested map
Serializer.register('map', new MapSerializer(Serializer))
Serializer.register('byte_array', new ByteArraySerializer())
Serializer.register('string', new StringSerializer())
Serializer.register('bits', new BitsSerializer())
Serializer.register('variant', new VariantSerializer(Serializer))
Serializer.register('bytes', new BytesSerializer())
Serializer.register('address', new AddressSerializer())
Serializer.register('contract', new ContractSerializer())
Serializer.register('oracle', new OracleSerializer())
Serializer.register('oracle_query', new OracleQuerySerializer())
Serializer.register('channel', new ChannelSerializer())

module.exports = Serializer
16 changes: 16 additions & 0 deletions src/Serializers/AddressSerializer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const FATE = require('../fate.js')
const RLPInt = require('../utils/RLPInt.js')

AddressSerializer = function () {}

AddressSerializer.prototype = {
serialize: function (value) {
return [
FATE.OBJECT,
FATE.OTYPE_ADDRESS,
...RLPInt(value)
]
}
}

module.exports = AddressSerializer
18 changes: 18 additions & 0 deletions src/Serializers/BitsSerializer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const FATE = require('../fate.js')
const RLPInt = require('../utils/RLPInt.js')

BitsSerializer = function () {}

BitsSerializer.prototype = {
serialize: function (value) {
const absVal = Math.abs(value)
const prefix = value >= 0 ? FATE.POS_BITS : FATE.NEG_BITS

return [
prefix,
...RLPInt(absVal)
]
}
}

module.exports = BitsSerializer
11 changes: 11 additions & 0 deletions src/Serializers/BoolSerializer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
const FATE = require('../fate.js')

BoolSerializer = function () {}

BoolSerializer.prototype = {
serialize: function (value) {
return (value === true) ? [FATE.TRUE] : [FATE.FALSE]
}
}

module.exports = BoolSerializer
31 changes: 31 additions & 0 deletions src/Serializers/ByteArraySerializer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const FATE = require('../fate.js')
const IntSerializer = require('./IntSerializer.js')

const intSerializer = new IntSerializer()

ByteArraySerializer = function () {}

ByteArraySerializer.prototype = {
serialize: function (data) {
if (data.length === 0) {
return [FATE.EMPTY_STRING]
}

if (data.length < 64) {
const prefix = (data.length << 2) | FATE.SHORT_STRING

return [
prefix,
...data
]
}

return [
FATE.LONG_STRING,
...intSerializer.serialize((data.length - 64)),
...data
]
}
}

module.exports = ByteArraySerializer
19 changes: 19 additions & 0 deletions src/Serializers/BytesSerializer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const FATE = require('../fate.js')
const Int2ByteArray = require('../utils/Int2ByteArray.js')
const ByteArraySerializer = require('./ByteArraySerializer.js')

const byteArraySerializer = new ByteArraySerializer()

BytesSerializer = function () {}

BytesSerializer.prototype = {
serialize: function (value) {
return [
FATE.OBJECT,
FATE.OTYPE_BYTES,
...byteArraySerializer.serialize(Int2ByteArray(value))
]
}
}

module.exports = BytesSerializer
16 changes: 16 additions & 0 deletions src/Serializers/ChannelSerializer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const FATE = require('../fate.js')
const RLPInt = require('../utils/RLPInt.js')

ChannelSerializer = function () {}

ChannelSerializer.prototype = {
serialize: function (value) {
return [
FATE.OBJECT,
FATE.OTYPE_CHANNEL,
...RLPInt(value)
]
}
}

module.exports = ChannelSerializer
16 changes: 16 additions & 0 deletions src/Serializers/ContractSerializer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const FATE = require('../fate.js')
const RLPInt = require('../utils/RLPInt.js')

ContractSerializer = function () {}

ContractSerializer.prototype = {
serialize: function (value) {
return [
FATE.OBJECT,
FATE.OTYPE_CONTRACT,
...RLPInt(value)
]
}
}

module.exports = ContractSerializer
Loading

0 comments on commit e5364e6

Please sign in to comment.