Version: current

      1 <?php
      2  /**
      3  * This file is part of phpMorphy library
      4  *
      5  * Copyright c 2007-2008 Kamaev Vladimir <heromantor@users.sourceforge.net>
      6  *
      7  * This library is free software; you can redistribute it and/or
      8  * modify it under the terms of the GNU Lesser General Public
      9  * License as published by the Free Software Foundation; either
     10  * version 2 of the License, or (at your option) any later version.
     11  *
     12  * This library is distributed in the hope that it will be useful,
     13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15  * Lesser General Public License for more details.
     16  *
     17  * You should have received a copy of the GNU Lesser General Public
     18  * License along with this library; if not, write to the
     19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
     20  * Boston, MA 02111-1307, USA.
     21  */
     22
     23 define('PHPMORPHY_STORAGE_FILE',    'file');
     24 define('PHPMORPHY_STORAGE_MEM',     'mem');
     25 define('PHPMORPHY_STORAGE_SHM',     'shm');
     26
     27 abstract class phpMorphy_Storage {
     28     protected
     29         $file_name,
     30         $resource;
     31
     32     function __construct($fileName) {
     33         $this->file_name = $fileName;
     34         $this->resource = $this->open($fileName);
     35     }
     36
     37     function getFileName() { return $this->file_name; }
     38     function getResource() { return $this->resource; }
     39     function getTypeAsString() { return $this->getType(); }
     40     function read($offset, $len, $exactLength = true) {
     41         if($offset >= $this->getFileSize()) {
     42             throw new phpMorphy_Exception("Can`t read $len bytes beyond end of '" . $this->getFileName() . "' file, offset = $offset, file_size = " . $this->getFileSize());
     43         }
     44
     45         try {
     46             $result = $this->readUnsafe($offset, $len);
     47         } catch (Exception $e) {
     48             throw new phpMorphy_Exception("Can`t read $len bytes at $offset offset, from '" . $this->getFileName() . "' file: " . $e->getMessage());
     49         }
     50
     51         if($exactLength && $GLOBALS['__phpmorphy_strlen']($result) < $len) {
     52             throw new phpMorphy_Exception("Can`t read $len bytes at $offset offset, from '" . $this->getFileName() . "' file");
     53         }
     54
     55         return $result;
     56     }
     57
     58     abstract function readUnsafe($offset, $len);
     59     abstract function getFileSize();
     60     abstract function getType();
     61     abstract protected function open($fileName);
     62 };
     63
     64 class phpMorphy_Storage_Proxy extends phpMorphy_Storage {
     65     protected
     66         $file_name,
     67         $type,
     68         $factory;
     69
     70     function __construct($type, $fileName, $factory) {
     71         $this->file_name = $fileName;
     72         $this->type = $type;
     73         $this->factory = $factory;
     74     }
     75
     76     function getFileName() { return $this->__obj->getFileName(); }
     77     function getResource() { return $this->__obj->getResource(); }
     78     function getFileSize() { return $this->__obj->getFileSize(); }
     79     function getType() { return $this->__obj->getType(); }
     80     function readUnsafe($offset, $len) { return $this->__obj->readUnsafe($offset, $len); }
     81     protected function open($fileName) { return $this->__obj->open($fileName); }
     82
     83     function __get($propName) {
     84         if($propName === '__obj') {
     85             $this->__obj = $this->factory->open($this->type, $this->file_name, false);
     86
     87             unset($this->file_name);
     88             unset($this->type);
     89             unset($this->factory);
     90
     91             return $this->__obj;
     92         }
     93
     94         throw new phpMorphy_Exception("Unknown '$propName' property");
     95     }
     96 }
     97
     98 class phpMorphy_Storage_File extends phpMorphy_Storage {
     99     function getType() { return PHPMORPHY_STORAGE_FILE; }
    100
    101     function getFileSize() {
    102         if(false === ($stat = fstat($this->resource))) {
    103             throw new phpMorphy_Exception('Can`t invoke fstat for ' . $this->file_name . ' file');
    104         }
    105
    106         return $stat['size'];
    107     }
    108
    109     function readUnsafe($offset, $len) {
    110         if(0 !== fseek($this->resource, $offset)) {
    111             throw new phpMorphy_Exception("Can`t seek to $offset offset");
    112         }
    113
    114         return fread($this->resource, $len);
    115     }
    116
    117     function open($fileName) {
    118         if(false === ($fh = fopen($fileName, 'rb'))) {
    119             throw new phpMorphy_Exception("Can`t open $this->file_name file");
    120         }
    121
    122         return $fh;
    123     }
    124 }
    125
    126 class phpMorphy_Storage_Mem extends phpMorphy_Storage {
    127     function getType() { return PHPMORPHY_STORAGE_MEM; }
    128
    129     function getFileSize() {
    130         return $GLOBALS['__phpmorphy_strlen']($this->resource);
    131     }
    132
    133     function readUnsafe($offset, $len) {
    134         return $GLOBALS['__phpmorphy_substr']($this->resource, $offset, $len);
    135     }
    136
    137     function open($fileName) {
    138         if(false === ($string = file_get_contents($fileName))) {
    139             throw new phpMorphy_Exception("Can`t read $fileName file");
    140         }
    141
    142         return $string;
    143     }
    144 }
    145
    146 class phpMorphy_Storage_Shm extends phpMorphy_Storage {
    147     protected
    148         $descriptor;
    149
    150     function __construct($fileName, $shmCache) {
    151         $this->cache = $shmCache;
    152
    153         parent::__construct($fileName);
    154     }
    155
    156     function getFileSize() {
    157         return $this->descriptor->getFileSize();
    158     }
    159
    160     function getType() { return PHPMORPHY_STORAGE_SHM; }
    161
    162     function readUnsafe($offset, $len) {
    163         return shmop_read($this->resource['shm_id'], $this->resource['offset'] + $offset, $len);
    164     }
    165
    166     function open($fileName) {
    167         $this->descriptor = $this->cache->get($fileName);
    168
    169         return array(
    170             'shm_id' => $this->descriptor->getShmId(),
    171             'offset' => $this->descriptor->getOffset()
    172         );
    173     }
    174 }
    175
    176 class phpMorphy_Storage_Factory {
    177     protected
    178         $shm_cache,
    179         $shm_options;
    180
    181     function __construct($shmOptions = array()) {
    182         $this->shm_options = $shmOptions;
    183     }
    184
    185     function getShmCache() {
    186         if(!isset($this->shm_cache)) {
    187             $this->shm_cache = $this->createShmCache($this->shm_options);
    188         }
    189
    190         return $this->shm_cache;
    191     }
    192
    193     function open($type, $fileName, $lazy) {
    194         switch($type) {
    195             case PHPMORPHY_STORAGE_FILE:
    196             case PHPMORPHY_STORAGE_MEM:
    197             case PHPMORPHY_STORAGE_SHM: break;
    198             default:
    199                 throw new phpMorphy_Exception("Invalid storage type $type specified");
    200         }
    201
    202         if($lazy) {
    203             return new phpMorphy_Storage_Proxy($type, $fileName, $this);
    204         }
    205
    206         $clazz = 'phpMorphy_Storage_' . ucfirst($GLOBALS['__phpmorphy_strtolower']($type));
    207
    208         if($type != PHPMORPHY_STORAGE_SHM) {
    209             return new $clazz($fileName);
    210         } else {
    211             return new $clazz($fileName, $this->getShmCache());
    212         }
    213     }
    214
    215     protected function createShmCache($options) {
    216         require_once(PHPMORPHY_DIR . '/shm_utils.php');
    217
    218         return new phpMorphy_Shm_Cache($options, !empty($options['clear_on_create']));
    219     }
    220 }
    221

[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the Silverstripe Forums to ask development related questions. -