~ancarda/psr7-string-stream

bdc210839b65343629b6634cda8ca01092adc44e — Mark Dain 1 year, 9 months ago 534f6c3
Fix write() to not prepend

This commit brings write() more inline with how fwrite() works, given
that's ultimately what StreamInterface is trying to provide; a wrapper
around streams and the various file functions

It's still possible to append by writing beyond the capacity of the
string
2 files changed, 21 insertions(+), 25 deletions(-)

M src/StringStream.php
M tests/StringStreamTest.php
M src/StringStream.php => src/StringStream.php +5 -11
@@ 177,15 177,9 @@ class StringStream implements StreamInterface
    {
        // If we're at the end of the data, we can just append.
        if ($this->eof()) {
            $this->length += strlen($string);
            $this->data   .= $string;
            return strlen($string);
        }

        // If we're at the start of the data, we can just prepend.
        if ($this->pointer === 0) {
            $this->length += strlen($string);
            $this->data   = $string . $this->data;
            $this->length  += strlen($string);
            $this->data    .= $string;
            $this->pointer = $this->length;
            return strlen($string);
        }



@@ 197,8 191,8 @@ class StringStream implements StreamInterface
            substr($this->data, $this->pointer + strlen($string));

        // Since we can do both overwriting and appending here, we'll just recalculate:
        $this->length = strlen($this->data);

        $this->length  = strlen($this->data);
        $this->pointer = $this->length;
        return strlen($string);
    }


M tests/StringStreamTest.php => tests/StringStreamTest.php +16 -14
@@ 82,40 82,42 @@ class StringStreamTest extends TestCase
        static::assertSame($fullString, (string) $stringStream);
        static::assertSame(strlen(', isn\'t it a lovely day'), $bytesWritten);

        // Can we write at the start of a string?
        // Can we overwrite at the start of the string to fix the capitalization?
        $stringStream->seek(0);
        $bytesWritten = $stringStream->write('Oh! ');
        $fullString = 'Oh! hello world, isn\'t it a lovely day';
        static::assertSame(strlen($fullString), $stringStream->getSize());
        static::assertSame($fullString, (string) $stringStream);
        static::assertSame(4, $bytesWritten);

        // Can we write in the middle of the string to fix the capitalization?
        $stringStream->seek(4);
        $bytesWritten = $stringStream->write('H');
        $fullString = 'Oh! Hello world, isn\'t it a lovely day';
        $fullString = 'Hello world, isn\'t it a lovely day';
        static::assertSame(strlen($fullString), $stringStream->getSize());
        static::assertSame($fullString, (string) $stringStream);
        static::assertSame(1, $bytesWritten);

        // Can we make a multi-word replacement? We'll replace 2 bytes with 0x7F (DEL) which in a
        // real world application could be filtered out as deleted bytes.
        $stringStream->seek(4);
        $stringStream->seek(0);
        $bytesWritten = $stringStream->write('Hey' . chr(127) . chr(127));
        $fullString = 'Oh! Hey' . chr(127) . chr(127) . ' world, isn\'t it a lovely day';
        $fullString = 'Hey' . chr(127) . chr(127) . ' world, isn\'t it a lovely day';
        static::assertSame(strlen($fullString), $stringStream->getSize());
        static::assertSame($fullString, (string) $stringStream);
        static::assertSame(5, $bytesWritten);

        // Finally, can we replace and append?
        $stringStream->seek(35);
        $stringStream->seek(31);
        $bytesWritten = $stringStream->write('evening?');
        $fullString = 'Oh! Hey' . chr(127) . chr(127) . ' world, isn\'t it a lovely evening?';
        $fullString = 'Hey' . chr(127) . chr(127) . ' world, isn\'t it a lovely evening?';
        static::assertSame(strlen($fullString), $stringStream->getSize());
        static::assertSame($fullString, (string) $stringStream);
        static::assertSame(8, $bytesWritten);
    }

    public function testOverwriteWorksCorrectly(): void
    {
        $stream = new StringStream('');
        $stream->write('abc');
        $stream->write('def');
        $stream->rewind();
        $stream->write('XXX');
        static::assertSame('XXXdef', (string) $stream);
    }

    public function testMiscFunctions(): void
    {
        $stringStream = new StringStream('hello world');