Projekt

Obecné

Profil

Stáhnout (3.25 KB) Statistiky
| Větev: | Revize:
1 3a515b92 cagy
'use strict';
2
3
const { EMPTY_BUFFER } = require('./constants');
4
5
/**
6
 * Merges an array of buffers into a new buffer.
7
 *
8
 * @param {Buffer[]} list The array of buffers to concat
9
 * @param {Number} totalLength The total length of buffers in the list
10
 * @return {Buffer} The resulting buffer
11
 * @public
12
 */
13
function concat(list, totalLength) {
14
  if (list.length === 0) return EMPTY_BUFFER;
15
  if (list.length === 1) return list[0];
16
17
  const target = Buffer.allocUnsafe(totalLength);
18
  var offset = 0;
19
20
  for (var i = 0; i < list.length; i++) {
21
    const buf = list[i];
22
    buf.copy(target, offset);
23
    offset += buf.length;
24
  }
25
26
  return target;
27
}
28
29
/**
30
 * Masks a buffer using the given mask.
31
 *
32
 * @param {Buffer} source The buffer to mask
33
 * @param {Buffer} mask The mask to use
34
 * @param {Buffer} output The buffer where to store the result
35
 * @param {Number} offset The offset at which to start writing
36
 * @param {Number} length The number of bytes to mask.
37
 * @public
38
 */
39
function _mask(source, mask, output, offset, length) {
40
  for (var i = 0; i < length; i++) {
41
    output[offset + i] = source[i] ^ mask[i & 3];
42
  }
43
}
44
45
/**
46
 * Unmasks a buffer using the given mask.
47
 *
48
 * @param {Buffer} buffer The buffer to unmask
49
 * @param {Buffer} mask The mask to use
50
 * @public
51
 */
52
function _unmask(buffer, mask) {
53
  // Required until https://github.com/nodejs/node/issues/9006 is resolved.
54
  const length = buffer.length;
55
  for (var i = 0; i < length; i++) {
56
    buffer[i] ^= mask[i & 3];
57
  }
58
}
59
60
/**
61
 * Converts a buffer to an `ArrayBuffer`.
62
 *
63
 * @param {Buffer} buf The buffer to convert
64
 * @return {ArrayBuffer} Converted buffer
65
 * @public
66
 */
67
function toArrayBuffer(buf) {
68
  if (buf.byteLength === buf.buffer.byteLength) {
69
    return buf.buffer;
70
  }
71
72
  return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
73
}
74
75
/**
76
 * Converts `data` to a `Buffer`.
77
 *
78
 * @param {*} data The data to convert
79
 * @return {Buffer} The buffer
80
 * @throws {TypeError}
81
 * @public
82
 */
83
function toBuffer(data) {
84
  toBuffer.readOnly = true;
85
86
  if (Buffer.isBuffer(data)) return data;
87
88
  var buf;
89
90
  if (data instanceof ArrayBuffer) {
91
    buf = Buffer.from(data);
92
  } else if (ArrayBuffer.isView(data)) {
93
    buf = viewToBuffer(data);
94
  } else {
95
    buf = Buffer.from(data);
96
    toBuffer.readOnly = false;
97
  }
98
99
  return buf;
100
}
101
102
/**
103
 * Converts an `ArrayBuffer` view into a buffer.
104
 *
105
 * @param {(DataView|TypedArray)} view The view to convert
106
 * @return {Buffer} Converted view
107
 * @private
108
 */
109
function viewToBuffer(view) {
110
  const buf = Buffer.from(view.buffer);
111
112
  if (view.byteLength !== view.buffer.byteLength) {
113
    return buf.slice(view.byteOffset, view.byteOffset + view.byteLength);
114
  }
115
116
  return buf;
117
}
118
119
try {
120
  const bufferUtil = require('bufferutil');
121
  const bu = bufferUtil.BufferUtil || bufferUtil;
122
123
  module.exports = {
124
    concat,
125
    mask(source, mask, output, offset, length) {
126
      if (length < 48) _mask(source, mask, output, offset, length);
127
      else bu.mask(source, mask, output, offset, length);
128
    },
129
    toArrayBuffer,
130
    toBuffer,
131
    unmask(buffer, mask) {
132
      if (buffer.length < 32) _unmask(buffer, mask);
133
      else bu.unmask(buffer, mask);
134
    }
135
  };
136
} catch (e) /* istanbul ignore next */ {
137
  module.exports = {
138
    concat,
139
    mask: _mask,
140
    toArrayBuffer,
141
    toBuffer,
142
    unmask: _unmask
143
  };
144
}