| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 | '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}
 |