source: trip-planner-front/node_modules/tar/lib/pax.js@ fa375fe

Last change on this file since fa375fe was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 3.9 KB
Line 
1'use strict'
2const Header = require('./header.js')
3const path = require('path')
4
5class Pax {
6 constructor (obj, global) {
7 this.atime = obj.atime || null
8 this.charset = obj.charset || null
9 this.comment = obj.comment || null
10 this.ctime = obj.ctime || null
11 this.gid = obj.gid || null
12 this.gname = obj.gname || null
13 this.linkpath = obj.linkpath || null
14 this.mtime = obj.mtime || null
15 this.path = obj.path || null
16 this.size = obj.size || null
17 this.uid = obj.uid || null
18 this.uname = obj.uname || null
19 this.dev = obj.dev || null
20 this.ino = obj.ino || null
21 this.nlink = obj.nlink || null
22 this.global = global || false
23 }
24
25 encode () {
26 const body = this.encodeBody()
27 if (body === '')
28 return null
29
30 const bodyLen = Buffer.byteLength(body)
31 // round up to 512 bytes
32 // add 512 for header
33 const bufLen = 512 * Math.ceil(1 + bodyLen / 512)
34 const buf = Buffer.allocUnsafe(bufLen)
35
36 // 0-fill the header section, it might not hit every field
37 for (let i = 0; i < 512; i++)
38 buf[i] = 0
39
40 new Header({
41 // XXX split the path
42 // then the path should be PaxHeader + basename, but less than 99,
43 // prepend with the dirname
44 path: ('PaxHeader/' + path.basename(this.path)).slice(0, 99),
45 mode: this.mode || 0o644,
46 uid: this.uid || null,
47 gid: this.gid || null,
48 size: bodyLen,
49 mtime: this.mtime || null,
50 type: this.global ? 'GlobalExtendedHeader' : 'ExtendedHeader',
51 linkpath: '',
52 uname: this.uname || '',
53 gname: this.gname || '',
54 devmaj: 0,
55 devmin: 0,
56 atime: this.atime || null,
57 ctime: this.ctime || null,
58 }).encode(buf)
59
60 buf.write(body, 512, bodyLen, 'utf8')
61
62 // null pad after the body
63 for (let i = bodyLen + 512; i < buf.length; i++)
64 buf[i] = 0
65
66 return buf
67 }
68
69 encodeBody () {
70 return (
71 this.encodeField('path') +
72 this.encodeField('ctime') +
73 this.encodeField('atime') +
74 this.encodeField('dev') +
75 this.encodeField('ino') +
76 this.encodeField('nlink') +
77 this.encodeField('charset') +
78 this.encodeField('comment') +
79 this.encodeField('gid') +
80 this.encodeField('gname') +
81 this.encodeField('linkpath') +
82 this.encodeField('mtime') +
83 this.encodeField('size') +
84 this.encodeField('uid') +
85 this.encodeField('uname')
86 )
87 }
88
89 encodeField (field) {
90 if (this[field] === null || this[field] === undefined)
91 return ''
92 const v = this[field] instanceof Date ? this[field].getTime() / 1000
93 : this[field]
94 const s = ' ' +
95 (field === 'dev' || field === 'ino' || field === 'nlink'
96 ? 'SCHILY.' : '') +
97 field + '=' + v + '\n'
98 const byteLen = Buffer.byteLength(s)
99 // the digits includes the length of the digits in ascii base-10
100 // so if it's 9 characters, then adding 1 for the 9 makes it 10
101 // which makes it 11 chars.
102 let digits = Math.floor(Math.log(byteLen) / Math.log(10)) + 1
103 if (byteLen + digits >= Math.pow(10, digits))
104 digits += 1
105 const len = digits + byteLen
106 return len + s
107 }
108}
109
110Pax.parse = (string, ex, g) => new Pax(merge(parseKV(string), ex), g)
111
112const merge = (a, b) =>
113 b ? Object.keys(a).reduce((s, k) => (s[k] = a[k], s), b) : a
114
115const parseKV = string =>
116 string
117 .replace(/\n$/, '')
118 .split('\n')
119 .reduce(parseKVLine, Object.create(null))
120
121const parseKVLine = (set, line) => {
122 const n = parseInt(line, 10)
123
124 // XXX Values with \n in them will fail this.
125 // Refactor to not be a naive line-by-line parse.
126 if (n !== Buffer.byteLength(line) + 1)
127 return set
128
129 line = line.substr((n + ' ').length)
130 const kv = line.split('=')
131 const k = kv.shift().replace(/^SCHILY\.(dev|ino|nlink)/, '$1')
132 if (!k)
133 return set
134
135 const v = kv.join('=')
136 set[k] = /^([A-Z]+\.)?([mac]|birth|creation)time$/.test(k)
137 ? new Date(v * 1000)
138 : /^[0-9]+$/.test(v) ? +v
139 : v
140 return set
141}
142
143module.exports = Pax
Note: See TracBrowser for help on using the repository browser.