@@ -24,82 +24,148 @@ function createPool() {
24
24
}
25
25
createPool ( ) ;
26
26
27
+ function Buffer ( arg ) {
28
+ if ( ! ( this instanceof Buffer ) ) {
29
+ // Avoid going through an ArgumentsAdaptorTrampoline in the common case.
30
+ if ( arguments . length > 1 )
31
+ return new Buffer ( arg , arguments [ 1 ] ) ;
27
32
28
- function Buffer ( subject , encoding ) {
29
- if ( ! ( this instanceof Buffer ) )
30
- return new Buffer ( subject , encoding ) ;
31
-
32
- if ( typeof subject === 'number' ) {
33
- this . length = + subject ;
34
-
35
- } else if ( typeof subject === 'string' ) {
36
- if ( typeof encoding !== 'string' || encoding . length === 0 )
37
- encoding = 'utf8' ;
38
- this . length = Buffer . byteLength ( subject , encoding ) ;
33
+ return new Buffer ( arg ) ;
34
+ }
39
35
40
- // Handle Arrays, Buffers, Uint8Arrays or JSON.
41
- } else if ( subject !== null && typeof subject === 'object' ) {
42
- if ( subject . type === 'Buffer' && Array . isArray ( subject . data ) )
43
- subject = subject . data ;
44
- this . length = + subject . length ;
36
+ this . length = 0 ;
37
+ this . parent = undefined ;
45
38
46
- } else {
47
- throw new TypeError ( 'must start with number, buffer, array or string' ) ;
39
+ // Common case.
40
+ if ( typeof ( arg ) === 'number' ) {
41
+ fromNumber ( this , arg ) ;
42
+ return ;
48
43
}
49
44
50
- if ( this . length > kMaxLength ) {
51
- throw new RangeError ( 'Attempt to allocate Buffer larger than maximum ' +
52
- 'size: 0x' + kMaxLength . toString ( 16 ) + ' bytes' ) ;
45
+ // Slightly less common case.
46
+ if ( typeof ( arg ) === 'string' ) {
47
+ fromString ( this , arg , arguments . length > 1 ? arguments [ 1 ] : 'utf8' ) ;
48
+ return ;
53
49
}
54
50
55
- if ( this . length < 0 )
56
- this . length = 0 ;
57
- else
58
- this . length >>>= 0 ; // Coerce to uint32.
51
+ // Unusual.
52
+ fromObject ( this , arg ) ;
53
+ }
59
54
60
- this . parent = undefined ;
61
- if ( this . length <= ( Buffer . poolSize >>> 1 ) && this . length > 0 ) {
62
- if ( this . length > poolSize - poolOffset )
63
- createPool ( ) ;
64
- this . parent = sliceOnto ( allocPool ,
65
- this ,
66
- poolOffset ,
67
- poolOffset + this . length ) ;
68
- poolOffset += this . length ;
69
- } else {
70
- alloc ( this , this . length ) ;
71
- }
55
+ function fromNumber ( that , length ) {
56
+ allocate ( that , length < 0 ? 0 : checked ( length ) | 0 ) ;
57
+ }
72
58
73
- if ( typeof subject === 'number' ) {
74
- return ;
59
+ function fromString ( that , string , encoding ) {
60
+ if ( typeof ( encoding ) !== 'string' || encoding === '' )
61
+ encoding = 'utf8' ;
62
+
63
+ // Assumption: byteLength() return value is always < kMaxLength.
64
+ var length = byteLength ( string , encoding ) | 0 ;
65
+ allocate ( that , length ) ;
66
+
67
+ var actual = that . write ( string , encoding ) | 0 ;
68
+ if ( actual !== length ) {
69
+ // Fix up for truncated base64 input. Don't bother returning
70
+ // the unused two or three bytes to the pool.
71
+ that . length = actual ;
72
+ truncate ( that , actual ) ;
75
73
}
74
+ }
76
75
77
- if ( typeof subject === 'string' ) {
78
- // In the case of base64 it's possible that the size of the buffer
79
- // allocated was slightly too large. In this case we need to rewrite
80
- // the length to the actual length written.
81
- var len = this . write ( subject , encoding ) ;
82
- // Buffer was truncated after decode, realloc internal ExternalArray
83
- if ( len !== this . length ) {
84
- var prevLen = this . length ;
85
- this . length = len ;
86
- truncate ( this , this . length ) ;
87
- // Only need to readjust the poolOffset if the allocation is a slice.
88
- if ( this . parent != undefined )
89
- poolOffset -= ( prevLen - len ) ;
90
- }
76
+ function fromObject ( that , object ) {
77
+ if ( object instanceof Buffer )
78
+ return fromBuffer ( that , object ) ;
79
+
80
+ if ( Array . isArray ( object ) )
81
+ return fromArray ( that , object ) ;
82
+
83
+ if ( object == null )
84
+ throw new TypeError ( 'must start with number, buffer, array or string' ) ;
91
85
92
- } else if ( subject instanceof Buffer ) {
93
- subject . copy ( this , 0 , 0 , this . length ) ;
86
+ if ( object . buffer instanceof ArrayBuffer )
87
+ return fromTypedArray ( that , object ) ;
88
+
89
+ if ( object . length )
90
+ return fromArrayLike ( that , object ) ;
91
+
92
+ return fromJsonObject ( that , object ) ;
93
+ }
94
+
95
+ function fromBuffer ( that , buffer ) {
96
+ var length = checked ( buffer . length ) | 0 ;
97
+ allocate ( that , length ) ;
98
+ buffer . copy ( that , 0 , 0 , length ) ;
99
+ }
100
+
101
+ function fromArray ( that , array ) {
102
+ var length = checked ( array . length ) | 0 ;
103
+ allocate ( that , length ) ;
104
+ for ( var i = 0 ; i < length ; i += 1 )
105
+ that [ i ] = array [ i ] & 255 ;
106
+ }
94
107
95
- } else if ( typeof subject . length === 'number' || Array . isArray ( subject ) ) {
96
- // Really crappy way to handle Uint8Arrays, but V8 doesn't give a simple
97
- // way to access the data from the C++ API.
98
- for ( var i = 0 ; i < this . length ; i ++ )
99
- this [ i ] = subject [ i ] ;
108
+ // Duplicate of fromArray() to keep fromArray() monomorphic.
109
+ function fromTypedArray ( that , array ) {
110
+ var length = checked ( array . length ) | 0 ;
111
+ allocate ( that , length ) ;
112
+ // Truncating the elements is probably not what people expect from typed
113
+ // arrays with BYTES_PER_ELEMENT > 1 but it's compatible with the behavior
114
+ // of the old Buffer constructor.
115
+ for ( var i = 0 ; i < length ; i += 1 )
116
+ that [ i ] = array [ i ] & 255 ;
117
+ }
118
+
119
+ function fromArrayLike ( that , array ) {
120
+ var length = checked ( array . length ) | 0 ;
121
+ allocate ( that , length ) ;
122
+ for ( var i = 0 ; i < length ; i += 1 )
123
+ that [ i ] = array [ i ] & 255 ;
124
+ }
125
+
126
+ // Deserialize { type: 'Buffer', data: [1,2,3,...] } into a Buffer object.
127
+ // Returns a zero-length buffer for inputs that don't conform to the spec.
128
+ function fromJsonObject ( that , object ) {
129
+ var array ;
130
+ var length = 0 ;
131
+
132
+ if ( object . type === 'Buffer' && Array . isArray ( object . data ) ) {
133
+ array = object . data ;
134
+ length = checked ( array . length ) | 0 ;
100
135
}
136
+ allocate ( that , length ) ;
137
+
138
+ for ( var i = 0 ; i < length ; i += 1 )
139
+ that [ i ] = array [ i ] & 255 ;
140
+ }
141
+
142
+ function allocate ( that , length ) {
143
+ var fromPool = length !== 0 && length <= Buffer . poolSize >>> 1 ;
144
+ that . parent = fromPool ? palloc ( that , length ) : alloc ( that , length ) ;
145
+ that . length = length ;
101
146
}
102
147
148
+ function palloc ( that , length ) {
149
+ if ( length > poolSize - poolOffset )
150
+ createPool ( ) ;
151
+
152
+ var start = poolOffset ;
153
+ var end = start + length ;
154
+ var buf = sliceOnto ( allocPool , that , start , end ) ;
155
+ poolOffset = end ;
156
+
157
+ return buf ;
158
+ }
159
+
160
+ function checked ( length ) {
161
+ // Note: cannot use `length < kMaxLength` here because that fails when
162
+ // length is NaN (which is otherwise coerced to zero.)
163
+ if ( length >= kMaxLength ) {
164
+ throw new RangeError ( 'Attempt to allocate Buffer larger than maximum ' +
165
+ 'size: 0x' + kMaxLength . toString ( 16 ) + ' bytes' ) ;
166
+ }
167
+ return length >>> 0 ;
168
+ }
103
169
104
170
function SlowBuffer ( length ) {
105
171
length = length >>> 0 ;
@@ -197,30 +263,30 @@ Buffer.concat = function(list, length) {
197
263
} ;
198
264
199
265
200
- Buffer . byteLength = function ( str , enc ) {
201
- var ret ;
202
- str = str + '' ;
203
- switch ( enc ) {
266
+ function byteLength ( string , encoding ) {
267
+ if ( typeof ( string ) !== 'string' )
268
+ string = String ( string ) ;
269
+
270
+ switch ( encoding ) {
204
271
case 'ascii' :
205
272
case 'binary' :
206
273
case 'raw' :
207
- ret = str . length ;
208
- break ;
274
+ return string . length ;
275
+
209
276
case 'ucs2' :
210
277
case 'ucs-2' :
211
278
case 'utf16le' :
212
279
case 'utf-16le' :
213
- ret = str . length * 2 ;
214
- break ;
280
+ return string . length * 2 ;
281
+
215
282
case 'hex' :
216
- ret = str . length >>> 1 ;
217
- break ;
218
- default :
219
- ret = binding . byteLength ( str , enc ) ;
283
+ return string . length >>> 1 ;
220
284
}
221
- return ret ;
222
- } ;
223
285
286
+ return binding . byteLength ( string , encoding ) ;
287
+ }
288
+
289
+ Buffer . byteLength = byteLength ;
224
290
225
291
// toString(encoding, start=0, end=buffer.length)
226
292
Buffer . prototype . toString = function ( encoding , start , end ) {
0 commit comments