Passed
Push — master ( 17b1a9...6a1a74 )
by Rafael S.
01:24
created

src/from-bytes.js   B

Complexity

Total Complexity 41
Complexity/F 1.86

Size

Lines of Code 323
Function Count 22

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
cc 0
nc 1
dl 0
loc 323
rs 8.2769
c 5
b 0
f 0
wmc 41
mnd 2
bc 42
fnc 22
bpm 1.909
cpm 1.8636
noi 1

22 Functions

Rating   Name   Duplication   Size   Complexity  
A from-bytes.js ➔ uIntFrom1Byte 0 3 1
A from-bytes.js ➔ intFromNibble 0 3 1
A from-bytes.js ➔ intFromCrumb 0 3 1
A from-bytes.js ➔ intFrom1Byte 0 3 1
A from-bytes.js ➔ fromBoolean 0 3 1
B from-bytes.js ➔ fromBytes 0 23 4
A from-bytes.js ➔ signed 0 6 2
A from-bytes.js ➔ bytesToInt 0 10 3
A from-bytes.js ➔ intFrom4Bytes 0 6 2
A from-bytes.js ➔ stringFromBytes 0 3 1
A from-bytes.js ➔ uIntFrom3Bytes 0 6 2
A from-bytes.js ➔ uIntFrom2Bytes 0 6 2
A from-bytes.js ➔ intFrom3Bytes 0 6 2
A from-bytes.js ➔ intFrom6Bytes 0 6 2
A from-bytes.js ➔ floatFrom4Bytes 0 6 2
A from-bytes.js ➔ uIntFrom6Bytes 0 6 2
A from-bytes.js ➔ uIntFrom5Bytes 0 6 2
A from-bytes.js ➔ uIntFrom4Bytes 0 6 2
A from-bytes.js ➔ intFrom2Bytes 0 6 2
A from-bytes.js ➔ floatFrom2Bytes 0 6 2
A from-bytes.js ➔ floatFrom8Bytes 0 6 2
A from-bytes.js ➔ intFrom5Bytes 0 6 2

How to fix   Complexity   

Complexity

Complex classes like src/from-bytes.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
/*
2
 * from-bytes: convert bytes to numbers and strings.
3
 * Copyright (c) 2017 Rafael da Silva Rocha.
4
 * https://github.com/rochars/byte-data
5
 */
6
7
const pad = require("../src/byte-padding.js");
0 ignored issues
show
Unused Code introduced by
The constant pad seems to be never used. Consider removing it.
Loading history...
8
const endianness = require("endianness");
9
const reader = require("../src/read-bytes.js");
10
const bitDepths = require("../src/bit-depth.js");
11
12
/**
13
 * Turn a array of bytes into an array of what the bytes should represent.
14
 * @param {!Array<number>|Uint8Array} bytes An array of bytes.
15
 * @param {number} base The base. 2, 10 or 16.
16
 * @param {Function} reader The function to read the bytes.
17
 * @param {number} bitDepth The bitDepth. 1, 2, 4, 8, 16, 24, 32, 40, 48, 64.
18
 * @param {boolean} isSigned If readed numbers should be signed or not.
19
 * @return {!Array<number>} The values represented in the bytes.
20
 */
21
function fromBytes(bytes, base, reader, bitDepth, isSigned=false) {
22
    let numbers = [];
23
    let i = 0;
24
    let j = 0;
25
    let offset = bitDepths.bitDepthOffsets[bitDepth];
26
    let len = bytes.length - (offset -1);
27
    let maxBitDepthValue = bitDepths.maxBitDepth[bitDepth];
28
    bytesToInt(bytes, base);   
29
    if (isSigned) {
30
        while (i < len) {
31
            numbers[j] = signed(reader(bytes, i), maxBitDepthValue);
32
            i += offset;
33
            j++;
34
        }    
35
    } else {
36
        while (i < len) {
37
            numbers[j] = reader(bytes, i);
38
            i += offset;
39
            j++;
40
        }    
41
    }
42
    return numbers;
43
}
44
45
/**
46
 * Turn bytes to base 10.
47
 * @param {!Array<number>|Uint8Array} bytes The bytes as binary or hex strings.
48
 * @param {number} base The base.
49
 */
