Ferreteria/v0.6/clade/Sys/FileSys/Aspect/InOut
Jump to navigation
Jump to search
| ||||||||||||||||||||||||
Code
as of 2025-10-07
interface iInOut extends BaseIface, OpenerIface {
// SETTINGS: access
function Mode(ModeIface $o=NULL) : ModeIface;
// LIFECYCLE (from OpenerIface)
# function Open() : ActionIface;
# function Shut() : ActionIface;
// I/O
function Write(string &$s) : ActionIface;
}
class cInOut extends BaseClass implements iInOut {
use OpenerTrait;
// ++ STRUCT ++ //
protected function NewNode() : NodeIface {
$oNode = new ($this->NodeClass());
$oNode->InOut($this);
return $oNode;
}
// -- STRUCT -- //
// ++ SETTINGS ++ //
private $oMode = NULL;
public function Mode(ModeIface $o=NULL) : ModeIface {
if (is_null($o)) {
$o = $this->oMode;
if (is_null($o)) {
$o = new ModeClass;
$this->oMode = $o;
}
} else {
$this->oMode = $o;
}
return $o;
}
// -- SETTINGS -- //
// ++ LIFECYCLE ++ //
protected function ActualOpen() : ActionIface {
#self::GotToHere('Trying to open the data file...');
$oAct = new ActionClass;
$oMode = $this->Mode();
if ($oMode->IsValid()) {
$sMode = $oMode->NativeString();
$ok = TRUE; // only FALSE if an action is required and it fails
$fs = $this->Node()->Ident()->SpecFull();
// If we're writing to the file, then make sure the path exists:
if ($this->Mode()->CanCreate()->IsRequired()) {
// Yes -- so we need to make sure the folder-path exists too, because fopen() doesn't handle that.
$fp = dirname($fs);
if (!file_exists($fp)) {
$ok = mkdir($fp,0777,TRUE);
if (!$ok) {
$oAct->SetOkay(FALSE);
$oAct->AddMsgString("Could not create path [$fp].");
}
}
}
if ($ok) {
#self::GotToHere('Calling fopen()...');
// all clear to call fopen() now:
$r = fopen($fs,$sMode);
if (is_resource($r)) {
$this->QNative()->SetIt($r);
$oAct->SetOkay(TRUE);
} else {
$oAct->SetOkay(FALSE);
$oAct->AddMsgString("Couldn't open file [$fs].");
}
}
} else {
$sMode = $oMode->Request();
self::GotToHere("Mode-request '$sMode' is not valid.");
$oAct->SetOkay(FALSE);
$oAct->AddMsgString('Need to set a valid Mode() before opening the file.');
}
return $oAct;
}
protected function ActualShut() : ActionIface {
$oAct = new ActionClass;
if ($this->IsOpen()) {
$osNat = $this->QNative();
$rNat = $osNat->GetIt();
$ok = fclose($rNat);
$osNat->ZapIt();
$oAct->SetOkay($ok);
} else {
$oAct->SetNoOp();
}
return $oAct;
}
// -- LIFECYCLE -- //
// ++ I/O ++ //
public function Write(string &$s) : ActionIface {
$ok = fwrite($this->QNative()->GetIt(),$s);
$oAct = new ActionClass;
$oAct->SetOkay(is_integer($ok));
if ($ok === FALSE) {
$oAct->AddMsgString('Could not write to data file.'); // TODO: get file error message
}
return $oAct;
}
public function Read(int $nMax=0) : ReadResultIface {
$sData = fread($this->QNative()->GetIt(),$nMax);
$oRR = new ReadResultClass;
if (is_string($sData)) {
$oRR->QData()->SetIt($sData);
} else {
$oRR->SetOkay(FALSE);
// Docs are unclear, but I *think* this only happens if there's an actual read-error.
// ...and EoF will just be indicated by returning an empty string.
}
return $oRR;
}
// -- I/O -- //
}