Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
89.36% |
42 / 47 |
|
70.59% |
12 / 17 |
CRAP | |
0.00% |
0 / 1 |
StringStream | |
89.36% |
42 / 47 |
|
70.59% |
12 / 17 |
30.01 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
copyToStream | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
__toString | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
close | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
detach | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getSize | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
tell | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
eof | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
isSeekable | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
seek | |
92.86% |
13 / 14 |
|
0.00% |
0 / 1 |
7.02 | |||
rewind | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
isWritable | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
write | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
2 | |||
isReadable | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
read | |
85.71% |
6 / 7 |
|
0.00% |
0 / 1 |
4.05 | |||
getContents | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
3 | |||
getMetadata | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Rest; |
4 | |
5 | use InvalidArgumentException; |
6 | |
7 | /** |
8 | * A stream class which uses a string as the underlying storage. Surprisingly, |
9 | * Guzzle does not appear to have one of these. BufferStream does not do what |
10 | * we want. |
11 | * |
12 | * The normal use of this class should be to first write to the stream, then |
13 | * rewind, then read back the whole buffer with getContents(). |
14 | * |
15 | * Seeking is supported, however seeking past the end of the string does not |
16 | * fill with null bytes as in a real file, it throws an exception instead. |
17 | */ |
18 | class StringStream implements CopyableStreamInterface { |
19 | |
20 | /** @var string */ |
21 | private $contents; |
22 | /** @var int */ |
23 | private $offset = 0; |
24 | |
25 | /** |
26 | * Construct a StringStream with the given contents. |
27 | * |
28 | * The offset will start at 0, ready for reading. If appending to the |
29 | * given string is desired, you should first seek to the end. |
30 | * |
31 | * @param string $contents |
32 | */ |
33 | public function __construct( $contents = '' ) { |
34 | $this->contents = $contents; |
35 | } |
36 | |
37 | public function copyToStream( $stream ) { |
38 | fwrite( $stream, $this->getContents() ); |
39 | } |
40 | |
41 | public function __toString() { |
42 | return $this->contents; |
43 | } |
44 | |
45 | public function close() { |
46 | } |
47 | |
48 | public function detach() { |
49 | return null; |
50 | } |
51 | |
52 | public function getSize() { |
53 | return strlen( $this->contents ); |
54 | } |
55 | |
56 | public function tell() { |
57 | return $this->offset; |
58 | } |
59 | |
60 | public function eof() { |
61 | return $this->offset >= strlen( $this->contents ); |
62 | } |
63 | |
64 | public function isSeekable() { |
65 | return true; |
66 | } |
67 | |
68 | public function seek( $offset, $whence = SEEK_SET ) { |
69 | switch ( $whence ) { |
70 | case SEEK_SET: |
71 | $this->offset = $offset; |
72 | break; |
73 | |
74 | case SEEK_CUR: |
75 | $this->offset += $offset; |
76 | break; |
77 | |
78 | case SEEK_END: |
79 | $this->offset = strlen( $this->contents ) + $offset; |
80 | break; |
81 | |
82 | default: |
83 | throw new InvalidArgumentException( "Invalid value for \$whence" ); |
84 | } |
85 | if ( $this->offset > strlen( $this->contents ) ) { |
86 | throw new InvalidArgumentException( "Cannot seek beyond the end of a StringStream" ); |
87 | } |
88 | if ( $this->offset < 0 ) { |
89 | throw new InvalidArgumentException( "Cannot seek before the start of a StringStream" ); |
90 | } |
91 | } |
92 | |
93 | public function rewind() { |
94 | $this->offset = 0; |
95 | } |
96 | |
97 | public function isWritable() { |
98 | return true; |
99 | } |
100 | |
101 | public function write( $string ) { |
102 | if ( $this->offset === strlen( $this->contents ) ) { |
103 | $this->contents .= $string; |
104 | } else { |
105 | $this->contents = substr_replace( $this->contents, $string, |
106 | $this->offset, strlen( $string ) ); |
107 | } |
108 | $this->offset += strlen( $string ); |
109 | return strlen( $string ); |
110 | } |
111 | |
112 | public function isReadable() { |
113 | return true; |
114 | } |
115 | |
116 | public function read( $length ) { |
117 | if ( $this->offset === 0 && $length >= strlen( $this->contents ) ) { |
118 | $ret = $this->contents; |
119 | } elseif ( $this->offset >= strlen( $this->contents ) ) { |
120 | $ret = ''; |
121 | } else { |
122 | $ret = substr( $this->contents, $this->offset, $length ); |
123 | } |
124 | $this->offset += strlen( $ret ); |
125 | return $ret; |
126 | } |
127 | |
128 | public function getContents() { |
129 | if ( $this->offset === 0 ) { |
130 | $ret = $this->contents; |
131 | } elseif ( $this->offset >= strlen( $this->contents ) ) { |
132 | $ret = ''; |
133 | } else { |
134 | $ret = substr( $this->contents, $this->offset ); |
135 | } |
136 | $this->offset = strlen( $this->contents ); |
137 | return $ret; |
138 | } |
139 | |
140 | public function getMetadata( $key = null ) { |
141 | return null; |
142 | } |
143 | } |