Initial commit
[yaffs-website] / node_modules / tar / lib / entry-writer.js
1 module.exports = EntryWriter
2
3 var tar = require("../tar.js")
4   , TarHeader = require("./header.js")
5   , Entry = require("./entry.js")
6   , inherits = require("inherits")
7   , BlockStream = require("block-stream")
8   , ExtendedHeaderWriter
9   , Stream = require("stream").Stream
10   , EOF = {}
11
12 inherits(EntryWriter, Stream)
13
14 function EntryWriter (props) {
15   var me = this
16
17   if (!(me instanceof EntryWriter)) {
18     return new EntryWriter(props)
19   }
20
21   Stream.apply(this)
22
23   me.writable = true
24   me.readable = true
25
26   me._stream = new BlockStream(512)
27
28   me._stream.on("data", function (c) {
29     me.emit("data", c)
30   })
31
32   me._stream.on("drain", function () {
33     me.emit("drain")
34   })
35
36   me._stream.on("end", function () {
37     me.emit("end")
38     me.emit("close")
39   })
40
41   me.props = props
42   if (props.type === "Directory") {
43     props.size = 0
44   }
45   props.ustar = "ustar\0"
46   props.ustarver = "00"
47   me.path = props.path
48
49   me._buffer = []
50   me._didHeader = false
51   me._meta = false
52
53   me.on("pipe", function () {
54     me._process()
55   })
56 }
57
58 EntryWriter.prototype.write = function (c) {
59   // console.error(".. ew write")
60   if (this._ended) return this.emit("error", new Error("write after end"))
61   this._buffer.push(c)
62   this._process()
63   this._needDrain = this._buffer.length > 0
64   return !this._needDrain
65 }
66
67 EntryWriter.prototype.end = function (c) {
68   // console.error(".. ew end")
69   if (c) this._buffer.push(c)
70   this._buffer.push(EOF)
71   this._ended = true
72   this._process()
73   this._needDrain = this._buffer.length > 0
74 }
75
76 EntryWriter.prototype.pause = function () {
77   // console.error(".. ew pause")
78   this._paused = true
79   this.emit("pause")
80 }
81
82 EntryWriter.prototype.resume = function () {
83   // console.error(".. ew resume")
84   this._paused = false
85   this.emit("resume")
86   this._process()
87 }
88
89 EntryWriter.prototype.add = function (entry) {
90   // console.error(".. ew add")
91   if (!this.parent) return this.emit("error", new Error("no parent"))
92
93   // make sure that the _header and such is emitted, and clear out
94   // the _currentEntry link on the parent.
95   if (!this._ended) this.end()
96
97   return this.parent.add(entry)
98 }
99
100 EntryWriter.prototype._header = function () {
101   // console.error(".. ew header")
102   if (this._didHeader) return
103   this._didHeader = true
104
105   var headerBlock = TarHeader.encode(this.props)
106
107   if (this.props.needExtended && !this._meta) {
108     var me = this
109
110     ExtendedHeaderWriter = ExtendedHeaderWriter ||
111       require("./extended-header-writer.js")
112
113     ExtendedHeaderWriter(this.props)
114       .on("data", function (c) {
115         me.emit("data", c)
116       })
117       .on("error", function (er) {
118         me.emit("error", er)
119       })
120       .end()
121   }
122
123   // console.error(".. .. ew headerBlock emitting")
124   this.emit("data", headerBlock)
125   this.emit("header")
126 }
127
128 EntryWriter.prototype._process = function () {
129   // console.error(".. .. ew process")
130   if (!this._didHeader && !this._meta) {
131     this._header()
132   }
133
134   if (this._paused || this._processing) {
135     // console.error(".. .. .. paused=%j, processing=%j", this._paused, this._processing)
136     return
137   }
138
139   this._processing = true
140
141   var buf = this._buffer
142   for (var i = 0; i < buf.length; i ++) {
143     // console.error(".. .. .. i=%d", i)
144
145     var c = buf[i]
146
147     if (c === EOF) this._stream.end()
148     else this._stream.write(c)
149
150     if (this._paused) {
151       // console.error(".. .. .. paused mid-emission")
152       this._processing = false
153       if (i < buf.length) {
154         this._needDrain = true
155         this._buffer = buf.slice(i + 1)
156       }
157       return
158     }
159   }
160
161   // console.error(".. .. .. emitted")
162   this._buffer.length = 0
163   this._processing = false
164
165   // console.error(".. .. .. emitting drain")
166   this.emit("drain")
167 }
168
169 EntryWriter.prototype.destroy = function () {}