*
* @author Roland Haeder <webmaster@shipsimu.org>
* @version 0.0.0
- * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2012 Core Developer Team
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2013 Core Developer Team
* @license GNU GPL 3.0 or any newer version
* @link http://www.shipsimu.org
*
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
+ /**
+ * Separator for header data
+ */
+ const SEPARATOR_HEADER_DATA = 0x01;
+
+ /**
+ * Separator header->entries
+ */
+ const SEPARATOR_HEADER_ENTRIES = 0x02;
+
+ /**
+ * Separator hash->name
+ */
+ const SEPARATOR_HASH_NAME = 0x03;
+
+ /**
+ * Separator entry->entry
+ */
+ const SEPARATOR_ENTRIES = 0x04;
+
+ /**
+ * Length of count
+ */
+ const LENGTH_COUNT = 20;
+
+ /**
+ * Length of position
+ */
+ const LENGTH_POSITION = 20;
+
+ /**
+ * Length of name
+ */
+ const LENGTH_NAME = 10;
+
/**
* The real class name
*/
private $sourceInstance = NULL;
/**
- * An instance of a InputStreamable class
+ * An instance of a InputStream class
*/
private $inputStreamInstance = NULL;
/**
- * An instance of a OutputStreamable class
+ * An instance of a OutputStream class
*/
private $outputStreamInstance = NULL;
*/
private $wrapperInstance = NULL;
+ /**
+ * An instance of a file I/O pointer class (not handler)
+ */
+ private $pointerInstance = NULL;
+
+ /**
+ * An instance of an Indexable class
+ */
+ private $indexInstance = NULL;
+
+ /**
+ * An instance of a Block class
+ */
+ private $blockInstance = NULL;
+
/**
* Thousands separator
*/
*/
private $genericArray = array();
+ /**
+ * Length of output from hash()
+ */
+ private static $hashLength = NULL;
+
+ /**
+ * Counter for total entries
+ */
+ private $totalEntries = 0;
+
+ /**
+ * Current seek position
+ */
+ private $seekPosition = 0;
+
+ /**
+ * Size of header
+ */
+ private $headerSize = 0;
+
+ /**
+ * File header
+ */
+ private $header = array();
+
+ /**
+ * Seek positions for gaps ("fragmentation")
+ */
+ private $gaps = array();
+
+ /**
+ * Seek positions for damaged entries (e.g. mismatching hash sum, ...)
+ */
+ private $damagedEntries = array();
+
/***********************
* Exception codes.... *
***********************/
const EXCEPTION_ARRAY_ELEMENTS_MISSING = 0x02c;
const EXCEPTION_TEMPLATE_ENGINE_UNSUPPORTED = 0x02d;
const EXCEPTION_UNSPPORTED_OPERATION = 0x02e;
+ const EXCEPTION_FACTORY_REQUIRE_PARAMETER = 0x02f;
const EXCEPTION_MISSING_ELEMENT = 0x030;
const EXCEPTION_HEADERS_ALREADY_SENT = 0x031;
const EXCEPTION_DEFAULT_CONTROLLER_GONE = 0x032;
const EXCEPTION_ASSERTION_FAILED = 0x037;
const EXCEPTION_FILE_CANNOT_BE_READ = 0x038;
const EXCEPTION_DATABASE_UPDATED_NOT_ALLOWED = 0x039;
- const EXCEPTION_FILTER_CHAIN_INTERCEPTED = 0x040;
+ const EXCEPTION_FILTER_CHAIN_INTERCEPTED = 0x03a;
/**
* Hexadecimal->Decimal translation array
} else {
// Do not call this twice
trigger_error(__METHOD__ . ': Called twice.');
+ exit;
}
}
$this->debugBackTrace(sprintf('Tried to set a missing field. name=%s, value[%s]=%s',
$name,
gettype($value),
- $value
+ print_r($value, TRUE)
));
}
}
/**
- * Getter for a InputStreamable instance
+ * Getter for a InputStream instance
*
- * @param $inputStreamInstance The InputStreamable instance
+ * @param $inputStreamInstance The InputStream instance
*/
protected final function getInputStreamInstance () {
return $this->inputStreamInstance;
}
/**
- * Setter for a InputStreamable instance
+ * Setter for a InputStream instance
*
- * @param $inputStreamInstance The InputStreamable instance
+ * @param $inputStreamInstance The InputStream instance
* @return void
*/
- protected final function setInputStreamInstance (InputStreamable $inputStreamInstance) {
+ protected final function setInputStreamInstance (InputStream $inputStreamInstance) {
$this->inputStreamInstance = $inputStreamInstance;
}
/**
- * Getter for a OutputStreamable instance
+ * Getter for a OutputStream instance
*
- * @param $outputStreamInstance The OutputStreamable instance
+ * @param $outputStreamInstance The OutputStream instance
*/
protected final function getOutputStreamInstance () {
return $this->outputStreamInstance;
}
/**
- * Setter for a OutputStreamable instance
+ * Setter for a OutputStream instance
*
- * @param $outputStreamInstance The OutputStreamable instance
+ * @param $outputStreamInstance The OutputStream instance
* @return void
*/
- protected final function setOutputStreamInstance (OutputStreamable $outputStreamInstance) {
+ protected final function setOutputStreamInstance (OutputStream $outputStreamInstance) {
$this->outputStreamInstance = $outputStreamInstance;
}
return $this->iteratorInstance;
}
+ /**
+ * Setter for InputOutputPointer instance
+ *
+ * @param $pointerInstance An instance of an InputOutputPointer class
+ * @return void
+ */
+ protected final function setPointerInstance (InputOutputPointer $pointerInstance) {
+ $this->pointerInstance = $pointerInstance;
+ }
+
+ /**
+ * Getter for InputOutputPointer instance
+ *
+ * @return $pointerInstance An instance of an InputOutputPointer class
+ */
+ public final function getPointerInstance () {
+ return $this->pointerInstance;
+ }
+
+ /**
+ * Setter for Indexable instance
+ *
+ * @param $indexInstance An instance of an Indexable class
+ * @return void
+ */
+ protected final function setIndexInstance (Indexable $indexInstance) {
+ $this->indexInstance = $indexInstance;
+ }
+
+ /**
+ * Getter for Indexable instance
+ *
+ * @return $indexInstance An instance of an Indexable class
+ */
+ public final function getIndexInstance () {
+ return $this->indexInstance;
+ }
+
+ /**
+ * Setter for Block instance
+ *
+ * @param $blockInstance An instance of an Block class
+ * @return void
+ */
+ protected final function setBlockInstance (Block $blockInstance) {
+ $this->blockInstance = $blockInstance;
+ }
+
+ /**
+ * Getter for Block instance
+ *
+ * @return $blockInstance An instance of an Block class
+ */
+ public final function getBlockInstance () {
+ return $this->blockInstance;
+ }
+
/**
* Checks whether an object equals this object. You should overwrite this
* method to implement own equality checks
} else {
// Trigger an error
trigger_error($stubMessage);
+ exit;
}
}
* @return $debugInstance An instance of a debugger class
*/
public final static function createDebugInstance ($className) {
- // Init debug instance
- $debugInstance = NULL;
+ // Is the instance set?
+ if (!Registry::getRegistry()->instanceExists('debug')) {
+ // Init debug instance
+ $debugInstance = NULL;
+
+ // Try it
+ try {
+ // Get a debugger instance
+ $debugInstance = DebugMiddleware::createDebugMiddleware(FrameworkConfiguration::getSelfInstance()->getConfigEntry('debug_class'));
+ } catch (NullPointerException $e) {
+ // Didn't work, no instance there
+ exit('Cannot create debugInstance! Exception=' . $e->__toString() . ', message=' . $e->getMessage());
+ }
- // Try it
- try {
- // Get a debugger instance
- $debugInstance = DebugMiddleware::createDebugMiddleware(FrameworkConfiguration::getSelfInstance()->getConfigEntry('debug_class'));
- } catch (NullPointerException $e) {
- // Didn't work, no instance there
- exit('Cannot create debugInstance! Exception=' . $e->__toString() . ', message=' . $e->getMessage());
- }
+ // Empty string should be ignored and used for testing the middleware
+ DebugMiddleware::getSelfInstance()->output('');
- // Empty string should be ignored and used for testing the middleware
- DebugMiddleware::getSelfInstance()->output('');
+ // Set it in its own class. This will set it in the registry
+ $debugInstance->setDebugInstance($debugInstance);
+ } else {
+ // Get instance from registry
+ $debugInstance = Registry::getRegistry()->getDebugInstance();
+ }
// Return it
return $debugInstance;
} else {
// Trigger an error
trigger_error($message . "<br />\n");
+ exit;
}
} else {
// @TODO Finish this part!
}
/**
- * Hashes a given string with a simple but stronger hash function (no salts)
+ * Hashes a given string with a simple but stronger hash function (no salt)
+ * and hex-encode it.
*
* @param $str The string to be hashed
* @return $hash The hash from string $str
*/
- public function hashString ($str) {
+ public static final function hash ($str) {
// Hash given string with (better secure) hasher
- $hash = mhash(MHASH_SHA256, $str);
+ $hash = bin2hex(mhash(MHASH_SHA256, $str));
// Return it
return $hash;
}
+ /**
+ * "Getter" for length of hash() output. This will be "cached" to speed up
+ * things.
+ *
+ * @return $length Length of hash() output
+ */
+ public static final function getHashLength () {
+ // Is it cashed?
+ if (is_null(self::$hashLength)) {
+ // No, then hash a string and save its length.
+ self::$hashLength = strlen(self::hash('abc123'));
+ } // END - if
+
+ // Return it
+ return self::$hashLength;
+ }
+
/**
* Checks whether the given number is really a number (only chars 0-9).
*
if (!$this->isGenericArrayGroupSet($keyGroup, $subGroup)) {
// No, then abort here
trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' not found.');
+ exit;
} // END - if
// Debug message
if (($forceInit === FALSE) && ($this->isGenericArrayGroupSet($keyGroup, $subGroup))) {
// Already initialized
trigger_error(__METHOD__ . ':keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' already initialized.');
+ exit;
} // END - if
// Initialize it
if (($forceInit === FALSE) && ($this->isGenericArrayKeySet($keyGroup, $subGroup, $key))) {
// Already initialized
trigger_error(__METHOD__ . ':keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ' already initialized.');
+ exit;
} // END - if
// Initialize it
if (($forceInit === FALSE) && ($this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element))) {
// Already initialized
trigger_error(__METHOD__ . ':keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ' already initialized.');
+ exit;
} // END - if
// Initialize it
if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
// Not found
trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ' not found.');
+ exit;
} // END - if
// Then "pop" it
if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
// Not found
trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ' not found.');
+ exit;
} // END - if
// Then "shift" it
if (!isset($this->genericArray[$keyGroup])) {
// Abort here
trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ' not found.');
+ exit;
} // END - if
// Then count it
if (!$this->isGenericArrayGroupSet($keyGroup, $subGroup)) {
// Abort here
trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' not found.');
+ exit;
} // END - if
// Then count it
if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
// Abort here
trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' not found.');
+ exit;
} elseif (!$this->isValidGenericArrayGroup($keyGroup, $subGroup)) {
// Not valid
trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ' is not an array.');
+ exit;
}
// Then count it
if (!isset($this->genericArray[$keyGroup])) {
// Then abort here
trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ' does not exist.');
+ exit;
} // END - if
// Return it
if (!$this->isGenericArrayKeySet($keyGroup, $subGroup, $key)) {
// Then abort here
trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ' does not exist.');
+ exit;
} // END - if
// Return it
if (!$this->isGenericArrayElementSet($keyGroup, $subGroup, $key, $element)) {
// Then abort here
trigger_error(__METHOD__ . ': keyGroup=' . $keyGroup . ',subGroup=' . $subGroup . ',key=' . $key . ',element=' . $element . ' does not exist.');
+ exit;
} // END - if
// Return it
// Return it
return $isValid;
}
+
+ /**
+ * Translates boolean TRUE to 'Y' and FALSE to 'N'
+ *
+ * @param $boolean Boolean value
+ * @return $translated Translated boolean value
+ */
+ public static final function translateBooleanToYesNo ($boolean) {
+ // Make sure it is really boolean
+ assert(is_bool($boolean));
+
+ // "Translate" it
+ $translated = ($boolean === TRUE) ? 'Y' : 'N';
+
+ // ... and return it
+ return $translated;
+ }
+
+ /**
+ * Initializes counter for valid entries, arrays for damaged entries and
+ * an array for gap seek positions. If you call this method on your own,
+ * please re-analyze the file structure. So you are better to call
+ * analyzeFile() instead of this method.
+ *
+ * @return void
+ */
+ protected function initCountersGapsArray () {
+ // Init counter and seek position
+ $this->setCounter(0);
+ $this->setSeekPosition(0);
+
+ // Init arrays
+ $this->gaps = array();
+ $this->damagedEntries = array();
+ }
+
+ /**
+ * Getter for total entries
+ *
+ * @return $totalEntries Total entries in this file
+ */
+ protected final function getCounter () {
+ // Get it
+ return $this->totalEntries;
+ }
+
+ /**
+ * Setter for total entries
+ *
+ * @param $totalEntries Total entries in this file
+ * @return void
+ */
+ protected final function setCounter ($counter) {
+ // Set it
+ $this->totalEntries = $counter;
+ }
+
+ /**
+ * Increment counter
+ *
+ * @return void
+ */
+ protected final function incrementCounter () {
+ // Get it
+ $this->totalEntries++;
+ }
+
+ /**
+ * Getter for header size
+ *
+ * @return $totalEntries Size of file header
+ */
+ public final function getHeaderSize () {
+ // Get it
+ return $this->headerSize;
+ }
+
+ /**
+ * Setter for header size
+ *
+ * @param $headerSize Size of file header
+ * @return void
+ */
+ protected final function setHeaderSize ($headerSize) {
+ // Set it
+ $this->headerSize = $headerSize;
+ }
+
+ /**
+ * Getter for header array
+ *
+ * @return $totalEntries Size of file header
+ */
+ protected final function getHeade () {
+ // Get it
+ return $this->header;
+ }
+
+ /**
+ * Setter for header
+ *
+ * @param $header Array for a file header
+ * @return void
+ */
+ protected final function setHeader (array $header) {
+ // Set it
+ $this->header = $header;
+ }
+
+ /**
+ * Getter for seek position
+ *
+ * @return $seekPosition Current seek position (stored here in object)
+ */
+ protected final function getSeekPosition () {
+ // Get it
+ return $this->seekPosition;
+ }
+
+ /**
+ * Setter for seek position
+ *
+ * @param $seekPosition Current seek position (stored here in object)
+ * @return void
+ */
+ protected final function setSeekPosition ($seekPosition) {
+ // And set it
+ $this->seekPosition = $seekPosition;
+ }
+
+ /**
+ * Updates seekPosition attribute from file to avoid to much access on file.
+ *
+ * @return void
+ */
+ protected function updateSeekPosition () {
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
+
+ // Get key (= seek position)
+ $seekPosition = $this->getIteratorInstance()->key();
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Setting seekPosition=%s', __METHOD__, __LINE__, $seekPosition));
+
+ // And set it here
+ $this->setSeekPosition($seekPosition);
+
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!', __METHOD__, __LINE__));
+ }
+
+ /**
+ * Seeks to beginning of file, updates seek position in this object and
+ * flushes the header.
+ *
+ * @return void
+ */
+ protected function rewineUpdateSeekPosition () {
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
+
+ // flushFileHeader must be callable
+ assert(is_callable(array($this, 'flushFileHeader')));
+
+ // Seek to beginning of file
+ $this->getIteratorInstance()->rewind();
+
+ // And update seek position ...
+ $this->updateSeekPosition();
+
+ // ... to write it back into the file
+ $this->flushFileHeader();
+
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!!', __METHOD__, __LINE__));
+ }
+
+ /**
+ * Seeks to old position
+ *
+ * @return void
+ */
+ protected function seekToOldPosition () {
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
+
+ // Seek to currently ("old") saved position
+ $this->getIteratorInstance()->seek($this->getSeekPosition());
+
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!!', __METHOD__, __LINE__));
+ }
+
+ /**
+ * Checks whether the block separator has been found
+ *
+ * @param $str String to look in
+ * @return $isFound Whether the block separator has been found
+ */
+ public function isBlockSeparatorFound ($str) {
+ // Determine it
+ $isFound = (strpos($str, self::getBlockSeparator()) !== FALSE);
+
+ // Return result
+ return $isFound;
+ }
+
+ /**
+ * Getter for block separator character(s)
+ *
+ * @return $blockSeparator A separator for blocks
+ */
+ protected static final function getBlockSeparator () {
+ return chr(self::SEPARATOR_ENTRIES);
+ }
}
// [EOF]