You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					95 lines
				
				2.5 KiB
			
		
		
			
		
	
	
					95 lines
				
				2.5 KiB
			| 
								 
											4 years ago
										 
									 | 
							
								'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
							 | 
						||
| 
								 | 
							
								}
							 |