1 <?php
2 /**
3 * @package Joomla.Platform
4 * @subpackage FileSystem
5 *
6 * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved.
7 * @license GNU General Public License version 2 or later; see LICENSE
8 */
9
10 defined('JPATH_PLATFORM') or die;
11
12 jimport('joomla.filesystem.support.stringcontroller');
13
14 /**
15 * String Stream Wrapper
16 *
17 * This class allows you to use a PHP string in the same way that
18 * you would normally use a regular stream wrapper
19 *
20 * @since 11.1
21 */
22 class JStreamString
23 {
24 /**
25 * The current string
26 *
27 * @var string
28 * @since 12.1
29 */
30 protected $currentString;
31
32 /**
33 * The path
34 *
35 * @var string
36 * @since 12.1
37 */
38 protected $path;
39
40 /**
41 * The mode
42 *
43 * @var string
44 * @since 12.1
45 */
46 protected $mode;
47
48 /**
49 * Enter description here ...
50 *
51 * @var string
52 * @since 12.1
53 */
54 protected $options;
55
56 /**
57 * Enter description here ...
58 *
59 * @var string
60 * @since 12.1
61 */
62 protected $openedPath;
63
64 /**
65 * Current position
66 *
67 * @var integer
68 * @since 12.1
69 */
70 protected $pos;
71
72 /**
73 * Length of the string
74 *
75 * @var string
76 * @since 12.1
77 */
78 protected $len;
79
80 /**
81 * Statistics for a file
82 *
83 * @var array
84 * @since 12.1
85 *
86 * @link http://us.php.net/manual/en/function.stat.php
87 */
88 protected $stat;
89
90 /**
91 * Method to open a file or URL.
92 *
93 * @param string $path The stream path.
94 * @param string $mode Not used.
95 * @param integer $options Not used.
96 * @param string &$opened_path Not used.
97 *
98 * @return boolean
99 *
100 * @since 11.1
101 */
102 public function stream_open($path, $mode, $options, &$opened_path)
103 {
104 $this->currentString = &JStringController::getRef(str_replace('string://', '', $path));
105
106 if ($this->currentString)
107 {
108 $this->len = strlen($this->currentString);
109 $this->pos = 0;
110 $this->stat = $this->url_stat($path, 0);
111
112 return true;
113 }
114 else
115 {
116 return false;
117 }
118 }
119
120 /**
121 * Method to retrieve information from a file resource
122 *
123 * @return array
124 *
125 * @link https://secure.php.net/manual/en/streamwrapper.stream-stat.php
126 * @since 11.1
127 */
128 public function stream_stat()
129 {
130 return $this->stat;
131 }
132
133 /**
134 * Method to retrieve information about a file.
135 *
136 * @param string $path File path or URL to stat
137 * @param integer $flags Additional flags set by the streams API
138 *
139 * @return array
140 *
141 * @link https://secure.php.net/manual/en/streamwrapper.url-stat.php
142 * @since 11.1
143 */
144 public function url_stat($path, $flags = 0)
145 {
146 $now = time();
147 $string = &JStringController::getRef(str_replace('string://', '', $path));
148 $stat = array(
149 'dev' => 0,
150 'ino' => 0,
151 'mode' => 0,
152 'nlink' => 1,
153 'uid' => 0,
154 'gid' => 0,
155 'rdev' => 0,
156 'size' => strlen($string),
157 'atime' => $now,
158 'mtime' => $now,
159 'ctime' => $now,
160 'blksize' => '512',
161 'blocks' => ceil(strlen($string) / 512),
162 );
163
164 return $stat;
165 }
166
167 /**
168 * Method to read a given number of bytes starting at the current position
169 * and moving to the end of the string defined by the current position plus the
170 * given number.
171 *
172 * @param integer $count Bytes of data from the current position should be returned.
173 *
174 * @return void
175 *
176 * @since 11.1
177 *
178 * @link https://secure.php.net/manual/en/streamwrapper.stream-read.php
179 */
180 public function stream_read($count)
181 {
182 $result = substr($this->currentString, $this->pos, $count);
183 $this->pos += $count;
184
185 return $result;
186 }
187
188 /**
189 * Stream write, always returning false.
190 *
191 * @param string $data The data to write.
192 *
193 * @return boolean
194 *
195 * @since 11.1
196 * @note Updating the string is not supported.
197 */
198 public function stream_write($data)
199 {
200 // We don't support updating the string.
201 return false;
202 }
203
204 /**
205 * Method to get the current position
206 *
207 * @return integer The position
208 *
209 * @since 11.1
210 */
211 public function stream_tell()
212 {
213 return $this->pos;
214 }
215
216 /**
217 * End of field check
218 *
219 * @return boolean True if at end of field.
220 *
221 * @since 11.1
222 */
223 public function stream_eof()
224 {
225 if ($this->pos > $this->len)
226 {
227 return true;
228 }
229
230 return false;
231 }
232
233 /**
234 * Stream offset
235 *
236 * @param integer $offset The starting offset.
237 * @param integer $whence SEEK_SET, SEEK_CUR, SEEK_END
238 *
239 * @return boolean True on success.
240 *
241 * @since 11.1
242 */
243 public function stream_seek($offset, $whence)
244 {
245 // $whence: SEEK_SET, SEEK_CUR, SEEK_END
246 if ($offset > $this->len)
247 {
248 // We can't seek beyond our len.
249 return false;
250 }
251
252 switch ($whence)
253 {
254 case SEEK_SET:
255 $this->pos = $offset;
256 break;
257
258 case SEEK_CUR:
259 if (($this->pos + $offset) < $this->len)
260 {
261 $this->pos += $offset;
262 }
263 else
264 {
265 return false;
266 }
267 break;
268
269 case SEEK_END:
270 $this->pos = $this->len - $offset;
271 break;
272 }
273
274 return true;
275 }
276
277 /**
278 * Stream flush, always returns true.
279 *
280 * @return boolean
281 *
282 * @since 11.1
283 * @note Data storage is not supported
284 */
285 public function stream_flush()
286 {
287 // We don't store data.
288 return true;
289 }
290 }
291
292 stream_wrapper_register('string', 'JStreamString') or die('JStreamString Wrapper Registration Failed');
293