Skip to content

Commit 1701f96

Browse files
committed
Define custom line delimiter
1 parent cd33ad2 commit 1701f96

File tree

3 files changed

+54
-14
lines changed

3 files changed

+54
-14
lines changed

README.md

+11-2
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,24 @@ Line reader stream to forward complete lines to a stream.
1111

1212
### LineReader
1313

14-
The center of this project is the `LineReader` class. This class checks incoming data for an new line delimiter, if the delimeter has been found in the current data chunk the data will be exposed on the stream. When the new line delimeter isn't found the data chunk, it will be buffered until a delimiter occures. The `LineReader` is a duplex stream, so a readable and writable stream at the same time.
14+
The center of this project is the `LineReader` class.
15+
This class checks incoming data for an new line delimiter, if the delimeter has been found in the current data chunk the data will be exposed on the stream.
16+
When the new line delimeter isn't found the data chunk,
17+
it will be buffered until a delimiter occures.
18+
The `LineReader` is a duplex stream, so a readable and writable stream at the same time.
1519

1620
Checkout `examples` how you can use this project.
1721

1822
```
1923
$ cat words.txt | php examples/readLine.php
2024
```
2125

22-
This example makes clear what example this project can be used for. Every line with a new line delimiter will put into the readable stream. Every other line without a new line delimiter will be buffered until another occures.
26+
This example makes clear what example this project can be used for.
27+
Every line with a new line delimiter will put into the readable stream.
28+
Every other line without a new line delimiter will be buffered until another occures.
29+
30+
The first parameter of the `LineReader` is the custom delimiter.
31+
The default value of this delimiter is `PHP_EOL`.
2332

2433
## Install
2534

src/LineReader.php

+25-12
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,43 @@
88
use React\Stream\Util;
99

1010
/**
11-
* Read the stream line wise. This class is a duplex stream so a writeable and readable
12-
* stream at the same time
11+
* Read the stream line wise. This class is a duplex stream so a writeable and readable
12+
* stream at the same time
1313
*/
1414
class LineReader extends EventEmitter implements ReadableStreamInterface, WritableStreamInterface
1515
{
1616
private $closed = false;
1717
private $buffer = '';
18-
18+
private $eol;
19+
1920
/**
20-
* Reads the incomg data until the new line delimiter occures,
21-
* if there is no delimiter in the chunk the data will be buffered until
21+
* @param string $eol - delimiter that defines the end of line
22+
*/
23+
public function __construct($eol = PHP_EOL)
24+
{
25+
$this->eol = $eol;
26+
}
27+
28+
/**
29+
* Reads the incomg data until the new line delimiter occures,
30+
* if there is no delimiter in the chunk the data will be buffered until
2231
* the next data chunk comes in
2332
*
2433
* @param string $chunk - string entered by the input stream
2534
*/
2635
public function write($chunk)
2736
{
28-
for ($i = 0; $i < strlen($chunk); $i++) {
29-
$this->buffer .= $chunk[$i];
30-
31-
if ($chunk[$i] == PHP_EOL) {
32-
$this->emit('data', array($this->buffer));
33-
$this->buffer = '';
37+
$this->buffer .= $chunk;
38+
while ($this->buffer !== "") {
39+
$position = strpos($this->buffer, $this->eol);
40+
41+
if ($position === false) {
42+
return;
3443
}
44+
45+
$data = substr($this->buffer, 0, $position + strlen($this->eol));
46+
$this->emit('data', array($data));
47+
$this->buffer = substr($this->buffer, $position + strlen($this->eol));
3548
}
3649
}
3750

@@ -74,7 +87,7 @@ public function close()
7487
$this->emit('close');
7588
$this->removeAllListeners();
7689
}
77-
90+
7891
public function isWritable()
7992
{
8093
return !$this->closed;

tests/LineReaderTest.php

+18
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,24 @@ public function testStreamIsAlreadyClosed()
111111
$lineReader->close();
112112
}
113113

114+
public function testDefinedEolWillSeperateStrings()
115+
{
116+
$lineReader = new LineReader('you');
117+
$input = new ReadableStream();
118+
$input->pipe($lineReader);
119+
120+
$expectedValues = array(
121+
'hello you',
122+
' world you'
123+
);
124+
125+
$lineReader->on('data', $this->expectCallableConsecutive(2, $expectedValues));
126+
127+
$input->emit('data', array(
128+
'hello you world you'
129+
));
130+
}
131+
114132
private function expectCallableConsecutive($numberOfCalls, array $with)
115133
{
116134
$mock = $this->createCallableMock();

0 commit comments

Comments
 (0)