@@ -104,7 +104,6 @@ const {
104104 isAnyArrayBuffer,
105105 isArrayBufferView,
106106 isUint8Array,
107- isTypedArray,
108107} = require ( 'internal/util/types' ) ;
109108const {
110109 inspect : utilInspect ,
@@ -154,6 +153,14 @@ FastBuffer.prototype.constructor = Buffer;
154153Buffer . prototype = FastBuffer . prototype ;
155154addBufferPrototypeMethods ( Buffer . prototype ) ;
156155
156+ const BUFFER_NAMES = [
157+ 'ArrayBuffer' ,
158+ 'Buffer' ,
159+ 'TypedArray' ,
160+ 'DataView' ,
161+ 'SharedArrayBuffer' ,
162+ ] ;
163+
157164const constants = ObjectDefineProperties ( { } , {
158165 MAX_LENGTH : {
159166 __proto__ : null ,
@@ -232,10 +239,18 @@ function toInteger(n, defaultVal) {
232239}
233240
234241function copyImpl ( source , target , targetStart , sourceStart , sourceEnd ) {
235- if ( ! ArrayBufferIsView ( source ) )
236- throw new ERR_INVALID_ARG_TYPE ( 'source' , [ 'Buffer' , 'Uint8Array' ] , source ) ;
237- if ( ! ArrayBufferIsView ( target ) )
238- throw new ERR_INVALID_ARG_TYPE ( 'target' , [ 'Buffer' , 'Uint8Array' ] , target ) ;
242+ if ( source ?. constructor === DataView || isAnyArrayBuffer ( source ) ) {
243+ source = new Uint8Array ( source . buffer ?? source , source . byteOffset ?? 0 ,
244+ source . byteLength ) ;
245+ } else if ( ! isArrayBufferView ( source ) ) {
246+ throw new ERR_INVALID_ARG_TYPE ( 'source' , BUFFER_NAMES , source ) ;
247+ }
248+ if ( target ?. constructor === DataView || isAnyArrayBuffer ( target ) ) {
249+ target = new Uint8Array ( target . buffer ?? target , target . byteOffset ?? 0 ,
250+ target . byteLength ) ;
251+ } else if ( ! isArrayBufferView ( target ) ) {
252+ throw new ERR_INVALID_ARG_TYPE ( 'target' , BUFFER_NAMES , target ) ;
253+ }
239254
240255 if ( targetStart === undefined ) {
241256 targetStart = 0 ;
@@ -359,22 +374,29 @@ Buffer.from = function from(value, encodingOrOffset, length) {
359374
360375 throw new ERR_INVALID_ARG_TYPE (
361376 'first argument' ,
362- [ 'string' , 'Buffer' , 'ArrayBuffer' , ' Array', 'Array-like Object' ] ,
377+ [ 'string' , 'Array' , 'Array-like Object' , ... BUFFER_NAMES ] ,
363378 value ,
364379 ) ;
365380} ;
366381
367382/**
368383 * Creates the Buffer as a copy of the underlying ArrayBuffer of the view
369384 * rather than the contents of the view.
370- * @param {TypedArray } view
385+ * @param {Buffer| TypedArray|DataView } view
371386 * @param {number } [offset]
372387 * @param {number } [length]
373388 * @returns {Buffer }
374389 */
375390Buffer . copyBytesFrom = function copyBytesFrom ( view , offset , length ) {
376- if ( ! isTypedArray ( view ) ) {
377- throw new ERR_INVALID_ARG_TYPE ( 'view' , [ 'TypedArray' ] , view ) ;
391+ if ( view ?. constructor === DataView ) {
392+ // Normalize DataView to Uint8Array so we can use TypedArray primordials.
393+ view = new Uint8Array ( view . buffer , view . byteOffset , view . byteLength ) ;
394+ } else if ( isArrayBufferView ( view ) ) {
395+ // Do nothing..
396+ } else if ( isAnyArrayBuffer ( view ) ) {
397+ view = new Uint8Array ( view ) ;
398+ } else {
399+ throw new ERR_INVALID_ARG_TYPE ( 'view' , BUFFER_NAMES , view ) ;
378400 }
379401
380402 const viewLength = TypedArrayPrototypeGetLength ( view ) ;
@@ -399,16 +421,11 @@ Buffer.copyBytesFrom = function copyBytesFrom(view, offset, length) {
399421
400422 if ( end <= start ) return new FastBuffer ( ) ;
401423
402- const viewByteLength = TypedArrayPrototypeGetByteLength ( view ) ;
403- const elementSize = viewByteLength / viewLength ;
404- const srcByteOffset = TypedArrayPrototypeGetByteOffset ( view ) +
405- start * elementSize ;
406- const srcByteLength = ( end - start ) * elementSize ;
407-
424+ const srcView = TypedArrayPrototypeSubarray ( view , start , end ) ;
408425 return fromArrayLike ( new Uint8Array (
409- TypedArrayPrototypeGetBuffer ( view ) ,
410- srcByteOffset ,
411- srcByteLength ) ) ;
426+ TypedArrayPrototypeGetBuffer ( srcView ) ,
427+ TypedArrayPrototypeGetByteOffset ( srcView ) ,
428+ TypedArrayPrototypeGetByteLength ( srcView ) ) ) ;
412429} ;
413430
414431// Identical to the built-in %TypedArray%.of(), but avoids using the deprecated
@@ -620,12 +637,17 @@ Buffer.concat = function concat(list, length) {
620637 if ( length === undefined ) {
621638 length = 0 ;
622639 for ( let i = 0 ; i < list . length ; i ++ ) {
623- const buf = list [ i ] ;
624- if ( ! isUint8Array ( buf ) ) {
640+ let buf = list [ i ] ;
641+ if ( buf ?. constructor === DataView || isAnyArrayBuffer ( buf ) ) {
642+ buf = list [ i ] = new Uint8Array ( buf . buffer ?? buf , buf . byteOffset ?? 0 ,
643+ buf . byteLength ) ;
644+ } else if ( isArrayBufferView ( buf ) ) {
645+ // Do nothing..
646+ } else {
625647 // TODO(BridgeAR): This should not be of type ERR_INVALID_ARG_TYPE.
626648 // Instead, find the proper error code for this.
627649 throw new ERR_INVALID_ARG_TYPE (
628- `list[${ i } ]` , [ 'Buffer' , 'Uint8Array' ] , buf ) ;
650+ `list[${ i } ]` , BUFFER_NAMES , buf ) ;
629651 }
630652 length += TypedArrayPrototypeGetByteLength ( buf ) ;
631653 }
@@ -647,11 +669,17 @@ Buffer.concat = function concat(list, length) {
647669
648670 validateOffset ( length , 'length' ) ;
649671 for ( let i = 0 ; i < list . length ; i ++ ) {
650- if ( ! isUint8Array ( list [ i ] ) ) {
672+ if ( list [ i ] ?. constructor === DataView || isAnyArrayBuffer ( list [ i ] ) ) {
673+ const buf = list [ i ] ;
674+ list [ i ] = new Uint8Array ( buf . buffer ?? buf , buf . byteOffset ?? 0 ,
675+ buf . byteLength ) ;
676+ } else if ( isArrayBufferView ( list [ i ] ) ) {
677+ // Do nothing..
678+ } else {
651679 // TODO(BridgeAR): This should not be of type ERR_INVALID_ARG_TYPE.
652680 // Instead, find the proper error code for this.
653681 throw new ERR_INVALID_ARG_TYPE (
654- `list[${ i } ]` , [ 'Buffer' , 'Uint8Array' ] , list [ i ] ) ;
682+ `list[${ i } ]` , BUFFER_NAMES , list [ i ] ) ;
655683 }
656684 }
657685
@@ -834,10 +862,7 @@ function byteLength(string, encoding) {
834862 if ( isArrayBufferView ( string ) || isAnyArrayBuffer ( string ) ) {
835863 return string . byteLength ;
836864 }
837-
838- throw new ERR_INVALID_ARG_TYPE (
839- 'string' , [ 'string' , 'Buffer' , 'ArrayBuffer' ] , string ,
840- ) ;
865+ throw new ERR_INVALID_ARG_TYPE ( 'string' , [ 'string' , ...BUFFER_NAMES ] , string ) ;
841866 }
842867
843868 const len = string . length ;
@@ -926,15 +951,18 @@ Buffer.prototype.toString = function toString(encoding, start, end) {
926951} ;
927952
928953Buffer . prototype . equals = function equals ( otherBuffer ) {
929- if ( ! isUint8Array ( otherBuffer ) ) {
930- throw new ERR_INVALID_ARG_TYPE (
931- 'otherBuffer' , [ 'Buffer' , 'Uint8Array' ] , otherBuffer ) ;
954+ if ( isArrayBufferView ( otherBuffer ) ) {
955+ // Do nothing..
956+ } else if ( isAnyArrayBuffer ( otherBuffer ) ) {
957+ otherBuffer = new Uint8Array ( otherBuffer ) ;
958+ } else {
959+ throw new ERR_INVALID_ARG_TYPE ( 'otherBuffer' , BUFFER_NAMES , otherBuffer ) ;
932960 }
933961
934962 if ( this === otherBuffer )
935963 return true ;
936964 const len = TypedArrayPrototypeGetByteLength ( this ) ;
937- if ( len !== TypedArrayPrototypeGetByteLength ( otherBuffer ) )
965+ if ( len !== otherBuffer . byteLength )
938966 return false ;
939967
940968 return len === 0 || _compare ( this , otherBuffer ) === 0 ;
@@ -988,9 +1016,14 @@ Buffer.prototype.compare = function compare(target,
9881016 targetEnd ,
9891017 sourceStart ,
9901018 sourceEnd ) {
991- if ( ! isUint8Array ( target ) ) {
992- throw new ERR_INVALID_ARG_TYPE ( 'target' , [ 'Buffer' , 'Uint8Array' ] , target ) ;
1019+ if ( isArrayBufferView ( target ) ) {
1020+ // Do nothing..
1021+ } else if ( isAnyArrayBuffer ( target ) ) {
1022+ target = new Uint8Array ( target ) ;
1023+ } else {
1024+ throw new ERR_INVALID_ARG_TYPE ( 'target' , BUFFER_NAMES , target ) ;
9931025 }
1026+
9941027 if ( arguments . length === 1 )
9951028 return _compare ( this , target ) ;
9961029
@@ -1066,14 +1099,14 @@ function bidirectionalIndexOf(buffer, val, byteOffset, encoding, dir) {
10661099 return ops . indexOf ( buffer , val , byteOffset , dir ) ;
10671100 }
10681101
1069- if ( isUint8Array ( val ) ) {
1102+ if ( isArrayBufferView ( val ) || isAnyArrayBuffer ( val ) ) {
10701103 const encodingVal =
10711104 ( ops === undefined ? encodingsMap . utf8 : ops . encodingVal ) ;
10721105 return indexOfBuffer ( buffer , val , byteOffset , encodingVal , dir ) ;
10731106 }
10741107
10751108 throw new ERR_INVALID_ARG_TYPE (
1076- 'value' , [ 'number' , 'string' , 'Buffer' , 'Uint8Array' ] , val ,
1109+ 'value' , [ 'number' , 'string' , ... BUFFER_NAMES ] , val ,
10771110 ) ;
10781111}
10791112
@@ -1244,7 +1277,9 @@ Buffer.prototype.subarray = function subarray(start, end) {
12441277 start = adjustOffset ( start , srcLength ) ;
12451278 end = end !== undefined ? adjustOffset ( end , srcLength ) : srcLength ;
12461279 const newLength = end > start ? end - start : 0 ;
1247- return new FastBuffer ( this . buffer , this . byteOffset + start , newLength ) ;
1280+ return new FastBuffer ( TypedArrayPrototypeGetBuffer ( this ) ,
1281+ TypedArrayPrototypeGetByteOffset ( this ) + start ,
1282+ newLength ) ;
12481283} ;
12491284
12501285Buffer . prototype . slice = function slice ( start , end ) {
@@ -1328,9 +1363,8 @@ if (internalBinding('config').hasIntl) {
13281363 // Transcodes the Buffer from one encoding to another, returning a new
13291364 // Buffer instance.
13301365 transcode = function transcode ( source , fromEncoding , toEncoding ) {
1331- if ( ! isUint8Array ( source ) ) {
1332- throw new ERR_INVALID_ARG_TYPE ( 'source' ,
1333- [ 'Buffer' , 'Uint8Array' ] , source ) ;
1366+ if ( ! ArrayBufferIsView ( source ) && ! isAnyArrayBuffer ( source ) ) {
1367+ throw new ERR_INVALID_ARG_TYPE ( 'source' , BUFFER_NAMES , source ) ;
13341368 }
13351369 if ( source . length === 0 ) return new FastBuffer ( ) ;
13361370
@@ -1386,19 +1420,19 @@ function atob(input) {
13861420}
13871421
13881422function isUtf8 ( input ) {
1389- if ( isTypedArray ( input ) || isAnyArrayBuffer ( input ) ) {
1423+ if ( isArrayBufferView ( input ) || isAnyArrayBuffer ( input ) ) {
13901424 return bindingIsUtf8 ( input ) ;
13911425 }
13921426
1393- throw new ERR_INVALID_ARG_TYPE ( 'input' , [ 'ArrayBuffer' , 'Buffer' , 'TypedArray' ] , input ) ;
1427+ throw new ERR_INVALID_ARG_TYPE ( 'input' , BUFFER_NAMES , input ) ;
13941428}
13951429
13961430function isAscii ( input ) {
1397- if ( isTypedArray ( input ) || isAnyArrayBuffer ( input ) ) {
1431+ if ( isArrayBufferView ( input ) || isAnyArrayBuffer ( input ) ) {
13981432 return bindingIsAscii ( input ) ;
13991433 }
14001434
1401- throw new ERR_INVALID_ARG_TYPE ( 'input' , [ 'ArrayBuffer' , 'Buffer' , 'TypedArray' ] , input ) ;
1435+ throw new ERR_INVALID_ARG_TYPE ( 'input' , BUFFER_NAMES , input ) ;
14021436}
14031437
14041438module . exports = {
0 commit comments