Overview

Namespaces

  • Contrib
    • Bundle
      • CoverallsBundle
        • Console
        • Entity
      • CoverallsV1Bundle
        • Api
        • Collector
        • Command
        • Config
        • Entity
          • Git
    • Component
      • File
      • Log
      • System
        • Git
  • Guzzle
    • Batch
      • Exception
    • Cache
    • Common
      • Exception
    • Http
      • Curl
      • Exception
      • Message
      • QueryAggregator
    • Inflection
    • Iterator
    • Log
    • Parser
      • Cookie
      • Message
      • UriTemplate
      • Url
    • Plugin
      • Async
      • Backoff
      • Cache
      • Cookie
        • CookieJar
        • Exception
      • CurlAuth
      • ErrorResponse
        • Exception
      • History
      • Log
      • Md5
      • Mock
      • Oauth
    • Service
      • Builder
      • Command
        • Factory
        • LocationVisitor
          • Request
          • Response
      • Description
      • Exception
      • Resource
    • Stream
  • PHP
  • Psr
    • Log
  • Symfony
    • Component
      • Config
        • Definition
          • Builder
          • Exception
        • Exception
        • Loader
        • Resource
        • Util
      • Console
        • Command
        • Formatter
        • Helper
        • Input
        • Output
        • Tester
      • EventDispatcher
        • Debug
      • Finder
        • Adapter
        • Comparator
        • Exception
        • Expression
        • Iterator
        • Shell
      • Stopwatch
      • Yaml
        • Exception

Classes

  • PhpStreamRequestFactory
  • Stream

