Passed
Push — master ( 2cddad...eee927 )
by Rafael S.
01:38
created

to-bytes.js ➔ writeBytes   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 4
c 3
b 0
f 0
nc 6
nop 3
dl 0
loc 19
rs 9.2
1
/*
2
 * to-bytes: bytes to numbers and strings.
3
 * Copyright (c) 2017 Rafael da Silva Rocha.
4
 * https://github.com/rochars/byte-data
5
 */
6
7
const writer = require("../src/write-bytes.js");
8
const helpers = require("../src/helpers.js");
9
const bitDepthLib = require("../src/bit-depth.js");
10
11
/**
12
 * Turn numbers and strings to bytes.
13
 * @param {!Array<number>|number|string} values The data.
14
 * @param {number} bitDepth The bit depth of the data.
15
 *   Possible values are 1, 2, 4, 8, 16, 24, 32, 40, 48 or 64.
16
 * @param {Object} options The options:
17
 *   - "float": True for floating point numbers. Default is false.
18
 *       This option is available for 16, 32 and 64-bit numbers.
19
 *   - "signed": True for signed values. Default is false.
20
 *   - "base": The base of the output. Default is 10. Can be 2, 10 or 16.
21
 *   - "char": If the bytes represent a string. Default is false.
22
 *   - "be": If the values are big endian. Default is false (little endian).
23
 *   - "buffer": If the bytes should be returned as a Uint8Array.
24
 *       Default is false (bytes are returned as a regular array).
25
 * @return {!Array<number>|!Array<string>|Uint8Array} the data as a byte buffer.
26
 */
27
function toBytes(values, bitDepth, options={"base": 10, "signed": false}) {
28
    helpers.buildType(options, bitDepth);
29
    values = helpers.turnToArray(values);
30
    let bytes = writeBytes(values, options, bitDepth);
31
    helpers.makeBigEndian(bytes, options.be, bitDepth);
32
    helpers.outputToBase(bytes, bitDepth, options.base);
33
    helpers.fixFloat16Endianness(bytes, options);
34
    if (options.buffer) {
35
        bytes = new Uint8Array(bytes);
36
    }
37
    return bytes;
38
}
39
40
/**
41
 * Write values as bytes.
42
 * @param {!Array<number>|number|string} values The data.
43
 * @param {Object} options The options according to the type.
44
 * @param {number} bitDepth The bitDepth of the data.
45
 * @return {!Array<number>} the bytes.
46
 */
47
function writeBytes(values, options, bitDepth) {
48
    let bitWriter;
49
    if (options.char) {
50
        bitWriter = writer.writeString;
51
    } else {
52
        bitWriter = writer['write' + bitDepth + 'Bit' + (options.float ? "Float" : "")];
53
    }
54
    let i = 0;
55
    let j = 0;
56
    let len = values.length;
57
    let bytes = [];
58
    let minMax = getBitDepthMinMax(options, bitDepth);
59
    while (i < len) {
60
        checkOverflow(values, i, minMax, options);
61
        j = bitWriter(bytes, values, i, j, options.signed);
62
        i++;
63
    }
64
    return bytes;
65
}
66
67
/**
68
 * Get the minimum and maximum values accordind to the type.
69
 * @param {Object} options The options according to the type.
70
 * @param {number} bitDepth The bit depth of the data.
71
 * @return {Object}
72
 */
73
function getBitDepthMinMax(options, bitDepth) {
74
    let minMax = {};
75
    if (options.signed) {
76
        minMax.max = (bitDepthLib.BitDepthMaxValues[bitDepth] / 2) - 1;
77
        minMax.min = (bitDepthLib.BitDepthMaxValues[bitDepth] / 2) * -1;
78
    } else {
79
        minMax.max = bitDepthLib.BitDepthMaxValues[bitDepth] - 1;
80
        minMax.min = 0;
81
    }
82
    return minMax;
83
}
84
85
/**
86
 * Limit the value according to the bit depth in case of
87
 * overflow or underflow.
88
 * @param {!Array<number>|number|string} values The data.
89
 * @param {number} index The index of the value in the array.
90
 * @param {Object} minMax The minimum value.
91
 * @param {Object} options The maximum value.
92
 */
93
function checkOverflow(values, index, minMax, options) {
94
    if (!options.float) {
95
        if (values[index] > minMax.max) {
96
            values[index] = minMax.max;
97
        } else if(values[index] < minMax.min) {
98
            values[index] = minMax.min;
99
        }
100
    }
101
}
102
103
module.exports.toBytes = toBytes;
104