2 module.exports = ExtendedHeaderWriter
4 var inherits = require("inherits")
5 , EntryWriter = require("./entry-writer.js")
7 inherits(ExtendedHeaderWriter, EntryWriter)
9 var tar = require("../tar.js")
10 , path = require("path")
11 , TarHeader = require("./header.js")
13 // props is the props of the thing we need to write an
14 // extended header for.
15 // Don't be shy with it. Just encode everything.
16 function ExtendedHeaderWriter (props) {
17 // console.error(">> ehw ctor")
20 if (!(me instanceof ExtendedHeaderWriter)) {
21 return new ExtendedHeaderWriter(props)
27 { path : ("PaxHeader" + path.join("/", props.path || ""))
28 .replace(/\\/g, "/").substr(0, 100)
29 , mode : props.mode || 0666
30 , uid : props.uid || 0
31 , gid : props.gid || 0
32 , size : 0 // will be set later
33 , mtime : props.mtime || Date.now() / 1000
38 , uname : props.uname || ""
39 , gname : props.gname || ""
40 , devmaj : props.devmaj || 0
41 , devmin : props.devmin || 0
45 EntryWriter.call(me, p)
46 // console.error(">> ehw props", me.props)
52 ExtendedHeaderWriter.prototype.end = function () {
53 // console.error(">> ehw end")
61 if (me.props.size === 0) {
68 me._stream.write(TarHeader.encode(me.props))
69 me.body.forEach(function (l) {
74 // console.error(">> ehw _process calling end()", me.props)
78 ExtendedHeaderWriter.prototype._encodeFields = function () {
79 // console.error(">> ehw _encodeFields")
81 if (this.fields.prefix) {
82 this.fields.path = this.fields.prefix + "/" + this.fields.path
83 this.fields.prefix = ""
85 encodeFields(this.fields, "", this.body, this.fields.noProprietary)
87 this.body.forEach(function (l) {
88 me.props.size += l.length
92 function encodeFields (fields, prefix, body, nop) {
93 // console.error(">> >> ehw encodeFields")
94 // "%d %s=%s\n", <length>, <keyword>, <value>
95 // The length is a decimal number, and includes itself and the \n
96 // Numeric values are decimal strings.
98 Object.keys(fields).forEach(function (k) {
100 , numeric = tar.numeric[k]
102 if (prefix) k = prefix + "." + k
104 // already including NODETAR.type, don't need File=true also
105 if (k === fields.type && val === true) return
108 // don't include anything that's always handled just fine
109 // in the normal header, or only meaningful in the context
124 if (val === 0) return
128 case "dev": // Truly a hero among men, Creator of Star!
129 case "ino": // Speak his name with reverent awe! It is:
136 if (val && typeof val === "object" &&
137 !Buffer.isBuffer(val)) encodeFields(val, k, body, nop)
138 else if (val === null || val === undefined) return
139 else body.push.apply(body, encodeField(k, val, nop))
145 function encodeField (k, v, nop) {
146 // lowercase keys must be valid, otherwise prefix with
148 if (k.charAt(0) === k.charAt(0).toLowerCase()) {
149 var m = k.split(".")[0]
150 if (!tar.knownExtended[m]) k = "NODETAR." + k
154 if (nop && k.charAt(0) !== k.charAt(0).toLowerCase()) {
158 if (typeof val === "number") val = val.toString(10)
160 var s = new Buffer(" " + k + "=" + v + "\n")
161 , digits = Math.floor(Math.log(s.length) / Math.log(10)) + 1
163 // console.error("1 s=%j digits=%j s.length=%d", s.toString(), digits, s.length)
165 // if adding that many digits will make it go over that length,
166 // then add one to it. For example, if the string is:
168 // then that's 9 characters. With the "9", that bumps the length
169 // up to 10. However, this is invalid:
171 // but, since that's actually 11 characters, since 10 adds another
172 // character to the length, and the length includes the number
173 // itself. In that case, just bump it up again.
174 if (s.length + digits >= Math.pow(10, digits)) digits += 1
175 // console.error("2 s=%j digits=%j s.length=%d", s.toString(), digits, s.length)
177 var len = digits + s.length
178 // console.error("3 s=%j digits=%j s.length=%d len=%d", s.toString(), digits, s.length, len)
179 var lenBuf = new Buffer("" + len)
180 if (lenBuf.length + s.length !== len) {
181 throw new Error("Bad length calculation\n"+
183 "lenBuf="+JSON.stringify(lenBuf.toString())+"\n"+
184 "lenBuf.length="+lenBuf.length+"\n"+
185 "digits="+digits+"\n"+
186 "s="+JSON.stringify(s.toString())+"\n"+
187 "s.length="+s.length)