getch/src/Console/Getch.php

71 lines
1.8 KiB
PHP
Raw Normal View History

2021-01-25 12:35:32 -08:00
<?php
declare(strict_types=1);
2020-12-22 14:19:32 -08:00
/*
* Copyright (c) 2020 https://rewiv.com sikofitt@gmail.com
*
* This Source Code Form is subject to the
* terms of the Mozilla Public License, v. 2.0.
*
* If a copy of the MPL was not distributed with this file,
* You can obtain one at https://mozilla.org/MPL/2.0/.
*/
namespace Sikofitt\Console;
use FFI;
use RuntimeException;
final class Getch
{
2021-01-25 12:35:32 -08:00
private const LINUX_LIBRARY = __DIR__.'/Resources/libgetch.so';
2020-12-22 14:19:32 -08:00
private const WINDOWS_LIBRARY = 'ucrtbase.dll';
2021-01-25 12:35:32 -08:00
private const DECLARATIONS = <<<DECLARATIONS
int _getch();
int _ungetch(int c);
DECLARATIONS;
2020-12-22 14:19:32 -08:00
private static ?FFI $ffi = null;
public function __construct(string $linuxLibrary = null)
{
if (null === $linuxLibrary) {
$linuxLibrary = self::LINUX_LIBRARY;
}
2021-01-25 12:35:32 -08:00
if (null === self::$ffi) {
2020-12-22 14:19:32 -08:00
$osFamily = PHP_OS_FAMILY;
2021-01-25 12:35:32 -08:00
if ('Windows' === $osFamily) {
self::$ffi = FFI::cdef(self::DECLARATIONS, self::WINDOWS_LIBRARY);
} elseif ('Linux' === $osFamily) {
2020-12-22 14:19:32 -08:00
if (!file_exists($linuxLibrary)) {
throw new RuntimeException(sprintf('Could not find library file %s.', $linuxLibrary));
}
2021-01-25 12:35:32 -08:00
self::$ffi = FFI::cdef(self::DECLARATIONS, $linuxLibrary);
2020-12-22 14:19:32 -08:00
} else {
throw new RuntimeException(sprintf('Sorry, %s is not supported yet.', $osFamily));
}
}
}
2021-01-25 12:35:32 -08:00
public function getch(): int
2020-12-22 14:19:32 -08:00
{
2021-01-07 13:56:08 -08:00
return self::$ffi->_getch();
}
2021-01-25 12:35:32 -08:00
public function ungetch($char): int
2021-01-07 14:13:05 -08:00
{
2021-01-25 12:35:32 -08:00
if (!is_string($char) && !is_int($char)) {
throw new \TypeError('ungetch takes a parameter of int or string.');
}
2021-01-07 14:13:05 -08:00
2021-01-25 12:35:32 -08:00
if (is_string($char)) {
$char = ord($char[0]);
2021-01-07 14:13:05 -08:00
}
2021-01-25 12:35:32 -08:00
return self::$ffi->_ungetch($char);
2020-12-22 14:19:32 -08:00
}
}