]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.maps.server/node/node-v4.8.0-win-x64/node_modules/npm/node_modules/fstream/lib/dir-writer.js
Adding integrated tile server
[simantics/district.git] / org.simantics.maps.server / node / node-v4.8.0-win-x64 / node_modules / npm / node_modules / fstream / lib / dir-writer.js
1 // It is expected that, when .add() returns false, the consumer
2 // of the DirWriter will pause until a "drain" event occurs. Note
3 // that this is *almost always going to be the case*, unless the
4 // thing being written is some sort of unsupported type, and thus
5 // skipped over.
6
7 module.exports = DirWriter
8
9 var Writer = require('./writer.js')
10 var inherits = require('inherits')
11 var mkdir = require('mkdirp')
12 var path = require('path')
13 var collect = require('./collect.js')
14
15 inherits(DirWriter, Writer)
16
17 function DirWriter (props) {
18   var self = this
19   if (!(self instanceof DirWriter)) {
20     self.error('DirWriter must be called as constructor.', null, true)
21   }
22
23   // should already be established as a Directory type
24   if (props.type !== 'Directory' || !props.Directory) {
25     self.error('Non-directory type ' + props.type + ' ' +
26       JSON.stringify(props), null, true)
27   }
28
29   Writer.call(this, props)
30 }
31
32 DirWriter.prototype._create = function () {
33   var self = this
34   mkdir(self._path, Writer.dirmode, function (er) {
35     if (er) return self.error(er)
36     // ready to start getting entries!
37     self.ready = true
38     self.emit('ready')
39     self._process()
40   })
41 }
42
43 // a DirWriter has an add(entry) method, but its .write() doesn't
44 // do anything.  Why a no-op rather than a throw?  Because this
45 // leaves open the door for writing directory metadata for
46 // gnu/solaris style dumpdirs.
47 DirWriter.prototype.write = function () {
48   return true
49 }
50
51 DirWriter.prototype.end = function () {
52   this._ended = true
53   this._process()
54 }
55
56 DirWriter.prototype.add = function (entry) {
57   var self = this
58
59   // console.error('\tadd', entry._path, '->', self._path)
60   collect(entry)
61   if (!self.ready || self._currentEntry) {
62     self._buffer.push(entry)
63     return false
64   }
65
66   // create a new writer, and pipe the incoming entry into it.
67   if (self._ended) {
68     return self.error('add after end')
69   }
70
71   self._buffer.push(entry)
72   self._process()
73
74   return this._buffer.length === 0
75 }
76
77 DirWriter.prototype._process = function () {
78   var self = this
79
80   // console.error('DW Process p=%j', self._processing, self.basename)
81
82   if (self._processing) return
83
84   var entry = self._buffer.shift()
85   if (!entry) {
86     // console.error("DW Drain")
87     self.emit('drain')
88     if (self._ended) self._finish()
89     return
90   }
91
92   self._processing = true
93   // console.error("DW Entry", entry._path)
94
95   self.emit('entry', entry)
96
97   // ok, add this entry
98   //
99   // don't allow recursive copying
100   var p = entry
101   var pp
102   do {
103     pp = p._path || p.path
104     if (pp === self.root._path || pp === self._path ||
105       (pp && pp.indexOf(self._path) === 0)) {
106       // console.error('DW Exit (recursive)', entry.basename, self._path)
107       self._processing = false
108       if (entry._collected) entry.pipe()
109       return self._process()
110     }
111     p = p.parent
112   } while (p)
113
114   // console.error("DW not recursive")
115
116   // chop off the entry's root dir, replace with ours
117   var props = {
118     parent: self,
119     root: self.root || self,
120     type: entry.type,
121     depth: self.depth + 1
122   }
123
124   pp = entry._path || entry.path || entry.props.path
125   if (entry.parent) {
126     pp = pp.substr(entry.parent._path.length + 1)
127   }
128   // get rid of any ../../ shenanigans
129   props.path = path.join(self.path, path.join('/', pp))
130
131   // if i have a filter, the child should inherit it.
132   props.filter = self.filter
133
134   // all the rest of the stuff, copy over from the source.
135   Object.keys(entry.props).forEach(function (k) {
136     if (!props.hasOwnProperty(k)) {
137       props[k] = entry.props[k]
138     }
139   })
140
141   // not sure at this point what kind of writer this is.
142   var child = self._currentChild = new Writer(props)
143   child.on('ready', function () {
144     // console.error("DW Child Ready", child.type, child._path)
145     // console.error("  resuming", entry._path)
146     entry.pipe(child)
147     entry.resume()
148   })
149
150   // XXX Make this work in node.
151   // Long filenames should not break stuff.
152   child.on('error', function (er) {
153     if (child._swallowErrors) {
154       self.warn(er)
155       child.emit('end')
156       child.emit('close')
157     } else {
158       self.emit('error', er)
159     }
160   })
161
162   // we fire _end internally *after* end, so that we don't move on
163   // until any "end" listeners have had their chance to do stuff.
164   child.on('close', onend)
165   var ended = false
166   function onend () {
167     if (ended) return
168     ended = true
169     // console.error("* DW Child end", child.basename)
170     self._currentChild = null
171     self._processing = false
172     self._process()
173   }
174 }