Interfaces

  • StreamInterface
  • StreamRequestFactoryInterface
  • Overview
  • Namespace
  • Class
  • Tree
  • Todo
  1: <?php
  2: 
  3: namespace Guzzle\Stream;
  4: 
  5: use Guzzle\Common\Exception\InvalidArgumentException;
  6: 
  7: /**
  8:  * PHP stream implementation
  9:  */
 10: class Stream implements StreamInterface
 11: {
 12:     const STREAM_TYPE = 'stream_type';
 13:     const WRAPPER_TYPE = 'wrapper_type';
 14:     const IS_LOCAL = 'is_local';
 15:     const IS_READABLE = 'is_readable';
 16:     const IS_WRITABLE = 'is_writable';
 17:     const SEEKABLE = 'seekable';
 18: 
 19:     /**
 20:      * @var resource Stream resource
 21:      */
 22:     protected $stream;
 23: 
 24:     /**
 25:      * @var int Size of the stream contents in bytes
 26:      */
 27:     protected $size;
 28: 
 29:     /**
 30:      * @var array Stream cached data
 31:      */
 32:     protected $cache = array();
 33: 
 34:     /**
 35:      * @var array Custom stream data
 36:      */
 37:     protected $customData = array();
 38: 
 39:     /**
 40:      * @var array Hash table of readable and writeable stream types for fast lookups
 41:      */
 42:     protected static $readWriteHash = array(
 43:         'read' => array(
 44:             'r' => true, 'w+' => true, 'r+' => true, 'x+' => true, 'c+' => true,
 45:             'rb' => true, 'w+b' => true, 'r+b' => true, 'x+b' => true, 'c+b' => true,
 46:             'rt' => true, 'w+t' => true, 'r+t' => true, 'x+t' => true, 'c+t' => true, 'a+' => true
 47:         ),
 48:         'write' => array(
 49:             'w' => true, 'w+' => true, 'rw' => true, 'r+' => true, 'x+' => true, 'c+' => true,
 50:             'wb' => true, 'w+b' => true, 'r+b' => true, 'x+b' => true, 'c+b' => true,
 51:             'w+t' => true, 'r+t' => true, 'x+t' => true, 'c+t' => true, 'a' => true, 'a+' => true
 52:         )
 53:     );
 54: 
 55:     /**
 56:      * Construct a new Stream
 57:      *
 58:      * @param resource $stream Stream resource to wrap
 59:      * @param int      $size   Size of the stream in bytes. Only pass if the size cannot be obtained from the stream.
 60:      *
 61:      * @throws InvalidArgumentException if the stream is not a stream resource
 62:      */
 63:     public function __construct($stream, $size = null)
 64:     {
 65:         $this->setStream($stream, $size);
 66:     }
 67: 
 68:     /**
 69:      * Closes the stream when the helper is destructed
 70:      */
 71:     public function __destruct()
 72:     {
 73:         $this->close();
 74:     }
 75: 
 76:     /**
 77:      * {@inheritdoc}
 78:      */
 79:     public function __toString()
 80:     {
 81:         if (!$this->isReadable() || (!$this->isSeekable() && $this->isConsumed())) {
 82:             return '';
 83:         }
 84: 
 85:         $originalPos = $this->ftell();
 86:         $body = stream_get_contents($this->stream, -1, 0);
 87:         $this->seek($originalPos);
 88: 
 89:         return $body;
 90:     }
 91: 
 92:     /**
 93:      * {@inheritdoc}
 94:      */
 95:     public function close()
 96:     {
 97:         if (is_resource($this->stream)) {
 98:             fclose($this->stream);
 99:         }
100:         $this->cache[self::IS_READABLE] = false;
101:         $this->cache[self::IS_WRITABLE] = false;
102:     }
103: 
104:     /**
105:      * Calculate a hash of a Stream
106:      *
107:      * @param StreamInterface $stream    Stream to calculate the hash for
108:      * @param string          $algo      Hash algorithm (e.g. md5, crc32, etc)
109:      * @param bool            $rawOutput Whether or not to use raw output
110:      *
111:      * @return bool|string Returns false on failure or a hash string on success
112:      */
113:     public static function getHash(StreamInterface $stream, $algo, $rawOutput = false)
114:     {
115:         $pos = $stream->ftell();
116:         if (!$stream->seek(0)) {
117:             return false;
118:         }
119: 
120:         $ctx = hash_init($algo);
121:         while ($data = $stream->read(8192)) {
122:             hash_update($ctx, $data);
123:         }
124: 
125:         $out = hash_final($ctx, (bool) $rawOutput);
126:         $stream->seek($pos);
127: 
128:         return $out;
129:     }
130: 
131:     /**
132:      * {@inheritdoc}
133:      */
134:     public function getMetaData($key = null)
135:     {
136:         $meta = stream_get_meta_data($this->stream);
137: 
138:         return !$key ? $meta : (array_key_exists($key, $meta) ? $meta[$key] : null);
139:     }
140: 
141:     /**
142:      * {@inheritdoc}
143:      */
144:     public function getStream()
145:     {
146:         return $this->stream;
147:     }
148: 
149:     /**
150:      * {@inheritdoc}
151:      */
152:     public function setStream($stream, $size = null)
153:     {
154:         if (!is_resource($stream)) {
155:             throw new InvalidArgumentException('Stream must be a resource');
156:         }
157: 
158:         $this->size = $size;
159:         $this->stream = $stream;
160:         $this->rebuildCache();
161: 
162:         return $this;
163:     }
164: 
165:     /**
166:      * {@inheritdoc}
167:      */
168:     public function getWrapper()
169:     {
170:         return $this->cache[self::WRAPPER_TYPE];
171:     }
172: 
173:     /**
174:      * {@inheritdoc}
175:      */
176:     public function getWrapperData()
177:     {
178:         return $this->getMetaData('wrapper_data') ?: array();
179:     }
180: 
181:     /**
182:      * {@inheritdoc}
183:      */
184:     public function getStreamType()
185:     {
186:         return $this->cache[self::STREAM_TYPE];
187:     }
188: 
189:     /**
190:      * {@inheritdoc}
191:      */
192:     public function getUri()
193:     {
194:         return $this->cache['uri'];
195:     }
196: 
197:     /**
198:      * {@inheritdoc}
199:      */
200:     public function getSize()
201:     {
202:         if ($this->size !== null) {
203:             return $this->size;
204:         }
205: 
206:         // If the stream is a file based stream and local, then use fstat
207:         if ($this->isLocal()) {
208:             clearstatcache(true, $this->getUri());
209:             $stats = fstat($this->stream);
210:             if (isset($stats['size'])) {
211:                 return $stats['size'];
212:             }
213:         }
214: 
215:         // Only get the size based on the content if the the stream is readable and seekable
216:         if (!$this->cache[self::IS_READABLE] || !$this->cache[self::SEEKABLE]) {
217:             return false;
218:         } else {
219:             $pos = $this->ftell();
220:             $this->size = strlen((string) $this);
221:             $this->seek($pos);
222:             return $this->size;
223:         }
224:     }
225: 
226:     /**
227:      * {@inheritdoc}
228:      */
229:     public function isReadable()
230:     {
231:         return $this->cache[self::IS_READABLE];
232:     }
233: 
234:     /**
235:      * {@inheritdoc}
236:      */
237:     public function isWritable()
238:     {
239:         return $this->cache[self::IS_WRITABLE];
240:     }
241: 
242:     /**
243:      * {@inheritdoc}
244:      */
245:     public function isConsumed()
246:     {
247:         return feof($this->stream);
248:     }
249: 
250:     /**
251:      * {@inheritdoc}
252:      */
253:     public function feof()
254:     {
255:         return $this->isConsumed();
256:     }
257: 
258:     /**
259:      * {@inheritdoc}
260:      */
261:     public function isLocal()
262:     {
263:         return $this->cache[self::IS_LOCAL];
264:     }
265: 
266:     /**
267:      * {@inheritdoc}
268:      */
269:     public function isSeekable()
270:     {
271:         return $this->cache[self::SEEKABLE];
272:     }
273: 
274:     /**
275:      * {@inheritdoc}
276:      */
277:     public function setSize($size)
278:     {
279:         $this->size = $size;
280: 
281:         return $this;
282:     }
283: 
284:     /**
285:      * {@inheritdoc}
286:      */
287:     public function seek($offset, $whence = SEEK_SET)
288:     {
289:         return $this->cache[self::SEEKABLE] ? fseek($this->stream, $offset, $whence) === 0 : false;
290:     }
291: 
292:     /**
293:      * {@inheritdoc}
294:      */
295:     public function read($length)
296:     {
297:         return $this->cache[self::IS_READABLE] ? fread($this->stream, $length) : false;
298:     }
299: 
300:     /**
301:      * {@inheritdoc}
302:      */
303:     public function write($string)
304:     {
305:         if (!$this->cache[self::IS_WRITABLE]) {
306:             return 0;
307:         }
308: 
309:         $bytes = fwrite($this->stream, $string);
310: 
311:         // We can't know the size after writing if any bytes were written
312:         if ($bytes) {
313:             $this->size = null;
314:         }
315: 
316:         return $bytes;
317:     }
318: 
319:     /**
320:      * {@inheritdoc}
321:      */
322:     public function ftell()
323:     {
324:         return ftell($this->stream);
325:     }
326: 
327:     /**
328:      * {@inheritdoc}
329:      */
330:     public function rewind()
331:     {
332:         return $this->seek(0);
333:     }
334: 
335:     /**
336:      * {@inheritdoc}
337:      */
338:     public function readLine($maxLength = null)
339:     {
340:         if (!$this->cache[self::IS_READABLE]) {
341:             return false;
342:         } else {
343:             return $maxLength ? fgets($this->getStream(), $maxLength) : fgets($this->getStream());
344:         }
345:     }
346: 
347:     /**
348:      * {@inheritdoc}
349:      */
350:     public function setCustomData($key, $value)
351:     {
352:         $this->customData[$key] = $value;
353: 
354:         return $this;
355:     }
356: 
357:     /**
358:      * {@inheritdoc}
359:      */
360:     public function getCustomData($key)
361:     {
362:         return isset($this->customData[$key]) ? $this->customData[$key] : null;
363:     }
364: 
365: 
366:     /**
367:      * Reprocess stream metadata
368:      */
369:     protected function rebuildCache()
370:     {
371:         $this->cache = stream_get_meta_data($this->stream);
372:         $this->cache[self::IS_LOCAL] = stream_is_local($this->stream);
373:         $this->cache[self::IS_READABLE] = isset(self::$readWriteHash['read'][$this->cache['mode']]);
374:         $this->cache[self::IS_WRITABLE] = isset(self::$readWriteHash['write'][$this->cache['mode']]);
375:     }
376: }
377: 
php-coveralls API documentation generated by ApiGen 2.8.0