1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
//! ref: composer/src/Composer/Downloader/GzipDownloader.php
use anyhow::Result;
use shirabe_external_packages::react::promise::promise_interface::PromiseInterface;
use shirabe_php_shim::{
RuntimeException,
extension_loaded, fclose, fopen, fwrite, gzclose, gzopen, gzread,
implode, parse_url, pathinfo, strtr,
DIRECTORY_SEPARATOR, PATHINFO_FILENAME, PHP_URL_PATH,
};
use crate::downloader::archive_downloader::ArchiveDownloader;
use crate::package::package_interface::PackageInterface;
use crate::util::platform::Platform;
pub struct GzipDownloader {
inner: ArchiveDownloader,
}
impl GzipDownloader {
pub(crate) fn extract(&self, package: &dyn PackageInterface, file: &str, path: &str) -> Result<Box<dyn PromiseInterface>> {
let filename = pathinfo(
parse_url(&strtr(&package.get_dist_url().unwrap_or_default(), "\\", "/"), PHP_URL_PATH),
PATHINFO_FILENAME,
);
let target_filepath = format!("{}{}{}", path, DIRECTORY_SEPARATOR, filename);
if !Platform::is_windows() {
let command = vec![
"sh".to_string(),
"-c".to_string(),
"gzip -cd -- \"$0\" > \"$1\"".to_string(),
file.to_string(),
target_filepath.clone(),
];
if self.inner.process.execute(&command, &mut String::new()) == 0 {
return Ok(shirabe_external_packages::react::promise::resolve(None));
}
if extension_loaded("zlib") {
self.extract_using_ext(file, &target_filepath);
return Ok(shirabe_external_packages::react::promise::resolve(None));
}
let process_error = format!(
"Failed to execute {}\n\n{}",
implode(" ", &command),
self.inner.process.get_error_output(),
);
return Err(anyhow::anyhow!(RuntimeException { message: process_error, code: 0 }));
}
self.extract_using_ext(file, &target_filepath);
Ok(shirabe_external_packages::react::promise::resolve(None))
}
fn extract_using_ext(&self, file: &str, target_filepath: &str) {
let archive_file = gzopen(file, "rb");
let target_file = fopen(target_filepath, "wb");
loop {
let string = gzread(archive_file.clone(), 4096);
if string.is_empty() {
break;
}
fwrite(target_file.clone(), &string, Platform::strlen(&string));
}
gzclose(archive_file);
fclose(target_file);
}
}
|