2 const types = require('./types.js')
3 const MiniPass = require('minipass')
5 const SLURP = Symbol('slurp')
6 module.exports = class ReadEntry extends MiniPass {
7 constructor (header, ex, gex) {
9 // read entries always start life paused. this is to avoid the
10 // situation where Minipass's auto-ending empty streams results
11 // in an entry ending before we're ready for it.
14 this.globalExtended = gex
16 this.startBlockSize = 512 * Math.ceil(header.size / 512)
17 this.blockRemain = this.startBlockSize
18 this.remain = header.size
19 this.type = header.type
27 case 'CharacterDevice':
31 case 'ContiguousFile':
35 case 'NextFileHasLongLinkpath':
36 case 'NextFileHasLongPath':
37 case 'OldGnuLongPath':
38 case 'GlobalExtendedHeader':
39 case 'ExtendedHeader':
40 case 'OldExtendedHeader':
44 // NOTE: gnutar and bsdtar treat unrecognized types as 'File'
45 // it may be worth doing the same, but with a warning.
50 this.path = header.path
51 this.mode = header.mode
53 this.mode = this.mode & 0o7777
56 this.uname = header.uname
57 this.gname = header.gname
58 this.size = header.size
59 this.mtime = header.mtime
60 this.atime = header.atime
61 this.ctime = header.ctime
62 this.linkpath = header.linkpath
63 this.uname = header.uname
64 this.gname = header.gname
66 if (ex) this[SLURP](ex)
67 if (gex) this[SLURP](gex, true)
71 const writeLen = data.length
72 if (writeLen > this.blockRemain)
73 throw new Error('writing more to entry than is appropriate')
76 const br = this.blockRemain
77 this.remain = Math.max(0, r - writeLen)
78 this.blockRemain = Math.max(0, br - writeLen)
83 return super.write(data)
86 return super.write(data.slice(0, r))
89 [SLURP] (ex, global) {
91 // we slurp in everything except for the path attribute in
92 // a global extended header, because that's weird.
93 if (ex[k] !== null && ex[k] !== undefined &&
94 !(global && k === 'path'))