Skip to content

Commit ca594a3

Browse files
authored
Merge pull request #1 from kbond/features
Add Features
2 parents 01bd1d7 + 31a801d commit ca594a3

File tree

2 files changed

+79
-3
lines changed

2 files changed

+79
-3
lines changed

src/Stream.php

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
/**
66
* @author Kevin Bond <kevinbond@gmail.com>
77
*/
8-
final class Stream
8+
final class Stream implements \Stringable
99
{
1010
/** @var resource */
1111
private $resource;
@@ -22,6 +22,11 @@ private function __construct($resource)
2222
$this->resource = $resource;
2323
}
2424

25+
public function __toString(): string
26+
{
27+
return $this->contents();
28+
}
29+
2530
/**
2631
* @param string|resource|self $what
2732
*/
@@ -104,7 +109,7 @@ public function type(): string
104109
*/
105110
public function contents(?int $length = null, int $offset = -1): string
106111
{
107-
if ($this->metadata('seekable')) {
112+
if ($this->isSeekable()) {
108113
$this->rewind();
109114
}
110115

@@ -115,12 +120,26 @@ public function contents(?int $length = null, int $offset = -1): string
115120
return $contents;
116121
}
117122

123+
/**
124+
* @see \file_put_contents()
125+
*
126+
* @param resource|null $context
127+
*/
128+
public function putContents(string $filename, int $flags = 0, $context = null): self
129+
{
130+
if (false === @\file_put_contents($filename, $this->get(), $flags, $context)) {
131+
throw new \RuntimeException(\sprintf('Unable to dump contents of stream to "%s".', $filename));
132+
}
133+
134+
return $this;
135+
}
136+
118137
/**
119138
* @see \rewind()
120139
*/
121140
public function rewind(): self
122141
{
123-
if (!$this->metadata('seekable')) {
142+
if (!$this->isSeekable()) {
124143
throw new \RuntimeException('Stream does not support seeking.');
125144
}
126145

@@ -131,6 +150,21 @@ public function rewind(): self
131150
return $this;
132151
}
133152

153+
public function isOpen(): bool
154+
{
155+
return \is_resource($this->resource);
156+
}
157+
158+
public function isClosed(): bool
159+
{
160+
return !$this->isOpen();
161+
}
162+
163+
public function isSeekable(): bool
164+
{
165+
return $this->metadata('seekable');
166+
}
167+
134168
/**
135169
* @see \fwrite()
136170
* @see \stream_copy_to_stream()

tests/StreamTest.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ public function can_create_from_string(): void
2828
$this->assertSame('different data', \stream_get_contents(Stream::wrap('different data')->get()));
2929
}
3030

31+
/**
32+
* @test
33+
*/
34+
public function stringable(): void
35+
{
36+
$this->assertSame('some data', (string) Stream::wrap('some data'));
37+
}
38+
3139
/**
3240
* @test
3341
*/
@@ -131,6 +139,7 @@ public function can_get_metadata(): void
131139

132140
$this->assertSame('php://memory', $stream->metadata()['uri']);
133141
$this->assertSame('php://memory', $stream->metadata('uri'));
142+
$this->assertTrue($stream->isSeekable());
134143
}
135144

136145
/**
@@ -166,4 +175,37 @@ public function can_get_id(): void
166175

167176
$this->assertIsInt($stream->id());
168177
}
178+
179+
/**
180+
* @test
181+
*/
182+
public function is_open_closed(): void
183+
{
184+
$stream = Stream::wrap($resource = \fopen(__FILE__, 'r'));
185+
186+
$this->assertTrue($stream->isOpen());
187+
$this->assertFalse($stream->isClosed());
188+
189+
\fclose($resource);
190+
191+
$this->assertFalse($stream->isOpen());
192+
$this->assertTrue($stream->isClosed());
193+
}
194+
195+
/**
196+
* @test
197+
*/
198+
public function put_contents(): void
199+
{
200+
$file = Stream::tempFile()->uri();
201+
202+
\file_put_contents($file, '');
203+
204+
$this->assertFileExists($file);
205+
$this->assertSame('', \file_get_contents($file));
206+
207+
Stream::wrap('content')->putContents($file);
208+
209+
$this->assertSame('content', \file_get_contents($file));
210+
}
169211
}

0 commit comments

Comments
 (0)