|
|
- 'use strict'
-
- var bindexOf = require('buffer-indexof')
-
- var equalSign = new Buffer('=')
-
- module.exports = function (opts) {
- var binary = opts ? opts.binary : false
- var that = {}
-
- that.encode = function (data, buf, offset) {
- if (!data) data = {}
- if (!offset) offset = 0
- if (!buf) buf = new Buffer(that.encodingLength(data) + offset)
-
- var oldOffset = offset
- var keys = Object.keys(data)
-
- if (keys.length === 0) {
- buf[offset] = 0
- offset++
- }
-
- keys.forEach(function (key) {
- var val = data[key]
- var oldOffset = offset
- offset++
-
- if (val === true) {
- offset += buf.write(key, offset)
- } else if (Buffer.isBuffer(val)) {
- offset += buf.write(key + '=', offset)
- var len = val.length
- val.copy(buf, offset, 0, len)
- offset += len
- } else {
- offset += buf.write(key + '=' + val, offset)
- }
-
- buf[oldOffset] = offset - oldOffset - 1
- })
-
- that.encode.bytes = offset - oldOffset
- return buf
- }
-
- that.decode = function (buf, offset, len) {
- if (!offset) offset = 0
- if (!Number.isFinite(len)) len = buf.length
- var data = {}
- var oldOffset = offset
-
- while (offset < len) {
- var b = decodeBlock(buf, offset)
- var i = bindexOf(b, equalSign)
- offset += decodeBlock.bytes
-
- if (b.length === 0) continue // ignore: most likely a single zero byte
- if (i === -1) data[b.toString().toLowerCase()] = true
- else if (i === 0) continue // ignore: invalid key-length
- else {
- var key = b.slice(0, i).toString().toLowerCase()
- if (key in data) continue // ignore: overwriting not allowed
- data[key] = binary ? b.slice(i + 1) : b.slice(i + 1).toString()
- }
- }
-
- that.decode.bytes = offset - oldOffset
- return data
- }
-
- that.encodingLength = function (data) {
- if (!data) return 1 // 1 byte (single empty byte)
- var keys = Object.keys(data)
- if (keys.length === 0) return 1 // 1 byte (single empty byte)
- return keys.reduce(function (total, key) {
- var val = data[key]
- total += Buffer.byteLength(key) + 1 // +1 byte to store field length
- if (Buffer.isBuffer(val)) total += val.length + 1 // +1 byte to fit equal sign
- else if (val !== true) total += Buffer.byteLength(String(val)) + 1 // +1 byte to fit equal sign
- return total
- }, 0)
- }
-
- return that
- }
-
- function decodeBlock (buf, offset) {
- var len = buf[offset]
- var to = offset + 1 + len
- var b = buf.slice(offset + 1, to > buf.length ? buf.length : to)
- decodeBlock.bytes = len + 1
- return b
- }
|