[6a3a178] | 1 | 'use strict'
|
---|
| 2 |
|
---|
| 3 | var bindexOf = require('buffer-indexof')
|
---|
| 4 |
|
---|
| 5 | var equalSign = new Buffer('=')
|
---|
| 6 |
|
---|
| 7 | module.exports = function (opts) {
|
---|
| 8 | var binary = opts ? opts.binary : false
|
---|
| 9 | var that = {}
|
---|
| 10 |
|
---|
| 11 | that.encode = function (data, buf, offset) {
|
---|
| 12 | if (!data) data = {}
|
---|
| 13 | if (!offset) offset = 0
|
---|
| 14 | if (!buf) buf = new Buffer(that.encodingLength(data) + offset)
|
---|
| 15 |
|
---|
| 16 | var oldOffset = offset
|
---|
| 17 | var keys = Object.keys(data)
|
---|
| 18 |
|
---|
| 19 | if (keys.length === 0) {
|
---|
| 20 | buf[offset] = 0
|
---|
| 21 | offset++
|
---|
| 22 | }
|
---|
| 23 |
|
---|
| 24 | keys.forEach(function (key) {
|
---|
| 25 | var val = data[key]
|
---|
| 26 | var oldOffset = offset
|
---|
| 27 | offset++
|
---|
| 28 |
|
---|
| 29 | if (val === true) {
|
---|
| 30 | offset += buf.write(key, offset)
|
---|
| 31 | } else if (Buffer.isBuffer(val)) {
|
---|
| 32 | offset += buf.write(key + '=', offset)
|
---|
| 33 | var len = val.length
|
---|
| 34 | val.copy(buf, offset, 0, len)
|
---|
| 35 | offset += len
|
---|
| 36 | } else {
|
---|
| 37 | offset += buf.write(key + '=' + val, offset)
|
---|
| 38 | }
|
---|
| 39 |
|
---|
| 40 | buf[oldOffset] = offset - oldOffset - 1
|
---|
| 41 | })
|
---|
| 42 |
|
---|
| 43 | that.encode.bytes = offset - oldOffset
|
---|
| 44 | return buf
|
---|
| 45 | }
|
---|
| 46 |
|
---|
| 47 | that.decode = function (buf, offset, len) {
|
---|
| 48 | if (!offset) offset = 0
|
---|
| 49 | if (!Number.isFinite(len)) len = buf.length
|
---|
| 50 | var data = {}
|
---|
| 51 | var oldOffset = offset
|
---|
| 52 |
|
---|
| 53 | while (offset < len) {
|
---|
| 54 | var b = decodeBlock(buf, offset)
|
---|
| 55 | var i = bindexOf(b, equalSign)
|
---|
| 56 | offset += decodeBlock.bytes
|
---|
| 57 |
|
---|
| 58 | if (b.length === 0) continue // ignore: most likely a single zero byte
|
---|
| 59 | if (i === -1) data[b.toString().toLowerCase()] = true
|
---|
| 60 | else if (i === 0) continue // ignore: invalid key-length
|
---|
| 61 | else {
|
---|
| 62 | var key = b.slice(0, i).toString().toLowerCase()
|
---|
| 63 | if (key in data) continue // ignore: overwriting not allowed
|
---|
| 64 | data[key] = binary ? b.slice(i + 1) : b.slice(i + 1).toString()
|
---|
| 65 | }
|
---|
| 66 | }
|
---|
| 67 |
|
---|
| 68 | that.decode.bytes = offset - oldOffset
|
---|
| 69 | return data
|
---|
| 70 | }
|
---|
| 71 |
|
---|
| 72 | that.encodingLength = function (data) {
|
---|
| 73 | if (!data) return 1 // 1 byte (single empty byte)
|
---|
| 74 | var keys = Object.keys(data)
|
---|
| 75 | if (keys.length === 0) return 1 // 1 byte (single empty byte)
|
---|
| 76 | return keys.reduce(function (total, key) {
|
---|
| 77 | var val = data[key]
|
---|
| 78 | total += Buffer.byteLength(key) + 1 // +1 byte to store field length
|
---|
| 79 | if (Buffer.isBuffer(val)) total += val.length + 1 // +1 byte to fit equal sign
|
---|
| 80 | else if (val !== true) total += Buffer.byteLength(String(val)) + 1 // +1 byte to fit equal sign
|
---|
| 81 | return total
|
---|
| 82 | }, 0)
|
---|
| 83 | }
|
---|
| 84 |
|
---|
| 85 | return that
|
---|
| 86 | }
|
---|
| 87 |
|
---|
| 88 | function decodeBlock (buf, offset) {
|
---|
| 89 | var len = buf[offset]
|
---|
| 90 | var to = offset + 1 + len
|
---|
| 91 | var b = buf.slice(offset + 1, to > buf.length ? buf.length : to)
|
---|
| 92 | decodeBlock.bytes = len + 1
|
---|
| 93 | return b
|
---|
| 94 | }
|
---|