1: <?php declare(strict_types=1);
2:
3: namespace Salient\Contract\Polyfill;
4:
5: /**
6: * Base class for stream wrappers
7: *
8: * This class provides an abstraction of the streamWrapper prototype described
9: * in the PHP manual.
10: *
11: * @api
12: *
13: * @link https://www.php.net/manual/en/class.streamwrapper.php
14: */
15: abstract class StreamWrapper implements StreamWrapperInterface
16: {
17: /** @var resource|null */
18: public $context;
19:
20: /**
21: * Retrieve the underlying resource
22: *
23: * This method is called in response to {@see stream_select()}.
24: *
25: * @param int $cast_as Can be {@see \STREAM_CAST_FOR_SELECT} when
26: * {@see stream_select()} is calling **stream_cast()** or
27: * {@see \STREAM_CAST_AS_STREAM} when **stream_cast()** is called for other
28: * uses.
29: * @return resource|false The underlying stream resource used by the
30: * wrapper, or `false`.
31: */
32: abstract public function stream_cast(int $cast_as);
33:
34: /**
35: * Close a resource
36: *
37: * This method is called in response to {@see fclose()}.
38: *
39: * All resources that were locked, or allocated, by the wrapper should be
40: * released.
41: */
42: abstract public function stream_close(): void;
43:
44: /**
45: * Tests for end-of-file on a file pointer
46: *
47: * This method is called in response to {@see feof()}.
48: *
49: * @return bool `true` if the read/write position is at the end of the
50: * stream and if no more data is available to be read, or `false` otherwise.
51: */
52: abstract public function stream_eof(): bool;
53:
54: /**
55: * Flushes the output
56: *
57: * This method is called in response to {@see fflush()} and when the stream
58: * is being closed while any unflushed data has been written to it before.
59: *
60: * If you have cached data in your stream but not yet stored it into the
61: * underlying storage, you should do so now.
62: *
63: * @return bool `true` if the cached data was successfully stored (or if
64: * there was no data to store), or `false` if the data could not be stored.
65: */
66: abstract public function stream_flush(): bool;
67:
68: /**
69: * Change stream metadata
70: *
71: * This method is called to set metadata on the stream. It is called when
72: * one of the following functions is called on a stream URL:
73: *
74: * - {@see touch()}
75: * - {@see chmod()}
76: * - {@see chown()}
77: * - {@see chgrp()}
78: *
79: * @param string $path The file path or URL to set metadata. Note that in
80: * the case of a URL, it must be a :// delimited URL. Other URL forms are
81: * not supported.
82: * @param int $option One of:
83: *
84: * - {@see \STREAM_META_TOUCH} (The method was called in response to
85: * {@see touch()})
86: * - {@see \STREAM_META_OWNER_NAME} (The method was called in response to
87: * {@see chown()})
88: * - {@see \STREAM_META_OWNER} (The method was called in response to
89: * {@see chown()})
90: * - {@see \STREAM_META_GROUP_NAME} (The method was called in response to
91: * {@see chgrp()})
92: * - {@see \STREAM_META_GROUP} (The method was called in response to
93: * {@see chgrp()})
94: * - {@see \STREAM_META_ACCESS} (The method was called in response to
95: * {@see chmod()})
96: * @param mixed $value If **`option`** is
97: *
98: * - {@see \STREAM_META_TOUCH}: Array consisting of two arguments of the
99: * {@see touch()} function.
100: * - {@see \STREAM_META_OWNER_NAME} or {@see \STREAM_META_GROUP_NAME}: The
101: * name of the owner user/group as `string`.
102: * - {@see \STREAM_META_OWNER} or {@see \STREAM_META_GROUP}: The value of
103: * the owner user/group as `int`.
104: * - {@see \STREAM_META_ACCESS}: The argument of the {@see chmod()} function
105: * as `int`.
106: * @return bool `true` on success or `false` on failure. If **`option`** is
107: * not implemented, `false` should be returned.
108: */
109: abstract public function stream_metadata(string $path, int $option, $value): bool;
110:
111: /**
112: * Opens file or URL
113: *
114: * This method is called immediately after the wrapper is initialized (e.g.
115: * by {@see fopen()} and {@see file_get_contents()}).
116: *
117: * @param string $path Specifies the URL that was passed to the original
118: * function. Only URLs delimited by :// are supported.
119: * @param string $mode The mode used to open the file, as detailed for
120: * {@see fopen()}.
121: * @param int $options Holds additional flags set by the streams API. It can
122: * hold one or more of the following values OR'd together.
123: *
124: * - {@see \STREAM_USE_PATH}: If **`path`** is relative, search for the
125: * resource using the include_path.
126: * - {@see \STREAM_REPORT_ERRORS}: If this flag is set, you are responsible
127: * for raising errors using {@see trigger_error()} during opening of the
128: * stream. If this flag is not set, you should not raise any errors.
129: * @param string|null $opened_path If the **`path`** is opened successfully,
130: * and {@see \STREAM_USE_PATH} is set in **`options`**, **`opened_path`**
131: * should be set to the full path of the file/resource that was actually
132: * opened.
133: * @return bool `true` on success or `false` on failure.
134: */
135: abstract public function stream_open(
136: string $path,
137: string $mode,
138: int $options,
139: ?string &$opened_path
140: ): bool;
141:
142: /**
143: * Read from stream
144: *
145: * This method is called in response to {@see fread()} and {@see fgets()}.
146: *
147: * > Remember to update the read/write position of the stream (by the number
148: * > of bytes that were successfully read).
149: *
150: * @param int $count How many bytes of data from the current position should
151: * be returned.
152: * @return string|false If there are less than **`count`** bytes available,
153: * as many as are available should be returned. If no more data is
154: * available, an empty string should be returned. To signal that reading
155: * failed, `false` should be returned.
156: */
157: abstract public function stream_read(int $count);
158:
159: /**
160: * Seeks to specific location in a stream
161: *
162: * This method is called in response to {@see fseek()}.
163: *
164: * @param int $offset The stream offset to seek to.
165: * @param int $whence Possible values:
166: *
167: * - {@see \SEEK_SET}: Set position equal to **`offset`** bytes.
168: * - {@see \SEEK_CUR}: Set position to current location plus **`offset`**.
169: * (Never used by current implementation; always internally converted to
170: * {@see \SEEK_SET}.)
171: * - {@see \SEEK_END}: Set position to end-of-file plus **`offset`**.
172: * @return bool `true` if the position was updated, `false` otherwise.
173: */
174: abstract public function stream_seek(int $offset, int $whence = \SEEK_SET): bool;
175:
176: /**
177: * Change stream options
178: *
179: * @param int $option One of:
180: *
181: * - {@see \STREAM_OPTION_BLOCKING} (The method was called in response to
182: * {@see stream_set_blocking()})
183: * - {@see \STREAM_OPTION_READ_TIMEOUT} (The method was called in response
184: * to {@see stream_set_timeout()})
185: * - {@see \STREAM_OPTION_READ_BUFFER} (The method was called in response to
186: * {@see stream_set_read_buffer()})
187: * - {@see \STREAM_OPTION_WRITE_BUFFER} (The method was called in response
188: * to {@see stream_set_write_buffer()})
189: * @param int $arg1 If **`option`** is
190: *
191: * - {@see \STREAM_OPTION_BLOCKING}: requested blocking mode (1 meaning
192: * block, 0 not blocking).
193: * - {@see \STREAM_OPTION_READ_TIMEOUT}: the timeout in seconds.
194: * - {@see \STREAM_OPTION_READ_BUFFER}: buffer mode
195: * ({@see \STREAM_BUFFER_NONE} or {@see \STREAM_BUFFER_FULL}).
196: * - {@see \STREAM_OPTION_WRITE_BUFFER}: buffer mode
197: * ({@see \STREAM_BUFFER_NONE} or {@see \STREAM_BUFFER_FULL}).
198: * @param int $arg2 If **`option`** is
199: *
200: * - {@see \STREAM_OPTION_BLOCKING}: not set.
201: * - {@see \STREAM_OPTION_READ_TIMEOUT}: the timeout in microseconds.
202: * - {@see \STREAM_OPTION_READ_BUFFER}: the requested buffer size.
203: * - {@see \STREAM_OPTION_WRITE_BUFFER}: the requested buffer size.
204: * @return bool `true` on success or `false` on failure. If **`option`** is
205: * not implemented, `false` should be returned.
206: */
207: abstract public function stream_set_option(int $option, int $arg1, int $arg2): bool;
208:
209: /**
210: * Retrieve information about a file resource
211: *
212: * This method is called in response to {@see fstat()}.
213: *
214: * @return mixed[]|false
215: */
216: abstract public function stream_stat();
217:
218: /**
219: * Retrieve the current position of a stream
220: *
221: * This method is called in response to {@see fseek()}.
222: */
223: abstract public function stream_tell(): int;
224:
225: /**
226: * Truncate stream
227: *
228: * This method is called in response to {@see ftruncate()}.
229: *
230: * @return bool `true` on success or `false` on failure.
231: */
232: abstract public function stream_truncate(int $new_size): bool;
233:
234: /**
235: * Write to stream
236: *
237: * This method is called in response to {@see fwrite()}.
238: *
239: * > Remember to update the current position of the stream by number of
240: * > bytes that were successfully written.
241: *
242: * @param string $data Should be stored into the underlying stream. If there
243: * is not enough room in the underlying stream, store as much as possible.
244: * @return int The number of bytes that were successfully stored, or `0` if
245: * none could be stored.
246: */
247: abstract public function stream_write(string $data): int;
248:
249: /**
250: * Retrieve information about a file
251: *
252: * This method is called in response to all {@see stat()} related functions.
253: *
254: * @param string $path The file path or URL to stat. Note that in the case
255: * of a URL, it must be a :// delimited URL. Other URL forms are not
256: * supported.
257: * @param int $flags Holds additional flags set by the streams API. It can
258: * hold one or more of the following values OR'd together.
259: *
260: * - {@see \STREAM_URL_STAT_LINK}: For resources with the ability to link to
261: * other resource (such as an HTTP Location: forward, or a filesystem
262: * symlink). This flag specified that only information about the link
263: * itself should be returned, not the resource pointed to by the link.
264: * This flag is set in response to calls to {@see lstat()},
265: * {@see is_link()}, or {@see filetype()}.
266: * - {@see \STREAM_URL_STAT_QUIET}: If this flag is set, your wrapper should
267: * not raise any errors. If this flag is not set, you are responsible for
268: * reporting errors using the {@see trigger_error()} function.
269: * @return mixed[]|false `false` on failure, otherwise an `array` with the
270: * same elements returned by {@see stat()}. Unknown or unavailable values
271: * should be set to a rational value (usually `0`). Special attention should
272: * be paid to **`mode`** as documented under {@see stat()}.
273: */
274: abstract public function url_stat(string $path, int $flags);
275: }
276:
277: /**
278: * @internal
279: */
280: interface StreamWrapperInterface
281: {
282: /**
283: * Constructs a new stream wrapper
284: *
285: * Called when opening the stream wrapper, right before
286: * {@see StreamWrapper::stream_open()}.
287: */
288: public function __construct();
289: }
290: