You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Test-Miroir/SourceQuery/Buffer.php

172 lines
3.4 KiB

<?php
declare(strict_types=1);
/**
* @author Pavel Djundik
*
* @link https://xpaw.me
* @link https://github.com/xPaw/PHP-Source-Query
*
* @license GNU Lesser General Public License, version 2.1
*
* @internal
*/
namespace xPaw\SourceQuery;
use xPaw\SourceQuery\Exception\InvalidPacketException;
/**
* Class Buffer
*
* @package xPaw\SourceQuery
*
* @uses xPaw\SourceQuery\Exception\InvalidPacketException
*/
final class Buffer
{
/**
* Buffer
*/
private string $Buffer = '';
/**
* Buffer length
*/
private int $Length = 0;
/**
* Current position in buffer
*/
private int $Position = 0;
/**
* Sets buffer
*/
public function Set(string $Buffer): void
{
$this->Buffer = $Buffer;
$this->Length = strlen($Buffer);
$this->Position = 0;
}
/**
* Get remaining bytes
*
* @return int Remaining bytes in buffer
*/
public function Remaining(): int
{
return $this->Length - $this->Position;
}
/**
* Gets data from buffer
*
* @param int $Length Bytes to read
*/
public function Get(int $Length = -1): string
{
if ($Length === 0) {
return '';
}
$Remaining = $this->Remaining();
if ($Length === -1) {
$Length = $Remaining;
} elseif ($Length > $Remaining) {
return '';
}
$Data = substr($this->Buffer, $this->Position, $Length);
$this->Position += $Length;
return $Data;
}
/**
* Get byte from buffer
*/
public function GetByte(): int
{
return ord($this->Get(1));
}
/**
* Get short from buffer
*/
public function GetShort(): int
{
if ($this->Remaining() < 2) {
throw new InvalidPacketException('Not enough data to unpack a short.', InvalidPacketException::BUFFER_EMPTY);
}
$Data = unpack('v', $this->Get(2));
return (int)$Data[ 1 ];
}
/**
* Get long from buffer
*/
public function GetLong(): int
{
if ($this->Remaining() < 4) {
throw new InvalidPacketException('Not enough data to unpack a long.', InvalidPacketException::BUFFER_EMPTY);
}
$Data = unpack('l', $this->Get(4));
return (int)$Data[ 1 ];
}
/**
* Get float from buffer
*/
public function GetFloat(): float
{
if ($this->Remaining() < 4) {
throw new InvalidPacketException('Not enough data to unpack a float.', InvalidPacketException::BUFFER_EMPTY);
}
$Data = unpack('f', $this->Get(4));
return (float)$Data[ 1 ];
}
/**
* Get unsigned long from buffer
*/
public function GetUnsignedLong(): int
{
if ($this->Remaining() < 4) {
throw new InvalidPacketException('Not enough data to unpack an usigned long.', InvalidPacketException::BUFFER_EMPTY);
}
$Data = unpack('V', $this->Get(4));
return (int)$Data[ 1 ];
}
/**
* Read one string from buffer ending with null byte
*/
public function GetString(): string
{
$ZeroBytePosition = strpos($this->Buffer, "\0", $this->Position);
if ($ZeroBytePosition === false) {
return '';
}
$String = $this->Get($ZeroBytePosition - $this->Position);
$this->Position++;
return $String;
}
}