Completed
Push — master ( adfc9c...0aaf86 )
by Rafael S.
01:37
created

main.js (1 issue)

Severity
1
/*
2
 * Copyright (c) 2017-2018 Rafael da Silva Rocha.
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining
5
 * a copy of this software and associated documentation files (the
6
 * "Software"), to deal in the Software without restriction, including
7
 * without limitation the rights to use, copy, modify, merge, publish,
8
 * distribute, sublicense, and/or sell copies of the Software, and to
9
 * permit persons to whom the Software is furnished to do so, subject to
10
 * the following conditions:
11
 *
12
 * The above copyright notice and this permission notice shall be
13
 * included in all copies or substantial portions of the Software.
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
 *
23
 */
24
25
/**
26
 * @fileoverview The byte-data API.
27
 * @see https://github.com/rochars/byte-data
28
 */
29
30
/** @module byteData */
31
32
import endianness from './lib/endianness.js';
33
import {reader_, setUp_, writeBytes_,
34
  fromBytes_, toBytes_} from './lib/packer.js';
35
import {validateType, validateNotUndefined,
0 ignored issues
show
The variable validateType seems to be never used. Consider removing it.
Loading history...
36
  validateASCIICode} from './lib/validation.js';
37
38
// ASCII characters
39
/**
40
 * Read a string of ASCII characters from a byte buffer.
41
 * @param {!Uint8Array} bytes A byte buffer.
42
 * @param {number=} index The index to read.
43
 * @param {?number=} len The number of bytes to read.
44
 * @return {string}
45
 * @throws {Error} If a character in the string is not valid ASCII.
46
 */
47
export function unpackString(bytes, index=0, len=null) {
48
  let chrs = '';
49
  len = len ? index + len : bytes.length;
50
  while (index < len) {
51
    validateASCIICode(bytes[index]);
52
    chrs += String.fromCharCode(bytes[index]);
53
    index++;
54
  }
55
  return chrs;
56
}
57
58
/**
59
 * Write a string of ASCII characters as a byte buffer.
60
 * @param {string} str The string to pack.
61
 * @return {!Array<number>} The next index to write on the buffer.
62
 * @throws {Error} If a character in the string is not valid ASCII.
63
 */
64
export function packString(str) {
65
  let bytes = [];
66
  for (let i = 0; i < str.length; i++) {
67
    let code = str.charCodeAt(i);
68
    validateASCIICode(code);
69
    bytes[i] = code;
70
  }
71
  return bytes;
72
}
73
74
/**
75
 * Write a string of ASCII characters to a byte buffer.
76
 * @param {string} str The string to pack.
77
 * @param {!Uint8Array} bytes A byte buffer.
78
 * @param {number=} index The index to write in the buffer.
79
 * @return {number} The next index to write in the buffer.
80
 * @throws {Error} If a character in the string is not valid ASCII.
81
 */
82
export function packStringTo(str, bytes, index=0) {
83
  for (let i = 0; i < str.length; i++) {
84
    let code = str.charCodeAt(i);
85
    validateASCIICode(code);
86
    bytes[index] = code;
87
    index++;
88
  }
89
  return index;
90
}
91
92
// Numbers
93
/**
94
 * Pack a number as a byte buffer.
95
 * @param {number} value The number.
96
 * @param {!Object} theType The type definition.
97
 * @return {!Array<number>} The packed value.
98
 * @throws {Error} If the type definition is not valid.
99
 * @throws {Error} If the value is not valid.
100
 */
101
export function pack(value, theType) {
102
  setUp_(theType);
103
  return toBytes_([value], theType);
104
}
105
106
/**
107
 * Pack an array of numbers as a byte buffer.
108
 * @param {!Array<number>} values The values.
109
 * @param {!Object} theType The type definition.
110
 * @return {!Array<number>} The packed values.
111
 * @throws {Error} If the type definition is not valid.
112
 * @throws {Error} If any of the values are not valid.
113
 */
114
export function packArray(values, theType) {
115
  setUp_(theType);
116
  return toBytes_(values, theType);
117
}
118
119
/**
120
 * Pack a number to a byte buffer.
121
 * @param {number} value The value.
122
 * @param {!Object} theType The type definition.
123
 * @param {!Uint8Array} buffer The output buffer.
124
 * @param {number=} index The index to write.
125
 * @return {number} The next index to write.
126
 * @throws {Error} If the type definition is not valid.
127
 * @throws {Error} If the value is not valid.
128
 */
