11'use strict' ;
22
3- const { Reflect } = primordials ;
3+ const { Object , Reflect } = primordials ;
44
55const { Buffer, kMaxLength } = require ( 'buffer' ) ;
66const {
@@ -16,7 +16,8 @@ const {
1616} = require ( 'internal/errors' ) ;
1717const {
1818 isUint8Array,
19- isDate
19+ isDate,
20+ isBigUint64Array
2021} = require ( 'internal/util/types' ) ;
2122const { once } = require ( 'internal/util' ) ;
2223const { toPathIfFileURL } = require ( 'internal/url' ) ;
@@ -230,27 +231,9 @@ function preprocessSymlinkDestination(path, type, linkPath) {
230231 }
231232}
232233
233- function dateFromNumeric ( num ) {
234- return new Date ( Number ( num ) + 0.5 ) ;
235- }
236-
237234// Constructor for file stats.
238- function Stats (
239- dev ,
240- mode ,
241- nlink ,
242- uid ,
243- gid ,
244- rdev ,
245- blksize ,
246- ino ,
247- size ,
248- blocks ,
249- atim_msec ,
250- mtim_msec ,
251- ctim_msec ,
252- birthtim_msec
253- ) {
235+ function StatsBase ( dev , mode , nlink , uid , gid , rdev , blksize ,
236+ ino , size , blocks ) {
254237 this . dev = dev ;
255238 this . mode = mode ;
256239 this . nlink = nlink ;
@@ -261,63 +244,132 @@ function Stats(
261244 this . ino = ino ;
262245 this . size = size ;
263246 this . blocks = blocks ;
264- this . atimeMs = atim_msec ;
265- this . mtimeMs = mtim_msec ;
266- this . ctimeMs = ctim_msec ;
267- this . birthtimeMs = birthtim_msec ;
268- this . atime = dateFromNumeric ( atim_msec ) ;
269- this . mtime = dateFromNumeric ( mtim_msec ) ;
270- this . ctime = dateFromNumeric ( ctim_msec ) ;
271- this . birthtime = dateFromNumeric ( birthtim_msec ) ;
272247}
273248
274- Stats . prototype . _checkModeProperty = function ( property ) {
275- if ( isWindows && ( property === S_IFIFO || property === S_IFBLK ||
276- property === S_IFSOCK ) ) {
277- return false ; // Some types are not available on Windows
278- }
279- if ( typeof this . mode === 'bigint' ) { // eslint-disable-line valid-typeof
280- return ( this . mode & BigInt ( S_IFMT ) ) === BigInt ( property ) ;
281- }
282- return ( this . mode & S_IFMT ) === property ;
283- } ;
284-
285- Stats . prototype . isDirectory = function ( ) {
249+ StatsBase . prototype . isDirectory = function ( ) {
286250 return this . _checkModeProperty ( S_IFDIR ) ;
287251} ;
288252
289- Stats . prototype . isFile = function ( ) {
253+ StatsBase . prototype . isFile = function ( ) {
290254 return this . _checkModeProperty ( S_IFREG ) ;
291255} ;
292256
293- Stats . prototype . isBlockDevice = function ( ) {
257+ StatsBase . prototype . isBlockDevice = function ( ) {
294258 return this . _checkModeProperty ( S_IFBLK ) ;
295259} ;
296260
297- Stats . prototype . isCharacterDevice = function ( ) {
261+ StatsBase . prototype . isCharacterDevice = function ( ) {
298262 return this . _checkModeProperty ( S_IFCHR ) ;
299263} ;
300264
301- Stats . prototype . isSymbolicLink = function ( ) {
265+ StatsBase . prototype . isSymbolicLink = function ( ) {
302266 return this . _checkModeProperty ( S_IFLNK ) ;
303267} ;
304268
305- Stats . prototype . isFIFO = function ( ) {
269+ StatsBase . prototype . isFIFO = function ( ) {
306270 return this . _checkModeProperty ( S_IFIFO ) ;
307271} ;
308272
309- Stats . prototype . isSocket = function ( ) {
273+ StatsBase . prototype . isSocket = function ( ) {
310274 return this . _checkModeProperty ( S_IFSOCK ) ;
311275} ;
312276
277+ const kNsPerMsBigInt = 10n ** 6n ;
278+ const kNsPerSecBigInt = 10n ** 9n ;
279+ const kMsPerSec = 10 ** 3 ;
280+ const kNsPerMs = 10 ** 6 ;
281+ function msFromTimeSpec ( sec , nsec ) {
282+ return sec * kMsPerSec + nsec / kNsPerMs ;
283+ }
284+
285+ function nsFromTimeSpecBigInt ( sec , nsec ) {
286+ return sec * kNsPerSecBigInt + nsec ;
287+ }
288+
289+ function dateFromMs ( ms ) {
290+ return new Date ( Number ( ms ) + 0.5 ) ;
291+ }
292+
293+ function BigIntStats ( dev , mode , nlink , uid , gid , rdev , blksize ,
294+ ino , size , blocks ,
295+ atimeNs , mtimeNs , ctimeNs , birthtimeNs ) {
296+ StatsBase . call ( this , dev , mode , nlink , uid , gid , rdev , blksize ,
297+ ino , size , blocks ) ;
298+
299+ this . atimeMs = atimeNs / kNsPerMsBigInt ;
300+ this . mtimeMs = mtimeNs / kNsPerMsBigInt ;
301+ this . ctimeMs = ctimeNs / kNsPerMsBigInt ;
302+ this . birthtimeMs = birthtimeNs / kNsPerMsBigInt ;
303+ this . atimeNs = atimeNs ;
304+ this . mtimeNs = mtimeNs ;
305+ this . ctimeNs = ctimeNs ;
306+ this . birthtimeNs = birthtimeNs ;
307+ this . atime = dateFromMs ( this . atimeMs ) ;
308+ this . mtime = dateFromMs ( this . mtimeMs ) ;
309+ this . ctime = dateFromMs ( this . ctimeMs ) ;
310+ this . birthtime = dateFromMs ( this . birthtimeMs ) ;
311+ }
312+
313+ Object . setPrototypeOf ( BigIntStats . prototype , StatsBase . prototype ) ;
314+ Object . setPrototypeOf ( BigIntStats , StatsBase ) ;
315+
316+ BigIntStats . prototype . _checkModeProperty = function ( property ) {
317+ if ( isWindows && ( property === S_IFIFO || property === S_IFBLK ||
318+ property === S_IFSOCK ) ) {
319+ return false ; // Some types are not available on Windows
320+ }
321+ return ( this . mode & BigInt ( S_IFMT ) ) === BigInt ( property ) ;
322+ } ;
323+
324+ function Stats ( dev , mode , nlink , uid , gid , rdev , blksize ,
325+ ino , size , blocks ,
326+ atimeMs , mtimeMs , ctimeMs , birthtimeMs ) {
327+ StatsBase . call ( this , dev , mode , nlink , uid , gid , rdev , blksize ,
328+ ino , size , blocks ) ;
329+ this . atimeMs = atimeMs ;
330+ this . mtimeMs = mtimeMs ;
331+ this . ctimeMs = ctimeMs ;
332+ this . birthtimeMs = birthtimeMs ;
333+ this . atime = dateFromMs ( atimeMs ) ;
334+ this . mtime = dateFromMs ( mtimeMs ) ;
335+ this . ctime = dateFromMs ( ctimeMs ) ;
336+ this . birthtime = dateFromMs ( birthtimeMs ) ;
337+ }
338+
339+ Object . setPrototypeOf ( Stats . prototype , StatsBase . prototype ) ;
340+ Object . setPrototypeOf ( Stats , StatsBase ) ;
341+
342+ Stats . prototype . _checkModeProperty = function ( property ) {
343+ if ( isWindows && ( property === S_IFIFO || property === S_IFBLK ||
344+ property === S_IFSOCK ) ) {
345+ return false ; // Some types are not available on Windows
346+ }
347+ return ( this . mode & S_IFMT ) === property ;
348+ } ;
349+
313350function getStatsFromBinding ( stats , offset = 0 ) {
314- return new Stats ( stats [ 0 + offset ] , stats [ 1 + offset ] , stats [ 2 + offset ] ,
315- stats [ 3 + offset ] , stats [ 4 + offset ] , stats [ 5 + offset ] ,
316- stats [ 6 + offset ] , // blksize
317- stats [ 7 + offset ] , stats [ 8 + offset ] ,
318- stats [ 9 + offset ] , // blocks
319- stats [ 10 + offset ] , stats [ 11 + offset ] ,
320- stats [ 12 + offset ] , stats [ 13 + offset ] ) ;
351+ if ( isBigUint64Array ( stats ) ) {
352+ return new BigIntStats (
353+ stats [ 0 + offset ] , stats [ 1 + offset ] , stats [ 2 + offset ] ,
354+ stats [ 3 + offset ] , stats [ 4 + offset ] , stats [ 5 + offset ] ,
355+ stats [ 6 + offset ] , stats [ 7 + offset ] , stats [ 8 + offset ] ,
356+ stats [ 9 + offset ] ,
357+ nsFromTimeSpecBigInt ( stats [ 10 + offset ] , stats [ 11 + offset ] ) ,
358+ nsFromTimeSpecBigInt ( stats [ 12 + offset ] , stats [ 13 + offset ] ) ,
359+ nsFromTimeSpecBigInt ( stats [ 14 + offset ] , stats [ 15 + offset ] ) ,
360+ nsFromTimeSpecBigInt ( stats [ 16 + offset ] , stats [ 17 + offset ] )
361+ ) ;
362+ }
363+ return new Stats (
364+ stats [ 0 + offset ] , stats [ 1 + offset ] , stats [ 2 + offset ] ,
365+ stats [ 3 + offset ] , stats [ 4 + offset ] , stats [ 5 + offset ] ,
366+ stats [ 6 + offset ] , stats [ 7 + offset ] , stats [ 8 + offset ] ,
367+ stats [ 9 + offset ] ,
368+ msFromTimeSpec ( stats [ 10 + offset ] , stats [ 11 + offset ] ) ,
369+ msFromTimeSpec ( stats [ 12 + offset ] , stats [ 13 + offset ] ) ,
370+ msFromTimeSpec ( stats [ 14 + offset ] , stats [ 15 + offset ] ) ,
371+ msFromTimeSpec ( stats [ 16 + offset ] , stats [ 17 + offset ] )
372+ ) ;
321373}
322374
323375function stringToFlags ( flags ) {
@@ -453,6 +505,7 @@ function warnOnNonPortableTemplate(template) {
453505
454506module . exports = {
455507 assertEncoding,
508+ BigIntStats, // for testing
456509 copyObject,
457510 Dirent,
458511 getDirents,
0 commit comments