50
function bytesToInt(bytes, base) {
51
    if (base != 10) {
52
        let i = 0;
53
        let len = bytes.length;
54
        while(i < len) {
55
            bytes[i] = parseInt(bytes[i], base);
56
            i++;
57
        }
58
    }
59
}
60
61
/**
62
 * Turn a unsigned number to a signed number.
63
 * @param {number} number The number.
64
 * @param {number} maxValue The max range for the number bit depth.
65
 */
66
function signed(number, maxValue) {
67
    if (number > parseInt(maxValue / 2, 10) - 1) {
68
        number -= maxValue;
69
    }
70
    return number;
71
}
72
73
/**
74
 * Read numbers from a array of booleans.
75
 * @param {!Array<number>|Uint8Array} booleans An array of booleans.
76
 * @param {number} base The base. Defaults to 10.
77
 * @return {!Array<number>} The numbers.
78
 */
79
function fromBoolean(booleans, base=10) {
80
    return fromBytes(booleans, base, reader.read1Bit, 1);
81
}
82
83
/**
84
 * Read 2-bit signed ints from an array of crumbs.
85
 * @param {!Array<number>|Uint8Array} bytes An array of crumbs.
86
 * @param {number} base The base. Defaults to 10.
87
 * @return {!Array<number>} The numbers.
88
 */
89
function intFromCrumb(bytes, base=10) {
90
    return fromBytes(bytes, base, reader.read8Bit, 2, true);
91
}
92
93
/**
94
 * Read 4-bit signed ints from an array of nibbles.
95
 * @param {!Array<number>|Uint8Array} bytes An array of nibbles.
96
 * @param {number} base The base. Defaults to 10.
97
 * @return {!Array<number>} The numbers.
98
 */
99
function intFromNibble(bytes, base=10) {
100
    return fromBytes(bytes, base, reader.read8Bit, 4, true);
101
}
102
103
/**
104
 * Read 8-bit unsigned ints from an array of bytes.
105
 * Just return a copy of the original array.
106
 * @param {!Array<number>|Uint8Array} bytes An array of bytes.
107
 * @param {number} base The base. Defaults to 10.
108
 * @return {!Array<number>} The numbers.
109
 */
110
function uIntFrom1Byte(bytes, base=10) {
111
    return fromBytes(bytes, base, reader.read8Bit, 8);
112
}
113
114
/**
115
 * Read 8-bit signed ints from an array of bytes.
116
 * @param {!Array<number>|Uint8Array} bytes An array of bytes.
117
 * @param {number} base The base. Defaults to 10.
118
 * @return {!Array<number>} The numbers.
119
 */
120
function intFrom1Byte(bytes, base=10) {
121
    return fromBytes(bytes, base, reader.read8Bit, 8, true);
122
}
123
124
/**
125
 * Read 16-bit unsigned ints from an array of bytes.
126
 * @param {!Array<number>|Uint8Array} bytes An array of bytes.
127
 * @param {number} base The base. Defaults to 10.
128
 * @param {boolean} bigEndian If the bytes are big endian. Defaults to false.
129
 * @return {!Array<number>} The numbers.
130
 */
131
function uIntFrom2Bytes(bytes, base=10, bigEndian=false) {
132
    if (bigEndian) {
133
        endianness.endianness(bytes, 2);
134
    }
135
    return fromBytes(bytes, base, reader.read16Bit, 16);
136
}
137
138
/**
139
 * Read 16-bit signed ints from an array of bytes.
140
 * Thanks https://stackoverflow.com/a/38298413
141
 * @param {!Array<number>|Uint8Array} bytes An array of bytes.
142
 * @param {number} base The base. Defaults to 10.
143
 * @param {boolean} bigEndian If the bytes are big endian. Defaults to false.
144
 * @return {!Array<number>} The numbers.
145
 */
