PHP Classes

File: src/Generics/Streams/MemoryStream.php

Recommend this page to a friend!
  Classes of Maik Greubel   PHP Generics   src/Generics/Streams/MemoryStream.php   Download  
File: src/Generics/Streams/MemoryStream.php
Role: Class source
Content type: text/plain
Description: Memory stream implementation
Class: PHP Generics
Framework for accessing streams, sockets and logs
Author: By
Last change: Update of src/Generics/Streams/MemoryStream.php
Date: 2 months ago
Size: 5,000 bytes
 

Contents

Class file image Download
<?php

/**
 * This file is part of the PHP Generics package.
 *
 * @package Generics
 */
namespace Generics\Streams;

use
Generics\Util\Interpolator;

/**
 * This class provides a memory stream for both input and output
 *
 * @author Maik Greubel <greubel@nkey.de>
 */
class MemoryStream implements InputOutputStream
{
    use
Interpolator {
       
interpolate as tinterpolate;
    }

   
/**
     * The local memory buffer
     *
     * @var string
     */
   
private $memory;

   
/**
     * Current position in memory buffer
     *
     * @var int
     */
   
private $current;

   
/**
     * Whether it is possible to perform reading action
     *
     * @var boolean
     */
   
private $ready;

   
/**
     * Whether stream is closed
     *
     * @var boolean
     */
   
private $closed;

   
/**
     * Create a new MemoryStream
     *
     * @param InputStream $in
     * optional existing input stream - will be copied
     */
   
public function __construct(InputStream $in = null)
    {
       
$this->memory = "";
        if (
$in != null) {
           
$copy = clone $in;
           
$copy->reset();
            while (
$copy->ready()) {
               
$this->memory .= $copy->read();
            }
           
$copy->close();
        }
       
$this->current = 0;
       
$this->ready = true;
       
$this->closed = false;
    }

   
/**
     *
     * {@inheritdoc}
     * @see \Generics\Streams\Stream::close()
     */
   
public function close()
    {
        unset(
$this->memory);
       
$this->current = 0;
       
$this->ready = false;
       
$this->closed = true;
    }

   
/**
     *
     * {@inheritdoc}
     * @see \Generics\Streams\Stream::ready()
     */
   
public function ready(): bool
   
{
        return
$this->ready;
    }

   
/**
     *
     * {@inheritdoc}
     * @see \Generics\Streams\OutputStream::write()
     */
   
public function write($buffer)
    {
        if (
$this->closed) {
            throw new
StreamException("Stream is not open");
        }
       
$this->memory .= $buffer;
       
$this->ready = true;
    }

   
/**
     *
     * {@inheritdoc}
     * @see \Generics\Streams\InputStream::read()
     */
   
public function read($length = 1, $offset = null): string
   
{
        if (
$this->closed) {
            throw new
StreamException("Stream is not open");
        }
       
        if (
$offset !== null) {
           
$this->current = intval($offset);
        }
       
        if (
strlen($this->memory) <= $this->current) {
           
$this->ready = false;
            return
"";
        }
       
        if (
strlen($this->memory) - $this->current < $length) {
           
$length = strlen($this->memory) - $this->current;
        }
       
       
$out = substr($this->memory, $this->current, $length);
       
$this->current += $length;
       
        if (
$this->current == strlen($this->memory)) {
           
$this->ready = false;
        }
       
        return
$out;
    }

   
/**
     *
     * {@inheritdoc}
     * @see \Countable::count()
     */
   
public function count(): int
   
{
        if (
$this->closed) {
            throw new
StreamException("Stream is not open");
        }
        if (! isset(
$this->memory)) {
            return
0;
        }
        return
strlen($this->memory);
    }

   
/**
     *
     * {@inheritdoc}
     * @see \Generics\Resettable::reset()
     */
   
public function reset()
    {
        if (
$this->closed) {
            throw new
StreamException("Stream is not open");
        }
       
$this->current = 0;
       
$this->ready = true;
    }

   
/**
     * Write to stream by interpolation of context vars into a string
     *
     * @param string $string
     * The string to interpolate, may contains placeholders in format {placeholder}.
     * @param array $context
     * The context array containing the associative replacers and its values.
     */
   
public function interpolate($string, array $context)
    {
       
$this->write($this->tinterpolate($string, $context));
    }

   
/**
     *
     * {@inheritdoc}
     * @see \Generics\Streams\OutputStream::isWriteable()
     */
   
public function isWriteable(): bool
   
{
        return
true;
    }

   
/**
     *
     * {@inheritdoc}
     * @see \Generics\Streams\OutputStream::flush()
     */
   
public function flush()
    {
        if (
$this->closed) {
            throw new
StreamException("Stream is not open");
        }
       
        unset(
$this->memory);
       
$this->memory = "";
       
$this->reset();
    }

   
/**
     *
     * {@inheritdoc}
     * @see \Generics\Streams\Stream::isOpen()
     */
   
public function isOpen(): bool
   
{
        return
true;
    }

   
/**
     * Retrieve the whole memory string content
     *
     * @return string
     */
   
public function slurp(): string
   
{
       
$str = "";
        while (
$this->ready()) {
           
$str .= $this->read($this->count());
        }
       
        return
$str;
    }
}