11import { assert , assertUint8 } from './assert.js'
22
3- // TODO: make Buffer optional
3+ const { Buffer } = globalThis // Buffer is optional, only used when native
4+ const haveNativeBuffer = Buffer && ! Buffer . TYPED_ARRAY_SUPPORT
5+
6+ let hexArray
7+ let hexMap
48
59// From Uint8Array or a Buffer, defaults to uint8
610export function fromUint8Super ( arr , format = 'uint8' ) {
@@ -14,8 +18,13 @@ export function fromUint8Super(arr, format = 'uint8') {
1418 return Buffer . from ( arr . buffer , arr . byteOffset , arr . byteLength )
1519 case 'hex' :
1620 if ( Uint8Array . prototype . toHex && arr . toHex === Uint8Array . prototype . toHex ) return arr . toHex ( )
17- if ( arr . constructor === Buffer && Buffer . isBuffer ( arr ) ) return arr . toString ( 'hex' )
18- return Buffer . from ( arr . buffer , arr . byteOffset , arr . byteLength ) . toString ( 'hex' )
21+ if ( haveNativeBuffer ) {
22+ if ( arr . constructor === Buffer && Buffer . isBuffer ( arr ) ) return arr . toString ( 'hex' )
23+ return Buffer . from ( arr . buffer , arr . byteOffset , arr . byteLength ) . toString ( 'hex' )
24+ }
25+ // TODO: measure perf/optimize?
26+ if ( ! hexArray ) hexArray = Array . from ( { length : 256 } , ( _ , i ) => i . toString ( 16 ) . padStart ( 2 , '0' ) )
27+ return Array . from ( { length : arr . length } , ( _ , i ) => hexArray [ arr [ i ] ] ) . join ( '' )
1928 }
2029
2130 throw new TypeError ( 'Unexpected format' )
@@ -26,5 +35,13 @@ export function fromHex(arg, format = 'uint8') {
2635 if ( Uint8Array . fromHex ) return fromUint8Super ( Uint8Array . fromHex ( arg ) , format )
2736 if ( typeof arg !== 'string' ) throw new TypeError ( 'Input is not a string' )
2837 assert ( arg . length % 2 === 0 && ! / [ ^ 0 - 9 a - f ] / ui. test ( arg ) , 'Input is not a hex string' )
29- return fromUint8Super ( Buffer . from ( arg , 'hex' ) , format )
38+ if ( haveNativeBuffer ) return fromUint8Super ( Buffer . from ( arg , 'hex' ) , format )
39+ // TODO: measure perf/optimize?
40+ if ( ! hexMap ) {
41+ hexMap = Object . create ( null )
42+ for ( let i = 0 ; i < 256 ; i ++ ) hexMap [ i . toString ( 16 ) . padStart ( 2 , '0' ) ] = i
43+ }
44+ const length = arg . length / 2
45+ const arr = Uint8Array . from ( { length } , ( _ , i ) => hexMap [ arg [ 2 * i ] + arg [ 2 * i + 1 ] ] )
46+ return fromUint8Super ( arr , format )
3047}
0 commit comments