"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/fstream/lib/reader.js" (7 Feb 2017, 7084 Bytes) of archive /windows/misc/atom-windows.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Javascript source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 module.exports = Reader
    2 
    3 var fs = require('graceful-fs')
    4 var Stream = require('stream').Stream
    5 var inherits = require('inherits')
    6 var path = require('path')
    7 var getType = require('./get-type.js')
    8 var hardLinks = Reader.hardLinks = {}
    9 var Abstract = require('./abstract.js')
   10 
   11 // Must do this *before* loading the child classes
   12 inherits(Reader, Abstract)
   13 
   14 var LinkReader = require('./link-reader.js')
   15 
   16 function Reader (props, currentStat) {
   17   var self = this
   18   if (!(self instanceof Reader)) return new Reader(props, currentStat)
   19 
   20   if (typeof props === 'string') {
   21     props = { path: props }
   22   }
   23 
   24   if (!props.path) {
   25     self.error('Must provide a path', null, true)
   26   }
   27 
   28   // polymorphism.
   29   // call fstream.Reader(dir) to get a DirReader object, etc.
   30   // Note that, unlike in the Writer case, ProxyReader is going
   31   // to be the *normal* state of affairs, since we rarely know
   32   // the type of a file prior to reading it.
   33 
   34   var type
   35   var ClassType
   36 
   37   if (props.type && typeof props.type === 'function') {
   38     type = props.type
   39     ClassType = type
   40   } else {
   41     type = getType(props)
   42     ClassType = Reader
   43   }
   44 
   45   if (currentStat && !type) {
   46     type = getType(currentStat)
   47     props[type] = true
   48     props.type = type
   49   }
   50 
   51   switch (type) {
   52     case 'Directory':
   53       ClassType = require('./dir-reader.js')
   54       break
   55 
   56     case 'Link':
   57     // XXX hard links are just files.
   58     // However, it would be good to keep track of files' dev+inode
   59     // and nlink values, and create a HardLinkReader that emits
   60     // a linkpath value of the original copy, so that the tar
   61     // writer can preserve them.
   62     // ClassType = HardLinkReader
   63     // break
   64 
   65     case 'File':
   66       ClassType = require('./file-reader.js')
   67       break
   68 
   69     case 'SymbolicLink':
   70       ClassType = LinkReader
   71       break
   72 
   73     case 'Socket':
   74       ClassType = require('./socket-reader.js')
   75       break
   76 
   77     case null:
   78       ClassType = require('./proxy-reader.js')
   79       break
   80   }
   81 
   82   if (!(self instanceof ClassType)) {
   83     return new ClassType(props)
   84   }
   85 
   86   Abstract.call(self)
   87 
   88   self.readable = true
   89   self.writable = false
   90 
   91   self.type = type
   92   self.props = props
   93   self.depth = props.depth = props.depth || 0
   94   self.parent = props.parent || null
   95   self.root = props.root || (props.parent && props.parent.root) || self
   96 
   97   self._path = self.path = path.resolve(props.path)
   98   if (process.platform === 'win32') {
   99     self.path = self._path = self.path.replace(/\?/g, '_')
  100     if (self._path.length >= 260) {
  101       // how DOES one create files on the moon?
  102       // if the path has spaces in it, then UNC will fail.
  103       self._swallowErrors = true
  104       // if (self._path.indexOf(" ") === -1) {
  105       self._path = '\\\\?\\' + self.path.replace(/\//g, '\\')
  106     // }
  107     }
  108   }
  109   self.basename = props.basename = path.basename(self.path)
  110   self.dirname = props.dirname = path.dirname(self.path)
  111 
  112   // these have served their purpose, and are now just noisy clutter
  113   props.parent = props.root = null
  114 
  115   // console.error("\n\n\n%s setting size to", props.path, props.size)
  116   self.size = props.size
  117   self.filter = typeof props.filter === 'function' ? props.filter : null
  118   if (props.sort === 'alpha') props.sort = alphasort
  119 
  120   // start the ball rolling.
  121   // this will stat the thing, and then call self._read()
  122   // to start reading whatever it is.
  123   // console.error("calling stat", props.path, currentStat)
  124   self._stat(currentStat)
  125 }
  126 
  127 function alphasort (a, b) {
  128   return a === b ? 0
  129     : a.toLowerCase() > b.toLowerCase() ? 1
  130       : a.toLowerCase() < b.toLowerCase() ? -1
  131         : a > b ? 1
  132           : -1
  133 }
  134 
  135 Reader.prototype._stat = function (currentStat) {
  136   var self = this
  137   var props = self.props
  138   var stat = props.follow ? 'stat' : 'lstat'
  139   // console.error("Reader._stat", self._path, currentStat)
  140   if (currentStat) process.nextTick(statCb.bind(null, null, currentStat))
  141   else fs[stat](self._path, statCb)
  142 
  143   function statCb (er, props_) {
  144     // console.error("Reader._stat, statCb", self._path, props_, props_.nlink)
  145     if (er) return self.error(er)
  146 
  147     Object.keys(props_).forEach(function (k) {
  148       props[k] = props_[k]
  149     })
  150 
  151     // if it's not the expected size, then abort here.
  152     if (undefined !== self.size && props.size !== self.size) {
  153       return self.error('incorrect size')
  154     }
  155     self.size = props.size
  156 
  157     var type = getType(props)
  158     var handleHardlinks = props.hardlinks !== false
  159 
  160     // special little thing for handling hardlinks.
  161     if (handleHardlinks && type !== 'Directory' && props.nlink && props.nlink > 1) {
  162       var k = props.dev + ':' + props.ino
  163       // console.error("Reader has nlink", self._path, k)
  164       if (hardLinks[k] === self._path || !hardLinks[k]) {
  165         hardLinks[k] = self._path
  166       } else {
  167         // switch into hardlink mode.
  168         type = self.type = self.props.type = 'Link'
  169         self.Link = self.props.Link = true
  170         self.linkpath = self.props.linkpath = hardLinks[k]
  171         // console.error("Hardlink detected, switching mode", self._path, self.linkpath)
  172         // Setting __proto__ would arguably be the "correct"
  173         // approach here, but that just seems too wrong.
  174         self._stat = self._read = LinkReader.prototype._read
  175       }
  176     }
  177 
  178     if (self.type && self.type !== type) {
  179       self.error('Unexpected type: ' + type)
  180     }
  181 
  182     // if the filter doesn't pass, then just skip over this one.
  183     // still have to emit end so that dir-walking can move on.
  184     if (self.filter) {
  185       var who = self._proxy || self
  186       // special handling for ProxyReaders
  187       if (!self.filter.call(who, who, props)) {
  188         if (!self._disowned) {
  189           self.abort()
  190           self.emit('end')
  191           self.emit('close')
  192         }
  193         return
  194       }
  195     }
  196 
  197     // last chance to abort or disown before the flow starts!
  198     var events = ['_stat', 'stat', 'ready']
  199     var e = 0
  200     ;(function go () {
  201       if (self._aborted) {
  202         self.emit('end')
  203         self.emit('close')
  204         return
  205       }
  206 
  207       if (self._paused && self.type !== 'Directory') {
  208         self.once('resume', go)
  209         return
  210       }
  211 
  212       var ev = events[e++]
  213       if (!ev) {
  214         return self._read()
  215       }
  216       self.emit(ev, props)
  217       go()
  218     })()
  219   }
  220 }
  221 
  222 Reader.prototype.pipe = function (dest) {
  223   var self = this
  224   if (typeof dest.add === 'function') {
  225     // piping to a multi-compatible, and we've got directory entries.
  226     self.on('entry', function (entry) {
  227       var ret = dest.add(entry)
  228       if (ret === false) {
  229         self.pause()
  230       }
  231     })
  232   }
  233 
  234   // console.error("R Pipe apply Stream Pipe")
  235   return Stream.prototype.pipe.apply(this, arguments)
  236 }
  237 
  238 Reader.prototype.pause = function (who) {
  239   this._paused = true
  240   who = who || this
  241   this.emit('pause', who)
  242   if (this._stream) this._stream.pause(who)
  243 }
  244 
  245 Reader.prototype.resume = function (who) {
  246   this._paused = false
  247   who = who || this
  248   this.emit('resume', who)
  249   if (this._stream) this._stream.resume(who)
  250   this._read()
  251 }
  252 
  253 Reader.prototype._read = function () {
  254   this.error('Cannot read unknown type: ' + this.type)
  255 }