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

index.js ➔ getStructDefSize   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
c 0
b 0
f 0
nc 2
dl 0
loc 7
rs 9.4285
nop 1
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
12
/** @private */
13
let Type = require("./src/type");
14
15
/**
16
 * Turn a number or fixed-length string into a byte buffer.
17
 * @param {number|string} value The value.
18
 * @param {Object} type One of the available types.
19
 * @param {number} base The base of the output. Optional. Default is 10.
20
 *      Possible values are 2, 10 or 16.
21
 * @return {!Array<number>|!Array<string>}
22
 */
23
function pack(value, type, base=10) {
24
    let theType = rw.getType(type, base, true);
25
    value = theType.char ? value.slice(0, type.bits / 8) : value;
26
    return rw.toBytes(rw.turnToArray(value), theType);
27
}
28
29
/**
30
 * Turn a byte buffer into a number or a fixed-length string.
31
 * @param {!Array<number>|!Array<string>|Uint8Array} buffer An array of bytes.
32
 * @param {Object} type One of the available types.
33
 * @param {number} base The base of the input. Optional. Default is 10.
34
 *      Possible values are 2, 10 or 16.
35
 * @return {number|string}
36
 */
37
function unpack(buffer, type, base=10) {
38
    return rw.fromBytes(buffer, rw.getType(type, base, true));
39
}
40
41
/**
42
 * Turn a array of numbers or a string into a byte buffer.
43
 * @param {!Array<number>|string} values The values.
44
 * @param {Object} type One of the available types.
45
 * @param {number} base The base of the output. Optional. Default is 10.
46
 *      Possible values are 2, 10 or 16.
47
 * @return {!Array<number>|!Array<string>}
48
 */
49
function packArray(values, type, base=10) {
50
    return rw.toBytes(values, rw.getType(type, base, false));
51
}
52
53
/**
54
 * Turn a byte buffer into a array of numbers or a string.
55
 * @param {!Array<number>|!Array<string>|Uint8Array} buffer The byte array.
56
 * @param {Object} type One of the available types.
57
 * @param {number} base The base of the input. Optional. Default is 10.
58
 *      Possible values are 2, 10 or 16.
59
 * @return {!Array<number>|string}
60
 */
61
function unpackArray(buffer, type, base=10) {
62
    return rw.fromBytes(buffer, rw.getType(type, base, false));
63
}
64
65
/**
66
 * Find and return the start index of some string.
67
 * Return -1 if the string is not found.
68
 * @param {!Array<number>|Uint8Array} buffer A byte buffer.
69
 * @param {string} text Some string to look for.
70
 * @return {number} The start index of the first occurrence, -1 if not found
71
 */
72
function findString(buffer, text) {
73
    let found = "";
74
    for (let i = 0; i < buffer.length; i++) {
75
        found = unpack(
76
                buffer.slice(i, i + text.length + 1),
77
                new Type({"bits": text.length * 8, "char": true})
78
            );
79
        if (found == text) {
80
            return i;
81
        }
82
    }
83
    return -1;
84
}
85
86
/**
87
 * Turn a struct into a byte buffer.
88
 * A struct is an array of values of not necessarily the same type.
89
 * @param {Array} struct The struct values.
90
 * @param {!Array<Object>} def The struct type definition.
91
 * @param {number} base The base of the output. Optional. Default is 10.
92
 *      Possible values are 2, 10 or 16.
93
 * @return {!Array<number>|!Array<string>}
94
 */
95
function packStruct(struct, def, base=10) {
96
    if (struct.length < def.length) {
97
        return [];
98
    }
99
    let bytes = [];
100
    for (let i = 0; i < def.length; i++) {
101
        bytes = bytes.concat(pack(struct[i], def[i], base));
102
    }
103
    return bytes;
104
}
105
106
/**
107
 * Turn a byte buffer into a struct.
108
 * A struct is an array of values of not necessarily the same type.
109
 * @param {!Array<number>|!Array<string>|Uint8Array} buffer The byte buffer.
110
 * @param {!Array<Object>} def The struct type definition.
111
 * @param {number} base The base of the input. Optional. Default is 10.
112
 *      Possible values are 2, 10 or 16.
113
 * @return {Array}
114
 */
