Skip to content

Commit

Permalink
Add readSigned3BytesInDataView() and writeSigned3BytesInDataView() utils
Browse files Browse the repository at this point in the history
  • Loading branch information
ibc committed Aug 25, 2023
1 parent 8eaa075 commit 4404382
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 3 deletions.
37 changes: 35 additions & 2 deletions src/tests/utils/byteOps.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {
read3BytesInDataView,
write3BytesInDataView
write3BytesInDataView,
readSigned3BytesInDataView,
writeSigned3BytesInDataView
} from '../../utils/byteOps';

let view: DataView;
Expand All @@ -10,7 +12,10 @@ beforeEach(() =>
const array = new Uint8Array(
[
0b00000000, 0b00000001, 0b00000010, 0b00000011,
0b10000000, 0b01000000, 0b00100000, 0b00010000
0b10000000, 0b01000000, 0b00100000, 0b00010000,
0b01111111, 0b11111111, 0b11111111, 0b00000000,
0b11111111, 0b11111111, 0b11111111, 0b00000000,
0b10000000, 0b00000000, 0b00000000, 0b00000000
]
);

Expand All @@ -32,3 +37,31 @@ test('write3BytesInDataView()', () =>
write3BytesInDataView({ view, pos: 1, value: 8405024 });
expect(read3BytesInDataView({ view, pos: 1 })).toBe(8405024);
});

test('readSigned3BytesInDataView()', () =>
{
// Bytes 8, 9 and 10 in the array are number 8388607 since first bit is 0 and
// all other bits are 1, so it must be maximum positive 24 bits signed integer,
// which is Math.pow(2, 23) - 1 = 8388607.
expect(readSigned3BytesInDataView({ view, pos: 8 })).toBe(8388607);

// Bytes 12, 13 and 14 in the array are number -1.
expect(readSigned3BytesInDataView({ view, pos: 12 })).toBe(-1);

// Bytes 16, 17 and 18 in the array are number -8388608 since first bit is 1
// and all other bits are 0, so it must be minimum negative 24 bits signed
// integer, which is -1 * Math.pow(2, 23) = -8388608.
expect(readSigned3BytesInDataView({ view, pos: 16 })).toBe(-8388608);
});

test('writeSigned3BytesInDataView()', () =>
{
writeSigned3BytesInDataView({ view, pos: 0, value: 8388607 });
expect(readSigned3BytesInDataView({ view, pos: 0 })).toBe(8388607);

writeSigned3BytesInDataView({ view, pos: 0, value: -1 });
expect(readSigned3BytesInDataView({ view, pos: 0 })).toBe(-1);

writeSigned3BytesInDataView({ view, pos: 0, value: -8388608 });
expect(readSigned3BytesInDataView({ view, pos: 0 })).toBe(-8388608);
});
38 changes: 37 additions & 1 deletion src/utils/byteOps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function read3BytesInDataView(
}

/**
* Write a unsigned value in 3 bytes starting from byte `pos` in `view`.
* Write an unsigned value in 3 bytes starting from byte `pos` in `view`.
*
* @category Utils
* @hidden
Expand All @@ -26,3 +26,39 @@ export function write3BytesInDataView(
view.setUint8(pos, value >> 16);
view.setUint16(pos + 1, value);
}

/**
* Read 3 bytes starting from byte `pos` in `view` as signed value.
*
* @category Utils
* @hidden
*/
export function readSigned3BytesInDataView(
{ view, pos }:
{ view: DataView; pos: number }
): number
{
const byte2 = view.getUint8(pos);
const byte1 = view.getUint8(pos + 1);
const byte0 = view.getUint8(pos + 2);

// Check bit 7 (sign).
const extension = byte2 & 0b10000000 ? 0b11111111 : 0b00000000;

return byte0 | (byte1 << 8) | (byte2 << 16) | (extension << 24);
}

/**
* Write a signed value in 3 bytes starting from byte `pos` in `view`.
*
* @category Utils
* @hidden
*/
export function writeSigned3BytesInDataView(
{ view, pos, value }:
{ view: DataView; pos: number; value: number }
): void
{
view.setInt8(pos, value >> 16);
view.setUint16(pos + 1, value);
}

0 comments on commit 4404382

Please sign in to comment.