* instance of get_called_class(): ILLI\Core\Std\Def\ADT* * instance of __CLASS__: ILLI\Core\Std\Def\ADT * * :adtDef * collection of defined __const_Type(s) * * @var array [{:hashAddr} => {:adtDef}] */ private static $__gc = []; /** * Instantiate a new Abstract Data Type. * * define ADT * * :offset * zero-based index * * :gcType * a valid __const_Type * * @param array $__defineTypes [{:offset} => {:gcType}] * @throws ILLI\Core\Std\Exception\ADT\ComponentInitializationException * @see ILLI\Core\Std\Def\__const_Type * @see ILLI\Core\Std\Def\ADTInstance * @see ILLI\Core\Std\Spl\Fsb */ public function __construct(array $__defineTypes = []) { try { if([] === $__defineTypes) throw new ArgumentLengthZeroException; $n = $this->createHashAddr($__defineTypes); $t = &self::$__gc[$n]; parent::setSize(1); parent::offsetSet(0, $n); if(FALSE === isset($t)) $t = Fsb::fromArray($this->parseDef($__defineTypes)); } catch(\Exception $E) { throw new ComponentInitializationException($E, ['class' => get_called_class()]); } } /** * value validation * * The type of given value equals with one of the registered gc-types * * @param mixed $__value * @return boolean * @see ILLI\Core\Std\Def\__const_Type */ public function validate($__value) { try { $v = &$__value; $t = getType($v); foreach($this->getGC() as $h) { if($t === $h ||($t === __const_Type::SPL_OBJECT && (class_exists($h) || interface_exists($h)) && (is_subclass_of($v, $h) || $v instanceOf $h))) return TRUE; } return FALSE; } catch(\Exception $E) { throw new ComponentMethodCallException($E, ComponentMethodCallException::ERROR_VALIDATE, ['method' => __METHOD__]); } } /** * get ADT-gc hash address * * @return string * @see ::$__gc */ public function getName() { try { return parent::offsetGet(0); } catch(\Exception $E) { throw new ComponentMethodCallException($E, ComponentMethodCallException::ERROR_GET_NAME, ['method' => __METHOD__]); } } /** * get ADT-gc * * @return ILLI\Core\Std\Spl\Fsb * @see ::$__gc */ public function getGC() { try { return self::$__gc[$this->getName()]; } catch(\Exception $E) { throw new ComponentMethodCallException($E, ComponentMethodCallException::ERROR_GET_GC, ['method' => __METHOD__]); } } /** * join registered gc-type(s) * * @return ILLI\Core\Std\Spl\Fsb * @see ::$__gc * @see ILLI\Core\Std\Def\__const_Type */ public function toString() { try { return implode('|', $this->getGC()->toArray()); } catch(\Exception $E) { throw new ComponentMethodCallException($E, ComponentMethodCallException::ERROR_TO_STRING, ['method' => __METHOD__]); } } /** * generate gc-hash-address from called-class or from spl_object_hash * * :offset * zero-based index * * :gcType * a valid __const_Type * * @param array $__defineTypes [{:offset} => {:gcType}] * @return string * @see ::$__gc */ protected function createHashAddr(array $__defineTypes = []) { try { #~ performanced ADT: cache request by called-class; otherwise by hash return ($c = get_called_class()) === __CLASS__ ? Spl::nameWithHash($c, $this) : $c; } catch(\Exception $E) { throw new ComponentMethodCallException($E, ComponentMethodCallException::ERROR_CREATE_HASH_ADDR, ['method' => __METHOD__]); } } /** * validate typedef request * * :offset * zero-based index * * :gcType * a valid __const_Type * * @param array $__defineTypes [{:offset} => {:gcType}] * @throws ILLI\Core\Std\Exception\ArgumentExpectedException when {:gcType} is not a string */ protected function parseDef(array $__defineTypes) { try { $r = []; foreach($__defineTypes as $k => $v) { if(FALSE === is_string($v)) throw new ArgumentExpectedException([ 'target' => $this->getName().'['.$k.']', 'expected' => 'string', 'detected' => $t = getType($v), 'value' => is_object($v) ? get_class($v) : ((is_string($v) && (class_exists($v) || interface_exists($v))) || is_scalar($v)) ? $v : $t ]); $r[$k] = $v; } if([] === $r) throw new ArgumentLengthZeroException; return $r; } catch(\Exception $E) { throw new ComponentMethodCallException($E, ComponentMethodCallException::ERROR_PARSE_DEF, ['method' => __METHOD__]); } } #:ILLI\Core\Std\Spl\Fsb: #:NotSupported: /** * @notSupported * @throws ILLI\Core\Std\Exception\NotSupportedException */ public function setSize($__size) { throw new NotSupportedException([ 'target' => __METHOD__ ]); } /** * @notSupported * @throws ILLI\Core\Std\Exception\NotSupportedException */ public function offsetSet($__offset, $__value) { throw new NotSupportedException([ 'target' => __METHOD__ ]); } /** * @notSupported * @throws ILLI\Core\Std\Exception\NotSupportedException */ public function offsetUnset($__offset) { throw new NotSupportedException([ 'target' => __METHOD__ ]); } #:: #:gc: public function getSize() { return $this->getGC()->getSize(); } public function offsetGet($__offset) { return $this->getGC()->offsetGet($__offset); } public function offsetExists($__offset) { return $this->getGC()->offsetExists($__offset); } public function rewind() { return $this->getGC()->rewind(); } public function end() { return $this->getGC()->end(); } public function valid() { return $this->getGC()->valid(); } public function current() { return $this->getGC()->current(); } public function key() { return $this->getGC()->key(); } public function prev() { return $this->getGC()->prev(); } public function next() { return $this->getGC()->next(); } public function count() { return $this->getGC()->count(); } public function keys() { return $this->getGC()->keys(); } public function values() { return $this->getGC()->values(); } #:: #:: }