129
export function packTo(value, theType, buffer, index=0) {
130
  setUp_(theType);
131
  return writeBytes_(value,
132
    theType,
133
    buffer,
134
    index,
135
    index + theType.offset,
136
    validateNotUndefined,
137
    theType.be);
138
}
139
140
/**
141
 * Pack a array of numbers to a byte buffer.
142
 * @param {!Array<number>} values The value.
143
 * @param {!Object} theType The type definition.
144
 * @param {!Uint8Array} buffer The output buffer.
145
 * @param {number=} index The buffer index to write.
146
 * @return {number} The next index to write.
147
 * @throws {Error} If the type definition is not valid.
148
 * @throws {Error} If the value is not valid.
149
 */
150
export function packArrayTo(values, theType, buffer, index=0) {
151
  setUp_(theType);
152
  let be = theType.be;
153
  let offset = theType.offset;
154
  for (let i=0; i<values.length; i++) {
155
    index = writeBytes_(
156
      values[i],
157
      theType,
158
      buffer,
159
      index,
160
      index + offset,
161
      validateNotUndefined,
162
      be);
163
  }
164
  return index;
165
}
166
167
/**
168
 * Unpack a number from a byte buffer.
169
 * @param {!Uint8Array} buffer The byte buffer.
170
 * @param {!Object} theType The type definition.
171
 * @return {number}
172
 * @throws {Error} If the type definition is not valid
173
 */
174
export function unpack(buffer, theType) {
175
  setUp_(theType);
176
  let values = fromBytes_(
177
    buffer.slice(0, theType.offset), theType);
178
  return values[0];
179
}
180
181
/**
182
 * Unpack an array of numbers from a byte buffer.
183
 * @param {!Uint8Array} buffer The byte buffer.
184
 * @param {!Object} theType The type definition.
185
 * @return {!Array<number>}
186
 * @throws {Error} If the type definition is not valid.
187
 */
188
export function unpackArray(buffer, theType) {
189
  setUp_(theType);
190
  return fromBytes_(buffer, theType);
191
}
192
193
/**
194
 * Unpack a number from a byte buffer by index.
195
 * @param {!Uint8Array} buffer The byte buffer.
196
 * @param {!Object} theType The type definition.
197
 * @param {number=} index The buffer index to read.
198
 * @return {number}
199
 * @throws {Error} If the type definition is not valid
200
 */
201
export function unpackFrom(buffer, theType, index=0) {
202
  setUp_(theType);
203
  if (theType.be) {
204
    endianness(buffer, theType.offset, index, index + theType.offset);
205
  }
206
  let value = reader_(buffer, index);
207
  if (theType.be) {
208
    endianness(buffer, theType.offset, index, index + theType.offset);
209
  }
210
  return value;
211
}
212
213
/**
214
 * Unpack a array of numbers from a byte buffer by index.
215
 * @param {!Uint8Array} buffer The byte buffer.
216
 * @param {!Object} theType The type definition.
217
 * @param {number=} start The start index. Assumes 0.
218
 * @param {?number=} end The end index. Assumes the buffer length.
219
 * @return {!Array<number>}
220
 * @throws {Error} If the type definition is not valid
221
 */
222
export function unpackArrayFrom(buffer, theType, start=0, end=null) {
223
  setUp_(theType);
224
  if (theType.be) {
225
    endianness(buffer, theType.offset);
226
  }
227
  let len = end || buffer.length;
228
  let values = [];
229
  let step = theType.offset;
230
  while (start < len) {
231
    values.push(reader_(buffer, start));
232
    start += step;
233
  }
234
  if (theType.be) {
235
    endianness(buffer, theType.offset);
236
  }
237
  return values;
238
}
239
240
/**
241
 * Unpack a array of numbers to a typed array.
242
 * @param {!Uint8Array} buffer The byte buffer.
243
 * @param {!Object} theType The type definition.
244
 * @param {!TypedArray} output The output array.
245
 * @throws {Error} If the type definition is not valid
246
 */
247
export function unpackArrayTo(buffer, theType, output) {
248
  setUp_(theType);
249
  if (theType.be) {
250
    endianness(buffer, theType.offset);
251
  }
252
  let len = buffer.length;
253
  let outputIndex = 0;
254
  let step = theType.offset;
255
  for (let i=0; i<len; i+=step) {
256
    output.set([reader_(buffer, i)], outputIndex);
257
    outputIndex++;
258
  }
259
  if (theType.be) {
260
    endianness(buffer, theType.offset);
261
  }
262
}
263