aboutsummaryrefslogtreecommitdiffhomepage
path: root/crates
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-05-12 04:20:57 +0900
committernsfisis <nsfisis@gmail.com>2026-05-12 04:20:57 +0900
commit213c3d019a43d765638c2a0fdf26b7b322899ca1 (patch)
treeebf18e97e0e6b8c75c436490c6135916398876fb /crates
parent698bccd425ccefcb4728c4035fa08ebd9dd258f6 (diff)
downloadphp-shirabe-213c3d019a43d765638c2a0fdf26b7b322899ca1.tar.gz
php-shirabe-213c3d019a43d765638c2a0fdf26b7b322899ca1.tar.zst
php-shirabe-213c3d019a43d765638c2a0fdf26b7b322899ca1.zip
feat(port): port GzipDownloader.php
Diffstat (limited to 'crates')
-rw-r--r--crates/shirabe-php-shim/src/lib.rs50
-rw-r--r--crates/shirabe/src/downloader/gzip_downloader.rs70
2 files changed, 119 insertions, 1 deletions
diff --git a/crates/shirabe-php-shim/src/lib.rs b/crates/shirabe-php-shim/src/lib.rs
index f1a9fb1..ef74970 100644
--- a/crates/shirabe-php-shim/src/lib.rs
+++ b/crates/shirabe-php-shim/src/lib.rs
@@ -1,6 +1,6 @@
use indexmap::IndexMap;
-#[derive(Debug)]
+#[derive(Debug, Clone)]
pub enum PhpMixed {
Null,
Bool(bool),
@@ -47,6 +47,54 @@ pub fn hash(algo: &str, data: &str) -> String {
todo!()
}
+pub fn extension_loaded(name: &str) -> bool {
+ todo!()
+}
+
+pub fn gzopen(file: &str, mode: &str) -> PhpMixed {
+ todo!()
+}
+
+pub fn gzread(file: PhpMixed, length: i64) -> String {
+ todo!()
+}
+
+pub fn gzclose(file: PhpMixed) {
+ todo!()
+}
+
+pub fn fopen(file: &str, mode: &str) -> PhpMixed {
+ todo!()
+}
+
+pub fn fwrite(file: PhpMixed, data: &str, length: i64) {
+ todo!()
+}
+
+pub fn fclose(file: PhpMixed) {
+ todo!()
+}
+
+pub fn parse_url(url: &str, component: i64) -> PhpMixed {
+ todo!()
+}
+
+pub fn pathinfo(path: PhpMixed, option: i64) -> PhpMixed {
+ todo!()
+}
+
+pub fn strtr(str: &str, from: &str, to: &str) -> String {
+ todo!()
+}
+
+pub fn implode(glue: &str, pieces: &[String]) -> String {
+ todo!()
+}
+
+pub const PHP_URL_PATH: i64 = 5;
+pub const PATHINFO_FILENAME: i64 = 64;
+pub const DIRECTORY_SEPARATOR: &str = "/";
+
pub const HHVM_VERSION: Option<&str> = None;
#[derive(Debug)]
diff --git a/crates/shirabe/src/downloader/gzip_downloader.rs b/crates/shirabe/src/downloader/gzip_downloader.rs
index bb976da..2158126 100644
--- a/crates/shirabe/src/downloader/gzip_downloader.rs
+++ b/crates/shirabe/src/downloader/gzip_downloader.rs
@@ -1 +1,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);
+ }
+}