-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit ab96af8
Showing
29 changed files
with
6,158 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
* text=auto |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
composer.lock | ||
vendor | ||
examples | ||
build | ||
test | ||
logs | ||
artifacts | ||
|
||
.buildpath | ||
.settings | ||
.DS_Store | ||
.phpunit* | ||
.project | ||
.vscode | ||
.idea | ||
.env | ||
|
||
*.env | ||
*.log |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
{ | ||
"name": "localzet/psr", | ||
"description": "PSR Classes", | ||
"type": "library", | ||
"keywords": [ | ||
"localzet" | ||
], | ||
"license": "GPL-3.0-only", | ||
"authors": [{ | ||
"name": "localzet", | ||
"email": "[email protected]", | ||
"homepage": "https://www.localzet.ru", | ||
"role": "Developer" | ||
}], | ||
"support": { | ||
"email": "[email protected]", | ||
"docs": "https://localzet.gitbook.io" | ||
}, | ||
"funding": [{ | ||
"type": "other", | ||
"url": "https://www.tinkoff.ru/cf/Ad5MBNhodod" | ||
}], | ||
"require": { | ||
"php": ">=5.4.0", | ||
"psr/http-message": "~1.0" | ||
}, | ||
"require-dev": { | ||
"phpunit/phpunit": "~4.0" | ||
}, | ||
"provide": { | ||
"psr/http-message-implementation": "1.0" | ||
}, | ||
"autoload": { | ||
"psr-4": { | ||
"localzet\\PSR\\": "src/" | ||
}, | ||
"files": [ | ||
"src/functions_include.php" | ||
] | ||
}, | ||
"extra": { | ||
"branch-alias": { | ||
"dev-master": "1.5-dev" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,254 @@ | ||
<?php | ||
|
||
/** | ||
* @package PSR Http Message | ||
* @link https://localzet.gitbook.io | ||
* | ||
* @author localzet <[email protected]> | ||
* | ||
* @copyright Copyright (c) 2018-2020 Zorin Projects | ||
* @copyright Copyright (c) 2020-2022 NONA Team | ||
* | ||
* @license https://www.localzet.ru/license GNU GPLv3 License | ||
*/ | ||
|
||
namespace localzet\PSR\PSR7; | ||
|
||
use Psr\Http\Message\StreamInterface; | ||
|
||
/** | ||
* Reads from multiple streams, one after the other. | ||
* | ||
* This is a read-only stream decorator. | ||
*/ | ||
class AppendStream implements StreamInterface | ||
{ | ||
/** @var StreamInterface[] Streams being decorated */ | ||
private $streams = []; | ||
|
||
private $seekable = true; | ||
private $current = 0; | ||
private $pos = 0; | ||
|
||
/** | ||
* @param StreamInterface[] $streams Streams to decorate. Each stream must | ||
* be readable. | ||
*/ | ||
public function __construct(array $streams = []) | ||
{ | ||
foreach ($streams as $stream) { | ||
$this->addStream($stream); | ||
} | ||
} | ||
|
||
public function __toString() | ||
{ | ||
try { | ||
$this->rewind(); | ||
return $this->getContents(); | ||
} catch (\Exception $e) { | ||
return ''; | ||
} | ||
} | ||
|
||
/** | ||
* Add a stream to the AppendStream | ||
* | ||
* @param StreamInterface $stream Stream to append. Must be readable. | ||
* | ||
* @throws \InvalidArgumentException if the stream is not readable | ||
*/ | ||
public function addStream(StreamInterface $stream) | ||
{ | ||
if (!$stream->isReadable()) { | ||
throw new \InvalidArgumentException('Each stream must be readable'); | ||
} | ||
|
||
// The stream is only seekable if all streams are seekable | ||
if (!$stream->isSeekable()) { | ||
$this->seekable = false; | ||
} | ||
|
||
$this->streams[] = $stream; | ||
} | ||
|
||
public function getContents() | ||
{ | ||
return copy_to_string($this); | ||
} | ||
|
||
/** | ||
* Closes each attached stream. | ||
* | ||
* {@inheritdoc} | ||
*/ | ||
public function close() | ||
{ | ||
$this->pos = $this->current = 0; | ||
$this->seekable = true; | ||
|
||
foreach ($this->streams as $stream) { | ||
$stream->close(); | ||
} | ||
|
||
$this->streams = []; | ||
} | ||
|
||
/** | ||
* Detaches each attached stream. | ||
* | ||
* Returns null as it's not clear which underlying stream resource to return. | ||
* | ||
* {@inheritdoc} | ||
*/ | ||
public function detach() | ||
{ | ||
$this->pos = $this->current = 0; | ||
$this->seekable = true; | ||
|
||
foreach ($this->streams as $stream) { | ||
$stream->detach(); | ||
} | ||
|
||
$this->streams = []; | ||
} | ||
|
||
public function tell() | ||
{ | ||
return $this->pos; | ||
} | ||
|
||
/** | ||
* Tries to calculate the size by adding the size of each stream. | ||
* | ||
* If any of the streams do not return a valid number, then the size of the | ||
* append stream cannot be determined and null is returned. | ||
* | ||
* {@inheritdoc} | ||
*/ | ||
public function getSize() | ||
{ | ||
$size = 0; | ||
|
||
foreach ($this->streams as $stream) { | ||
$s = $stream->getSize(); | ||
if ($s === null) { | ||
return null; | ||
} | ||
$size += $s; | ||
} | ||
|
||
return $size; | ||
} | ||
|
||
public function eof() | ||
{ | ||
return !$this->streams || | ||
($this->current >= count($this->streams) - 1 && | ||
$this->streams[$this->current]->eof()); | ||
} | ||
|
||
public function rewind() | ||
{ | ||
$this->seek(0); | ||
} | ||
|
||
/** | ||
* Attempts to seek to the given position. Only supports SEEK_SET. | ||
* | ||
* {@inheritdoc} | ||
*/ | ||
public function seek($offset, $whence = SEEK_SET) | ||
{ | ||
if (!$this->seekable) { | ||
throw new \RuntimeException('This AppendStream is not seekable'); | ||
} elseif ($whence !== SEEK_SET) { | ||
throw new \RuntimeException('The AppendStream can only seek with SEEK_SET'); | ||
} | ||
|
||
$this->pos = $this->current = 0; | ||
|
||
// Rewind each stream | ||
foreach ($this->streams as $i => $stream) { | ||
try { | ||
$stream->rewind(); | ||
} catch (\Exception $e) { | ||
throw new \RuntimeException('Unable to seek stream ' | ||
. $i . ' of the AppendStream', 0, $e); | ||
} | ||
} | ||
|
||
// Seek to the actual position by reading from each stream | ||
while ($this->pos < $offset && !$this->eof()) { | ||
$result = $this->read(min(8096, $offset - $this->pos)); | ||
if ($result === '') { | ||
break; | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Reads from all of the appended streams until the length is met or EOF. | ||
* | ||
* {@inheritdoc} | ||
*/ | ||
public function read($length) | ||
{ | ||
$buffer = ''; | ||
$total = count($this->streams) - 1; | ||
$remaining = $length; | ||
$progressToNext = false; | ||
|
||
while ($remaining > 0) { | ||
|
||
// Progress to the next stream if needed. | ||
if ($progressToNext || $this->streams[$this->current]->eof()) { | ||
$progressToNext = false; | ||
if ($this->current === $total) { | ||
break; | ||
} | ||
$this->current++; | ||
} | ||
|
||
$result = $this->streams[$this->current]->read($remaining); | ||
|
||
// Using a loose comparison here to match on '', false, and null | ||
if ($result == null) { | ||
$progressToNext = true; | ||
continue; | ||
} | ||
|
||
$buffer .= $result; | ||
$remaining = $length - strlen($buffer); | ||
} | ||
|
||
$this->pos += strlen($buffer); | ||
|
||
return $buffer; | ||
} | ||
|
||
public function isReadable() | ||
{ | ||
return true; | ||
} | ||
|
||
public function isWritable() | ||
{ | ||
return false; | ||
} | ||
|
||
public function isSeekable() | ||
{ | ||
return $this->seekable; | ||
} | ||
|
||
public function write($string) | ||
{ | ||
throw new \RuntimeException('Cannot write to an AppendStream'); | ||
} | ||
|
||
public function getMetadata($key = null) | ||
{ | ||
return $key ? null : []; | ||
} | ||
} |
Oops, something went wrong.