| 
<?php
/**
 * @package genericarray
 */
 
 /**
 * Generic array loader. Singleton.
 */
 final class ArrayOfGenericLoader {
 private static $instance;
 
 const PREFIX = 'ArrayOf';
 
 public static function getInstance() {
 if (!self::$instance) {
 self::$instance = new ArrayOfGenericLoader();
 }
 return self::$instance;
 }
 
 public $cachedir;
 
 private function __construct() {
 $this->cachedir = dirname(__FILE__) . '/cache';
 }
 
 public function loadClass($classname) {
 if (substr($classname, 0, strlen(self::PREFIX)) != self::PREFIX) return false;
 if ($this->inCache($classname)) {
 $this->loadFromCache($classname);
 return true;
 }
 $this->createGeneric($classname);
 return true;
 }
 
 private function inCache($classname) {
 if (!file_exists($this->cachedir . '/check.' . $classname . '.php')) return false;
 if (!file_exists($this->cachedir . '/' . $classname . '.php')) return false;
 return require($this->cachedir . '/check.' . $classname . '.php');
 }
 
 private function loadFromCache($classname) {
 require_once $this->cachedir . '/' . $classname . '.php';
 }
 
 private function createGeneric($classname) {
 $genericClass = new ReflectionClass(self::PREFIX . 'GenericX');
 $genericFile = $genericClass->getFileName();
 $genericX = substr($classname, strlen(self::PREFIX));
 
 $tokens = token_get_all(file_get_contents($genericFile));
 $code = '';
 foreach ($tokens as $token) {
 if (is_array($token)) {
 if ($token[0] == T_STRING) {
 $token[1] = str_replace('GenericX', $genericX, $token[1]);
 } else if ($token[0] == T_COMMENT || $token[0] == T_DOC_COMMENT) {
 $token[1] = str_replace('GenericX', $genericX, $token[1]);
 }
 $code .= $token[1];
 } else {
 $code .= $token;
 }
 }
 
 $checkCode  = "<?php\n";
 $checkCode .= "if (filemtime('" . addcslashes($genericFile, "'\\") . "') > filemtime(__FILE__)) {\n";
 $checkCode .= "    return false;\n";
 $checkCode .= "}\n";
 $checkCode .= "return true;\n";
 
 file_put_contents($this->cachedir . '/check.' . $classname . '.php', $checkCode);
 if (file_put_contents($this->cachedir . '/' . $classname . '.php', $code)) {
 $this->loadFromCache($classname);
 } else {
 eval("?>$code");
 }
 }
 }
 ?>
 |