Skip to content

Commit

Permalink
Add convenience function for creating a DataView (#45)
Browse files Browse the repository at this point in the history
* Add convenience function for creating a DataView

* Support Node.js Buffer
  • Loading branch information
Mrtenz authored Oct 14, 2022
1 parent e35fa7d commit 0e252ee
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 0 deletions.
81 changes: 81 additions & 0 deletions src/bytes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
bytesToSignedBigInt,
bytesToString,
concatBytes,
createDataView,
hexToBytes,
isBytes,
numberToBytes,
Expand Down Expand Up @@ -414,3 +415,83 @@ describe('concatBytes', () => {
).toStrictEqual(Uint8Array.from([1, 2, 3, 52, 5]));
});
});

describe('createDataView', () => {
describe('Uint8Array', () => {
it('returns a DataView from a byte array', () => {
const dataView = createDataView(new Uint8Array([1, 2, 3]));

expect(dataView).toBeInstanceOf(DataView);
expect(dataView.getUint8(0)).toBe(1);
expect(dataView.getUint8(1)).toBe(2);
expect(dataView.getUint8(2)).toBe(3);
});

it('returns a DataView from a subarray of a byte array', () => {
const original = new Uint8Array([1, 2, 3, 4, 5]);
const subset = original.subarray(1, 4);

const dataView = createDataView(subset);

expect(dataView).toBeInstanceOf(DataView);
expect(dataView.byteOffset).toBe(1);
expect(dataView.byteLength).toBe(3);
expect(dataView.getUint8(0)).toBe(2);
expect(dataView.getUint8(1)).toBe(3);
expect(dataView.getUint8(2)).toBe(4);
});

it('returns a DataView from a slice of a byte array', () => {
const original = new Uint8Array([1, 2, 3, 4, 5]);
const subset = original.slice(1, 4);

const dataView = createDataView(subset);

expect(dataView).toBeInstanceOf(DataView);
expect(dataView.byteOffset).toBe(0);
expect(dataView.byteLength).toBe(3);
expect(dataView.getUint8(0)).toBe(2);
expect(dataView.getUint8(1)).toBe(3);
expect(dataView.getUint8(2)).toBe(4);
});
});

describe('Node.js Buffer', () => {
it('returns a DataView from a byte array', () => {
const dataView = createDataView(Buffer.from([1, 2, 3]));

expect(dataView).toBeInstanceOf(DataView);
expect(dataView.getUint8(0)).toBe(1);
expect(dataView.getUint8(1)).toBe(2);
expect(dataView.getUint8(2)).toBe(3);
});

it('returns a DataView from a subarray of a byte array', () => {
const original = Buffer.from([1, 2, 3, 4, 5]);
const subset = original.subarray(1, 4);

const dataView = createDataView(subset);

expect(dataView).toBeInstanceOf(DataView);
expect(dataView.byteOffset).toBe(0);
expect(dataView.byteLength).toBe(3);
expect(dataView.getUint8(0)).toBe(2);
expect(dataView.getUint8(1)).toBe(3);
expect(dataView.getUint8(2)).toBe(4);
});

it('returns a DataView from a slice of a byte array', () => {
const original = Buffer.from([1, 2, 3, 4, 5]);
const subset = original.slice(1, 4);

const dataView = createDataView(subset);

expect(dataView).toBeInstanceOf(DataView);
expect(dataView.byteOffset).toBe(0);
expect(dataView.byteLength).toBe(3);
expect(dataView.getUint8(0)).toBe(2);
expect(dataView.getUint8(1)).toBe(3);
expect(dataView.getUint8(2)).toBe(4);
});
});
});
35 changes: 35 additions & 0 deletions src/bytes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -393,3 +393,38 @@ export function concatBytes(values: Bytes[]): Uint8Array {

return bytes;
}

/**
* Create a {@link DataView} from a {@link Uint8Array}. This is a convenience
* function that avoids having to create a {@link DataView} manually, which
* requires passing the `byteOffset` and `byteLength` parameters every time.
*
* Not passing the `byteOffset` and `byteLength` parameters can result in
* unexpected behavior when the {@link Uint8Array} is a view of a larger
* {@link ArrayBuffer}, e.g., when using {@link Uint8Array.subarray}.
*
* This function also supports Node.js {@link Buffer}s.
*
* @example
* ```typescript
* const bytes = new Uint8Array([1, 2, 3]);
*
* // This is equivalent to:
* // const dataView = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
* const dataView = createDataView(bytes);
* ```
* @param bytes - The bytes to create the {@link DataView} from.
* @returns The {@link DataView}.
*/
export function createDataView(bytes: Uint8Array): DataView {
if (typeof Buffer !== 'undefined' && bytes instanceof Buffer) {
const buffer = bytes.buffer.slice(
bytes.byteOffset,
bytes.byteOffset + bytes.byteLength,
);

return new DataView(buffer);
}

return new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
}

0 comments on commit 0e252ee

Please sign in to comment.