115
function unpackStruct(buffer, def, base=10) {
116
    if (buffer.length < getStructDefSize(def)) {
117
        return [];
118
    }
119
    let struct = [];
120
    let i = 0;
121
    let j = 0;
122
    while (i < def.length) {
123
        let bits = def[i].bits < 8 ? 1 : def[i].bits / 8;
124
        struct = struct.concat(
125
                unpack(buffer.slice(j, j + bits), def[i], base)
126
            );
127
        j += bits;
128
        i++;
129
    }
130
    return struct;
131
}
132
133
/**
134
 * Get the length in bytes of a struct definition.
135
 * @param {!Array<Object>} def The struct type definition.
136
 * @return {number} The length of the structure in bytes.
137
 * @private
138
 */
139
function getStructDefSize(def) {
140
    let bits = 0;
141
    for (let i = 0; i < def.length; i++) {
142
        bits += def[i].bits / 8;
143
    }
144
    return bits;
145
}
146
147
// interface
148
module.exports.pack = pack;
149
module.exports.unpack = unpack;
150
module.exports.packArray = packArray;
151
module.exports.unpackArray = unpackArray;
152
module.exports.unpackStruct = unpackStruct;
153
module.exports.packStruct = packStruct;
154
module.exports.findString = findString;
155
module.exports.Type = Type;
156
157
// types
158
module.exports.chr = new Type({"bits": 8, "char": true});
159
module.exports.fourCC = new Type({"bits": 32, "char": true});
160
module.exports.bool = new Type({"bits": 1});
161
module.exports.int2 = new Type({"bits": 2, "signed": true});
162
module.exports.uInt2 = new Type({"bits": 2});
163
module.exports.int4 = new Type({"bits": 4, "signed": true});
164
module.exports.uInt4 = new Type({"bits": 4});
165
module.exports.int8 = new Type({"bits": 8, "signed": true});
166
module.exports.uInt8 = new Type({"bits": 8});
167
// LE
168
module.exports.int16  = new Type({"bits": 16, "signed": true});
169
module.exports.uInt16 = new Type({"bits": 16});
170
module.exports.float16 = new Type({"bits": 16, "float": true});
171
module.exports.int24 = new Type({"bits": 24, "signed": true});
172
module.exports.uInt24 = new Type({"bits": 24});
173
module.exports.int32 = new Type({"bits": 32, "signed": true});
174
module.exports.uInt32 = new Type({"bits": 32});
175
module.exports.float32 = new Type({"bits": 32, "float": true});
176
module.exports.int40 = new Type({"bits": 40, "signed": true});
177
module.exports.uInt40 = new Type({"bits": 40});
178
module.exports.int48 = new Type({"bits": 48, "signed": true});
179
module.exports.uInt48 = new Type({"bits": 48});
180
module.exports.float64 = new Type({"bits": 64, "float": true});
181
// BE
182
module.exports.int16BE  = new Type({"bits": 16, "signed": true, "be": true});
183
module.exports.uInt16BE = new Type({"bits": 16, "be": true});
184
module.exports.float16BE = new Type({"bits": 16, "float": true, "be": true});
185
module.exports.int24BE = new Type({"bits": 24, "signed": true, "be": true});
186
module.exports.uInt24BE = new Type({"bits": 24, "be": true});
187
module.exports.int32BE = new Type({"bits": 32, "signed": true, "be": true});
188
module.exports.uInt32BE = new Type({"bits": 32, "be": true});
189
module.exports.float32BE = new Type({"bits": 32, "float": true, "be": true});
190
module.exports.int40BE = new Type({"bits": 40, "signed": true, "be": true});
191
module.exports.uInt40BE = new Type({"bits": 40, "be": true});
192
module.exports.int48BE = new Type({"bits": 48, "signed": true, "be": true});
193
module.exports.uInt48BE = new Type({"bits": 48, "be": true});
194
module.exports.float64BE = new Type({"bits": 64, "float": true, "be": true});
195