|
| 1 | +// Buffer Source Conversion |
| 2 | +// ------------------------ |
| 3 | + |
| 4 | +export const bufferSourceToUint8Array = (bs: BufferSource) => bs instanceof ArrayBuffer |
| 5 | + ? new Uint8Array(bs) |
| 6 | + : new Uint8Array(bs.buffer, bs.byteOffset, bs.byteLength); |
| 7 | + |
| 8 | +const bs2u8 = bufferSourceToUint8Array; |
| 9 | + |
| 10 | +export const bufferSourceToDataView = (bs: BufferSource) => bs instanceof ArrayBuffer |
| 11 | + ? new DataView(bs) |
| 12 | + : new DataView(bs.buffer, bs.byteOffset, bs.byteLength); |
| 13 | + |
| 14 | +const bs2dv = bufferSourceToDataView; |
| 15 | + |
| 16 | + |
| 17 | +// Hex Functions |
| 18 | +// ------------- |
| 19 | + |
| 20 | +export const byteToHex = (byte: number) => byte.toString(16).padStart(2, '0'); |
| 21 | +export const hexToByte = (hexOctet: string) => parseInt(hexOctet, 16); |
| 22 | + |
| 23 | +export const hexStringToBytes = (hexString: string) => new Uint8Array(hexString.match(/[0-9a-f]{1,2}/ig).map(hexToByte)); |
| 24 | +export const bytesToHexString = (bufferSource: BufferSource) => Array.from(bs2u8(bufferSource), byte => byteToHex(byte)).join(''); |
| 25 | + |
| 26 | +export const bytesToHexArray = (bufferSource: BufferSource) => Array.from(bs2u8(bufferSource), byte => byteToHex(byte)); |
| 27 | + |
| 28 | + |
| 29 | +// Concatenation |
| 30 | +// ------------- |
| 31 | + |
| 32 | +export function concatUint8Arrays(...uint8Arrays: Uint8Array[]) { |
| 33 | + const size = uint8Arrays.reduce((size, u8) => size + u8.length, 0); |
| 34 | + const res = new Uint8Array(size); |
| 35 | + let i = 0; |
| 36 | + for (const u8 of uint8Arrays) { |
| 37 | + res.set(u8, i); |
| 38 | + i += u8.length; |
| 39 | + } |
| 40 | + return res; |
| 41 | +} |
| 42 | + |
| 43 | +export function concatBufferSources(...bufferSources: BufferSource[]) { |
| 44 | + return concatUint8Arrays(...bufferSources.map(bs2u8)); |
| 45 | +} |
| 46 | + |
| 47 | +// Splitting |
| 48 | +// --------- |
| 49 | + |
| 50 | +export function splitUint8Array(uint8Array: Uint8Array, ...indices: number[]) { |
| 51 | + const result: Uint8Array[] = new Array(indices.length + 1); |
| 52 | + let prev = 0; |
| 53 | + let i = 0; |
| 54 | + for (const index of indices) { |
| 55 | + result[i++] = uint8Array.subarray(prev, index); |
| 56 | + prev = index; |
| 57 | + } |
| 58 | + result[i] = uint8Array.subarray(prev); |
| 59 | + return result; |
| 60 | +} |
| 61 | + |
| 62 | +export function splitBufferSource(bufferSource: BufferSource, ...indices: number[]) { |
| 63 | + return splitUint8Array(bs2u8(bufferSource), ...indices); |
| 64 | +} |
| 65 | + |
| 66 | + |
| 67 | +// Comparison |
| 68 | +// ---------- |
| 69 | + |
| 70 | +export function compareUint8Arrays(u8_1: Uint8Array, ...u8s: Uint8Array[]) { |
| 71 | + if (u8s.some(u8_i => u8_1.byteLength !== u8_i.byteLength)) return false; |
| 72 | + let res = true; |
| 73 | + for (const u8_i of u8s) { |
| 74 | + for (let i = 0; i !== u8_1.length; i++) { |
| 75 | + const r = u8_1[i] === u8_i[i]; |
| 76 | + res = r && res; |
| 77 | + } |
| 78 | + } |
| 79 | + return res; |
| 80 | +} |
| 81 | + |
| 82 | +function compareDataViewsUint32(dv_1: DataView, ...dvs: DataView[]) { |
| 83 | + if (dvs.some(dv_i => dv_1.byteLength !== dv_i.byteLength)) return false; |
| 84 | + let res = true; |
| 85 | + for (const dv_i of dvs) { |
| 86 | + for (let i = 0; i !== dv_1.byteLength; i += 4) { |
| 87 | + const r = dv_1.getUint32(i) === dv_i.getUint32(i); |
| 88 | + res = r && res; |
| 89 | + } |
| 90 | + } |
| 91 | + return res; |
| 92 | +} |
| 93 | + |
| 94 | +export function compareBufferSources(bufferSource: BufferSource, ...bufferSources: BufferSource[]) { |
| 95 | + return compareDataViewsUint32(bs2dv(bufferSource), ...bufferSources.map(bs2dv)); |
| 96 | +} |
| 97 | + |
| 98 | +export function unsafeCompareUint8Arrays(u8_1: Uint8Array, ...u8s: Uint8Array[]) { |
| 99 | + if (u8s.some(u8_i => u8_1.byteLength !== u8_i.byteLength)) return false; |
| 100 | + return u8s.every(u8_i => { |
| 101 | + for (let i = 0; i !== u8_1.length; i++) if (u8_1[i] !== u8_i[i]) return false; |
| 102 | + return true; |
| 103 | + }); |
| 104 | +} |
| 105 | + |
| 106 | +function unsafeCompareDataViewsUint32(dv_1: DataView, ...dvs: DataView[]) { |
| 107 | + if (dvs.some((dv_i) => dv_1.byteLength !== dv_i.byteLength)) return false; |
| 108 | + return dvs.every(dv_i => { |
| 109 | + for (let i = 0; i !== dv_i.byteLength; i += 4) { |
| 110 | + if (dv_1.getUint32(i) !== dv_i.getUint32(i)) { |
| 111 | + return false; |
| 112 | + } |
| 113 | + } |
| 114 | + return true; |
| 115 | + }); |
| 116 | +} |
| 117 | + |
| 118 | +export function unsafeCompareBufferSources(bufferSource: BufferSource, ...bufferSources: BufferSource[]) { |
| 119 | + return unsafeCompareDataViewsUint32(bs2dv(bufferSource), ...bufferSources.map(bs2dv)); |
| 120 | +} |
0 commit comments