'use strict'
const {Buffer} = require('buffer')
const encoder = require('./encoder')
const decoder = require('./decoder')
const {MT} = require('./constants')
class CborMap extends Map {
constructor(iterable) {
super(iterable)
}
static _encode(key) {
return encoder.encodeCanonical(key).toString('base64')
}
static _decode(key) {
return decoder.decodeFirstSync(key, 'base64')
}
get(key) {
return super.get(CborMap._encode(key))
}
set(key, val) {
return super.set(CborMap._encode(key), val)
}
delete(key) {
return super.delete(CborMap._encode(key))
}
has(key) {
return super.has(CborMap._encode(key))
}
*keys() {
for (const k of super.keys()) {
yield CborMap._decode(k)
}
}
*entries() {
for (const kv of super.entries()) {
yield [CborMap._decode(kv[0]), kv[1]]
}
}
[Symbol.iterator]() {
return this.entries()
}
forEach(fun, thisArg) {
if (typeof fun !== 'function') {
throw new TypeError('Must be function')
}
for (const kv of super.entries()) {
fun.call(this, kv[1], CborMap._decode(kv[0]), this)
}
}
encodeCBOR(gen) {
if (!gen._pushInt(this.size, MT.MAP)) {
return false
}
if (gen.canonical) {
const entries = Array.from(super.entries())
.map(kv => [Buffer.from(kv[0], 'base64'), kv[1]])
entries.sort((a, b) => a[0].compare(b[0]))
for (const kv of entries) {
if (!(gen.push(kv[0]) && gen.pushAny(kv[1]))) {
return false
}
}
} else {
for (const kv of super.entries()) {
if (!(gen.push(Buffer.from(kv[0], 'base64')) && gen.pushAny(kv[1]))) {
return false
}
}
}
return true
}
}
module.exports = CborMap