@@ -20,7 +20,7 @@ var getPathParts = require('./filesystem').getPathParts;
20
20
* @return {* } Return (if callback is not provided).
21
21
*/
22
22
function maybeCallback ( callback , thisArg , func ) {
23
- if ( callback ) {
23
+ if ( callback && ( typeof callback === 'function' || typeof callback . oncomplete === 'function' ) ) {
24
24
var err = null ;
25
25
var val ;
26
26
try {
@@ -266,11 +266,36 @@ Binding.prototype.realpath = function(filepath, encoding, callback) {
266
266
} ) ;
267
267
} ;
268
268
269
+ /**
270
+ * Fill a Float64Array with stat information
271
+ * This is based on the internal FillStatsArray function in Node.
272
+ * https://github.com/nodejs/node/blob/4e05952a8a75af6df625415db612d3a9a1322682/src/node_file.cc#L533
273
+ * @param {object } stats An object with file stats
274
+ * @param {Float64Array } statValues A Float64Array where stat values should be inserted
275
+ * @returns {void }
276
+ */
277
+ function fillStatsArray ( stats , statValues ) {
278
+ statValues [ 0 ] = stats . dev ;
279
+ statValues [ 1 ] = stats . mode ;
280
+ statValues [ 2 ] = stats . nlink ;
281
+ statValues [ 3 ] = stats . uid ;
282
+ statValues [ 4 ] = stats . gid ;
283
+ statValues [ 5 ] = stats . rdev ;
284
+ statValues [ 6 ] = stats . blksize ;
285
+ statValues [ 7 ] = stats . ino ;
286
+ statValues [ 8 ] = stats . size ;
287
+ statValues [ 9 ] = stats . blocks ;
288
+ statValues [ 10 ] = + stats . atime ;
289
+ statValues [ 11 ] = + stats . mtime ;
290
+ statValues [ 12 ] = + stats . ctime ;
291
+ statValues [ 13 ] = + stats . birthtime ;
292
+ }
269
293
270
294
/**
271
295
* Stat an item.
272
296
* @param {string } filepath Path.
273
- * @param {function(Error, Stats) } callback Callback (optional).
297
+ * @param {function(Error, Stats)|Float64Array } callback Callback (optional). In Node 7.7.0+ this will be a Float64Array
298
+ * that should be filled with stat values.
274
299
* @return {Stats|undefined } Stats or undefined (if sync).
275
300
*/
276
301
Binding . prototype . stat = function ( filepath , callback ) {
@@ -283,22 +308,41 @@ Binding.prototype.stat = function(filepath, callback) {
283
308
if ( ! item ) {
284
309
throw new FSError ( 'ENOENT' , filepath ) ;
285
310
}
286
- return new Stats ( item . getStats ( ) ) ;
311
+ var stats = item . getStats ( ) ;
312
+
313
+ // In Node 7.7.0+, binding.stat accepts a Float64Array as the second argument,
314
+ // which should be filled with stat values.
315
+ // In prior versions of Node, binding.stat simply returns a Stats instance.
316
+ if ( callback instanceof Float64Array ) {
317
+ fillStatsArray ( stats , callback ) ;
318
+ } else {
319
+ return new Stats ( stats ) ;
320
+ }
287
321
} ) ;
288
322
} ;
289
323
290
324
291
325
/**
292
326
* Stat an item.
293
327
* @param {number } fd File descriptor.
294
- * @param {function(Error, Stats) } callback Callback (optional).
328
+ * @param {function(Error, Stats)|Float64Array } callback Callback (optional). In Node 7.7.0+ this will be a Float64Array
329
+ * that should be filled with stat values.
295
330
* @return {Stats|undefined } Stats or undefined (if sync).
296
331
*/
297
332
Binding . prototype . fstat = function ( fd , callback ) {
298
333
return maybeCallback ( callback , this , function ( ) {
299
334
var descriptor = this . _getDescriptorById ( fd ) ;
300
335
var item = descriptor . getItem ( ) ;
301
- return new Stats ( item . getStats ( ) ) ;
336
+ var stats = item . getStats ( ) ;
337
+
338
+ // In Node 7.7.0+, binding.stat accepts a Float64Array as the second argument,
339
+ // which should be filled with stat values.
340
+ // In prior versions of Node, binding.stat simply returns a Stats instance.
341
+ if ( callback instanceof Float64Array ) {
342
+ fillStatsArray ( stats , callback ) ;
343
+ } else {
344
+ return new Stats ( stats ) ;
345
+ }
302
346
} ) ;
303
347
} ;
304
348
@@ -933,7 +977,8 @@ Binding.prototype.readlink = function(pathname, encoding, callback) {
933
977
/**
934
978
* Stat an item.
935
979
* @param {string } filepath Path.
936
- * @param {function(Error, Stats) } callback Callback (optional).
980
+ * @param {function(Error, Stats)|Float64Array } callback Callback (optional). In Node 7.7.0+ this will be a Float64Array
981
+ * that should be filled with stat values.
937
982
* @return {Stats|undefined } Stats or undefined (if sync).
938
983
*/
939
984
Binding . prototype . lstat = function ( filepath , callback ) {
@@ -942,7 +987,16 @@ Binding.prototype.lstat = function(filepath, callback) {
942
987
if ( ! item ) {
943
988
throw new FSError ( 'ENOENT' , filepath ) ;
944
989
}
945
- return new Stats ( item . getStats ( ) ) ;
990
+ var stats = item . getStats ( ) ;
991
+
992
+ // In Node 7.7.0+, binding.stat accepts a Float64Array as the second argument,
993
+ // which should be filled with stat values.
994
+ // In prior versions of Node, binding.stat simply returns a Stats instance.
995
+ if ( callback instanceof Float64Array ) {
996
+ fillStatsArray ( stats , callback ) ;
997
+ } else {
998
+ return new Stats ( item . getStats ( ) ) ;
999
+ }
946
1000
} ) ;
947
1001
} ;
948
1002
0 commit comments