1 <?php
2 /**
3 * @package Joomla.Platform
4 * @subpackage Utilities
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 /**
13 * Generic Buffer stream handler
14 *
15 * This class provides a generic buffer stream. It can be used to store/retrieve/manipulate
16 * string buffers with the standard PHP filesystem I/O methods.
17 *
18 * @since 11.1
19 */
20 class JBuffer
21 {
22 /**
23 * Stream position
24 *
25 * @var integer
26 * @since 11.1
27 */
28 public $position = 0;
29
30 /**
31 * Buffer name
32 *
33 * @var string
34 * @since 11.1
35 */
36 public $name = null;
37
38 /**
39 * Buffer hash
40 *
41 * @var array
42 * @since 12.1
43 */
44 public $buffers = array();
45
46 /**
47 * Function to open file or url
48 *
49 * @param string $path The URL that was passed
50 * @param string $mode Mode used to open the file @see fopen
51 * @param integer $options Flags used by the API, may be STREAM_USE_PATH and
52 * STREAM_REPORT_ERRORS
53 * @param string &$opened_path Full path of the resource. Used with STREAN_USE_PATH option
54 *
55 * @return boolean
56 *
57 * @since 11.1
58 * @see streamWrapper::stream_open
59 */
60 public function stream_open($path, $mode, $options, &$opened_path)
61 {
62 $url = parse_url($path);
63 $this->name = $url['host'];
64 $this->buffers[$this->name] = null;
65 $this->position = 0;
66
67 return true;
68 }
69
70 /**
71 * Read stream
72 *
73 * @param integer $count How many bytes of data from the current position should be returned.
74 *
75 * @return mixed The data from the stream up to the specified number of bytes (all data if
76 * the total number of bytes in the stream is less than $count. Null if
77 * the stream is empty.
78 *
79 * @see streamWrapper::stream_read
80 * @since 11.1
81 */
82 public function stream_read($count)
83 {
84 $ret = substr($this->buffers[$this->name], $this->position, $count);
85 $this->position += strlen($ret);
86
87 return $ret;
88 }
89
90 /**
91 * Write stream
92 *
93 * @param string $data The data to write to the stream.
94 *
95 * @return integer
96 *
97 * @see streamWrapper::stream_write
98 * @since 11.1
99 */
100 public function stream_write($data)
101 {
102 $left = substr($this->buffers[$this->name], 0, $this->position);
103 $right = substr($this->buffers[$this->name], $this->position + strlen($data));
104 $this->buffers[$this->name] = $left . $data . $right;
105 $this->position += strlen($data);
106
107 return strlen($data);
108 }
109
110 /**
111 * Function to get the current position of the stream
112 *
113 * @return integer
114 *
115 * @see streamWrapper::stream_tell
116 * @since 11.1
117 */
118 public function stream_tell()
119 {
120 return $this->position;
121 }
122
123 /**
124 * Function to test for end of file pointer
125 *
126 * @return boolean True if the pointer is at the end of the stream
127 *
128 * @see streamWrapper::stream_eof
129 * @since 11.1
130 */
131 public function stream_eof()
132 {
133 return $this->position >= strlen($this->buffers[$this->name]);
134 }
135
136 /**
137 * The read write position updates in response to $offset and $whence
138 *
139 * @param integer $offset The offset in bytes
140 * @param integer $whence Position the offset is added to
141 * Options are SEEK_SET, SEEK_CUR, and SEEK_END
142 *
143 * @return boolean True if updated
144 *
145 * @see streamWrapper::stream_seek
146 * @since 11.1
147 */
148 public function stream_seek($offset, $whence)
149 {
150 switch ($whence)
151 {
152 case SEEK_SET :
153 return $this->seek_set($offset);
154
155 case SEEK_CUR :
156
157 return $this->seek_cur($offset);
158
159 case SEEK_END :
160
161 return $this->seek_end($offset);
162 }
163
164 return false;
165 }
166
167 /**
168 * Set the position to the offset
169 *
170 * @param integer $offset The offset in bytes
171 *
172 * @return bool
173 */
174 protected function seek_set($offset)
175 {
176 if ($offset < 0 || $offset > strlen($this->buffers[$this->name]))
177 {
178 return false;
179 }
180
181 $this->position = $offset;
182
183 return true;
184 }
185
186 /**
187 * Adds the offset to current position
188 *
189 * @param integer $offset The offset in bytes
190 *
191 * @return bool
192 */
193 protected function seek_cur($offset)
194 {
195 if ($offset < 0)
196 {
197 return false;
198 }
199
200 $this->position += $offset;
201
202 return true;
203 }
204
205 /**
206 * Sets the position to the end of the current buffer + offset
207 *
208 * @param integer $offset The offset in bytes
209 *
210 * @return bool
211 */
212 protected function seek_end($offset)
213 {
214 $offset += strlen($this->buffers[$this->name]);
215 if ($offset < 0)
216 {
217 return false;
218 }
219
220 $this->position = $offset;
221
222 return true;
223 }
224 }
225 // Register the stream
226 stream_wrapper_register('buffer', 'JBuffer');
227