File manager - Edit - /var/www/html/homologBancodetalentos/vendor/psy/psysh/src/Readline/Interactive/Input/StdinReader.php
Back
<?php /* * This file is part of Psy Shell. * * (c) 2012-2026 Justin Hileman * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Psy\Readline\Interactive\Input; /** * Read characters from stdin. */ class StdinReader { /** @var resource */ private $stream; /** * @param resource $stream */ public function __construct($stream = \STDIN) { $this->stream = $stream; } /** * Check if there's pending input (useful for paste detection). */ public function hasPendingInput(): bool { // Memory streams don't support stream_select. $meta = \stream_get_meta_data($this->stream); if (isset($meta['stream_type']) && $meta['stream_type'] === 'MEMORY') { return false; } \stream_set_blocking($this->stream, false); $read = [$this->stream]; $write = null; $except = null; $ready = @\stream_select($read, $write, $except, 0, 0); \stream_set_blocking($this->stream, true); return $ready > 0; } /** * Read all available input (used for handling pastes). * * @return string The pasted content */ public function readPastedContent(): string { // Memory streams don't support stream_select. $meta = \stream_get_meta_data($this->stream); if (isset($meta['stream_type']) && $meta['stream_type'] === 'MEMORY') { $content = ''; while (($char = \fgetc($this->stream)) !== false) { $content .= $char; } return $content; } \stream_set_blocking($this->stream, false); $content = ''; $timeout = 50000; $start = \microtime(true); while ((\microtime(true) - $start) < ($timeout / 1000000)) { $char = \fgetc($this->stream); if ($char === false) { $read = [$this->stream]; $write = null; $except = null; if (@\stream_select($read, $write, $except, 0, 1000) > 0) { continue; } break; } $content .= $char; } \stream_set_blocking($this->stream, true); return $content; } /** * Read a single key press from the input stream. */ public function readKey(): Key { $char = \fgetc($this->stream); if ($char === false) { return new Key('', Key::TYPE_EOF); } // Escape sequences must be handled before paste detection. if ($char === "\033") { $escapeKey = $this->readEscapeSequence($char); if ($escapeKey->getValue() === "\033[200~") { return $this->readBracketedPaste(); } return $escapeKey; } if ($this->hasPendingInput()) { $pastedContent = $char.$this->readPastedContent(); // No ungetc support in PHP, so return any buffered content as a paste. if (\strlen($pastedContent) > 1) { return new Key($pastedContent, Key::TYPE_PASTE); } } // CR/LF are handled as regular chars, not control characters. $ord = \ord($char); if ($ord < 32 && $char !== "\n" && $char !== "\r") { return new Key($char, Key::TYPE_CONTROL); } if ($ord === 127) { return new Key($char, Key::TYPE_CONTROL); } return new Key($char, Key::TYPE_CHAR); } /** * Read an escape sequence from the input stream. */ protected function readEscapeSequence(string $prefix): Key { \stream_set_blocking($this->stream, false); $sequence = $prefix; $timeout = 100000; $start = \microtime(true); while ((\microtime(true) - $start) < ($timeout / 1000000)) { $char = \fgetc($this->stream); if ($char === false) { \usleep(1000); // 1ms continue; } $sequence .= $char; if ($this->isCompleteEscapeSequence($sequence)) { break; } if (\strlen($sequence) > 32) { break; } } \stream_set_blocking($this->stream, true); return new Key($sequence, Key::TYPE_ESCAPE); } /** * Check if an escape sequence is complete. */ protected function isCompleteEscapeSequence(string $sequence): bool { // Esc+Enter remaps (common in terminal keybind customization). if ($sequence === "\033\r" || $sequence === "\033\n") { return true; } // Arrow keys: \033[A-D, Home/End: \033[H, \033[F if (\preg_match('/^\033\[[A-DHF]$/', $sequence)) { return true; } // Function keys, Delete, bracketed paste: \033[NNN~ or \033[27;2;13~ if (\preg_match('/^\033\[\d+(?:[;:]\d+)*~$/', $sequence)) { return true; } // Modified keys: \033[1;3C (Alt+Right), \033[1;5D (Ctrl+Left), etc. if (\preg_match('/^\033\[\d+(?:[;:]\d+)*[A-Za-z]$/', $sequence)) { return true; } // CSI-u protocol: \033[13;2u (Shift+Enter), \033[97;5u (Ctrl+A), etc. if (\preg_match('/^\033\[\d+(?:[;:]\d+)*u$/', $sequence)) { return true; } // SS3 keys: \033OM (keypad Enter), \033OA, etc. if (\preg_match('/^\033O[A-Z]$/', $sequence)) { return true; } // Alt+char: \033b, \033f, etc. if (\preg_match('/^\033[a-z]$/i', $sequence)) { return true; } return false; } /** * Read bracketed paste content. * * Called after detecting \033[200~ sequence. * Reads until \033[201~ is encountered. */ protected function readBracketedPaste(): Key { $content = ''; $escapeBuffer = ''; while (true) { $char = \fgetc($this->stream); if ($char === false) { break; } if ($char === "\033") { $escapeBuffer = $char; \stream_set_blocking($this->stream, false); $timeout = 10000; $start = \microtime(true); while ((\microtime(true) - $start) < ($timeout / 1000000)) { $nextChar = \fgetc($this->stream); if ($nextChar === false) { \usleep(500); continue; } $escapeBuffer .= $nextChar; if ($escapeBuffer === "\033[201~") { \stream_set_blocking($this->stream, true); return new Key($content, Key::TYPE_PASTE); } if ($this->isCompleteEscapeSequence($escapeBuffer)) { break; } if (\strlen($escapeBuffer) > 32) { break; } } \stream_set_blocking($this->stream, true); $content .= $escapeBuffer; $escapeBuffer = ''; } else { $content .= $char; } } return new Key($content, Key::TYPE_PASTE); } /** * Get the underlying stream resource. * * @return resource */ public function getStream() { return $this->stream; } }
| ver. 1.4 |
Github
|
.
| PHP 8.3.28 | Generation time: 0.01 |
proxy
|
phpinfo
|
Settings