Passed
Push — master ( 61bf3b...6af248 )
by Rafael S.
01:31
created

index.js (1 issue)

Labels
Severity
1
/*!
2
 * byte-data
3
 * Readable data to and from byte buffers.
4
 * Copyright (c) 2017 Rafael da Silva Rocha.
5
 * https://github.com/rochars/byte-data
6
 *
7
 */
8
9
/** @private */
10
const rw = require("./src/read-write");
11
let Type = require("./src/type");
12
13
/**
14
 * Turn a number or fixed-length string into a byte buffer.
15
 * @param {number|string} value The value.
16
 * @param {Object} type One of the available types.
17
 * @param {number} base The base of the output. Optional. Default is 10.
18
 *      Possible values are 2, 10 or 16.
19
 * @return {!Array<number>|!Array<string>}
20
 */
21
function pack(value, type, base=10) {
22
    let values;
23
    if (type.char) {
24
        values = type.char ? value.slice(0, type.realBits / 8) : value;
25
    } else if (!Array.isArray(value)) {
26
        values = [value];
27
    }
28
    return rw.toBytes(values, rw.getType(type, base));
0 ignored issues
show
The variable values does not seem to be initialized in case !Array.isArray(value) on line 25 is false. Are you sure the function toBytes handles undefined variables?
Loading history...
29
}
30
31
/**
32
 * Turn a byte buffer into a number or a fixed-length string.
33
 * @param {!Array<number>|!Array<string>|Uint8Array} buffer An array of bytes.
34
 * @param {Object} type One of the available types.
35
 * @param {number} base The base of the input. Optional. Default is 10.
36
 *      Possible values are 2, 10 or 16.
37
 * @return {number|string}
38
 */
39
function unpack(buffer, type, base=10) {
40
    let offset = type.bits < 8 ? type.bits : type.realBits / 8;
41
    let values = rw.fromBytes(
42
            buffer.slice(0, offset),
43
            rw.getType(type, base)
44
        );
45
    if (type.char) {
46
        values = values.slice(0, type.bits / 8);
47
    } else {
48
        values = values[0];
49
    }
50
    return values;
51
}
52
53
/**
54
 * Turn a array of numbers or a string into a byte buffer.
55
 * @param {!Array<number>|string} values The values.
56
 * @param {Object} type One of the available types.
57
 * @param {number} base The base of the output. Optional. Default is 10.
58
 *      Possible values are 2, 10 or 16.
59
 * @return {!Array<number>|!Array<string>}
60
 */
61
function packArray(values, type, base=10) {
62
    return rw.toBytes(values, rw.getType(type, base));
63
}
64
65
/**
66
 * Turn a byte buffer into a array of numbers or a string.
67
 * @param {!Array<number>|!Array<string>|Uint8Array} buffer The byte array.
68
 * @param {Object} type One of the available types.
69
 * @param {number} base The base of the input. Optional. Default is 10.
70
 *      Possible values are 2, 10 or 16.
71
 * @return {!Array<number>|string}
72
 */
73
function unpackArray(buffer, type, base=10) {
74
    return rw.fromBytes(buffer, rw.getType(type, base));
75
}
76
77
/**
78
 * Find and return the start index of some string.
79
 * Return -1 if the string is not found.
80
 * @param {!Array<number>|Uint8Array} buffer A byte buffer.
81
 * @param {string} text Some string to look for.
82
 * @return {number} The start index of the first occurrence, -1 if not found
83
 */
84
function findString(buffer, text) {
85
    let found = "";
86
    for (let i = 0; i < buffer.length; i++) {
87
        found = unpack(
88
                buffer.slice(i, i + text.length + 1),
89
                new Type({"bits": text.length * 8, "char": true})
90
            );
91
        if (found == text) {
92
            return i;
93
        }
94
    }
95
    return -1;
96
}
97
98
/**
99
 * Turn a struct into a byte buffer.
100
 * A struct is an array of values of not necessarily the same type.
101
 * @param {Array<number|string>} struct The struct values.
102
 * @param {!Array<Object>} def The struct type definition.
103
 * @param {number} base The base of the output. Optional. Default is 10.
104
 *      Possible values are 2, 10 or 16.
105
 * @return {!Array<number>|!Array<string>}
106
 */
