Gibt es in PHP eine Möglichkeit, alleine aufgrund eines übergebenen Strings zu ermitteln, aus wie vielen Bytes ein Zeichen besteht?
Es geht darum, dass ich einen StreamBuffer geschrieben habe (Klasse BufferedOutputStream):
In der Buffer-Klasse arbeite ich mit substr, also auf Byte-Ebene. Jetzt weiß ich aber nicht, bei welchem Byte ich schneiden darf. Das hängt vom Zeichensatz ab.
Kann mir wer weiterhelfen?
Es geht darum, dass ich einen StreamBuffer geschrieben habe (Klasse BufferedOutputStream):
PHP-Code:
<?php
error_reporting(~0);
interface Flushable
{
function flush();
}
interface OutputStream
{
}
abstract class FilteredOutputStream implements OutputStream
{
protected $target;
}
class BufferedOutputStream extends FilteredOutputStream implements Flushable
{
private $size;
private $buffer = '';
/**
* @param OutputStream $target
* @param int $size PHP_INT_MAX / 2 > size > 0 in Byte
*/
function __construct(OutputStream $target, $size = 1024)
{
if($size > PHP_INT_MAX / 2)
throw new Exception('size');
$this->target = $target;
$this->size = $size;
}
/**
* @param string $data
* @throws Exception Aktueller Buffer + $data sprengen die Buffergröße.
*/
function write($data)
{
$sizeBuffer = strlen($this->buffer);
$sizeData = strlen($data);
// Beispiel:
// Jedes Byte wird durch ein x dargestellt.
// Der Buffer hat hier max. 5 Bytes:
// xxxxx|xxxxx
// ++---
// + zeigt an, wie viel vom Buffer bereits belegt ist ($sizeBuffer).
// - zeigt den freien Platz vom Buffer an ($this->size - $sizeBuffer).
// Daneben gibt es weitere 5 x.
// $data darf diese 5 x plus den - Stellen lang sein, dann kann
// $data korrekt gespeichert bzw. zum Teil oder vollständig mit den + Stellen
// an write weitergericht werden.
if($sizeData > 2 * $this->size - $sizeBuffer)
throw new Exception('data');
if($sizeBuffer + $sizeData < $this->size)
{
// Buffer auffüllen
$this->buffer.= $data;
}
else
{
// Alte Bufferdaten und neuen Daten schreiben. Ev. einen Teil von data buffern.
$len = $this->size - $sizeBuffer;
$this->target->write($this->buffer.substr($data, 0, $len)); // Buffer + forderen data-Teil schreiben
$this->buffer = substr($data, $len); // Rest von data buffern
}
}
/**
* Reicht flush weiter.
*/
function flush()
{
if($this->buffer != '')
{
$this->target->write($this->buffer);
}
}
/**
* Liefert die Buffergröße.
* @return int
*/
function size()
{
return $this->size;
}
}
class DataOutputStream extends FilteredOutputStream implements Flushable // Dummy-Datei zum Testen
{
/**
* @param OutputStream $target
*/
function __construct(OutputStream $target)
{
$this->target = $target;
}
/**
* @param int $data
*/
function write($data)
{
$this->target->write((string)$data);
}
function flush()
{
$this->target->flush();
}
}
class ScreenOutputStream implements OutputStream // Dummy-Datei zum Testen
{
/**
* @param string $data
*/
function write($data)
{
echo $data;
}
}
$sout = new ScreenOutputStream(); // Ausgabe auf Bildschirm
$bout = new BufferedOutputStream($sout, 5); // buffern
$dout = new DataOutputStream($bout); // int -> string
$dout->write(12);
echo 'x';
$dout->write(3456);
echo 'x';
$dout->flush();
?>
Kann mir wer weiterhelfen?
Kommentar