// Import framework stuff
use Org\Mxchange\CoreFramework\EntryPoint\ApplicationEntryPoint;
-use Org\Mxchange\CoreFramework\Factory\ObjectFactory;
+use Org\Mxchange\CoreFramework\Factory\Object\ObjectFactory;
use Org\Mxchange\CoreFramework\Filesystem\FileNotFoundException;
+use Org\Mxchange\CoreFramework\Generic\FrameworkInterface;
use Org\Mxchange\CoreFramework\Generic\UnsupportedOperationException;
+use Org\Mxchange\CoreFramework\Middleware\Debug\DebugMiddleware;
use Org\Mxchange\CoreFramework\Object\BaseFrameworkSystem;
use Org\Mxchange\CoreFramework\Stream\Filesystem\FileInputStreamer;
use Org\Mxchange\CoreFramework\Stream\Filesystem\FileOutputStreamer;
// Import SPL stuff
+use \InvalidArgumentException;
+use \OutOfBoundsException;
use \SplFileInfo;
/**
*
* @author Roland Haeder <webmaster@shipsimu.org>
* @version 0.0.0
- * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2017 Core Developer Team
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2023 Core Developer Team
* @license GNU GPL 3.0 or any newer version
* @link http://www.shipsimu.org
*
/**
* Protected constructor
*/
- protected function __construct () {
+ private function __construct () {
// Call parent constructor
parent::__construct(__CLASS__);
}
*/
public static final function createFileIoStream () {
// Create new instance
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('FILE-IO-STREAM: CALLED!');
$ioInstance = new FileIoStream();
// Return the instance
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('FILE-IO-STREAM: ioInstance=%s - EXIT!', $ioInstance->__toString()));
return $ioInstance;
}
* @param $dataArray The data we shall store to the file
* @return void
* @see FileOutputStreamer
- * @todo This method needs heavy rewrite
+ * @throws InvalidArgumentException If an invalid parameter was given
+ * @throws OutOfBoundsException If an expected array element wasn't found
*/
public final function saveFile (SplFileInfo $fileInfoInstance, array $dataArray) {
- // Try it five times
- $dirName = '';
- $fileInstance = NULL;
-
- for ($idx = 0; $idx < 5; $idx++) {
+ // Trace message
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('FILE-IO-STREAM: fileInfoInstance=%s,dataArray()=%d - CALLED!', $fileInfoInstance, count($dataArray)));
+ if (count($dataArray) < 2) {
+ // Not valid array, at least 2 elements must be there!
+ throw new InvalidArgumentException(sprintf('Parameter "dataArray" should have at least 2 elements, has %d', count($dataArray)));
+ } else if (!isset($dataArray[0])) {
+ // Array element 0 not found
+ throw new OutOfBoundsException(sprintf('Array element dataArray[0] not found, dataArray=%s', json_encode($dataArray)));
+ } else if (!isset($dataArray[1])) {
+ // Array element 1 not found
+ throw new OutOfBoundsException(sprintf('Array element dataArray[1] not found, dataArray=%s', json_encode($dataArray)));
+ }
+
+ try {
// Get a file output pointer
- try {
- $fileInstance = ObjectFactory::createObjectByConfiguredName('file_raw_output_class', array($fileInfoInstance, 'wb'));
- } catch (FileNotFoundException $e) {
- // Bail out
- ApplicationEntryPoint::exitApplication('The application has made a fatal error. Exception: ' . $e->__toString() . ' with message: ' . $e->getMessage());
- }
- } // END - for
+ $fileInstance = ObjectFactory::createObjectByConfiguredName('file_raw_output_class', [$fileInfoInstance, 'wb']);
+ } catch (FileNotFoundException $e) {
+ // Bail out
+ ApplicationEntryPoint::exitApplication('The application has made a fatal error. Exception: ' . $e->__toString() . ' with message: ' . $e->getMessage());
+ }
// Write a header information for validation purposes
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('FILE-IO-STREAM: Writing header to fileInstance=%s ...', $fileInstance->__toString()));
$fileInstance->writeToFile(sprintf('%s%s%s%s%s%s%s%s%s' . PHP_EOL,
self::FILE_IO_FILE_HEADER_ID,
self::FILE_IO_SEPARATOR,
));
// Encode the (maybe) binary stream with Base64
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('FILE-IO-STREAM: Encoding %d bytes to BASE64 string ...', strlen($dataArray[1])));
$b64Stream = base64_encode($dataArray[1]);
- // write the data line by line
+ // write the data line-by-line
$line = str_repeat(' ', 50); $idx = 0;
while (strlen($line) == 50) {
// Get 50 chars or less
$line = substr($b64Stream, $idx, 50);
// Save it to the stream
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('FILE-IO-STREAM: Writing %d bytes to file ...', strlen($line)));
$fileInstance->writeToFile(sprintf('%s%s%s%s%s' . PHP_EOL,
self::FILE_IO_DATA_BLOCK_ID,
self::FILE_IO_SEPARATOR,
// Advance to the next 50-chars block
$idx += 50;
- } // END - while
+ }
// Close the file
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage('FILE-IO-STREAM: Closing file ...');
unset($fileInstance);
+
+ // Trace message
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('FILE-IO-STREAM: EXIT!');
}
/**
*/
public final function loadFileContents (SplFileInfo $infoInstance) {
// Initialize some variables and arrays
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('FILE-IO-STREAM: infoInstance=%s - CALLED!', $infoInstance));
$inputBuffer = '';
$lastBuffer = '';
- $header = array();
- $data = array();
+ $header = [];
+ $data = [];
$readData = ''; // This will contain our read data
// Get a file input handler
$fileInstance = ObjectFactory::createObjectByConfiguredName('file_raw_input_class', array($infoInstance));
// Read all it's contents (we very and transparently decompress it below)
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('FILE-IO-STREAM: fileInstance=%s', $fileInstance->__toString()));
while ($readRawLine = $fileInstance->readFromFile()) {
// Add the read line to the buffer
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('FILE-IO-STREAM: Adding %d read bytes to input buffer.', strlen($readRawLine)));
$inputBuffer .= $readRawLine;
// Break infinite loop maybe caused by the input handler
if ($lastBuffer == $inputBuffer) {
+ // Break out of loop, EOF reached?
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage('FILE-IO-STREAM: EOF reached!');
break;
- } // END - if
+ }
// Remember last read line for avoiding possible infinite loops
$lastBuffer = $inputBuffer;
- } // END - while
+ }
// Close directory handle
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage('FILE-IO-STREAM: Closing file ...');
unset($fileInstance);
// Convert it into an array
- $inputBuffer = explode(chr(10), $inputBuffer);
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('FILE-IO-STREAM: Read inputBuffer=%d bytes from infoInstance=%s', strlen($inputBuffer), $infoInstance));
+ $inputArray = explode(chr(10), $inputBuffer);
// Now process the read lines and verify it's content
- foreach ($inputBuffer as $rawLine) {
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('FILE-IO-STREAM: inputArray()=%d', count($inputArray)));
+ foreach ($inputArray as $rawLine) {
// Trim it a little but not the leading spaces/tab-stops
$rawLine = rtrim($rawLine);
// Analyze this line
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('FILE-IO-STREAM: rawLine()=%d', strlen($rawLine)));
if (substr($rawLine, 0, 5) == self::FILE_IO_FILE_HEADER_ID) {
// Header found, so let's extract it
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('FILE-IO-STREAM: Found header, rawLine=%s', $rawLine));
$header = explode(self::FILE_IO_SEPARATOR, $rawLine);
- $header = trim($header[1]);
+ $headerLine = trim($header[1]);
// Now we must convert it again into an array
- $header = explode(self::FILE_IO_CHUNKER, $header);
+ $header = explode(self::FILE_IO_CHUNKER, $headerLine);
// Is the header (maybe) valid?
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('FILE-IO-STREAM: header()=%d', count($header)));
if (count($header) != 4) {
// Throw an exception
- throw new InvalidArrayCountException(array($this, 'header', count($header), 4), self::EXCEPTION_ARRAY_HAS_INVALID_COUNT);
- } // END - if
+ throw new InvalidArrayCountException([$this, 'header', count($header), 4], self::EXCEPTION_ARRAY_HAS_INVALID_COUNT);
+ }
} elseif (substr($rawLine, 0, 5) == self::FILE_IO_DATA_BLOCK_ID) {
// Is a data line!
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('FILE-IO-STREAM: Data line found rawLine=%s', $rawLine));
$data = explode(self::FILE_IO_SEPARATOR, $rawLine);
- $data = $data[1];
+ $dataLine = $data[1];
// First element is the data, second the MD5 checksum
- $data = explode(self::FILE_IO_CHUNKER, $data);
+ $data = explode(self::FILE_IO_CHUNKER, $dataLine);
// Validate the read line
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('FILE-IO-STREAM: data()=%d', count($data)));
if (count($data) == 2) {
- if (md5($data[0]) != $data[1]) {
+ // Generate checksum (MD5 is okay here)
+ $checksum = md5($data[0]);
+
+ // Check if it matches provided one
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('FILE-IO-STREAM: checksum=%s,data[1]=%s', $checksum, $data[1]));
+ if ($checksum != $data[1]) {
// MD5 hash did not match!
- throw new InvalidMD5ChecksumException(array($this, md5($data[0]), $data[1]), self::EXCEPTION_MD5_CHECKSUMS_MISMATCH);
- } // END - if
+ throw new InvalidMD5ChecksumException([$this, $checksum, $data[1]], self::EXCEPTION_MD5_CHECKSUMS_MISMATCH);
+ }
} else {
// Invalid count!
- throw new InvalidArrayCountException(array($this, 'data', count($data), 2), self::EXCEPTION_ARRAY_HAS_INVALID_COUNT);
+ throw new InvalidArrayCountException([$this, 'data', count($data), 2], self::EXCEPTION_ARRAY_HAS_INVALID_COUNT);
}
// Add this to the readData string
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('FILE-IO-STREAM: Adding %d raw data to input stream', strlen($data[0])));
$readData .= $data[0];
} else {
// Other raw lines than header/data tagged lines and re-add the new-line char
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('FILE-IO-STREAM: Adding rawLine=%s(%d) + PHP_EOL to input stream', $rawLine, strlen($rawLine)));
$readData .= $rawLine . PHP_EOL;
}
- } // END - foreach
+ }
// Was raw lines read and no header/data?
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('FILE-IO-STREAM: readData()=%d,header()=%d,data()=%d', strlen($readData), count($header), count($data)));
if ((!empty($readData)) && (count($header) == 0) && (count($data) == 0)) {
// Return raw lines back
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('FILE-IO-STREAM: readData()=%d - EXIT!', strlen($readData)));
return $readData;
- } // END - if
+ }
// Was a header found?
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('FILE-IO-STREAM: header()=%d', count($header)));
if (count($header) != 4) {
// Throw an exception
- throw new InvalidArrayCountException(array($this, 'header', count($header), 4), self::EXCEPTION_ARRAY_HAS_INVALID_COUNT);
- } // END - if
+ throw new InvalidArrayCountException([$this, 'header', count($header), 4], self::EXCEPTION_ARRAY_HAS_INVALID_COUNT);
+ }
// Decode all from Base64
- $readData = @base64_decode($readData);
+ $decodedData = @base64_decode($readData);
// Does the size match?
- if (strlen($readData) != $header[2]) {
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('FILE-IO-STREAM: decodedData()=%d,header[2]=%d', strlen($decodedData), $header[2]));
+ if (strlen($decodedData) != $header[2]) {
// Size did not match
- throw new InvalidDataLengthException(array($this, strlen($readData), $header[2]), self::EXCEPTION_UNEXPECTED_STRING_SIZE);
- } // END - if
+ throw new InvalidDataLengthException([$this, strlen($decodedData), $header[2]], self::EXCEPTION_UNEXPECTED_STRING_SIZE);
+ }
+
+ // Generate checksum from whole read data
+ $checksum = md5($decodedData);
// Validate the decoded data with the final MD5 hash
- if (md5($readData) != $header[3]) {
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->debugMessage(sprintf('FILE-IO-STREAM: checksum=%s,header[3]=%s', $checksum, $header[3]));
+ if ($checksum != $header[3]) {
// MD5 hash did not match!
- throw new InvalidMD5ChecksumException(array($this, md5($readData), $header[3]), self::EXCEPTION_MD5_CHECKSUMS_MISMATCH);
- } // END - if
+ throw new InvalidMD5ChecksumException([$this, $checksum, $header[3]], self::EXCEPTION_MD5_CHECKSUMS_MISMATCH);
+ }
// Return all in an array
- return array(
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('FILE-IO-STREAM: header()=%d,decodedData()=%d - EXIT!', count($header), strlen($decodedData)));
+ return [
'header' => $header,
- 'data' => $readData
- );
+ 'data' => $decodedData,
+ ];
}
/**
* @return $data The data (string mostly) to "stream"
* @throws UnsupportedOperationException If this method is called
*/
- public function streamData ($data) {
- self::createDebugInstance(__CLASS__, __LINE__)->debugOutput('Unhandled ' . strlen($data) . ' bytes in this stream.');
- throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION);
+ public function streamData (string $data) {
+ // Not supported
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('FILE-IO-STREAM: data=()=%d - CALLED!', strlen($data)));
+ throw new UnsupportedOperationException([$this, __FUNCTION__], FrameworkInterface::EXCEPTION_UNSPPORTED_OPERATION);
}
/**
* @todo 0% done
*/
public function determineSeekPosition () {
- $this->partialStub();
+ // Trace message
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('FILE-IO-STREAM: CALLED!');
+ DebugMiddleware::getSelfInstance()->partialStub();
}
/**
* @param $whence Added to offset (default: only use offset to seek to)
* @return $status Status of file seek: 0 = success, -1 = failed
*/
- public function seek ($offset, $whence = SEEK_SET) {
- $this->partialStub('offset=' . $offset . ',whence=' . $whence);
+ public function seek (int $offset, int $whence = SEEK_SET) {
+ // Check parameters
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage(sprintf('FILE-IO-STREAM: offset=%d,whence=%d - CALLED!', $offset, $whence));
+ if ($offset < 0) {
+ // Throw IAE
+ throw new InvalidArgumentException(sprintf('offset=%d is below zero', $offset), FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+ } elseif ($whence < 0) {
+ // Throw IAE
+ throw new InvalidArgumentException(sprintf('whence=%d is below zero', $whence), FrameworkInterface::EXCEPTION_INVALID_ARGUMENT);
+ }
+
+ DebugMiddleware::getSelfInstance()->partialStub('offset=' . $offset . ',whence=' . $whence);
}
/**
* @return $size Size (in bytes) of file
*/
public function size () {
- $this->partialStub();
+ // Trace message
+ /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__, __LINE__)->traceMessage('FILE-IO-STREAM: CALLED!');
+ DebugMiddleware::getSelfInstance()->partialStub();
}
}