107
function packStruct(struct, def, base=10) {
108
    if (struct.length < def.length) {
109
        return [];
110
    }
111
    let bytes = [];
112
    for (let i = 0; i < def.length; i++) {
113
        bytes = bytes.concat(pack(struct[i], def[i], base));
114
    }
115
    return bytes;
116
}
117
118
/**
119
 * Turn a byte buffer into a struct.
120
 * A struct is an array of values of not necessarily the same type.
121
 * @param {!Array<number>|!Array<string>|Uint8Array} buffer The byte buffer.
122
 * @param {!Array<Object>} def The struct type definition.
123
 * @param {number} base The base of the input. Optional. Default is 10.
124
 *      Possible values are 2, 10 or 16.
125
 * @return {Array<number|string>}
126
 */
127
function unpackStruct(buffer, def, base=10) {
128
    if (buffer.length < getStructDefSize(def)) {
129
        return [];
130
    }
131
    let struct = [];
132
    let i = 0;
133
    let j = 0;
134
    while (i < def.length) {
135
        let bits = def[i].bits < 8 ? 1 : def[i].realBits / 8;
136
        struct = struct.concat(
137
                unpack(buffer.slice(j, j + bits), def[i], base)
138
            );
139
        j += bits;
140
        i++;
141
    }
142
    return struct;
143
}
144
145
/**
146
 * Get the length in bytes of a struct definition.
147
 * @param {!Array<Object>} def The struct type definition.
148
 * @return {number} The length of the structure in bytes.
149
 * @private
150
 */
151
function getStructDefSize(def) {
152
    let bits = 0;
153
    for (let i = 0; i < def.length; i++) {
154
        bits += def[i].realBits / 8;
155
    }
156
    return bits;
157
}
158
159
// interface
160
exports.pack = pack;
161
exports.unpack = unpack;
162
exports.packArray = packArray;
163
exports.unpackArray = unpackArray;
164
exports.unpackStruct = unpackStruct;
165
exports.packStruct = packStruct;
166
exports.findString = findString;
167
exports.Type = Type;
168
169
// types
170
/** 
171
 * A char.
172
 * @type {!Type}
173
 */
174
exports.chr = new Type({"bits": 8, "char": true});
175
/**
176
 * A 4-char string
177
 * @type {!Type}
178
 */
179
exports.fourCC = new Type({"bits": 32, "char": true});
180
/**
181
 * Booleans
182
 * @type {!Type}
183
 */
184
exports.bool = new Type({"bits": 1});
185
/**
186
 * Signed 2-bit integers
187
 * @type {!Type}
188
 */
189
exports.int2 = new Type({"bits": 2, "signed": true});
190
/**
191
 * Unsigned 2-bit integers
192
 * @type {!Type}
193
 */
194
exports.uInt2 = new Type({"bits": 2});
195
/**
196
 * Signed 4-bit integers
197
 * @type {!Type}
198
 */
199
exports.int4 = new Type({"bits": 4, "signed": true});
200
/**
201
 * Unsigned 4-bit integers
202
 * @type {!Type}
203
 */
204
exports.uInt4 = new Type({"bits": 4});
205
/**
206
 * Signed 8-bit integers
207
 * @type {!Type}
208
 */
209
exports.int8 = new Type({"bits": 8, "signed": true});
210
/**
211
 * Unsigned 4-bit integers
212
 * @type {!Type}
213
 */
214
exports.uInt8 = new Type({"bits": 8});
215
// LE
216
/**
217
 * Signed 16-bit integers little-endian
218
 * @type {!Type}
219
 */
220
exports.int16  = new Type({"bits": 16, "signed": true});
221
/**
222
 * Unsigned 16-bit integers little-endian
223
 * @type {!Type}
224
 */
225
exports.uInt16 = new Type({"bits": 16});
226
/**
227
 * Half-precision floating-point numbers little-endian
228
 * @type {!Type}
229
 */
