"Fossies" - the Fresh Open Source Software Archive

Member "Atom/resources/app/apm/node_modules/tar/lib/entry.js" (11 Apr 2017, 5282 Bytes) of package /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 // A passthrough read/write stream that sets its properties
    2 // based on a header, extendedHeader, and globalHeader
    3 //
    4 // Can be either a file system object of some sort, or
    5 // a pax/ustar metadata entry.
    6 
    7 module.exports = Entry
    8 
    9 var TarHeader = require("./header.js")
   10   , tar = require("../tar")
   11   , assert = require("assert").ok
   12   , Stream = require("stream").Stream
   13   , inherits = require("inherits")
   14   , fstream = require("fstream").Abstract
   15 
   16 function Entry (header, extended, global) {
   17   Stream.call(this)
   18   this.readable = true
   19   this.writable = true
   20 
   21   this._needDrain = false
   22   this._paused = false
   23   this._reading = false
   24   this._ending = false
   25   this._ended = false
   26   this._remaining = 0
   27   this._abort = false
   28   this._queue = []
   29   this._index = 0
   30   this._queueLen = 0
   31 
   32   this._read = this._read.bind(this)
   33 
   34   this.props = {}
   35   this._header = header
   36   this._extended = extended || {}
   37 
   38   // globals can change throughout the course of
   39   // a file parse operation.  Freeze it at its current state.
   40   this._global = {}
   41   var me = this
   42   Object.keys(global || {}).forEach(function (g) {
   43     me._global[g] = global[g]
   44   })
   45 
   46   this._setProps()
   47 }
   48 
   49 inherits(Entry, Stream)
   50 
   51 Entry.prototype.write = function (c) {
   52   if (this._ending) this.error("write() after end()", null, true)
   53   if (this._remaining === 0) {
   54     this.error("invalid bytes past eof")
   55   }
   56 
   57   // often we'll get a bunch of \0 at the end of the last write,
   58   // since chunks will always be 512 bytes when reading a tarball.
   59   if (c.length > this._remaining) {
   60     c = c.slice(0, this._remaining)
   61   }
   62   this._remaining -= c.length
   63 
   64   // put it on the stack.
   65   var ql = this._queueLen
   66   this._queue.push(c)
   67   this._queueLen ++
   68 
   69   this._read()
   70 
   71   // either paused, or buffered
   72   if (this._paused || ql > 0) {
   73     this._needDrain = true
   74     return false
   75   }
   76 
   77   return true
   78 }
   79 
   80 Entry.prototype.end = function (c) {
   81   if (c) this.write(c)
   82   this._ending = true
   83   this._read()
   84 }
   85 
   86 Entry.prototype.pause = function () {
   87   this._paused = true
   88   this.emit("pause")
   89 }
   90 
   91 Entry.prototype.resume = function () {
   92   // console.error("    Tar Entry resume", this.path)
   93   this.emit("resume")
   94   this._paused = false
   95   this._read()
   96   return this._queueLen - this._index > 1
   97 }
   98 
   99   // This is bound to the instance
  100 Entry.prototype._read = function () {
  101   // console.error("    Tar Entry _read", this.path)
  102 
  103   if (this._paused || this._reading || this._ended) return
  104 
  105   // set this flag so that event handlers don't inadvertently
  106   // get multiple _read() calls running.
  107   this._reading = true
  108 
  109   // have any data to emit?
  110   while (this._index < this._queueLen && !this._paused) {
  111     var chunk = this._queue[this._index ++]
  112     this.emit("data", chunk)
  113   }
  114 
  115   // check if we're drained
  116   if (this._index >= this._queueLen) {
  117     this._queue.length = this._queueLen = this._index = 0
  118     if (this._needDrain) {
  119       this._needDrain = false
  120       this.emit("drain")
  121     }
  122     if (this._ending) {
  123       this._ended = true
  124       this.emit("end")
  125     }
  126   }
  127 
  128   // if the queue gets too big, then pluck off whatever we can.
  129   // this should be fairly rare.
  130   var mql = this._maxQueueLen
  131   if (this._queueLen > mql && this._index > 0) {
  132     mql = Math.min(this._index, mql)
  133     this._index -= mql
  134     this._queueLen -= mql
  135     this._queue = this._queue.slice(mql)
  136   }
  137 
  138   this._reading = false
  139 }
  140 
  141 Entry.prototype._setProps = function () {
  142   // props = extended->global->header->{}
  143   var header = this._header
  144     , extended = this._extended
  145     , global = this._global
  146     , props = this.props
  147 
  148   // first get the values from the normal header.
  149   var fields = tar.fields
  150   for (var f = 0; fields[f] !== null; f ++) {
  151     var field = fields[f]
  152       , val = header[field]
  153     if (typeof val !== "undefined") props[field] = val
  154   }
  155 
  156   // next, the global header for this file.
  157   // numeric values, etc, will have already been parsed.
  158   ;[global, extended].forEach(function (p) {
  159     Object.keys(p).forEach(function (f) {
  160       if (typeof p[f] !== "undefined") props[f] = p[f]
  161     })
  162   })
  163 
  164   // no nulls allowed in path or linkpath
  165   ;["path", "linkpath"].forEach(function (p) {
  166     if (props.hasOwnProperty(p)) {
  167       props[p] = props[p].split("\0")[0]
  168     }
  169   })
  170 
  171 
  172   // set date fields to be a proper date
  173   ;["mtime", "ctime", "atime"].forEach(function (p) {
  174     if (props.hasOwnProperty(p)) {
  175       props[p] = new Date(props[p] * 1000)
  176     }
  177   })
  178 
  179   // set the type so that we know what kind of file to create
  180   var type
  181   switch (tar.types[props.type]) {
  182     case "OldFile":
  183     case "ContiguousFile":
  184       type = "File"
  185       break
  186 
  187     case "GNUDumpDir":
  188       type = "Directory"
  189       break
  190 
  191     case undefined:
  192       type = "Unknown"
  193       break
  194 
  195     case "Link":
  196     case "SymbolicLink":
  197     case "CharacterDevice":
  198     case "BlockDevice":
  199     case "Directory":
  200     case "FIFO":
  201     default:
  202       type = tar.types[props.type]
  203   }
  204 
  205   this.type = type
  206   this.path = props.path
  207   this.size = props.size
  208 
  209   // size is special, since it signals when the file needs to end.
  210   this._remaining = props.size
  211 }
  212 
  213 // the parser may not call write if _abort is true. 
  214 // useful for skipping data from some files quickly.
  215 Entry.prototype.abort = function(){
  216   this._abort = true
  217 }
  218 
  219 Entry.prototype.warn = fstream.warn
  220 Entry.prototype.error = fstream.error