Projekt

Obecné

Profil

Stáhnout (2.54 KB) Statistiky
| Větev: | Revize:
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
}
(5-5/7)