diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c83911..d8e4194 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -# [[v0.5-0](https://github.com/The-FireHub-Project/Runtime/compare/v0.4.3...v0.5.0)] – 2026-11-04 +# [[v0.5.1](https://github.com/The-FireHub-Project/Runtime/compare/v0.5.0...v0.5.1)] – 2026-11-04 + +### Added +* Add comprehensive stream utilities in `Runtime` by @dieselxxx + +# [[v0.5.0](https://github.com/The-FireHub-Project/Runtime/compare/v0.4.3...v0.5.0)] – 2026-11-04 ### Added * Add comprehensive stream utilities in `Runtime` by @dieselxxx diff --git a/README.md b/README.md index 1e21618..f3ff069 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,12 @@ PHP Runtime Foundation
release version @@ -22,25 +22,46 @@ /> -[![PHPStan](https://github.com/The-FireHub-Project/Runtime/actions/workflows/PHPStan.yml/badge.svg?branch=develop)](https://github.com/The-FireHub-Project/Runtime/actions/workflows/PHPStan.yml) -[![PHPUnit](https://github.com/The-FireHub-Project/Runtime/actions/workflows/PHPUnit.yml/badge.svg?branch=develop)](https://github.com/The-FireHub-Project/Runtime/actions/workflows/PHPUnit.yml) -[![Codecov](https://codecov.io/gh/The-FireHub-Project/Runtime/branch/develop/graph/badge.svg?token=XW2YEONF51)](https://app.codecov.io/gh/The-FireHub-Project/Runtime/tree/develop) -

- + + GitHub created at + GitHub last commit (branch) - + GitHub activity (branch) - + + GitHub contributors + GitHub commit difference between two branches + + GitHub top language + + GitHub repo size + + GitHub code size

@@ -54,47 +75,55 @@ Its role is to provide a consistent execution foundation between native PHP capa --- -## FireHub Icon Development Branch +## FireHub Icon Repository Purpose -⚠️ **This is the `develop` branch** +This repository provides a lightweight PHP runtime abstraction layer that wraps native PHP functionality into clean, consistent, and deterministic APIs. -- Unstable -- APIs may change without notice -- Not intended for production use +Its purpose is to reduce boilerplate and standardize common execution patterns across the FireHub ecosystem by offering ergonomic helper classes for arrays, strings, files, environment access, and other low-level runtime operations. -## FireHub Icon Branch Purpose +It is strictly focused on execution-level concerns and does not contain domain logic, business rules, or framework-level orchestration. It exists to improve developer productivity while preserving native PHP behavior and ensuring zero framework coupling. -The `develop` branch is the **primary integration branch** for all ongoing development. +## FireHub Icon Security -It serves as the staging area where: -- Feature branches are merged -- Bug fixes are integrated -- Experimental work is stabilized -- Code is prepared for upcoming releases +For security reporting and guidelines, please refer to our [SECURITY.md](https://github.com/The-FireHub-Project/.github/blob/master/.github/SECURITY.md) file. -All **release branches** are created **from `develop`**. +## FireHub Icon Community -## Stability Guarantee +![GitHub watchers](https://img.shields.io/github/watchers/The-FireHub-Project/Runtime?style=social) +![GitHub Repo stars](https://img.shields.io/github/stars/The-FireHub-Project/Runtime?style=social) +![GitHub forks](https://img.shields.io/github/forks/The-FireHub-Project/Runtime?style=social) -❌ No backward compatibility guarantee -❌ APIs may change without notice -❌ Behavior may be incomplete or inconsistent -❌ Breaking changes are expected +- Be sure to review the [Code of Conduct](https://github.com/The-FireHub-Project/.github/blob/master/.github/CODE_OF_CONDUCT.md). +- Read a [Contributing](https://github.com/The-FireHub-Project/.github/blob/master/.github/CONTRIBUTING.md) file to see how you can contribute to this project. +- Read our [Security policy](https://github.com/The-FireHub-Project/.github/blob/master/.github/SECURITY.md) file to see how you can report a vulnerability. +- Review the project [Governance model](https://github.com/The-FireHub-Project/.github/blob/master/.github/GOVERNANCE.md), including roles, decision-making, RFC process, and releases. -This branch is intended **only for contributors and advanced testers**. +## FireHub Icon Support -## FireHub Icon Composer Usage (Not Recommended) +

+ + GitHub in-progress issues + + GitHub total issues + + GitHub opened pull requests +

-For internal testing only: +For help with FireHub products, please refer to the following resources: -```json -{ - "require": { - "the-firehub-project/runtime": "dev-develop" - } -} -``` -⚠️ Never use dev-develop in production. +- **General questions & discussions**: [GitHub Discussions](https://github.com/orgs/The-FireHub-Project/discussions) +- **Bug reports & issues**: [Support](https://github.com/The-FireHub-Project/Runtime/issues) +- **Documentation & guides**: [FireHub Docs](https://the-firehub-project.github.io) +- **Commercial support** (Pro/Enterprise): contact your account manager ## FireHub Icon Authors and Contributors diff --git a/src/Stream/Enum/OpenMode.php b/src/Stream/Enum/OpenMode.php new file mode 100644 index 0000000..740800c --- /dev/null +++ b/src/Stream/Enum/OpenMode.php @@ -0,0 +1,168 @@ + + * @copyright 2026-present The FireHub Project - All rights reserved + * @license https://opensource.org/license/Apache-2-0 Apache License, Version 2.0 + * + * @php-version >=8.1 + * @package Runtime + */ + +namespace FireHub\Runtime\Stream\Enum; + +/** + * ### Stream Opening Modes + * + * Defines the supported modes for opening native PHP streams. + * + * Binary modes are recommended for consistent behavior across platforms. + * @since 1.0.0 + */ +enum OpenMode:string { + + /** + * ### Opens a stream for reading only + * + * The stream must exist. The pointer is positioned at the beginning. + * @since 1.0.0 + */ + case READ = 'r'; + + /** + * ### Opens a stream for reading and writing + * + * The stream must exist. The pointer is positioned at the beginning. + * @since 1.0.0 + */ + case READ_WRITE = 'r+'; + + /** + * ### Opens a stream for writing only + * + * Creates the file if it does not exist or truncates it if it exists. + * @since 1.0.0 + */ + case WRITE = 'w'; + + /** + * ### Opens a stream for reading and writing + * + * Creates the file if it does not exist or truncates it if it exists. + * @since 1.0.0 + */ + case WRITE_READ = 'w+'; + + /** + * ### Opens a stream for appending + * + * Creates the file if it does not exist. + * Writes are always performed at the end of the file. + * @since 1.0.0 + */ + case APPEND = 'a'; + + /** + * ### Opens a stream for reading and appending + * + * Creates the file if it does not exist. + * Writes are always performed at the end of the file. + * @since 1.0.0 + */ + case APPEND_READ = 'a+'; + + /** + * ### Creates a new stream for writing + * + * Fails if the file already exists. + * @since 1.0.0 + */ + case CREATE = 'x'; + + /** + * ### Creates a new stream for reading and writing + * + * Fails if the file already exists. + * @since 1.0.0 + */ + case CREATE_READ = 'x+'; + + /** + * ### Opens a stream for writing without truncation + * + * Creates the file if it does not exist. + * @since 1.0.0 + */ + case CREATE_OR_OPEN = 'c'; + + /** + * ### Opens a stream for reading and writing without truncation + * + * Creates the file if it does not exist. + * @since 1.0.0 + */ + case CREATE_OR_OPEN_READ = 'c+'; + + /** + * ### Opens a binary stream for reading only + * @since 1.0.0 + */ + case READ_BINARY = 'rb'; + + /** + * ### Opens a binary stream for reading and writing + * @since 1.0.0 + */ + case READ_WRITE_BINARY = 'r+b'; + + /** + * ### Opens a binary stream for writing only + * @since 1.0.0 + */ + case WRITE_BINARY = 'wb'; + + /** + * ### Opens a binary stream for reading and writing + * @since 1.0.0 + */ + case WRITE_READ_BINARY = 'w+b'; + + /** + * ### Opens a binary stream for appending + * @since 1.0.0 + */ + case APPEND_BINARY = 'ab'; + + /** + * ### Opens a binary stream for reading and appending + * @since 1.0.0 + */ + case APPEND_READ_BINARY = 'a+b'; + + /** + * ### Creates a new binary stream for writing + * @since 1.0.0 + */ + case CREATE_BINARY = 'xb'; + + /** + * ### Creates a new binary stream for reading and writing + * @since 1.0.0 + */ + case CREATE_READ_BINARY = 'x+b'; + + /** + * ### Opens a binary stream for writing without truncation + * @since 1.0.0 + */ + case CREATE_OR_OPEN_BINARY = 'cb'; + + /** + * ### Opens a binary stream for reading and writing without truncation + * @since 1.0.0 + */ + case CREATE_OR_OPEN_READ_BINARY = 'c+b'; + +} \ No newline at end of file diff --git a/src/Stream/Handle.php b/src/Stream/Handle.php new file mode 100644 index 0000000..f1e83c6 --- /dev/null +++ b/src/Stream/Handle.php @@ -0,0 +1,73 @@ + + * @copyright 2026-present The FireHub Project - All rights reserved + * @license https://opensource.org/license/Apache-2-0 Apache License, Version 2.0 + * + * @php-version >=8.2 + * @package Runtime + */ + +namespace FireHub\Runtime\Stream; + +use FireHub\Core\Boundary\Runtime\NativeRuntime; +use FireHub\Runtime\Stream\Enum\OpenMode; + +use function fopen; +use function fclose; + +/** + * ### PHP Runtime Stream Handle Utilities + * + * Provides low-level wrappers for opening and closing native PHP streams. + * + * Preserves native PHP stream behavior. + * @since 1.0.0 + */ +final readonly class Handle extends NativeRuntime { + + /** + * ### Opens a stream resource + * @since 1.0.0 + * + * @param non-empty-string $path

+ * File path or supported stream URI. + *

+ * @param \FireHub\Runtime\Stream\Enum\OpenMode $mode [optional]

+ * Stream opening mode. + *

+ * @param bool $use_include_path [optional]

+ * Whether to search the configured include path. + *

+ * @param null|resource $context [optional]

+ * Stream context resource. + *

+ * + * @return resource|false Opened stream resource, or false on failure. + */ + public static function open (string $path, OpenMode $mode, bool $use_include_path = false, mixed $context = null):mixed { + + return fopen($path, $mode->value, $use_include_path, $context); + + } + + /** + * ### Closes an open stream + * @since 1.0.0 + * + * @param resource $stream

+ * Stream resource to close. + *

+ * + * @return bool True on success, false on failure. + */ + public static function close (mixed $stream):bool { + + return fclose($stream); + + } + +} \ No newline at end of file diff --git a/src/Stream/Lock.php b/src/Stream/Lock.php new file mode 100644 index 0000000..ca7ea0e --- /dev/null +++ b/src/Stream/Lock.php @@ -0,0 +1,63 @@ + + * @copyright 2026-present The FireHub Project - All rights reserved + * @license https://opensource.org/license/Apache-2-0 Apache License, Version 2.0 + * + * @php-version >=8.2 + * @package Runtime + */ + +namespace FireHub\Runtime\Stream; + +use FireHub\Core\Boundary\Runtime\NativeRuntime; +use FireHub\Core\Type\IO\LockMode; + +use function flock; + +/** + * ### PHP Runtime Stream Lock Utilities + * + * Provides low-level wrappers for acquiring and releasing advisory locks on native PHP streams. + * + * Locking behavior depends on the underlying stream wrapper and operating system. + * @since 1.0.0 + */ +final readonly class Lock extends NativeRuntime { + + /** + * ### Performs a stream locking operation + * + * Acquires or releases an advisory lock on a stream. + * @since 1.0.0 + * + * @param resource $stream

+ * Stream resource. + *

+ * @param \FireHub\Core\Type\IO\LockMode $mode

+ * Locking operation. + *

+ * @param bool $non_blocking [optional]

+ * Whether to apply the non-blocking modifier. + *

+ * @param null|bool $would_block [optional]

+ * Receives whether the lock attempt would block. + *

+ * @param-out int $would_block + * + * @return bool True on success, false on failure. + */ + public static function operation (mixed $stream, LockMode $mode, bool $non_blocking = false, ?bool &$would_block = null):bool { + + return flock( + $stream, + $mode->value | ($non_blocking ? LOCK_NB : 0), + $would_block + ); + + } + +} \ No newline at end of file diff --git a/src/Stream/Metadata.php b/src/Stream/Metadata.php index 0cdde71..c55b275 100644 --- a/src/Stream/Metadata.php +++ b/src/Stream/Metadata.php @@ -15,6 +15,7 @@ use FireHub\Core\Boundary\Runtime\NativeRuntime; +use function fstat; use function stream_get_meta_data; use function stream_get_transports; @@ -67,4 +68,24 @@ public static function transports ():array { } + /** + * ### Gets stream resource statistics + * + * Retrieves information about the resource underlying the stream. + * + * The returned array may contain a device, inode, mode, size, timestamps, and other filesystem-related information. + * @since 1.0.0 + * + * @param resource $stream

+ * Stream resource. + *

+ * + * @return array|false Stream statistics, or false on failure. + */ + public static function statistics (mixed $stream):array|false { + + return fstat($stream); + + } + } \ No newline at end of file diff --git a/src/Stream/Position.php b/src/Stream/Position.php new file mode 100644 index 0000000..b01b993 --- /dev/null +++ b/src/Stream/Position.php @@ -0,0 +1,102 @@ + + * @copyright 2026-present The FireHub Project - All rights reserved + * @license https://opensource.org/license/Apache-2-0 Apache License, Version 2.0 + * + * @php-version >=8.2 + * @package Runtime + */ + +namespace FireHub\Runtime\Stream; + +use FireHub\Core\Boundary\Runtime\NativeRuntime; +use FireHub\Core\Type\IO\SeekOrigin; + +use function feof; +use function fseek; +use function ftell; +use function rewind; + +/** + * ### PHP Runtime Stream Position Utilities + * + * Provides low-level wrappers for inspecting and modifying the current position of native PHP streams. + * @since 1.0.0 + */ +final readonly class Position extends NativeRuntime { + + /** + * ### Moves the stream position + * @since 1.0.0 + * + * @param resource $stream

