Commit f65379392f63738750a80ce19d6c9d6d454c86d3
Allow using pull(readObjects, ...)
When reading from a packfile, block reading the next object until the current one is finishedCharles Lehner committed on 2/27/2016, 4:55:55 PM
Parent: 858cdead4fef03613e3213ced272d7902fa83a55
Files changed
lib/pack.js | changed |
lib/pack.js | ||
---|---|---|
@@ -102,8 +102,9 @@ | ||
102 | 102 | if (err) throw err |
103 | 103 | } |
104 | 104 | |
105 | 105 | var ended |
106 | + var inObject = false | |
106 | 107 | var numObjects = -1 |
107 | 108 | var checksum = createHash('sha1') |
108 | 109 | var b = buffered(read) |
109 | 110 | // TODO: optimize to pass through buffers to checksum |
@@ -111,8 +112,9 @@ | ||
111 | 112 | var readWord = checksum(b.chunks(4)) |
112 | 113 | var readHash = checksum(b.chunks(20)) |
113 | 114 | var readChecksum = b.chunks(20) |
114 | 115 | var expectChecksum = true |
116 | + var _cb | |
115 | 117 | |
116 | 118 | function readHeader(cb) { |
117 | 119 | readWord(null, function (end, header) { |
118 | 120 | if (ended = end) return cb(end) |
@@ -176,8 +178,9 @@ | ||
176 | 178 | } |
177 | 179 | } |
178 | 180 | |
179 | 181 | function getObject(cb) { |
182 | + inObject = true | |
180 | 183 | readTypedVarInt(function (end, type, length) { |
181 | 184 | if (opts.verbosity >= 2) |
182 | 185 | console.error('read object header', end, type, length) |
183 | 186 | numObjects-- |
@@ -185,16 +188,35 @@ | ||
185 | 188 | onEnd(new Error('Missing checksum')) |
186 | 189 | if (ended = end) return cb(end) |
187 | 190 | // TODO: verify that the inflated data is the correct length |
188 | 191 | if (type == 'ref-delta') |
189 | - getObjectFromRefDelta(length, cb) | |
192 | + getObjectFromRefDelta(length, gotObject) | |
190 | 193 | else |
191 | - cb(null, { | |
194 | + gotObject(null, { | |
192 | 195 | type: type, |
193 | 196 | length: length, |
194 | 197 | read: inflateBytes(readByte) |
195 | 198 | }) |
196 | 199 | }) |
200 | + | |
201 | + function gotObject(err, obj) { | |
202 | + // pass through the object but detect when it ends | |
203 | + if (err) return cb(err) | |
204 | + cb(null, { | |
205 | + type: obj.type, | |
206 | + length: obj.length, | |
207 | + read: pull( | |
208 | + obj.read, | |
209 | + pull.through(null, function () { | |
210 | + inObject = false | |
211 | + if (_cb) { | |
212 | + var cb = _cb | |
213 | + readObject(null, cb) | |
214 | + } | |
215 | + }) | |
216 | + ) | |
217 | + }) | |
218 | + } | |
197 | 219 | } |
198 | 220 | |
199 | 221 | // TODO: test with ref-delta objects in pack |
200 | 222 | function getObjectFromRefDelta(length, cb) { |
@@ -243,8 +265,9 @@ | ||
243 | 265 | } |
244 | 266 | |
245 | 267 | function readObject(abort, cb) { |
246 | 268 | if (ended) cb(ended) |
269 | + else if (inObject) _cb = cb | |
247 | 270 | else if (abort) read(abort, function (err) { cb(ended = err || abort) }) |
248 | 271 | else if (numObjects < 0) readHeader(cb) |
249 | 272 | else if (numObjects > 0) getObject(cb) |
250 | 273 | else if (expectChecksum) readTrailer(cb) |
Built with git-ssb-web