bireader 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/writer.js ADDED
@@ -0,0 +1,524 @@
1
+ /**
2
+ *
3
+ * byte reader, includes bitfields and strings
4
+ *
5
+ * @param {Buffer|Uint8Array} data - ```Buffer``` or ```Uint8Array```
6
+ * @param {number} byteoffset - byte offset to start writing, default is 0
7
+ * @param {number} bitoffset - bit offset to start writing, 0-7
8
+ * @param endianness - endianness ```big``` or ```little``` (default ```little```)
9
+ * @returns ```Buffer``` or ```Uint8Array```
10
+ */
11
+ class biwriter {
12
+ endian = "little";
13
+ offset = 0;
14
+ bitoffset = 0;
15
+ size = 0
16
+ data;
17
+
18
+ #isBuffer = function(obj) {
19
+ return (typeof Buffer !== 'undefined' && obj instanceof Buffer);
20
+ }
21
+
22
+ #isBufferOrUint8Array = function(obj) {
23
+ return obj instanceof Uint8Array || this.#isBuffer(obj);
24
+ }
25
+
26
+ extendArray = function(to_padd) {
27
+ if((typeof Buffer !== 'undefined' && this.data instanceof Buffer)){
28
+ var paddbuffer = Buffer.alloc(to_padd);
29
+ this.data = Buffer.concat([this.data, paddbuffer]);
30
+ } else {
31
+ const addArray = new Array(to_padd);
32
+ this.data = new Uint8Array([...this.data, ...addArray]);
33
+ }
34
+ }
35
+
36
+ #check_size = function(write_bytes, write_bit, offset){
37
+ const bits = (write_bit || 0) + this.bitoffset
38
+ var new_off = (offset || this.offset)
39
+ var readsize = write_bytes
40
+ if(bits != 0){
41
+ //add bits
42
+ readsize = readsize + Math.ceil(bits / 8)
43
+ }
44
+ //if biger extend
45
+ const needed_size = new_off + readsize
46
+ if(needed_size > this.size){
47
+ const dif = needed_size - this.size
48
+ this.extendArray(dif)
49
+ this.size = this.data.length
50
+ }
51
+ //start read location
52
+ this.offset = new_off
53
+ }
54
+
55
+ /**
56
+ *
57
+ * byte reader, includes bitfields and strings
58
+ *
59
+ * @param {Buffer|Uint8Array} data - ```Buffer``` or ```Uint8Array```
60
+ * @param {number} byteoffset - byte offset to start reader, default is 0
61
+ * @param {number} bitoffset - bit offset to start reader, 0-7
62
+ * @param endianness - endianness ```big``` or ```little``` (default ```little```)
63
+ */
64
+ constructor(data, byteoffset, bitoffset, endianness) {
65
+ if(endianness != undefined && typeof endianness != "string"){
66
+ throw Error("endianness must be big or little")
67
+ }
68
+ if(endianness != undefined && !(endianness == "big" || endianness == "little")){
69
+ throw Error("byteorder must be big or little")
70
+ }
71
+ this.endian = endianness || "little"
72
+
73
+ if(byteoffset != undefined ){
74
+ if(typeof byteoffset == "number"){
75
+ this.offset = Math.round(byteoffset) || 0
76
+ } else {
77
+ throw Error("Byteoffset must be number")
78
+ }
79
+ }
80
+ if(bitoffset!= undefined){
81
+ this.bitoffset = (bitoffset % 8)
82
+ }
83
+ this.data = data
84
+ if(this.data == undefined){
85
+ this.data = new Uint8Array(4)
86
+ } else {
87
+ if(!this.#isBufferOrUint8Array(this.data)){
88
+ throw Error("Write data must be UIntArray or Buffer")
89
+ }
90
+ }
91
+ this.size = this.data.length + ((bitoffset || 0) % 8)
92
+ }
93
+
94
+
95
+ endianness = function(order){
96
+ if(order == undefined || typeof order != "string"){
97
+ throw Error("endianness must be big or little")
98
+ }
99
+ if(order != undefined && !(order == "big" || order == "little")){
100
+ throw Error("byteorder must be big or little")
101
+ }
102
+ this.endian = order
103
+ }
104
+
105
+ /**
106
+ *
107
+ * write bits
108
+ *
109
+ * @param {number} value - value as int
110
+ * @param {number} numBits - number of bits to write
111
+ * @param {number} offsetBits - bit offset to start the write (default last write position)
112
+ * @param {number} offsetBytes - byte offset to start the write (default last write position)
113
+ * @returns ```Buffer``` or ```Uint8Array```
114
+ */
115
+ writeBits = function(value, numBits, offsetBits, offsetBytes) {
116
+ if (numBits <= 0 || numBits > 32) {
117
+ throw Error('Bit length must be between 1 and 32.');
118
+ }
119
+
120
+ if (value < 0 || value >= Math.pow(2, numBits)) {
121
+ throw Error('Value is out of range for the specified bit length.');
122
+ }
123
+ // Ensure the offset is within bounds
124
+
125
+ const size_needed = (((((offsetBits || 0) + (numBits-1)) + this.bitoffset) / 8) + (offsetBytes || this.offset))
126
+ if (size_needed > this.size) {
127
+ //add size
128
+ this.extendArray(size_needed-this.size)
129
+ }
130
+
131
+ var bits_to_write = value.toString(2).padStart(numBits, '0').split('')
132
+
133
+ let startByteIndex = this.offset //cur byte
134
+ let endByteIndex = this.offset + Math.floor(((numBits-1) + this.bitoffset) / 8) //end byte
135
+ let bytesToRead = (endByteIndex - startByteIndex) + 1 //at least 1
136
+ let startBitIndex = (offsetBits || 0) + this.bitoffset
137
+ let endBitIndex = (((offsetBits || 0) + (numBits-1)) + this.bitoffset)+1
138
+ let bitArray = []
139
+
140
+ let startByteIndexI = endByteIndex
141
+ let bytesToReadI = bytesToRead
142
+ do {
143
+ var element = this.data[startByteIndexI];
144
+ element = element.toString(2).padStart(8, '0').split('')
145
+ if(this.endian == "little"){
146
+ element = element.reverse()
147
+ }
148
+ bitArray.push(element)
149
+ startByteIndexI--
150
+ bytesToReadI--
151
+ } while (bytesToReadI != 0);
152
+
153
+ if(this.endian == "big"){
154
+ bitArray = bitArray.reverse()
155
+ }
156
+
157
+ bitArray = bitArray.flat()
158
+
159
+ let startBitIndexI = startBitIndex
160
+ let i = 0
161
+ do {
162
+ bitArray[startBitIndexI] = bits_to_write[i]
163
+ i++
164
+ startBitIndexI++
165
+ } while (startBitIndexI != endBitIndex);
166
+
167
+ bytesToReadI = bytesToRead
168
+ startByteIndexI = startByteIndex
169
+ i = 0
170
+ do {
171
+ var byte_data = bitArray.slice(i,i+8)
172
+ if(this.endian == "little"){
173
+ byte_data.reverse()
174
+ }
175
+ byte_data = Number("0b"+byte_data.join(""))
176
+ this.data[startByteIndexI] = byte_data
177
+ i = i+8
178
+ bytesToReadI--
179
+ startByteIndexI = startByteIndexI + 1
180
+ } while (bytesToReadI != 0);
181
+ this.offset = this.offset + Math.floor(((numBits) + this.bitoffset) / 8) //end byte
182
+ this.bitoffset = ((numBits) + this.bitoffset) % 8
183
+ }
184
+
185
+ //byte write
186
+
187
+ /**
188
+ *
189
+ * write byte
190
+ *
191
+ * @param {number} value - value as int
192
+ * @param {number} offset - byte offset (default last write position)
193
+ * @param signed - if the values are write with sign
194
+ * @returns ```Buffer``` or ```Uint8Array```
195
+ */
196
+ writeByte = function(value, offset, signed){
197
+ this.#check_size(1,0,offset)
198
+ this.data[this.offset] = (signed == undefined || signed == true)? value : value & 0xFF;
199
+ this.offset += 1
200
+ }
201
+
202
+ /**
203
+ *
204
+ * write byte
205
+ *
206
+ * @param {number} value - value as int
207
+ * @param {number} offset - byte offset (default last write position)
208
+ * @returns ```Buffer``` or ```Uint8Array```
209
+ */
210
+ writeUByte = function(value, offset){
211
+ return this.writeByte(value, offset, false)
212
+ }
213
+
214
+ /**
215
+ *
216
+ * write byte
217
+ *
218
+ * @param {number} value - value as int
219
+ * @param {number} offset - byte offset (default last write position)
220
+ * @returns ```Buffer``` or ```Uint8Array```
221
+ */
222
+ byte = function(value, offset){
223
+ return this.writeByte(value, offset, true)
224
+ }
225
+
226
+ /**
227
+ *
228
+ * write byte
229
+ *
230
+ * @param {number} value - value as int
231
+ * @param {number} offset - byte offset (default last write position)
232
+ * @returns ```Buffer``` or ```Uint8Array```
233
+ */
234
+ ubyte = function(value, offset){
235
+ return this.writeByte(value, offset, false)
236
+ }
237
+
238
+ /**
239
+ *
240
+ * write byte
241
+ *
242
+ * @param {number} value - value as int
243
+ * @param {number} offset - byte offset (default last write position)
244
+ * @returns ```Buffer``` or ```Uint8Array```
245
+ */
246
+ int8 = function(value, offset){
247
+ return this.writeByte(value, offset, true)
248
+ }
249
+
250
+ /**
251
+ *
252
+ * write byte
253
+ *
254
+ * @param {number} value - value as int
255
+ * @param {number} offset - byte offset (default last write position)
256
+ * @returns ```Buffer``` or ```Uint8Array```
257
+ */
258
+ uint8 = function(value, offset){
259
+ return this.writeByte(value, offset, false)
260
+ }
261
+
262
+ //int32 write
263
+
264
+ /**
265
+ *
266
+ * write int32
267
+ *
268
+ * @param {number} value - value as int
269
+ * @param {number} offset - byte offset (default last write position)
270
+ * @param signed - if the values are write with sign
271
+ * @returns ```Buffer``` or ```Uint8Array```
272
+ */
273
+ writeInt32LE = function(value, offset, signed) {
274
+ this.#check_size(4,0,offset)
275
+ this.data[this.offset] = signed ? value : value & 0xFF;
276
+ this.data[this.offset + 1] = signed ? (value >> 8) : (value >> 8) & 0xFF;
277
+ this.data[this.offset + 2] = signed ? (value >> 16) : (value >> 16) & 0xFF;
278
+ this.data[this.offset + 3] = signed ? (value >> 24) : (value >> 24) & 0xFF;
279
+ this.offset += 4
280
+ }
281
+
282
+ /**
283
+ *
284
+ * write int32
285
+ *
286
+ * @param {number} value - value as int
287
+ * @param {number} offset - byte offset (default last write position)
288
+ * @param signed - if the values are write with sign
289
+ * @returns ```Buffer``` or ```Uint8Array```
290
+ */
291
+ writeInt32BE = function(value, offset, signed) {
292
+ this.#check_size(4,0,offset)
293
+ this.data[this.offset] = signed ? (value >> 24) : (value >> 24) & 0xFF;
294
+ this.data[this.offset + 1] = signed ? (value >> 16): (value >> 16) & 0xFF;
295
+ this.data[this.offset + 2] = signed ? (value >> 8) : (value >> 8) & 0xFF;
296
+ this.data[this.offset + 3] = signed ? value : value & 0xFF;
297
+ this.offset += 4
298
+ }
299
+
300
+ /**
301
+ *
302
+ * write int32
303
+ *
304
+ * @param {number} value - value as int
305
+ * @param {number} offset - byte offset (default last write position)
306
+ * @returns ```Buffer``` or ```Uint8Array```
307
+ */
308
+ writeInt32 = function(value, offset){
309
+ if(this.endian == "little"){
310
+ return this.writeInt32LE(value, offset, true)
311
+ } else {
312
+ return this.writeInt32BE(value, offset, true)
313
+ }
314
+ }
315
+
316
+ /**
317
+ *
318
+ * write int32
319
+ *
320
+ * @param {number} value - value as int
321
+ * @param {number} offset - byte offset (default last write position)
322
+ * @returns ```Buffer``` or ```Uint8Array```
323
+ */
324
+ writeUInt32 = function(value, offset){
325
+ if(this.endian == "little"){
326
+ return this.writeInt32LE(value, offset, false)
327
+ } else {
328
+ return this.writeInt32BE(value, offset, false)
329
+ }
330
+ }
331
+
332
+ /**
333
+ *
334
+ * write int32
335
+ *
336
+ * @param {number} value - value as int
337
+ * @param {number} offset - byte offset (default last write position)
338
+ * @returns ```Buffer``` or ```Uint8Array```
339
+ */
340
+ int = function(value, offset){
341
+ if(this.endian == "little"){
342
+ return this.writeInt32LE(value, offset, true)
343
+ } else {
344
+ return this.writeInt32BE(value, offset, true)
345
+ }
346
+ }
347
+
348
+ /**
349
+ *
350
+ * write int32
351
+ *
352
+ * @param {number} value - value as int
353
+ * @param {number} offset - byte offset (default last write position)
354
+ * @returns ```Buffer``` or ```Uint8Array```
355
+ */
356
+ uint = function(value, offset){
357
+ if(this.endian == "little"){
358
+ return this.writeInt32LE(value, offset, false)
359
+ } else {
360
+ return this.writeInt32BE(value, offset, false)
361
+ }
362
+ }
363
+
364
+ /**
365
+ *
366
+ * write int32
367
+ *
368
+ * @param {number} value - value as int
369
+ * @param {number} offset - byte offset (default last write position)
370
+ * @returns ```Buffer``` or ```Uint8Array```
371
+ */
372
+ int32 = function(value, offset){
373
+ if(this.endian == "little"){
374
+ return this.writeInt32LE(value, offset, true)
375
+ } else {
376
+ return this.writeInt32BE(value, offset, true)
377
+ }
378
+ }
379
+
380
+ /**
381
+ *
382
+ * write int32
383
+ *
384
+ * @param {number} value - value as int
385
+ * @param {number} offset - byte offset (default last write position)
386
+ * @returns ```Buffer``` or ```Uint8Array```
387
+ */
388
+ uint32 = function(value, offset){
389
+ if(this.endian == "little"){
390
+ return this.writeInt32LE(value, offset, false)
391
+ } else {
392
+ return this.writeInt32BE(value, offset, false)
393
+ }
394
+ }
395
+
396
+ /**
397
+ *
398
+ * write int16
399
+ *
400
+ * @param {number} value - value as int
401
+ * @param {number} offset - byte offset (default last write position)
402
+ * @param signed - if the values are write with sign
403
+ * @returns ```Buffer``` or ```Uint8Array```
404
+ */
405
+ writeInt16LE = function(value, offset, signed) {
406
+ this.#check_size(2,0,offset)
407
+ this.data[this.offset] = signed ? value : value & 0xff;
408
+ this.data[this.offset + 1] = signed ? (value >> 8) : (value >> 8) & 0xff;
409
+ }
410
+
411
+ /**
412
+ *
413
+ * write int16
414
+ *
415
+ * @param {number} value - value as int
416
+ * @param {number} offset - byte offset (default last write position)
417
+ * @param signed - if the values are write with sign
418
+ * @returns ```Buffer``` or ```Uint8Array```
419
+ */
420
+ writeInt16BE = function(value, offset, signed) {
421
+ this.#check_size(2,0,offset)
422
+ this.data[this.offset] = signed ? (value >> 8) : (value >> 8) & 0xff;
423
+ this.data[this.offset + 1] = signed ? value : value& 0xff;
424
+ }
425
+
426
+ /**
427
+ *
428
+ * write int16
429
+ *
430
+ * @param {number} value - value as int
431
+ * @param {number} offset - byte offset (default last write position)
432
+ * @returns ```Buffer``` or ```Uint8Array```
433
+ */
434
+ writeInt16 = function(value, offset){
435
+ if(this.endian == "little"){
436
+ return this.writeInt16LE(value, offset, false)
437
+ } else {
438
+ return this.writeInt16BE(value, offset, false)
439
+ }
440
+ }
441
+
442
+ /**
443
+ *
444
+ * write int16
445
+ *
446
+ * @param {number} value - value as int
447
+ * @param {number} offset - byte offset (default last write position)
448
+ * @returns ```Buffer``` or ```Uint8Array```
449
+ */
450
+ writeUInt16 = function(value, offset){
451
+ if(this.endian == "little"){
452
+ return this.writeInt16LE(value, offset, true)
453
+ } else {
454
+ return this.writeInt16BE(value, offset, true)
455
+ }
456
+ }
457
+
458
+ /**
459
+ *
460
+ * write int16
461
+ *
462
+ * @param {number} value - value as int
463
+ * @param {number} offset - byte offset (default last write position)
464
+ * @returns ```Buffer``` or ```Uint8Array```
465
+ */
466
+ short = function(value, offset){
467
+ if(this.endian == "little"){
468
+ return this.writeInt16LE(value, offset, false)
469
+ } else {
470
+ return this.writeInt16BE(value, offset, false)
471
+ }
472
+ }
473
+
474
+ /**
475
+ *
476
+ * write int16
477
+ *
478
+ * @param {number} value - value as int
479
+ * @param {number} offset - byte offset (default last write position)
480
+ * @returns ```Buffer``` or ```Uint8Array```
481
+ */
482
+ ushort = function(value, offset){
483
+ if(this.endian == "little"){
484
+ return this.writeInt16LE(value, offset, true)
485
+ } else {
486
+ return this.writeInt16BE(value, offset, true)
487
+ }
488
+ }
489
+
490
+ /**
491
+ *
492
+ * write int16
493
+ *
494
+ * @param {number} value - value as int
495
+ * @param {number} offset - byte offset (default last write position)
496
+ * @returns ```Buffer``` or ```Uint8Array```
497
+ */
498
+ int16 = function(value, offset){
499
+ if(this.endian == "little"){
500
+ return this.writeInt16LE(value, offset, false)
501
+ } else {
502
+ return this.writeInt16BE(value, offset, false)
503
+ }
504
+ }
505
+
506
+ /**
507
+ *
508
+ * write int16
509
+ *
510
+ * @param {number} value - value as int
511
+ * @param {number} offset - byte offset (default last write position)
512
+ * @returns ```Buffer``` or ```Uint8Array```
513
+ */
514
+ uint16 = function(value, offset){
515
+ if(this.endian == "little"){
516
+ return this.writeInt16LE(value, offset, true)
517
+ } else {
518
+ return this.writeInt16BE(value, offset, true)
519
+ }
520
+ }
521
+
522
+ }
523
+
524
+ module.exports = biwriter