interface iBuffer extends BaseIface {
// STATUS
function NAvailBytes() : int; // bytes currently remaining in the buffer
function NSpentBytes() : int; // bytes already processed/transferred (read or written)
}
class cBuffer extends BaseClass implements iBuffer {
// ++ CONFIG ++ //
// CEMENT
public function SType() : string { return 'stream buffer'; }
// -- CONFIG -- //
// ++ STATUS ++ //
protected $sBuff;
public function NAvailBytes() : int { return strlen($this->sBuff); }
protected $nSpent;
public function NSpentBytes() : int { return $this->nSpent; }
public function HasBytes() : bool { return $this->sBuff !== ''; }
// -- STATUS -- //
// ++ ADMIN ++ //
protected function ActualOpen() : ActionIface {
$this->sBuff = '';
$this->nSpent = 0;
$o = new ActionClass;
$o->SetNoOp();
return $o;
}
protected function ActualShut() : ActionIface {
$o = new ActionClass;
$o->SetNoOp();
return $o;
}
// -- ADMIN -- //
// ++ I/O ++ //
// CEMENT
public function PullBytes(int $nMax=NULL) : string {
if (is_int($nMax)) {
$nAvail = $this->NAvailBytes();
$nPull = min($nAvail,$nMax);
// FIFO order
$sPull = substr($this->sBuff,0,$nPull); // grab N $nPull chars from buffer
$this->sBuff = substr($this->sBuff,$nPull); // remove $nPull chars from buffer
} else {
$sPull = $this->sBuff;
$this->sBuff = '';
}
$this->nSpent += strlen($sPull);
return $sPull;
}
// CEMENT
public function PushBytes(string $s) : int {
$this->sBuff .= $s;
$nNew = strlen($s);
$this->nSpent += $nNew;
return $nNew; // always pushes all bytes
}
}