146
function intFrom2Bytes(bytes, base=10, bigEndian=false) {
147
    if (bigEndian) {
148
        endianness.endianness(bytes, 2);
149
    }
150
    return fromBytes(bytes, base, reader.read16Bit, 16, true);
151
}
152
153
function floatFrom2Bytes(bytes, base=10, bigEndian=false) {
154
    if (bigEndian) {
155
        endianness.endianness(bytes, 2);
156
    }
157
    return fromBytes(bytes, base, reader.read16BitFloat, 16);
158
}
159
160
/**
161
 * Read 24-bit unsigned ints from an array of bytes.
162
 * @param {!Array<number>|Uint8Array} bytes An array of bytes.
163
 * @param {number} base The base. Defaults to 10.
164
 * @param {boolean} bigEndian If the bytes are big endian. Defaults to false.
165
 * @return {!Array<number>} The numbers.
166
 */
167
function uIntFrom3Bytes(bytes, base=10, bigEndian=false) {
168
    if (bigEndian) {
169
        endianness.endianness(bytes, 3);
170
    }
171
    return fromBytes(bytes, base, reader.read24Bit, 24);
172
}
173
174
/**
175
 * Read 24-bit signed ints from an array of bytes.
176
 * @param {!Array<number>|Uint8Array} bytes An array of bytes.
177
 * @param {number} base The base. Defaults to 10.
178
 * @param {boolean} bigEndian If the bytes are big endian. Defaults to false.
179
 * @return {!Array<number>} The numbers.
180
 */
181
function intFrom3Bytes(bytes, base=10, bigEndian=false) {
182
    if (bigEndian) {
183
        endianness.endianness(bytes, 3);
184
    }
185
    return fromBytes(bytes, base, reader.read24Bit, 24, true);
186
}
187
188
/**
189
 * Read 32-bit unsigned ints from an array of bytes.
190
 * @param {!Array<number>|Uint8Array} bytes An array of bytes.
191
 * @param {number} base The base. Defaults to 10.
192
 * @param {boolean} bigEndian If the bytes are big endian. Defaults to false.
193
 * @return {!Array<number>} The numbers.
194
 */
195
function uIntFrom4Bytes(bytes, base=10, bigEndian=false) {
196
    if (bigEndian) {
197
        endianness.endianness(bytes, 4);
198
    }
199
    return fromBytes(bytes, base, reader.read32Bit, 32);
200
}
201
202
/**
203
 * Read 32-bit signed ints from an array of bytes.
204
 * @param {!Array<number>|Uint8Array} bytes An array of bytes.
205
 * @param {number} base The base. Defaults to 10.
206
 * @param {boolean} bigEndian If the bytes are big endian. Defaults to false.
207
 * @return {!Array<number>} The numbers.
208
 */
209
function intFrom4Bytes(bytes, base=10, bigEndian=false) {
210
    if (bigEndian) {
211
        endianness.endianness(bytes, 4);
212
    }
213
    return fromBytes(bytes, base, reader.read32Bit, 32, true);
214
}
215
216
/**
217
 * Read 32-bit float numbers from an array of bytes.
218
 * @param {!Array<number>|Uint8Array} bytes An array of bytes.
219
 * @param {number} base The base. Defaults to 10.
220
 * @param {boolean} bigEndian If the bytes are big endian. Defaults to false.
221
 * @return {!Array<number>} The numbers.
222
 */
223
function floatFrom4Bytes(bytes, base=10, bigEndian=false) {
224
    if (bigEndian) {
225
        endianness.endianness(bytes, 4);
226
    }
227
    return fromBytes(bytes, base, reader.read32BitFloat, 32);
228
}
229
230
/**
231
 * Read 40-bit unsigned ints from an array of bytes.
232
 * @param {!Array<number>|Uint8Array} bytes An array of bytes.
233
 * @param {number} base The base. Defaults to 10.
234
 * @param {boolean} bigEndian If the bytes are big endian. Defaults to false.
235
 * @return {!Array<number>} The numbers.
236
 */
237
function uIntFrom5Bytes(bytes, base=10, bigEndian=false) {
238
    if (bigEndian) {
239
        endianness.endianness(bytes, 5);
240
    }
241
    return fromBytes(bytes, base, reader.read40Bit, 40);
242
}
243
244
/**
245
 * Read 40-bit unsigned ints from an array of bytes.
246
 * @param {!Array<number>|Uint8Array} bytes An array of bytes.
247
 * @param {number} base The base. Defaults to 10.
248
 * @param {boolean} bigEndian If the bytes are big endian. Defaults to false.
249
 * @return {!Array<number>} The numbers.
250
 */
