Ferreteria/v0.6/clade/IO/Aspect/Connx/Buffer/Sourced/File/Reader

From Woozle Writes Code
< Ferreteria‎ | v0.6‎ | clade‎ | IO‎ | Aspect‎ | Connx‎ | Buffer‎ | Sourced/File
Jump to navigation Jump to search


The item documented here is deprecated and should not be used.
Use IO\Aspect\Connx\Stream\File instead.
clade: IO\Aspect\Connx\Buffer\Sourced\File\Reader
Clade Family
File Reader Text
Clade Aliases
Alias Clade
Base* [ca,i] IO\Aspect\Connx\Buffer\File
FModeEnum Sys\FileSys\Mode
Subpages

About

  • Purpose: a Buffer which reads data from a file and sends it to the output stream

Functions

History

Code

as of 2025-12-16:

interface iReader extends BaseIface {}
class cReader extends BaseClass implements iReader {
    // ++ CONFIG ++ //

    protected const MAX_BUFF_LEN = 1024 * 1024; // whatever seems to work best

    public function SType()          : string { return 'file-read buffer'; }
    protected function ModesArray() : array {
        return [
          FModeEnum::FILE_READER,
          FModeEnum::FLAG_ON,  // need to read
          ];
    }

    // -- CONFIG -- //
    // ++ ACCESS ++ //

    // (WAS: "bytes currently remaining to read from source" -- but the code looks like "size of entire file")
    protected function AvailSrceByteCount() : int { return $this->DataFile()->Size(); }