230
exports.float16 = new Type({"bits": 16, "float": true});
231
/**
232
 * Signed 24-bit integers little-endian
233
 * @type {!Type}
234
 */
235
exports.int24 = new Type({"bits": 24, "signed": true});
236
/**
237
 * Unsigned 24-bit integers little-endian
238
 * @type {!Type}
239
 */
240
exports.uInt24 = new Type({"bits": 24});
241
/**
242
 * Signed 32-bit integers little-endian
243
 * @type {!Type}
244
 */
245
exports.int32 = new Type({"bits": 32, "signed": true});
246
/**
247
 * Unsigned 32-bit integers little-endian
248
 * @type {!Type}
249
 */
250
exports.uInt32 = new Type({"bits": 32});
251
/**
252
 * Single-precision floating-point numbers little-endian
253
 * @type {!Type}
254
 */
255
exports.float32 = new Type({"bits": 32, "float": true});
256
/**
257
 * Signed 40-bit integers little-endian
258
 * @type {!Type}
259
 */
260
exports.int40 = new Type({"bits": 40, "signed": true});
261
/**
262
 * Unsigned 40-bit integers little-endian
263
 * @type {!Type}
264
 */
265
exports.uInt40 = new Type({"bits": 40});
266
/**
267
 * Signed 48-bit integers little-endian
268
 * @type {!Type}
269
 */
270
exports.int48 = new Type({"bits": 48, "signed": true});
271
/**
272
 * Unsigned 48-bit integers little-endian
273
 * @type {!Type}
274
 */
275
exports.uInt48 = new Type({"bits": 48});
276
/**
277
 * Double-precision floating-point numbers little-endian
278
 * @type {!Type}
279
 */
280
exports.float64 = new Type({"bits": 64, "float": true});
281
// BE
282
/**
283
 * Signed 16-bit integers big-endian
284
 * @type {!Type}
285
 */
286
exports.int16BE  = new Type({"bits": 16, "signed": true, "be": true});
287
/**
288
 * Unsigned 16-bit integers big-endian
289
 * @type {!Type}
290
 */
291
exports.uInt16BE = new Type({"bits": 16, "be": true});
292
/**
293
 * Half-precision floating-point numbers big-endian
294
 * @type {!Type}
295
 */
296
exports.float16BE = new Type({"bits": 16, "float": true, "be": true});
297
/**
298
 * Signed 24-bit integers big-endian
299
 * @type {!Type}
300
 */
301
exports.int24BE = new Type({"bits": 24, "signed": true, "be": true});
302
/**
303
 * Unsigned 24-bit integers big-endian
304
 * @type {!Type}
305
 */
306
exports.uInt24BE = new Type({"bits": 24, "be": true});
307
/**
308
 * Signed 32-bit integers big-endian
309
 * @type {!Type}
310
 */
311
exports.int32BE = new Type({"bits": 32, "signed": true, "be": true});
312
/**
313
 * Unsigned 32-bit integers big-endian
314
 * @type {!Type}
315
 */
316
exports.uInt32BE = new Type({"bits": 32, "be": true});
317
/**
318
 * Single-precision floating-point numbers big-endian
319
 * @type {!Type}
320
 */
321
exports.float32BE = new Type({"bits": 32, "float": true, "be": true});
322
/**
323
 * Signed 40-bit integers big-endian
324
 * @type {!Type}
325
 */
326
exports.int40BE = new Type({"bits": 40, "signed": true, "be": true});
327
/**
328
 * Unsigned 40-bit integers big-endian
329
 * @type {!Type}
330
 */
331
exports.uInt40BE = new Type({"bits": 40, "be": true});
332
/**
333
 * Signed 48-bit integers big-endian
334
 * @type {!Type}
335
 */
336
exports.int48BE = new Type({"bits": 48, "signed": true, "be": true});
337
/**
338
 * Unsigned 48-bit integers big-endian
339
 * @type {!Type}
340
 */
341
exports.uInt48BE = new Type({"bits": 48, "be": true});
342
/**
343
 * Double-precision floating-point numbers big-endian
344
 * @type {!Type}
345
 */
346
exports.float64BE = new Type({"bits": 64, "float": true, "be": true});
347