+ * Stream resource. + *

+ * @param int $offset

+ * Position offset in bytes. + *

+ * @param \FireHub\Core\Type\IO\SeekOrigin $origin [optional]

+ * Reference position. + *

+ * + * @return int Zero on success, negative one on failure. + */ + public static function seek (mixed $stream, int $offset, SeekOrigin $origin = SeekOrigin::START):int { + + return fseek($stream, $offset, $origin->value); + + } + + /** + * ### Gets the current stream position + * @since 1.0.0 + * + * @param resource $stream

+ * Stream resource. + *

+ * + * @return int|false Current position, or false on failure. + */ + public static function tell (mixed $stream):int|false { + + return ftell($stream); + + } + + /** + * ### Rewinds the stream + * @since 1.0.0 + * + * @param resource $stream

+ * Stream resource. + *

+ * + * @return bool True on success, false on failure. + */ + public static function rewind (mixed $stream):bool { + + return rewind($stream); + + } + + /** + * ### Determines whether a stream has reached EOF + * @since 1.0.0 + * + * @param resource $stream

+ * Stream resource. + *

+ * + * @return bool True if EOF has been reached. + */ + public static function eof (mixed $stream):bool { + + return feof($stream); + + } + +} \ No newline at end of file diff --git a/src/Stream/Read.php b/src/Stream/Read.php index 0ed5903..5cdbf38 100644 --- a/src/Stream/Read.php +++ b/src/Stream/Read.php @@ -15,6 +15,11 @@ use FireHub\Core\Boundary\Runtime\NativeRuntime; +use function fread; +use function fgets; +use function fgetc; +use function fpassthru; +use function fscanf; use function stream_get_contents; use function stream_get_line; @@ -86,4 +91,105 @@ public static function line (mixed $stream, int $length, string $delimiter = '') } + /** + * ### Reads bytes from a stream + * + * Reads up to the specified number of bytes from the current stream position. + * + * The returned data may contain fewer bytes than requested. + * @since 1.0.0 + * + * @param resource $stream

+ * Stream resource to read from. + *

+ * @param positive-int $length

+ * Maximum number of bytes to read. + *

+ * + * @return string|false Read data, or false on failure. + */ + public static function bytes (mixed $stream, int $length):string|false { + + return fread($stream, $length); + + } + + /** + * ### Reads a line from a stream + * + * Reads data until a newline, the specified length, or the end of the stream is reached. + * @since 1.0.0 + * + * @param resource $stream

+ * Stream resource to read from. + *

+ * @param null|positive-int $length [optional]

+ * Maximum read length, including space for the terminating byte. + *

+ * + * @return string|false Read line, or false on failure. + */ + public static function lineNative (mixed $stream, ?int $length = null):string|false { + + return fgets($stream, $length); + + } + + /** + * ### Reads a character from a stream + * + * Reads a single byte from the current stream position. + * @since 1.0.0 + * + * @param resource $stream

+ * Stream resource to read from. + *

+ * + * @return string|false Single-byte string, or false on failure. + */ + public static function character (mixed $stream):string|false { + + return fgetc($stream); + + } + + /** + * ### Outputs all remaining data from a stream + * + * Reads from the current stream position until EOF and writes the data directly to the output. + * @since 1.0.0 + * + * @param resource $stream

+ * Stream resource to read from. + *

+ * + * @return int Number of bytes written to the output. + */ + public static function passthrough (mixed $stream):int { + + return fpassthru($stream); + + } + + /** + * ### Parses input from a stream according to a format + * + * Reads a line from the stream and parses its values according to the specified format. + * @since 1.0.0 + * + * @param resource $stream

+ * Stream resource to read from. + *

+ * @param string $format

+ * Format string containing conversion specifications. + *

+ * + * @return null|int|list|false Parsed values, null if no values are available, or false on failure. + */ + public static function scan (mixed $stream, string $format):null|array|int|false { + + return fscanf($stream, $format); + + } + } \ No newline at end of file diff --git a/src/Stream/Write.php b/src/Stream/Write.php new file mode 100644 index 0000000..aac6c0f --- /dev/null +++ b/src/Stream/Write.php @@ -0,0 +1,101 @@ + + * @copyright 2026-present The FireHub Project - All rights reserved + * @license https://opensource.org/license/Apache-2-0 Apache License, Version 2.0 + * + * @php-version >=8.2 + * @package Runtime + */ + +namespace FireHub\Runtime\Stream; + +use FireHub\Core\Boundary\Runtime\NativeRuntime; + +use function fflush; +use function ftruncate; +use function fwrite; + +/** + * ### PHP Runtime Stream Writing Utilities + * + * Provides low-level wrappers for writing, flushing, and truncating native PHP streams. + * + * Preserves native PHP stream behavior. + * @since 1.0.0 + */ +final readonly class Write extends NativeRuntime { + + /** + * ### Writes bytes to a stream + * + * Writes data at the current stream position. + * + * The number of bytes written may be smaller than the length of the supplied data. + * @since 1.0.0 + * + * @param resource $stream

+ * Destination stream resource. + *

+ * @param string $data

+ * Data to write. + *

+ * @param null|int<0, max> $length [optional]

+ * Maximum number of bytes to write. + *

+ * + * @return non-negative-int|false Number of bytes written, or false on failure. + */ + public static function bytes (mixed $stream, string $data, ?int $length = null):int|false { + + return fwrite($stream, $data, $length); + + } + + /** + * ### Flushes buffered output to a stream + * + * Flushes PHP's buffered output for the specified stream. + * + * This operation does not guarantee that data has been physically synchronized to persistent storage. + * @since 1.0.0 + * + * @param resource $stream

+ * Stream resource to flush. + *

+ * + * @return bool True on success, false on failure. + */ + public static function flush (mixed $stream):bool { + + return fflush($stream); + + } + + /** + * ### Truncates a stream + * + * Changes the stream size to the specified number of bytes. + * + * The current stream position is not changed. + * @since 1.0.0 + * + * @param resource $stream

+ * Stream resource to truncate. + *

+ * @param non-negative-int $size

+ * New stream size in bytes. + *

+ * + * @return bool True on success, false on failure. + */ + public static function truncate (mixed $stream, int $size):bool { + + return ftruncate($stream, $size); + + } + +} \ No newline at end of file