    // NOTE: This is different from $nSpent because it doesn't include what's in the buffer.
    private $nInPtr = NULL;
    public function RewindAll() : void {
        $this->nInPtr = 0;
        parent::RewindAll();
    }
    // OVERRIDE: need to load file bytes if buffer is empty
    public function &CurrentBytes() : string {
        $nBuff = $this->AvailBuffByteCount();    // what's in the buffer
        #$nFileAll = $this->AvailSrceByteCount();
        // 2025-12-11 This duplicates a lot of DiscardBytes().
        #$this->AmHere("nBuff=[$nBuff] nFileAll=[$nFileAll]");
        if ($nBuff === 0) {
            $this->RefillBuffer();
            /* moved to RefillBuffer()
            $nRoom = self::MAX_BUFF_LEN - $nBuff;    // room available
            $nFileNew = $nFileAll - $this->nInPtr;      // what hasn't been read from the file yet
            #$this->AmHere("REFILLING... nFileNew=[$nFileNew]");
            if ($nFileNew > 0) {
                $nToRead = min($nRoom,$nFileNew);
                $oRes = $this->DataFile()->InOut()->Read($nToRead);
                $osData = $oRes->QData();
                if ($osData->HasIt()) {
                    $sData = $osData->GetIt();
                    $nLen = strlen($sData);
                    #$this->AmHere("ADDING [$nLen] BYTES to buffer");
                    $this->AddBytesForFetch($sData);
                    #$this->AmHere('LENGTH of data now: ['.strlen($this->sBuff).']');
                #} else {
                    #$this->AmHere("NO DATA");
                }
            }
            */
        }
        return $this->sBuff;
    }
    protected function RefillBuffer() {
        $nBuff = $this->AvailBuffByteCount();    // what's in the buffer
        $nRoom = self::MAX_BUFF_LEN - $nBuff;    // room available

        $nFileAll = $this->AvailSrceByteCount();
        $nFileNew = $nFileAll - $this->nInPtr;      // what hasn't been read from the file yet
        #$this->AmHere("REFILLING... nFileNew=[$nFileNew]");

        // ++ DEBUG
        $ofLog = ProcAdmin::LogFile()->InOut();
        $sMsg = "REFILLING: nBuff=[$nBuff] nRoom=[$nRoom] nFileAll=[$nFileAll] nFileNew=[$nFileNew]";
        #$this->AmHere($sMsg);
        $ofLog->WriteEntry($sMsg);
        // -- DEBUG

        if ($nFileNew > 0) {
            $nToRead = min($nRoom,$nFileNew);

            #$this->AmHere("READING $nToRead bytes");
            $oRes = $this->DataFile()->InOut()->Read($nToRead);
            $osData = $oRes->QData();
            if ($osData->HasIt()) {
                $sData = $osData->GetIt();
                $nLen = strlen($sData);
                $this->nInPtr += $nLen; // increment file-read-pointer
                #$this->AmHere("ADDING [$nLen] BYTES to buffer");
                $this->AddBytesForFetch($sData);
                $ofLog->WriteEntry('FETCHED DATA:'.CRLF.$this->sBuff.CRLF."<<<< END DATA");
                #$this->AmHere('LENGTH of data now: ['.strlen($this->sBuff).']');
            } else {
                #$this->AmHere("NO DATA");
            }
        } else {
            #$this->AmHere('Nothing new to read.');
        }
    }
    // 2025-12-14 experimental
    public function RemoveLine() : string {
        $sBuff = $this->sBuff;
        $dxLine = strpos($sBuff,"\r");
        $doLoop = TRUE;
        $sLine = '';
        while ($doLoop) {
            if (is_int($dxLine)) {
                // EOL found in buffer -- get text up to that point
                $sLine .= substr($sBuff,0,$dxLine);
                $nLine = strlen($sLine);
                $this->DiscardBytes($nLine+strlen("\n"));
                $doLoop = TRUE;
                #$this->AmHere("GOT LINE, $dxLine bytes");
            } else {
                // EOL not found in buffer -- refill it from source
                $sLine .= $sBuff;
                $nLine = strlen($sLine);
                $this->DiscardBytes($nLine);
                $this->RefillBuffer();
                #$this->AmHere("EOL NOT FOUND; fetched another ".strlen($this->sBuff)." bytes");
            }
        }
        #$this->AmHere('GOT LINE of '.strlen($sLine).' bytes');
        return $sLine;
    }
    public function DiscardBytes(int $nBytes) {
        $this->ErrorIfShut('read from');
        parent::DiscardBytes($nBytes);  // basic buffer maintenance
        // Is there room in the buffer for more?
        $nBuff = $this->AvailBuffByteCount();    // what's in the buffer
        $nRoom = self::MAX_BUFF_LEN - $nBuff;    // room available
        if ($nRoom > 0) {
            $nFileAll = $this->AvailSrceByteCount();
            $nFileNew = $nFileAll - $this->nInPtr;      // what hasn't been read from the file yet
            if ($nFileNew > 0) {
                // There's more in the file, so refill the buffer:
                $nToRead = min($nRoom,$nFileNew);
                $oRes = $this->DataFile()->InOut()->Read($nToRead);
                $osData = $oRes->QData();
                if ($osData->HasIt()) {
                    $sData = $osData->GetIt();
                    $nLen = strlen($sData);
                    $this->AddBytesForFetch($sData);
                }
            }
        }
        $sOut = parent::RemoveBytes();  // grab existing buffer-contents
        $this->OnStatusChange();
    }
    // ACTION: remove all bytes from the buffer. Refill buffer if needed, I guess?
    // LATER: might want to add a $nMaxBytes parameter, but for now it doesn't seem needed.
    public function RemoveBytes() : string {
        $this->ErrorIfShut('read from');

        // Is there room in the buffer for more?
        $nBuff = $this->AvailBuffByteCount();    // what's in the buffer
        #$this->AmHere("Bytes remaining: [$nBuff]");
        $nRoom = self::MAX_BUFF_LEN - $nBuff;    // room available
        #$this->AmHere("Bytes remaining: [$nBuff] / Space remaining: [$nRoom]");
        if ($nRoom > 0) {
            $nFileAll = $this->AvailSrceByteCount();
            #echo $this->DataFile()->Ident()->ReflectThis()->Report();
            #$this->AmHere("File bytes: [$nFileAll] in ".$this->DataFile()->Ident()->SpecFull());
            $nFileNew = $nFileAll - $this->nInPtr;      // what hasn't been read from the file yet
            if ($nFileNew > 0) {
                // There's more in the file, so refill the buffer:
                $nToRead = min($nRoom,$nFileNew);
                #echo "ADDING $nToRead BYTES (nFileNew=$nFileNew, nRoom=$nRoom) from file".CRLF;
                $oRes = $this->DataFile()->InOut()->Read($nToRead);
                $osData = $oRes->QData();
                if ($osData->HasIt()) {
                    $sData = $osData->GetIt();
                    $nLen = strlen($sData);
                    $this->AddBytesForFetch($sData);
                }
            }
        }

        $sOut = parent::RemoveBytes();  // grab existing buffer-contents
        #$this->SetNote('bytes to send: '.strlen($sOut));

        $this->OnStatusChange();

        return $sOut;
    }

    // -- ACCESS -- //
    // ++ UI OUTPUT ++ //

    public function DescribeInline() : string {
        $nlRem = $this->AvailSrceByteCount();
        $sS = ($nlRem === 1) ? '' : 's';
        return "$nlRem byte$sS in file";
    }

    // -- UI OUTPUT -- //
}