Ferreteria/v0.6/clade/IO/Aspect/Connx/Buffer

From Woozle Writes Code
< Ferreteria‎ | v0.6‎ | clade‎ | IO‎ | Aspect‎ | Connx
Revision as of 02:47, 28 November 2025 by Woozle (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
clade: IO\Aspect\Connx\Buffer
Clade Family
Connx Buffer
Clade Aliases
Alias Clade
Base* IO\Aspect\Connx
Subpages

About

  • Purpose: base class for buffering I/O to external processes
    • For now, I'm implementing this as minimally as possible.
    • The idea is that podling classes can:
      • add other functionality which gets exceuted on Put/Get (e.g. update reporting).
      • implement more efficient buffering, maybe.
      • Might we want to be able to limit the number of bytes fetched by RemoveBytes()? Maybe later.

History

  • 2024-11-24 started
  • 2025-03-13 at first I removed HasBytes(), but (long story short) I really just need to clearly define what all these pieces are for before I can straighten anything out.
    • Functionality needed (with entity names as I work them out):
      • AvailBuffByteCount(): number of bytes available to read out from buffer (data buffered)
      • AvailSrceByteCount(): number of bytes available to read into buffer (data source), if available
      • IsMore() flag to indicate that the source is not permanently empty
        • (either there's more to read, or we expect there will be -- i.e. not EoF)
        • (for writing purposes, this could instead indicate that there's room to write)
      • SpentByteCount() (UI): number of bytes processed so far
      • RemoveBytes() (Action): fetch bytes from buffer (fill buffer if empty)
  • 2025-03-28 moved from [WFe]IO ⇒ [WFe]IO\Connx and re-parented to xConnx

Code

interface iBuffer extends BaseIface {
    // COUNTERS
    function AvailByteCount() : int;   // bytes currently remaining (buffered + source)
    #function SpentByteCount() : int;  // bytes already processed/transferret (read or written)
    // ACCESS
    function RewindAll() : void;        // reset to beginning of input or output file
    function AppendBytes(string $s);    // write bytes into buffer
    function RemoveBytes() : string;    // read bytes out of buffer
    function RestoreBytes(string $s);   // put bytes back into buffer (this is a bit of a kluge, I guess...)
    function IsMore() : bool;           // there is more to read (or room to write to, I guess?)
    function SpentByteCount() : int;
}
abstract class caBuffer extends BaseClass implements iBuffer {

    // ++ ACCESS ++ //

    private $sBuff;
    protected function AvailBuffByteCount() : int {    // bytes available to read from buffer
        return strlen($this->sBuff);
    }
    protected function AvailSrceByteCount() : int { echo self::PromptForMethod(); }   // bytes currently remaining to read from source

    // RETURNS: {bytes in buffer} + {size of file} - {bytes already read from file}
    public function AvailByteCount() : int { return $this->AvailBuffByteCount() + $this->AvailSrceByteCount() - $this->SpentByteCount(); }

    // ++ ACCESS: tracking ++ //

    private $nSpent;
    protected function IncSpentBytes(int $n) { $this->nSpent += $n; }
    public function SpentByteCount() : int { return $this->nSpent; }

    // ++ ACCESS: info ++ //

    public function IsMore() : bool { return $this->AvailByteCount() > 0; } // assumes static file

    // ++ ACCESS: R/W ++ //

    public function RewindAll() : void { $this->nSpent = 0; $this->sBuff = ''; }

    // TODO: rename to something better
    public function AppendBytes(string $s) {
        $this->ErrorIfShut('write to');
        #if (!$this->IsOpen()) {
        #    $id = $this->ObjectID();
        #    self::ThrowHissy("Writing to buffer (id$id) before it has been opened.");
        #}

        $this->sBuff .= $s;
        #self::GotToHere();
    }
    protected function AddBytesForFetch(string $s) { $this->sBuff .= $s; }

    // TODO: rename to something better
    public function RemoveBytes() : string {
        $this->ErrorIfShut('read from');
        $sOut = $this->sBuff;
        #echo 'nSpent BEFORE remove: '.$this->nSpent.CRLF;
        $nLen = strlen($sOut);
        #echo "REMOVING $nLen bytes".CRLF;
        $this->nSpent += $nLen;
        #echo 'nSpent AFTER remove: '.$this->nSpent.CRLF;
        $this->sBuff = '';
        return $sOut;
    }
    public function RestoreBytes(string $s) {
        #echo 'nSpent BEFORE restore: '.$this->nSpent.CRLF;
        $this->nSpent -= strlen($s);
        #echo 'nSpent AFTER restore: '.$this->nSpent.CRLF;
        $this->sBuff = $s.$this->sBuff; // restore $s to beginning of buffer
    }
    protected function ErrorIfShut(string $sAction) {
        if (!$this->IsOpen()) {
            $id = $this->ObjectID();
            self::ThrowHissy("Trying to $sAction closed buffer (id$id).");
        }
    }

    // -- ACCESS -- //
    // ++ DEBUGGING ++ //

    public function StatusLine() : string {
        $sID = $this->ObjectID();
        $nBuff = $this->AvailBuffByteCount();
        $nSrce = $this->AvailSrceByteCount();
        $nSpent = $this->SpentByteCount();
        $sAlive = $this->IsOpen() ? 'OPEN' : 'SHUT';
        return "buffer id$sID [$sAlive]: buff=$nBuff srce=$nSrce spent=$nSpent";
    }

    // -- DEBUGGING -- //
}