1
0
mirror of https://github.com/danog/byte-stream.git synced 2024-11-30 04:19:23 +01:00

Remove Parser

Moved to a separate repository at amphp/parser.
This commit is contained in:
Aaron Piotrowski 2017-06-07 22:23:44 -05:00
parent 6eb83c1218
commit 7a8d6d5f1f
5 changed files with 0 additions and 210 deletions

View File

@ -75,7 +75,3 @@ This package offers some basic implementations, other libraries might provide ev
* [`ResourceOutputStream`](./resource-streams.md)
* [`ZlibOutputStream`](./compression-streams.md)
## Parser
* [`Parser`](./parser.md)

View File

@ -1,5 +0,0 @@
---
title: Parser
permalink: /parser
---
TBD.

View File

@ -1,42 +0,0 @@
<?php
require __DIR__ . "/../vendor/autoload.php";
use Amp\ByteStream\Parser;
use Amp\Loop;
Loop::run(function () {
// Defines a generator that yields integers (number of bytes to read), strings (delimiter to search for), or
// null (read any amount of bytes).
$generator = function (callable $printer): \Generator {
while (true) {
$buffer = yield "\n"; // Reads until a new-line character is found.
$printer($buffer); // Use the received data.
}
};
// The user of Parser is responsible for creating the Generator object, allowing anything to be passed into the
// generator that may be required.
$parser = new Parser($generator(function (string $parsedData) {
static $i = 0;
printf("[%d] %s\n", $i++, $parsedData);
}));
$parser->write("This\nis\n");
Loop::delay(1000, function () use ($parser) {
$parser->write("an\nexample\nof\n");
});
Loop::delay(2000, function () use ($parser) {
$parser->write("a\nsimple\n");
});
Loop::delay(3000, function () use ($parser) {
$parser->write("incremental\nstream\nparser\n");
});
Loop::delay(4000, function () use ($parser) {
$parser->end(); // Marks the end of data.
});
});

View File

@ -1,119 +0,0 @@
<?php
namespace Amp\ByteStream;
use Amp\InvalidYieldError;
class Parser {
/** @var \Generator */
private $generator;
/** @var string */
private $buffer = '';
/** @var int|string|null */
private $delimiter;
/**
* @param \Generator $generator
*
* @throws \Amp\InvalidYieldError If the generator yields an invalid value.
*/
public function __construct(\Generator $generator) {
$this->generator = $generator;
$this->delimiter = $this->generator->current();
if (!$this->generator->valid()) {
$this->generator = null;
return;
}
if ($this->delimiter !== null
&& (!\is_int($this->delimiter) || $this->delimiter <= 0)
&& (!\is_string($this->delimiter) || !\strlen($this->delimiter))
) {
throw new InvalidYieldError(
$generator,
\sprintf(
"Unexpected yield; Expected NULL, an int greater than 0, or a non-empty string; %s given",
\is_object($this->delimiter) ? \sprintf("instance of %s", \get_class($this->delimiter)) : \gettype($this->delimiter)
)
);
}
}
/**
* Cancels the generator parser and returns any remaining data in the internal buffer. Writing data after calling
* this method will result in an error.
*
* @return string
*/
final public function cancel(): string {
$this->generator = null;
return $this->buffer;
}
final public function push(string $data) {
if ($this->generator === null) {
throw new StreamException("The parser is no longer writable");
}
$this->buffer .= $data;
$end = false;
try {
while ($this->buffer !== "") {
if (\is_int($this->delimiter)) {
if (\strlen($this->buffer) < $this->delimiter) {
break; // Too few bytes in buffer.
}
$send = \substr($this->buffer, 0, $this->delimiter);
$this->buffer = \substr($this->buffer, $this->delimiter);
} elseif (\is_string($this->delimiter)) {
if (($position = \strpos($this->buffer, $this->delimiter)) === false) {
break;
}
$send = \substr($this->buffer, 0, $position);
$this->buffer = \substr($this->buffer, $position + \strlen($this->delimiter));
} else {
$send = $this->buffer;
$this->buffer = "";
}
try {
$this->delimiter = $this->generator->send($send);
} catch (\Exception $exception) { // Wrap Exception instances into a StreamException.
throw new StreamException("The generator parser threw an exception", 0, $exception);
}
if (!$this->generator->valid()) {
$end = true;
break;
}
if ($this->delimiter !== null
&& (!\is_int($this->delimiter) || $this->delimiter <= 0)
&& (!\is_string($this->delimiter) || !\strlen($this->delimiter))
) {
throw new InvalidYieldError(
$this->generator,
\sprintf(
"Unexpected yield; Expected NULL, an int greater than 0, or a non-empty string; %s given",
\is_object($this->delimiter) ? \sprintf("instance of %s", \get_class($this->delimiter)) : \gettype($this->delimiter)
)
);
}
}
} catch (\Throwable $exception) {
$end = true;
throw $exception;
} finally {
if ($end) {
$this->generator = null;
}
}
}
}

View File

@ -1,40 +0,0 @@
<?php
namespace Amp\ByteStream\Test;
use Amp\ByteStream\Parser;
use PHPUnit\Framework\TestCase;
class ParserTest extends TestCase {
public function testIntDelimiter() {
$parser = new Parser((function () use (&$value) {
$value = yield 6;
})());
$parser->push("foobarfoo\r\n");
$this->assertSame("foobar", $value);
}
public function testStringDelimiter() {
$parser = new Parser((function () use (&$value1, &$value2) {
$value1 = yield "bar";
$value2 = yield "\r\n";
})());
$parser->push("foobarbaz\r\n");
$this->assertSame("foo", $value1);
$this->assertSame("baz", $value2);
}
public function testUndelimited() {
$parser = new Parser((function () use (&$value) {
$value = yield;
})());
$parser->push("foobarbaz\r\n");
$this->assertSame("foobarbaz\r\n", $value);
}
}