Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 28 |
|
0.00% |
0 / 6 |
CRAP | |
0.00% |
0 / 1 |
StreamReader | |
0.00% |
0 / 28 |
|
0.00% |
0 / 6 |
182 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
tell | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
pos | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
seek | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
12 | |||
read | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
12 | |||
write | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
12 |
1 | <?php |
2 | /** |
3 | * Base class for streaming media segment readers |
4 | * |
5 | * @file |
6 | * @ingroup HLS |
7 | */ |
8 | |
9 | namespace MediaWiki\TimedMediaHandler\HLS; |
10 | |
11 | use InvalidArgumentException; |
12 | use RuntimeException; |
13 | |
14 | /** |
15 | * Base class for reading/writing a media file with wrappers |
16 | * for exception handling and possible multi usage. |
17 | */ |
18 | class StreamReader { |
19 | /** |
20 | * @var resource |
21 | */ |
22 | protected $file; |
23 | |
24 | protected int $pos; |
25 | |
26 | /** |
27 | * @param resource $file |
28 | */ |
29 | public function __construct( $file ) { |
30 | if ( get_resource_type( $file ) !== 'stream' ) { |
31 | throw new InvalidArgumentException( 'Invalid file stream' ); |
32 | } |
33 | $this->file = $file; |
34 | $this->pos = $this->tell(); |
35 | } |
36 | |
37 | private function tell(): int { |
38 | return ftell( $this->file ); |
39 | } |
40 | |
41 | public function pos(): int { |
42 | return $this->pos; |
43 | } |
44 | |
45 | /** |
46 | * Seek to given absolute file position. |
47 | */ |
48 | public function seek( int $pos ): void { |
49 | $this->pos = $pos; |
50 | |
51 | if ( $this->pos === $this->tell() ) { |
52 | return; |
53 | } |
54 | $retval = fseek( $this->file, $this->pos, SEEK_SET ); |
55 | |
56 | if ( $retval < 0 ) { |
57 | throw new RuntimeException( "Failed to seek to $this->pos bytes" ); |
58 | } |
59 | } |
60 | |
61 | /** |
62 | * Read $len bytes or throw on EOF/short read. |
63 | * @throws ShortReadException on end of file |
64 | */ |
65 | public function read( int $len ): string { |
66 | $this->seek( $this->pos ); |
67 | $bytes = fread( $this->file, $len ); |
68 | if ( $bytes === false ) { |
69 | throw new RuntimeException( "Read error for $len bytes at $this->pos" ); |
70 | } |
71 | if ( strlen( $bytes ) < $len ) { |
72 | throw new ShortReadException( $bytes ); |
73 | } |
74 | $this->pos += strlen( $bytes ); |
75 | return $bytes; |
76 | } |
77 | |
78 | /** |
79 | * Write the given data to the stream. |
80 | */ |
81 | public function write( string $bytes ) { |
82 | $this->seek( $this->pos ); |
83 | $len = strlen( $bytes ); |
84 | $nbytes = fwrite( $this->file, $bytes ); |
85 | if ( $nbytes === false ) { |
86 | throw new RuntimeException( "Write error for $len bytes at $this->pos" ); |
87 | } |
88 | if ( $nbytes < $len ) { |
89 | throw new RuntimeException( "Short write; unexpected filesystem error" ); |
90 | } |
91 | $this->pos += $nbytes; |
92 | } |
93 | } |