source: node_modules/tar/lib/extract.js@ 81bc7da

finki-main main
Last change on this file since 81bc7da was 81bc7da, checked in by Klimentina Efremova <klimentina08642@…>, 3 months ago

Initial commit

  • Property mode set to 100644
File size: 2.8 KB
Line 
1'use strict'
2
3// tar -x
4const hlo = require('./high-level-opt.js')
5const Unpack = require('./unpack.js')
6const fs = require('fs')
7const fsm = require('fs-minipass')
8const path = require('path')
9const stripSlash = require('./strip-trailing-slashes.js')
10
11module.exports = (opt_, files, cb) => {
12 if (typeof opt_ === 'function') {
13 cb = opt_, files = null, opt_ = {}
14 } else if (Array.isArray(opt_)) {
15 files = opt_, opt_ = {}
16 }
17
18 if (typeof files === 'function') {
19 cb = files, files = null
20 }
21
22 if (!files) {
23 files = []
24 } else {
25 files = Array.from(files)
26 }
27
28 const opt = hlo(opt_)
29
30 if (opt.sync && typeof cb === 'function') {
31 throw new TypeError('callback not supported for sync tar functions')
32 }
33
34 if (!opt.file && typeof cb === 'function') {
35 throw new TypeError('callback only supported with file option')
36 }
37
38 if (files.length) {
39 filesFilter(opt, files)
40 }
41
42 return opt.file && opt.sync ? extractFileSync(opt)
43 : opt.file ? extractFile(opt, cb)
44 : opt.sync ? extractSync(opt)
45 : extract(opt)
46}
47
48// construct a filter that limits the file entries listed
49// include child entries if a dir is included
50const filesFilter = (opt, files) => {
51 const map = new Map(files.map(f => [stripSlash(f), true]))
52 const filter = opt.filter
53
54 const mapHas = (file, r) => {
55 const root = r || path.parse(file).root || '.'
56 const ret = file === root ? false
57 : map.has(file) ? map.get(file)
58 : mapHas(path.dirname(file), root)
59
60 map.set(file, ret)
61 return ret
62 }
63
64 opt.filter = filter
65 ? (file, entry) => filter(file, entry) && mapHas(stripSlash(file))
66 : file => mapHas(stripSlash(file))
67}
68
69const extractFileSync = opt => {
70 const u = new Unpack.Sync(opt)
71
72 const file = opt.file
73 const stat = fs.statSync(file)
74 // This trades a zero-byte read() syscall for a stat
75 // However, it will usually result in less memory allocation
76 const readSize = opt.maxReadSize || 16 * 1024 * 1024
77 const stream = new fsm.ReadStreamSync(file, {
78 readSize: readSize,
79 size: stat.size,
80 })
81 stream.pipe(u)
82}
83
84const extractFile = (opt, cb) => {
85 const u = new Unpack(opt)
86 const readSize = opt.maxReadSize || 16 * 1024 * 1024
87
88 const file = opt.file
89 const p = new Promise((resolve, reject) => {
90 u.on('error', reject)
91 u.on('close', resolve)
92
93 // This trades a zero-byte read() syscall for a stat
94 // However, it will usually result in less memory allocation
95 fs.stat(file, (er, stat) => {
96 if (er) {
97 reject(er)
98 } else {
99 const stream = new fsm.ReadStream(file, {
100 readSize: readSize,
101 size: stat.size,
102 })
103 stream.on('error', reject)
104 stream.pipe(u)
105 }
106 })
107 })
108 return cb ? p.then(cb, cb) : p
109}
110
111const extractSync = opt => new Unpack.Sync(opt)
112
113const extract = opt => new Unpack(opt)
Note: See TracBrowser for help on using the repository browser.