<?php

class MemoryStream
{
  public $Data;
  public $Position;
   
  function __construct()
  {
    $this->Data = '';
    $this->Position = 0;
  } 
   
  function __destruct() 
  {
  }
  
  public function ReadBlock($Count)
  {
    $Result = substr($this->Data, $this->Position, $Count);
    $this->Position = $this->Position + $Count;
    return($Result);
  }
  
  public function ReadByte()
  {
    $Result = $this->Data[$this->Position];
    $this->Position = $this->Position + 1;
    return($Result);
  }  
   
  public function ReadUint()
  {
    $val = unpack('V*', substr($this->Data, $this->Position, 4));
    $this->Position = $this->Position + 4;
    return($val[1]);
  }
   
  public function ReadInt()
  {
    $val = unpack('I*', substr($this->Data, $this->Position, 4));
    $this->Position = $this->Position + 4;
    return($val[1]);
  }  
   
  public function ReadFloat()
  {
    $val = unpack('f*', substr($this->Data, $this->Position, 4));
    $this->Position = $this->Position + 4;
    return($val[1]);
  }
   
  public function ReadChar()
  {
    $Result = $this->Data[$this->Position];
    $this->Position = $this->Position + 1;
    return($Result);
  }

  public function ReadLine($EndSymbol = "\r")
  {
    $Length = 0;
    $StartPosition = $this->Position;
    while(!$this->EOF())
    {
      $Char = $this->ReadChar();
      if($Char == $EndSymbol) break;
    }
    $Result = substr($this->Data, $StartPosition, $this->Position - $StartPosition);
    return($Result);
  }

  public function WriteBlock($Value, $Count)
  {
    $this->Data = substr_replace($this->Data, $Value, $this->Position, $Count);
    $this->Position = $this->Position + $Count;
  }  

  public function WriteByte($Value)
  {
    $this->Data[$this->Position] = pack('C*', $Value);
    $this->Position++;
  }  
   
  public function WriteUint($Value)
  {
    $this->WriteBlock(pack('V*', $Value), 4);
  }
   
  public function WriteInt($Value)
  {
    $this->WriteBlock(pack('I*', $Value), 4);
  }  
   
  public function WriteFloat($Value)
  {
    $this->WriteBlock(pack('f*', $Value), 4);
  }
   
  public function WriteChar($Value)
  {
    $this->Data[$this->Position] = pack('C*', $Value);
    $this->Position++;
  }    
  
  public function WriteLine($Value)
  {
    $this->WriteBlock($Value."\r\n", strlen($Value) + 2);
  }

  public function SetPosition($Position)
  {
    $this->Position = $Position;
  }
  
  public function GetPosition()
  {
    return($this->Position);
  }
  
  public function GetSize()
  {
    return(strlen($this->Data));
  }

  public function SetSize($Size)
  {
    return($this->Data = substr($this->Data, 0, $Size));
  }

  public function EOF()
  {
    return($this->Position >= strlen($this->Data));
  }
}

?>
