*
* @author Roland Haeder <webmaster@shipsimu.org>
* @version 0.0.0
- * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2013 Core Developer Team
+ * @copyright Copyright (c) 2007, 2008 Roland Haeder, 2009 - 2015 Core Developer Team
* @license GNU GPL 3.0 or any newer version
* @link http://www.shipsimu.org
*
*/
class BaseFrameworkSystem extends stdClass implements FrameworkInterface {
/**
- * Length of count
- */
- const LENGTH_COUNT = 20;
-
- /**
- * Length of position
+ * Length of output from hash()
*/
- const LENGTH_POSITION = 20;
+ private static $hashLength = NULL;
/**
* The real class name
/**
* Instance of the stacker
*/
- private $stackerInstance = NULL;
+ private $stackInstance = NULL;
/**
* A Compressor instance
private $parserInstance = NULL;
/**
- * A ProtocolHandler instance
+ * A HandleableProtocol instance
*/
private $protocolInstance = NULL;
private $helperInstance = NULL;
/**
- * An instance of a Sourceable class
+ * An instance of a Source class
*/
private $sourceInstance = NULL;
+ /**
+ * An instance of a UrlSource class
+ */
+ private $urlSourceInstance = NULL;
+
/**
* An instance of a InputStream class
*/
private $pointerInstance = NULL;
/**
- * An instance of an index
+ * An instance of an Indexable class
*/
private $indexInstance = NULL;
+ /**
+ * An instance of a Block class
+ */
+ private $blockInstance = NULL;
+
+ /**
+ * A Minable instance
+ */
+ private $minableInstance = NULL;
+
+ /**
+ * A FrameworkDirectory instance
+ */
+ private $directoryInstance = NULL;
+
+ /**
+ * Listener instance
+ */
+ private $listenerInstance = NULL;
+
+ /**
+ * An instance of a communicator
+ */
+ private $communicatorInstance = NULL;
+
+ /**
+ * The concrete output instance
+ */
+ private $outputInstance = NULL;
+
+ /**
+ * State instance
+ */
+ private $stateInstance = NULL;
+
/**
* Thousands separator
*/
*/
private $socketResource = FALSE;
+ /**
+ * Regular expression to use for validation
+ */
+ private $regularExpression = '';
+
/**
* Package data
*/
private $genericArray = array();
/**
- * Length of output from hash()
- */
- private static $hashLength = NULL;
-
- /**
- * Counter for total entries
+ * Command name
*/
- private $totalEntries = 0;
+ private $commandName = '';
/**
- * Current seek position
+ * Controller name
*/
- private $seekPosition = 0;
+ private $controllerName = '';
/**
- * Size of header
+ * Name of used protocol
*/
- private $headerSize = 0;
+ private $protocolName = 'invalid';
/**
- * File header
+ * Array with bitmasks and such for pack/unpack methods to support both
+ * 32-bit and 64-bit systems
*/
- private $header = array();
-
- /**
- * Seek positions for gaps ("fragmentation")
- */
- private $gaps = array();
+ private $packingData = array(
+ 32 => array(
+ 'step' => 3,
+ 'left' => 0xffff0000,
+ 'right' => 0x0000ffff,
+ 'factor' => 16,
+ 'format' => 'II',
+ ),
+ 64 => array(
+ 'step' => 7,
+ 'left' => 0xffffffff00000000,
+ 'right' => 0x00000000ffffffff,
+ 'factor' => 32,
+ 'format' => 'NN'
+ )
+ );
/**
- * Seek positions for damaged entries (e.g. mismatching hash sum, ...)
+ * Simple 64-bit check, thanks to "Salman A" from stackoverflow.com:
+ *
+ * The integer size is 4 bytes on 32-bit and 8 bytes on a 64-bit system.
*/
- private $damagedEntries = array();
+ private $archArrayElement = FALSE;
/***********************
* Exception codes.... *
const EXCEPTION_FATAL_ERROR = 0x035;
const EXCEPTION_FILE_NOT_FOUND = 0x036;
const EXCEPTION_ASSERTION_FAILED = 0x037;
- const EXCEPTION_FILE_CANNOT_BE_READ = 0x038;
- const EXCEPTION_DATABASE_UPDATED_NOT_ALLOWED = 0x039;
- const EXCEPTION_FILTER_CHAIN_INTERCEPTED = 0x03a;
+ const EXCEPTION_FILE_NOT_REACHABLE = 0x038;
+ const EXCEPTION_FILE_CANNOT_BE_READ = 0x039;
+ const EXCEPTION_FILE_CANNOT_BE_WRITTEN = 0x03a;
+ const EXCEPTION_PATH_CANNOT_BE_WRITTEN = 0x03b;
+ const EXCEPTION_DATABASE_UPDATED_NOT_ALLOWED = 0x03c;
+ const EXCEPTION_FILTER_CHAIN_INTERCEPTED = 0x03d;
/**
* Hexadecimal->Decimal translation array
// Then set it
self::$startupTime = microtime(TRUE);
} // END - if
+
+ // Set array element
+ $this->archArrayElement = (PHP_INT_SIZE === 8 ? 64 : 32);
}
/**
// Init argument string
$argsString = '';
- // Is it empty or an array?
- if (empty($args)) {
+ // Is it NULL, empty or an array?
+ if (is_null($args)) {
// No arguments
$argsString = 'NULL';
+ } elseif (empty($args)) {
+ // Empty arguments
+ $argsString = '(empty)';
} elseif (is_array($args)) {
// Some arguments are there
foreach ($args as $arg) {
}
/**
- * Magic function to catch setting of missing but set class fields/attributes
+ * Magic method to catch setting of missing but set class fields/attributes
*
* @param $name Name of the field/attribute
* @param $value Value to store
}
/**
- * Magic function to catch getting of missing fields/attributes
+ * Magic method to catch getting of missing fields/attributes
*
* @param $name Name of the field/attribute
* @return void
}
/**
- * Magic function to catch unsetting of missing fields/attributes
+ * Magic method to catch unsetting of missing fields/attributes
*
* @param $name Name of the field/attribute
* @return void
));
}
+ /**
+ * Magic method to catch object serialization
+ *
+ * @return $unsupported Unsupported method
+ * @throws UnsupportedOperationException Objects of this framework cannot be serialized
+ */
+ public final function __sleep () {
+ throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION);
+ }
+
+ /**
+ * Magic method to catch object deserialization
+ *
+ * @return $unsupported Unsupported method
+ * @throws UnsupportedOperationException Objects of this framework cannot be serialized
+ */
+ public final function __wakeup () {
+ throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION);
+ }
+
+ /**
+ * Magic method to catch calls when an object instance is called
+ *
+ * @return $unsupported Unsupported method
+ * @throws UnsupportedOperationException Objects of this framework cannot be serialized
+ */
+ public final function __invoke () {
+ throw new UnsupportedOperationException(array($this, __FUNCTION__), self::EXCEPTION_UNSPPORTED_OPERATION);
+ }
+
/**
* Setter for the real class name
*
/**
* Setter for stacker instance
*
- * @param $stackerInstance An instance of an stacker
+ * @param $stackInstance An instance of an stacker
* @return void
*/
- public final function setStackerInstance (Stackable $stackerInstance) {
- $this->stackerInstance = $stackerInstance;
+ public final function setStackInstance (Stackable $stackInstance) {
+ $this->stackInstance = $stackInstance;
}
/**
* Getter for stacker instance
*
- * @return $stackerInstance An instance of an stacker
+ * @return $stackInstance An instance of an stacker
*/
- public final function getStackerInstance () {
- return $this->stackerInstance;
+ public final function getStackInstance () {
+ return $this->stackInstance;
}
/**
}
/**
- * Setter for ProtocolHandler instance
+ * Setter for HandleableProtocol instance
*
- * @param $protocolInstance An instance of an ProtocolHandler
+ * @param $protocolInstance An instance of an HandleableProtocol
* @return void
*/
- public final function setProtocolInstance (ProtocolHandler $protocolInstance = NULL) {
+ public final function setProtocolInstance (HandleableProtocol $protocolInstance) {
$this->protocolInstance = $protocolInstance;
}
/**
- * Getter for ProtocolHandler instance
+ * Getter for HandleableProtocol instance
*
- * @return $protocolInstance An instance of an ProtocolHandler
+ * @return $protocolInstance An instance of an HandleableProtocol
*/
public final function getProtocolInstance () {
return $this->protocolInstance;
return $this->socketResource;
}
+ /**
+ * Setter for regular expression
+ *
+ * @param $regularExpression A valid regular expression
+ * @return void
+ */
+ public final function setRegularExpression ($regularExpression) {
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput($this->__toString() . '::' . __FUNCTION__ . ': regularExpression=' . $regularExpression . ',previous[' . gettype($this->regularExpression) . ']=' . $this->regularExpression);
+ $this->regularExpression = $regularExpression;
+ }
+
+ /**
+ * Getter for regular expression
+ *
+ * @return $regularExpression A valid regular expression
+ */
+ public final function getRegularExpression () {
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput($this->__toString() . '::' . __FUNCTION__ . ': regularExpression[' . gettype($this->regularExpression) . ']=' . $this->regularExpression);
+ return $this->regularExpression;
+ }
+
/**
* Setter for helper instance
*
}
/**
- * Setter for a Sourceable instance
+ * Setter for a Source instance
*
- * @param $sourceInstance The Sourceable instance
+ * @param $sourceInstance An instance of a Source class
* @return void
*/
- protected final function setSourceInstance (Sourceable $sourceInstance) {
+ protected final function setSourceInstance (Source $sourceInstance) {
$this->sourceInstance = $sourceInstance;
}
/**
- * Getter for a Sourceable instance
+ * Getter for a Source instance
*
- * @return $sourceInstance The Sourceable instance
+ * @return $sourceInstance An instance of a Source class
*/
protected final function getSourceInstance () {
return $this->sourceInstance;
}
+ /**
+ * Setter for a UrlSource instance
+ *
+ * @param $sourceInstance An instance of a UrlSource class
+ * @return void
+ */
+ protected final function setUrlSourceInstance (UrlSource $urlSourceInstance) {
+ $this->urlSourceInstance = $urlSourceInstance;
+ }
+
+ /**
+ * Getter for a UrlSource instance
+ *
+ * @return $urlSourceInstance An instance of a UrlSource class
+ */
+ protected final function getUrlSourceInstance () {
+ return $this->urlSourceInstance;
+ }
+
/**
* Getter for a InputStream instance
*
}
/**
- * Setter for InputOutputPointer instance
+ * Setter for FilePointer instance
*
- * @param $pointerInstance An instance of an InputOutputPointer class
+ * @param $pointerInstance An instance of an FilePointer class
* @return void
*/
- protected final function setPointerInstance (InputOutputPointer $pointerInstance) {
+ protected final function setPointerInstance (FilePointer $pointerInstance) {
$this->pointerInstance = $pointerInstance;
}
/**
- * Getter for InputOutputPointer instance
+ * Getter for FilePointer instance
*
- * @return $pointerInstance An instance of an InputOutputPointer class
+ * @return $pointerInstance An instance of an FilePointer class
*/
public final function getPointerInstance () {
return $this->pointerInstance;
}
+ /**
+ * Unsets pointer instance which triggers a call of __destruct() if the
+ * instance is still there. This is surely not fatal on already "closed"
+ * file pointer instances.
+ *
+ * I don't want to mess around with above setter by giving it a default
+ * value NULL as setter should always explicitly only set (existing) object
+ * instances and NULL is NULL.
+ *
+ * @return void
+ */
+ protected final function unsetPointerInstance () {
+ // Simply it to NULL
+ $this->pointerInstance = NULL;
+ }
+
/**
* Setter for Indexable instance
*
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;
+ }
+
+ /**
+ * Setter for Minable instance
+ *
+ * @param $minableInstance A Minable instance
+ * @return void
+ */
+ protected final function setMinableInstance (Minable $minableInstance) {
+ $this->minableInstance = $minableInstance;
+ }
+
+ /**
+ * Getter for minable instance
+ *
+ * @return $minableInstance A Minable instance
+ */
+ protected final function getMinableInstance () {
+ return $this->minableInstance;
+ }
+
+ /**
+ * Setter for FrameworkDirectory instance
+ *
+ * @param $directoryInstance A FrameworkDirectoryPointer instance
+ * @return void
+ */
+ protected final function setDirectoryInstance (FrameworkDirectory $directoryInstance) {
+ $this->directoryInstance = $directoryInstance;
+ }
+
+ /**
+ * Getter for FrameworkDirectory instance
+ *
+ * @return $directoryInstance A FrameworkDirectory instance
+ */
+ protected final function getDirectoryInstance () {
+ return $this->directoryInstance;
+ }
+
+ /**
+ * Setter for listener instance
+ *
+ * @param $listenerInstance A Listenable instance
+ * @return void
+ */
+ protected final function setListenerInstance (Listenable $listenerInstance) {
+ $this->listenerInstance = $listenerInstance;
+ }
+
+ /**
+ * Getter for listener instance
+ *
+ * @return $listenerInstance A Listenable instance
+ */
+ protected final function getListenerInstance () {
+ return $this->listenerInstance;
+ }
+
+ /**
+ * Getter for communicator instance
+ *
+ * @return $communicatorInstance An instance of a Communicator class
+ */
+ public final function getCommunicatorInstance () {
+ return $this->communicatorInstance;
+ }
+
+ /**
+ * Setter for communicator instance
+ *
+ * @param $communicatorInstance An instance of a Communicator class
+ * @return void
+ */
+ protected final function setCommunicatorInstance (Communicator $communicatorInstance) {
+ $this->communicatorInstance = $communicatorInstance;
+ }
+
+ /**
+ * Setter for state instance
+ *
+ * @param $stateInstance A Stateable instance
+ * @return void
+ */
+ public final function setStateInstance (Stateable $stateInstance) {
+ $this->stateInstance = $stateInstance;
+ }
+
+ /**
+ * Getter for state instance
+ *
+ * @return $stateInstance A Stateable instance
+ */
+ public final function getStateInstance () {
+ return $this->stateInstance;
+ }
+
+ /**
+ * Setter for output instance
+ *
+ * @param $outputInstance The debug output instance
+ * @return void
+ */
+ public final function setOutputInstance (OutputStreamer $outputInstance) {
+ $this->outputInstance = $outputInstance;
+ }
+
+ /**
+ * Getter for output instance
+ *
+ * @return $outputInstance The debug output instance
+ */
+ public final function getOutputInstance () {
+ return $this->outputInstance;
+ }
+
+ /**
+ * Setter for command name
+ *
+ * @param $commandName Last validated command name
+ * @return void
+ */
+ protected final function setCommandName ($commandName) {
+ $this->commandName = $commandName;
+ }
+
+ /**
+ * Getter for command name
+ *
+ * @return $commandName Last validated command name
+ */
+ protected final function getCommandName () {
+ return $this->commandName;
+ }
+
+ /**
+ * Setter for controller name
+ *
+ * @param $controllerName Last validated controller name
+ * @return void
+ */
+ protected final function setControllerName ($controllerName) {
+ $this->controllerName = $controllerName;
+ }
+
+ /**
+ * Getter for controller name
+ *
+ * @return $controllerName Last validated controller name
+ */
+ protected final function getControllerName () {
+ return $this->controllerName;
+ }
+
+ /**
+ * Getter for protocol name
+ *
+ * @return $protocolName Name of used protocol
+ */
+ public final function getProtocolName () {
+ return $this->protocolName;
+ }
+
+ /**
+ * Setter for protocol name
+ *
+ * @param $protocolName Name of used protocol
+ * @return void
+ */
+ protected final function setProtocolName ($protocolName) {
+ $this->protocolName = $protocolName;
+ }
+
/**
* Checks whether an object equals this object. You should overwrite this
* method to implement own equality checks
}
/**
- * Prepare the template engine (WebTemplateEngine by default) for a given
+ * Prepare the template engine (HtmlTemplateEngine by default) for a given
* application helper instance (ApplicationHelper by default).
*
* @param $applicationInstance An application helper instance or
} // END - if
// Initialize the template engine
- $templateInstance = ObjectFactory::createObjectByConfiguredName('web_template_class');
+ $templateInstance = ObjectFactory::createObjectByConfiguredName('html_template_class');
// Return the prepared instance
return $templateInstance;
// Try it
try {
// Get a debugger instance
- $debugInstance = DebugMiddleware::createDebugMiddleware(FrameworkConfiguration::getSelfInstance()->getConfigEntry('debug_class'));
+ $debugInstance = DebugMiddleware::createDebugMiddleware(FrameworkConfiguration::getSelfInstance()->getConfigEntry('debug_' . self::getResponseTypeFromSystem() . '_class'), $className);
} catch (NullPointerException $e) {
// Didn't work, no instance there
exit('Cannot create debugInstance! Exception=' . $e->__toString() . ', message=' . $e->getMessage());
* @param $str The string, what ever it is needs to be converted
* @return $className Generated class name
*/
- public function convertToClassName ($str) {
+ public static final function convertToClassName ($str) {
// Init class name
$className = '';
// Convert all dashes in underscores
- $str = $this->convertDashesToUnderscores($str);
+ $str = self::convertDashesToUnderscores($str);
// Now use that underscores to get classname parts for hungarian style
foreach (explode('_', $str) as $strPart) {
* @param $str The string with maybe dashes inside
* @return $str The converted string with no dashed, but underscores
*/
- public final function convertDashesToUnderscores ($str) {
+ public static final function convertDashesToUnderscores ($str) {
// Convert them all
$str = str_replace('-', '_', $str);
*/
protected final function getDatabaseEntry () {
// Is there an instance?
- if (is_null($this->getResultInstance())) {
+ if (!$this->getResultInstance() instanceof SearchableResult) {
// Throw an exception here
throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
} // END - if
// Do we have an entry?
if ($this->getResultInstance()->valid() === FALSE) {
- throw new InvalidDatabaseResultException(array($this, $this->getResultInstance()), DatabaseResult::EXCEPTION_INVALID_DATABASE_RESULT);
+ // @TODO Move the constant to e.g. BaseDatabaseResult when there is a non-cached database result available
+ throw new InvalidDatabaseResultException(array($this, $this->getResultInstance()), CachedDatabaseResult::EXCEPTION_INVALID_DATABASE_RESULT);
} // END - if
// Get next entry
//* DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput($fieldName.':<pre>'.print_r($fieldArray, TRUE).'</pre>');
// Convert dashes to underscore
- $fieldName = $this->convertDashesToUnderscores($fieldName);
+ $fieldName2 = self::convertDashesToUnderscores($fieldName);
// Does the field exist?
- if (isset($fieldArray[$fieldName])) {
+ if ($this->isFieldSet($fieldName)) {
// Get it
- $fieldValue = $fieldArray[$fieldName];
+ $fieldValue = $fieldArray[$fieldName2];
+ } elseif (defined('DEVELOPER')) {
+ // Missing field entry, may require debugging
+ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']:fieldArray<pre>=' . print_r($fieldArray, TRUE) . '</pre>,fieldName=' . $fieldName . ' not found!');
} else {
// Missing field entry, may require debugging
- self::createDebugInstance(__CLASS__)->debugOutput($this->__toString() . ':fieldname=' . $fieldName . ' not found!');
+ self::createDebugInstance(__CLASS__)->debugOutput('[' . __METHOD__ . ':' . __LINE__ . ']:fieldName=' . $fieldName . ' not found!');
}
// Return it
return $fieldValue;
}
+ /**
+ * Checks if given field is set
+ *
+ * @param $fieldName Field name to check
+ * @return $isSet Whether the given field name is set
+ * @throws NullPointerException If the result instance is null
+ */
+ public function isFieldSet ($fieldName) {
+ // Get result instance
+ $resultInstance = $this->getResultInstance();
+
+ // Is this instance null?
+ if (is_null($resultInstance)) {
+ // Then the user instance is no longer valid (expired cookies?)
+ throw new NullPointerException($this, self::EXCEPTION_IS_NULL_POINTER);
+ } // END - if
+
+ // Get current array
+ $fieldArray = $resultInstance->current();
+ //* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput('[' . $this->__toString() . ':' . __LINE__ . '] fieldName=' . $fieldName . ',fieldArray=<pre>'.print_r($fieldArray, TRUE).'</pre>');
+
+ // Convert dashes to underscore
+ $fieldName = self::convertDashesToUnderscores($fieldName);
+
+ // Determine it
+ $isSet = isset($fieldArray[$fieldName]);
+
+ // Return result
+ return $isSet;
+ }
+
/**
* Flushs all pending updates to the database layer
*
$configEntry = $resultInstance->getUpdateInstance()->getWrapperConfigEntry();
// Create object instance
- $wrapperInstance = ObjectFactory::createObjectByConfiguredName($configEntry);
+ $wrapperInstance = DatabaseWrapperFactory::createWrapperByConfiguredName($configEntry);
// Yes, then send the whole result to the database layer
$wrapperInstance->doUpdateByResult($this->getResultInstance());
*
* @return $responseType Analyzed response type
*/
- protected function getResponseTypeFromSystem () {
+ protected static function getResponseTypeFromSystem () {
// Default is console
$responseType = 'console';
// Is 'HTTP_HOST' set?
if (isset($_SERVER['HTTP_HOST'])) {
- // Then it is a HTTP response/request
- $responseType = 'http';
+ /*
+ * Then it is a HTML response/request as RSS and so on may be
+ * transfered over HTTP as well.
+ */
+ $responseType = 'html';
} // END - if
// Return it
return $isValid;
}
+ /**
+ * Initializes the web output instance
+ *
+ * @return void
+ */
+ protected function initWebOutputInstance () {
+ // Get application instance
+ $applicationInstance = Registry::getRegistry()->getInstance('app');
+
+ // Is this a response instance?
+ if ($this instanceof Responseable) {
+ // Then set it in application instance
+ $applicationInstance->setResponseInstance($this);
+ } // END - if
+
+ // Init web output instance
+ $outputInstance = ObjectFactory::createObjectByConfiguredName('output_class', array($applicationInstance));
+
+ // Set it locally
+ $this->setWebOutputInstance($outputInstance);
+ }
+
/**
* Translates boolean TRUE to 'Y' and FALSE to 'N'
*
}
/**
- * 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
- */
- protected 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__));
- }
-
- /**
- * Checks whether the file header is initialized
- *
- * @return $isInitialized Whether the file header is initialized
- */
- protected function isFileHeaderInitialized () {
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
-
- // Is the method there?
- assert(is_callable(array($this, 'readFileHeader')));
-
- // Default is not initialized
- $isInitialized = FALSE;
-
- // Is the file initialized?
- if ($this->isFileInitialized()) {
- // Some bytes has been written, so rewind to start of it.
- $rewindStatus = $this->getIteratorInstance()->rewind();
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] rewindStatus=%s', __METHOD__, __LINE__, $rewindStatus));
-
- // Is the rewind() call successfull?
- if ($rewindStatus != 1) {
- // Something bad happened
- self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Could not rewind().', __METHOD__, __LINE__));
- } // END - if
-
- // Read file header
- $this->readFileHeader();
-
- // The above method does already check the header
- $isInitialized = TRUE;
- } // END - if
-
- // Return result
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] isInitialized=%d - EXIT!', __METHOD__, __LINE__, intval($isInitialized)));
- return $isInitialized;
- }
-
- /**
- * Checks whether the assigned file has been initialized
+ * Encodes raw data (almost any type) by "serializing" it and then pack it
+ * into a "binary format".
*
- * @return $isInitialized Whether the file's size is zero
+ * @param $rawData Raw data (almost any type)
+ * @return $encoded Encoded data
*/
- protected function isFileInitialized () {
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
+ protected function encodeData ($rawData) {
+ // Make sure no objects or resources pass through
+ assert(!is_object($rawData));
+ assert(!is_resource($rawData));
- // Get it from iterator which holds the pointer instance. If FALSE is returned
- $fileSize = $this->getIteratorInstance()->size();
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] fileSize=%s', __METHOD__, __LINE__, $fileSize));
+ // First "serialize" it (json_encode() is faster than serialize())
+ $encoded = $this->packString(json_encode($rawData));
- /*
- * The returned file size should not be FALSE or NULL as this means
- * that the pointer class does not work correctly.
- */
- assert(is_int($fileSize));
-
- // Is more than 0 returned?
- $isInitialized = ($fileSize > 0);
-
- // Return result
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] isInitialized=%d - EXIT!', __METHOD__, __LINE__, intval($isInitialized)));
- return $isInitialized;
+ // And return it
+ return $encoded;
}
/**
- * Creates the assigned file
+ * Pack a string into a "binary format". Please execuse me that this is
+ * widely undocumented. :-(
*
- * @return void
+ * @param $str Unpacked string
+ * @return $packed Packed string
+ * @todo Improve documentation
*/
- protected function createFileHeader () {
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
+ protected function packString ($str) {
+ // Debug message
+ //* NOISY-DEBUG */ self::createDebugInstance(__CLASS__)->debugOutput('str=' . $str . ' - CALLED!');
- // The method flushFileHeader() must be callable
- assert(is_callable(array($this, 'flushFileHeader')));
+ // First compress the string (gzcompress is okay)
+ $str = gzcompress($str);
- // The file's header should not be initialized here
- assert(!$this->isFileHeaderInitialized());
+ // Init variable
+ $packed = '';
- // Simple flush file header which will create it.
- $this->flushFileHeader();
+ // And start the "encoding" loop
+ for ($idx = 0; $idx < strlen($str); $idx += $this->packingData[$this->archArrayElement]['step']) {
+ $big = 0;
+ for ($i = 0; $i < $this->packingData[$this->archArrayElement]['step']; $i++) {
+ $factor = ($this->packingData[$this->archArrayElement]['step'] - 1 - $i);
- // Rewind seek position (to beginning of file) and update/flush file header
- $this->rewineUpdateSeekPosition();
+ if (($idx + $i) <= strlen($str)) {
+ $ord = ord(substr($str, ($idx + $i), 1));
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!!', __METHOD__, __LINE__));
- }
+ $add = $ord * pow(256, $factor);
- /**
- * 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__));
-
- // Seek to beginning of file
- $this->getIteratorInstance()->rewind();
+ $big += $add;
- // And update seek position ...
- $this->updateSeekPosition();
+ //print 'idx=' . $idx . ',i=' . $i . ',ord=' . $ord . ',factor=' . $factor . ',add=' . $add . ',big=' . $big . PHP_EOL;
+ } // END - if
+ } // END - for
- // ... to write it back into the file
- $this->flushFileHeader();
+ $l = ($big & $this->packingData[$this->archArrayElement]['left']) >>$this->packingData[$this->archArrayElement]['factor'];
+ $r = $big & $this->packingData[$this->archArrayElement]['right'];
- /* 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__));
+ $chunk = str_pad(pack($this->packingData[$this->archArrayElement]['format'], $l, $r), 8, '0', STR_PAD_LEFT);
+ //* NOISY-DEBUG */ print 'big=' . $big . ',chunk('.strlen($chunk) . ')='.md5($chunk).PHP_EOL;
- // Seek to currently ("old") saved position
- $this->getIteratorInstance()->seek($this->getSeekPosition());
+ $packed .= $chunk;
+ } // END - for
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!!', __METHOD__, __LINE__));
+ // Return it
+ //* NOISY-DEBUG */ self::createDebugInstance(__CLASS__)->debugOutput('packed=' . $packed . ' - EXIT!');
+ return $packed;
}
/**
- * Writes data at given position
+ * Checks whether the given file/path is in open_basedir(). This does not
+ * gurantee that the file is actually readable and/or writeable. If you need
+ * such gurantee then please use isReadableFile() instead.
*
- * @param $seekPosition Seek position
- * @param $data Data to be written
- * @param $flushHeader Whether to flush the header (default: flush)
- * @return void
+ * @param $filePathName Name of the file/path to be checked
+ * @return $isReachable Whether it is within open_basedir()
*/
- protected function writeData ($seekPosition, $data, $flushHeader = TRUE) {
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] seekPosition=%s,data()=%s - CALLED!', __METHOD__, __LINE__, $seekPosition, strlen($data)));
+ public static function isReachableFilePath ($filePathName) {
+ // Is not reachable by default
+ $isReachable = FALSE;
- // Write data at given position
- $this->getIteratorInstance()->writeAtPosition($seekPosition, $data);
+ // Get open_basedir parameter
+ $openBaseDir = ini_get('open_basedir');
- // Update seek position
- $this->updateSeekPosition();
-
- // Flush the header?
- if ($flushHeader === TRUE) {
- // Flush header
- $this->flushFileHeader();
-
- // Seek to old position
- $this->seekToOldPosition();
- } // END - if
+ // Is it set?
+ if (!empty($openBaseDir)) {
+ // Check all entries
+ foreach (explode(PATH_SEPARATOR, $openBaseDir) as $dir) {
+ // Check on existence
+ if (substr($filePathName, 0, strlen($dir)) == $dir) {
+ // Is reachable
+ $isReachable = TRUE;
+ } // END - if
+ } // END - foreach
+ } else {
+ // If open_basedir is not set, all is allowed
+ $isReachable = TRUE;
+ }
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!', __METHOD__, __LINE__));
+ // Return status
+ return $isReachable;
}
/**
- * Pre-allocates file (if enabled) with some space for later faster write access.
+ * Checks whether the give file is within open_basedir() (done by
+ * isReachableFilePath()), is actually a file and is readable.
*
- * @param $type Type of the file
- * @return void
+ * @param $fileName Name of the file to be checked
+ * @return $isReadable Whether the file is readable (and therefor exists)
*/
- protected function preAllocateFile ($type) {
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] CALLED!', __METHOD__, __LINE__));
-
- // caluclateMinimumFileEntryLength() must be callable
- assert(is_callable(array($this, 'caluclateMinimumFileEntryLength')));
-
- // Is it enabled?
- if ($this->getConfigInstance()->getConfigEntry($type . '_pre_allocate_enabled') != 'Y') {
- // Not enabled
- self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Not pre-allocating file.', __METHOD__, __LINE__));
-
- // Don't continue here.
- return;
- } // END - if
-
- // Message to user
- self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] Pre-allocating file ...', __METHOD__, __LINE__));
-
- // Calculate minimum length for one entry
- $minLengthEntry = $this->caluclateMinimumFileEntryLength();
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] minLengthEntry=%s', __METHOD__, __LINE__, $minLengthEntry));
-
- // Calulcate seek position
- $seekPosition = $minLengthEntry * $this->getConfigInstance()->getConfigEntry($type . '_pre_allocate_count');
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] seekPosition=%s', __METHOD__, __LINE__, $seekPosition));
-
- // Now simply write a NUL there. This will pre-allocate the file.
- $this->writeData($seekPosition, chr(0));
+ public static function isReadableFile ($fileName) {
+ // Default is not readable
+ $isReadable = FALSE;
- // Rewind seek position (to beginning of file) and update/flush file header
- $this->rewineUpdateSeekPosition();
+ // Is within parameters, so check if it is a file and readable
+ $isReadable = ((self::isReachableFilePath($fileName)) && (file_exists($fileName)) && (is_file($fileName)) && (is_readable($fileName)));
- /* NOISY-DEBUG: */ self::createDebugInstance(__CLASS__)->debugOutput(sprintf('[%s:%d:] EXIT!', __METHOD__, __LINE__));
+ // Return status
+ return $isReadable;
}
}