diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-05-12 04:20:57 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-05-12 04:20:57 +0900 |
| commit | 213c3d019a43d765638c2a0fdf26b7b322899ca1 (patch) | |
| tree | ebf18e97e0e6b8c75c436490c6135916398876fb /crates | |
| parent | 698bccd425ccefcb4728c4035fa08ebd9dd258f6 (diff) | |
| download | php-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.rs | 50 | ||||
| -rw-r--r-- | crates/shirabe/src/downloader/gzip_downloader.rs | 70 |
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); + } +} |
