Passed
Push — master ( b04473...f9e2c0 )
by Rafael S.
01:46
created

src/read-write.js   A

Complexity

Total Complexity 31
Complexity/F 2.82

Size

Lines of Code 189
Function Count 11

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 0
wmc 31
c 1
b 0
f 0
nc 1
mnd 6
bc 28
fnc 11
dl 0
loc 189
rs 9.8
bpm 2.5454
cpm 2.8181
noi 1

11 Functions

Rating   Name   Duplication   Size   Complexity  
A read-write.js ➔ writeBytes 0 11 2
A read-write.js ➔ makeBigEndian 0 5 2
A read-write.js ➔ getType 0 6 1
A read-write.js ➔ bytesFromBase 0 10 3
A read-write.js ➔ turnToArray 0 6 3
A read-write.js ➔ bytesToBase 0 8 2
A read-write.js ➔ toBytes 0 9 2
A read-write.js ➔ getSingleValue 0 8 2
B read-write.js ➔ formatOutput 0 18 9
A read-write.js ➔ readBytes 0 15 3
A read-write.js ➔ fromBytes 0 12 2
1
/**
2
 * from-bytes: Numbers and strings from bytes.
3
 * Copyright (c) 2017 Rafael da Silva Rocha.
4
 * https://github.com/rochars/byte-data
5
 */
6
7
const Type = require("../src/type");
8
const endianness = require("endianness");
9
10
/**
11
 * Turn a byte buffer into what the bytes represent.
12
 * @param {!Array<number>|!Array<string>|Uint8Array} buffer An array of bytes.
13
 * @param {Object} type One of the available types.
14
 * @return {!Array<number>|number|string}
15
 */
16
function fromBytes(buffer, type) {
17
    makeBigEndian(buffer, type);
18
    bytesFromBase(buffer, type.base);
19
    let values = readBytes(
20
            buffer,
21
            type
22
        );
23
    if (type.single) {
24
        values = getSingleValue(values, type);
25
    }
26
    return values;
27
}
28
29
/**
30
 * Turn numbers and strings to bytes.
31
 * @param {!Array<number>|number|string} values The data.
32
 * @param {Object} type One of the available types.
33
 * @return {!Array<number>|!Array<string>|Uint8Array} the data as a byte buffer.
34
 */
35
function toBytes(values, type) {
36
    let bytes = writeBytes(values, type);
37
    makeBigEndian(bytes, type);
38
    if (type.base != 10) {
39
        bytesToBase(bytes, type.base);
40
        formatOutput(bytes, type);
41
    }
42
    return bytes;
43
}
44
45
/**
46
 * Get the full type spec for the reading/writing.
47
 * @param {Object} atype One of the available types.
48
 * @param {number} base The base of the input.
49
 * @param {boolean} single True if its a single value, false for array.
50
 * @return {Object}
51
 */
52
function getType(atype, base, single) {
53
    let theType = Object.assign(new Type({}), atype);
54
    theType.base = base;
55
    theType.single = single;
56
    return theType;
57
}
58
59
/**
60
 * Make a single value an array in case it is not.
61
 * If the value is a string it stays a string.
62
 * @param {!Array<number>|number|string} values The value or values.
63
 * @return {!Array<number>|string}
64
 */
65
function turnToArray(values) {
66
    if (!Array.isArray(values) && typeof values != "string") {
67
        values = [values];
68
    }
69
    return values;
70
}
71
72
/**
73
 * Return the first value from the result value array.
74
 * @param {!Array<number>|string} values The values.
75
 * @param {Object} type One of the available types.
76
 * @return {number|string}
77
 */
78
function getSingleValue(values, type) {
79
    if (type.char) {
80
        values = values.slice(0, type.bits / 8);
81
    } else {
82
        values = values[0];
83
    }
84
    return values;
85
}
86
87
/**
88
 * Turn a array of bytes into an array of what the bytes should represent.
89
 * @param {!Array<number>|Uint8Array} bytes An array of bytes.
90
 * @param {Object} type The type.
91
 * @return {!Array<number>|string}
92
 */
93
function readBytes(bytes, type) {
94
    let values = [];
95
    let i = 0;
96
    let len = bytes.length - (type.offset - 1);
97
    while (i < len) {
98
        values.push(
99
                type.sign(type.reader(bytes, i, type))
100
            );
101
        i += type.offset;
102
    }
103
    if (type.char) {
104
        values = values.join("");
105
    }
106
    return values;
107
}
108
109
/**
110
 * Turn bytes to base 10.
111
 * @param {!Array<number>|Uint8Array} bytes The bytes as binary or hex strings.
112
 * @param {number} base The base.
113
 */
114
function bytesFromBase(bytes, base) {
115
    if (base != 10) {
116
        let i = 0;
117
        let len = bytes.length;
118
        while(i < len) {
119
            bytes[i] = parseInt(bytes[i], base);
120
            i++;
121
        }
122
    }
123
}
124
125
/**
126
 * Swap the endianness to big endian.
127
 * @param {!Array<number>|!Array<string>|Uint8Array} bytes The values.
128
 * @param {Object} type The type.
129
 */
130
function makeBigEndian(bytes, type) {
131
    if (type.be) {
132
        endianness(bytes, type.offset);
133
    }
134
}
135
136
/**
137
 * Turn the output to the correct base.
138
 * @param {Array} bytes The bytes.
139
 * @param {Object} type The type.
140
 */
141
function formatOutput(bytes, type) {
142
    if (type.bits > 1) {
143
        let i = 0;
144
        let len = bytes.length;
145
        let offset;
146
        while(i < len) {
147
            if (type.bits == 2) {
148
                offset = (type.base == 2 ? 2 : 2) + 1;
149
            } else  if (type.bits == 4) {
150
                offset = (type.base == 2 ? 4 : 1) + 1;
151
            } else if (type.bits >= 4) {
152
                offset = (type.base == 2 ? 8 : 2) + 1;
153
            }
154
            bytes[i] = Array(offset - bytes[i].length).join("0") + bytes[i];
0 ignored issues
show
Bug introduced by
The variable offset seems to not be initialized for all possible execution paths.
Loading history...
155
            i++;
156
        }
157
    }
158
}
159
160
/**
161
 * Turn bytes to base 2, 10 or 16.
162
 * @param {!Array<string>|!Array<number>|null} bytes The bytes.
163
 * @param {number} base The base.
164
 */
165
function bytesToBase(bytes, base) {
166
    let i = 0;
167
    let len = bytes.length;
168
    while (i < len) {
169
        bytes[i] = bytes[i].toString(base);
170
        i++;
171
    }
172
}
173
174
/**
175
 * Write values as bytes.
176
 * @param {!Array<number>|number|string} values The data.
177
 * @param {Object} type One of the available types.
178
 * @return {!Array<number>} the bytes.
179
 */
180
function writeBytes(values, type) {
181
    let i = 0;
182
    let j = 0;
183
    let len = values.length;
184
    let bytes = [];
185
    while (i < len) {
186
        j = type.writer(bytes, type.overflow(values[i]), j);
187
        i++;
188
    }
189
    return bytes;
190
}
191
192
module.exports.getType = getType;
193
module.exports.turnToArray = turnToArray;
194
module.exports.toBytes = toBytes;
195
module.exports.fromBytes = fromBytes;
196