251
function intFrom5Bytes(bytes, base=10, bigEndian=false) {
252
    if (bigEndian) {
253
        endianness.endianness(bytes, 5);
254
    }
255
    return fromBytes(bytes, base, reader.read40Bit, 40, true);
256
}
257
258
/**
259
 * Read 48-bit unsigned ints from an array of bytes.
260
 * @param {!Array<number>|Uint8Array} bytes An array of bytes.
261
 * @param {number} base The base. Defaults to 10.
262
 * @param {boolean} bigEndian If the bytes are big endian. Defaults to false.
263
 * @return {!Array<number>} The numbers.
264
 */
265
function uIntFrom6Bytes(bytes, base=10, bigEndian=false) {
266
    if (bigEndian) {
267
        endianness.endianness(bytes, 6);
268
    }
269
    return fromBytes(bytes, base, reader.read48Bit, 48);
270
}
271
272
/**
273
 * Read 48-bit unsigned ints from an array of bytes.
274
 * @param {!Array<number>|Uint8Array} bytes An array of bytes.
275
 * @param {number} base The base. Defaults to 10.
276
 * @param {boolean} bigEndian If the bytes are big endian. Defaults to false.
277
 * @return {!Array<number>} The numbers.
278
 */
279
function intFrom6Bytes(bytes, base=10, bigEndian=false) {
280
    if (bigEndian) {
281
        endianness.endianness(bytes, 6);
282
    }
283
    return fromBytes(bytes, base, reader.read48Bit, 48, true);
284
}
285
286
/**
287
 * Read 64-bit double precision numbers from an array of bytes.
288
 * @param {!Array<number>|Uint8Array} bytes An array of bytes.
289
 * @param {number} base The base. Defaults to 10.
290
 * @param {boolean} bigEndian If the bytes are big endian. Defaults to false.
291
 * @return {!Array<number>} The numbers.
292
 */
293
function floatFrom8Bytes(bytes, base=10, bigEndian=false) {
294
    if (bigEndian) {
295
        endianness.endianness(bytes, 8);
296
    }
297
    return fromBytes(bytes, base, reader.read64Bit, 64);
298
}
299
300
/**
301
 * Convert an array of bytes to a string.
302
 * @param {!Array<number>|Uint8Array} bytes An array of bytes.
303
 * @return {string} The string.
304
 */
305
function stringFromBytes(bytes, base=10) {
306
    return fromBytes(bytes, base, reader.readChar, 8).join("");
307
}
308
309
module.exports.fromBoolean = fromBoolean;
310
module.exports.intFromCrumb = intFromCrumb;
311
module.exports.uIntFromCrumb = uIntFrom1Byte;
312
module.exports.intFromNibble = intFromNibble;
313
module.exports.uIntFromNibble = uIntFrom1Byte;
314
module.exports.intFrom1Byte = intFrom1Byte;
315
module.exports.uIntFrom1Byte = uIntFrom1Byte;
316
module.exports.intFrom2Bytes = intFrom2Bytes;
317
module.exports.uIntFrom2Bytes = uIntFrom2Bytes;
318
module.exports.floatFrom2Bytes = floatFrom2Bytes;
319
module.exports.intFrom3Bytes = intFrom3Bytes;
320
module.exports.uIntFrom3Bytes = uIntFrom3Bytes;
321
module.exports.intFrom4Bytes = intFrom4Bytes;
322
module.exports.uIntFrom4Bytes = uIntFrom4Bytes;
323
module.exports.floatFrom4Bytes = floatFrom4Bytes;
324
module.exports.intFrom5Bytes = intFrom5Bytes;
325
module.exports.uIntFrom5Bytes = uIntFrom5Bytes;
326
module.exports.intFrom6Bytes = intFrom6Bytes;
327
module.exports.uIntFrom6Bytes = uIntFrom6Bytes;
328
module.exports.floatFrom8Bytes = floatFrom8Bytes;
329
module.exports.stringFromBytes = stringFromBytes;
330