/
buffer.js
132 lines (118 loc) · 3.05 KB
/
buffer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/**
* Utility functions to work with buffers (Uint8Array).
*
* @module buffer
*/
import * as string from './string.js'
import * as env from './environment.js'
import * as encoding from './encoding.js'
import * as decoding from './decoding.js'
/**
* @param {number} len
*/
export const createUint8ArrayFromLen = len => new Uint8Array(len)
/**
* Create Uint8Array with initial content from buffer
*
* @param {ArrayBuffer} buffer
* @param {number} byteOffset
* @param {number} length
*/
export const createUint8ArrayViewFromArrayBuffer = (buffer, byteOffset, length) => new Uint8Array(buffer, byteOffset, length)
/**
* Create Uint8Array with initial content from buffer
*
* @param {ArrayBuffer} buffer
*/
export const createUint8ArrayFromArrayBuffer = buffer => new Uint8Array(buffer)
/* c8 ignore start */
/**
* @param {Uint8Array} bytes
* @return {string}
*/
const toBase64Browser = bytes => {
let s = ''
for (let i = 0; i < bytes.byteLength; i++) {
s += string.fromCharCode(bytes[i])
}
// eslint-disable-next-line no-undef
return btoa(s)
}
/* c8 ignore stop */
/**
* @param {Uint8Array} bytes
* @return {string}
*/
const toBase64Node = bytes => Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString('base64')
/* c8 ignore start */
/**
* @param {string} s
* @return {Uint8Array}
*/
const fromBase64Browser = s => {
// eslint-disable-next-line no-undef
const a = atob(s)
const bytes = createUint8ArrayFromLen(a.length)
for (let i = 0; i < a.length; i++) {
bytes[i] = a.charCodeAt(i)
}
return bytes
}
/* c8 ignore stop */
/**
* @param {string} s
*/
const fromBase64Node = s => {
const buf = Buffer.from(s, 'base64')
return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength)
}
/* c8 ignore next */
export const toBase64 = env.isBrowser ? toBase64Browser : toBase64Node
/* c8 ignore next */
export const fromBase64 = env.isBrowser ? fromBase64Browser : fromBase64Node
/**
* Copy the content of an Uint8Array view to a new ArrayBuffer.
*
* @param {Uint8Array} uint8Array
* @return {Uint8Array}
*/
export const copyUint8Array = uint8Array => {
const newBuf = createUint8ArrayFromLen(uint8Array.byteLength)
newBuf.set(uint8Array)
return newBuf
}
/**
* Encode anything as a UInt8Array. It's a pun on typescripts's `any` type.
* See encoding.writeAny for more information.
*
* @param {any} data
* @return {Uint8Array}
*/
export const encodeAny = data => {
const encoder = encoding.createEncoder()
encoding.writeAny(encoder, data)
return encoding.toUint8Array(encoder)
}
/**
* Decode an any-encoded value.
*
* @param {Uint8Array} buf
* @return {any}
*/
export const decodeAny = buf => decoding.readAny(decoding.createDecoder(buf))
/**
* Shift Byte Array {N} bits to the left. Does not expand byte array.
*
* @param {Uint8Array} bs
* @param {number} N should be in the range of [0-7]
*/
export const shiftNBitsLeft = (bs, N) => {
if (N === 0) return bs
bs = new Uint8Array(bs)
bs[0] <<= N
for (let i = 1; i < bs.length; i++) {
bs[i - 1] |= bs[i] >>> (8 - N)
bs[i] <<= N
}
return bs
}