mirror of
				https://github.com/Xahau/xahau.js.git
				synced 2025-11-04 04:55:48 +00:00 
			
		
		
		
	- Removes need for bundlers to polyfill the `Buffer` class. `UInt8Array` are used instead which are native to the browser and node. - Reduces bundle size 7.1kb gzipped and eliminates 4 runtime dependencies: `base-x`, `base64-js`, `buffer`, and `ieee754`. BREAKING CHANGE: All methods that previously took a `Buffer` now accept a `UInt8Array`. --------- Co-authored-by: Jackson Mills <jmills@ripple.com>
		
			
				
	
	
		
			153 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			153 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
// Even though this comes from NodeJS it is valid in the browser
 | 
						|
import TypedArray = NodeJS.TypedArray
 | 
						|
 | 
						|
/**
 | 
						|
 * Writes value to array at the specified offset. The value must be a valid unsigned 8-bit integer.
 | 
						|
 * @param array Uint8Array to be written to
 | 
						|
 * @param value Number to be written to array.
 | 
						|
 * @param offset plus the number of bytes written.
 | 
						|
 */
 | 
						|
export function writeUInt8(
 | 
						|
  array: Uint8Array,
 | 
						|
  value: number,
 | 
						|
  offset: number,
 | 
						|
): void {
 | 
						|
  value = Number(value)
 | 
						|
  array[offset] = value
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Writes value to array at the specified offset as big-endian. The value must be a valid unsigned 16-bit integer.
 | 
						|
 * @param array Uint8Array to be written to
 | 
						|
 * @param value Number to be written to array.
 | 
						|
 * @param offset plus the number of bytes written.
 | 
						|
 */
 | 
						|
export function writeUInt16BE(
 | 
						|
  array: Uint8Array,
 | 
						|
  value: number,
 | 
						|
  offset: number,
 | 
						|
): void {
 | 
						|
  value = Number(value)
 | 
						|
 | 
						|
  array[offset] = value >>> 8
 | 
						|
  array[offset + 1] = value
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Writes value to array at the specified offset as big-endian. The value must be a valid unsigned 32-bit integer.
 | 
						|
 * @param array Uint8Array to be written to
 | 
						|
 * @param value Number to be written to array.
 | 
						|
 * @param offset plus the number of bytes written.
 | 
						|
 */
 | 
						|
export function writeUInt32BE(
 | 
						|
  array: Uint8Array,
 | 
						|
  value: number,
 | 
						|
  offset: number,
 | 
						|
): void {
 | 
						|
  array[offset] = (value >>> 24) & 0xff
 | 
						|
  array[offset + 1] = (value >>> 16) & 0xff
 | 
						|
  array[offset + 2] = (value >>> 8) & 0xff
 | 
						|
  array[offset + 3] = value & 0xff
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Reads an unsigned, big-endian 16-bit integer from the array at the specified offset.
 | 
						|
 * @param array Uint8Array to read
 | 
						|
 * @param offset Number of bytes to skip before starting to read. Must satisfy 0 <= offset <= buf.length - 2
 | 
						|
 */
 | 
						|
export function readUInt16BE(array: Uint8Array, offset: number): string {
 | 
						|
  return new DataView(array.buffer).getUint16(offset, false).toString(10)
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Reads an unsigned, big-endian 16-bit integer from the array at the specified offset.
 | 
						|
 * @param array Uint8Array to read
 | 
						|
 * @param offset Number of bytes to skip before starting to read. Must satisfy 0 <= offset <= buf.length - 4
 | 
						|
 */
 | 
						|
export function readUInt32BE(array: Uint8Array, offset: number): string {
 | 
						|
  return new DataView(array.buffer).getUint32(offset, false).toString(10)
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Compares two Uint8Array or ArrayBuffers
 | 
						|
 * @param a first array to compare
 | 
						|
 * @param b second array to compare
 | 
						|
 */
 | 
						|
export function equal(
 | 
						|
  a: Uint8Array | ArrayBuffer,
 | 
						|
  b: Uint8Array | ArrayBuffer,
 | 
						|
): boolean {
 | 
						|
  const aUInt = a instanceof ArrayBuffer ? new Uint8Array(a, 0) : a
 | 
						|
  const bUInt = b instanceof ArrayBuffer ? new Uint8Array(b, 0) : b
 | 
						|
  if (aUInt.byteLength != bUInt.byteLength) return false
 | 
						|
  if (aligned32(aUInt) && aligned32(bUInt)) return compare32(aUInt, bUInt) === 0
 | 
						|
  if (aligned16(aUInt) && aligned16(bUInt)) return compare16(aUInt, bUInt) === 0
 | 
						|
  return compare8(aUInt, bUInt) === 0
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Compares two 8 bit aligned arrays
 | 
						|
 * @param a first array to compare
 | 
						|
 * @param b second array to compare
 | 
						|
 */
 | 
						|
function compare8(a, b) {
 | 
						|
  const ua = new Uint8Array(a.buffer, a.byteOffset, a.byteLength)
 | 
						|
  const ub = new Uint8Array(b.buffer, b.byteOffset, b.byteLength)
 | 
						|
  return compare(ua, ub)
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Compares two 16 bit aligned arrays
 | 
						|
 * @param a first array to compare
 | 
						|
 * @param b second array to compare
 | 
						|
 */
 | 
						|
function compare16(a: Uint8Array, b: Uint8Array) {
 | 
						|
  const ua = new Uint16Array(a.buffer, a.byteOffset, a.byteLength / 2)
 | 
						|
  const ub = new Uint16Array(b.buffer, b.byteOffset, b.byteLength / 2)
 | 
						|
  return compare(ua, ub)
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Compares two 32 bit aligned arrays
 | 
						|
 * @param a first array to compare
 | 
						|
 * @param b second array to compare
 | 
						|
 */
 | 
						|
function compare32(a: Uint8Array, b: Uint8Array) {
 | 
						|
  const ua = new Uint32Array(a.buffer, a.byteOffset, a.byteLength / 4)
 | 
						|
  const ub = new Uint32Array(b.buffer, b.byteOffset, b.byteLength / 4)
 | 
						|
  return compare(ua, ub)
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Compare two TypedArrays
 | 
						|
 * @param a first array to compare
 | 
						|
 * @param b second array to compare
 | 
						|
 */
 | 
						|
export function compare(a: TypedArray, b: TypedArray): 1 | -1 | 0 {
 | 
						|
  if (a.byteLength !== b.byteLength) {
 | 
						|
    throw new Error('Cannot compare arrays of different length')
 | 
						|
  }
 | 
						|
 | 
						|
  for (let i = 0; i < a.length - 1; i += 1) {
 | 
						|
    if (a[i] > b[i]) return 1
 | 
						|
    if (a[i] < b[i]) return -1
 | 
						|
  }
 | 
						|
  return 0
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Determine if TypedArray is 16 bit aligned
 | 
						|
 * @param array The array to check
 | 
						|
 */
 | 
						|
function aligned16(array: TypedArray) {
 | 
						|
  return array.byteOffset % 2 === 0 && array.byteLength % 2 === 0
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Determine if TypedArray is 32 bit aligned
 | 
						|
 * @param array The array to check
 | 
						|
 */
 | 
						|
function aligned32(array: TypedArray) {
 | 
						|
  return array.byteOffset % 4 === 0 && array.byteLength % 4 === 0
 | 
						|
}
 |