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