[ Index ]

PHP Cross Reference of PHK Manager

title

Body

[close]

/PHK/Virtual/ -> DC.php (source)

   1  <?php
   2  //=============================================================================
   3  //
   4  // Copyright Francois Laupretre <phk@tekwire.net>
   5  //
   6  //   Licensed under the Apache License, Version 2.0 (the "License");
   7  //   you may not use this file except in compliance with the License.
   8  //   You may obtain a copy of the License at
   9  //
  10  //       http://www.apache.org/licenses/LICENSE-2.0
  11  //
  12  //   Unless required by applicable law or agreed to in writing, software
  13  //   distributed under the License is distributed on an "AS IS" BASIS,
  14  //   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15  //   See the License for the specific language governing permissions and
  16  //   limitations under the License.
  17  //
  18  //=============================================================================
  19  /**
  20  * @copyright Francois Laupretre <phk@tekwire.net>
  21  * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, V 2.0
  22  * @category PHK
  23  * @package PHK
  24  *///==========================================================================
  25  
  26  namespace PHK\Virtual {
  27  
  28  if (!class_exists('PHK\Virtual\DC',false))
  29  {
  30  //=============================================================================
  31  /**
  32  * Data container
  33  *
  34  * Contains string data and supports compression.
  35  *
  36  * API status: Private
  37  * Included in the PHK PHP runtime: Yes
  38  * Implemented in the extension: No
  39  *///==========================================================================
  40  
  41  class DC    // Data Container
  42  {
  43  
  44  private $csz;    // Compressed size
  45  private $rsz;    // Real size
  46  private $flags;    // Compression method
  47  private $off;    // Offset
  48  private $data=null;    // Data cache (null if unset)
  49  private $fspace=null;
  50  
  51  //---------
  52  
  53  const COMPRESS_TYPE=7;    // Space reserved for 8 compression types
  54  
  55  const COMPRESS_NONE=0;
  56  const COMPRESS_GZIP=1;
  57  const COMPRESS_BZIP2=2;
  58  
  59  private static $compression_method_names=array('none','gzip','bzip2');
  60  
  61  private static $compression_needed_extensions=array(null,'zlib','bz2');
  62  
  63  //---------
  64  // Clears the data cache
  65  
  66  public function clearCache()
  67  {
  68  $data=null;
  69  }
  70  
  71  //---------
  72  
  73  public function setFspace($fspace)
  74  {
  75  $this->fspace=$fspace;
  76  }
  77  
  78  //---------
  79  
  80  private function compressionType()
  81  {
  82  return $this->flags & self::COMPRESS_TYPE;
  83  }
  84  
  85  //---------
  86  // Uncompress a buffer, given the compression method
  87  
  88  private function expand($buf)
  89  {
  90  $ctype=$this->compressionType();
  91  
  92  if ($buf==='' || $ctype==self::COMPRESS_NONE) return $buf;
  93  
  94  switch($ctype)
  95      {
  96      case self::COMPRESS_BZIP2:
  97          if(is_int($rbuf=bzdecompress($buf)))
  98              throw new \Exception("Cannot bzdecompress data - Error code $buf");
  99          break;
 100  
 101      case self::COMPRESS_GZIP:
 102          if(($rbuf=gzuncompress($buf))===false)
 103              throw new \Exception("Cannot gzuncompress data");
 104          break;
 105  
 106      default:
 107          throw new \Exception("Unknown compression method : $ctype");
 108      }
 109  return $rbuf;
 110  }
 111  
 112  //---
 113  // Read/uncompress/verify and cache data
 114  
 115  public function read()
 116  {
 117  if (is_null($this->data))
 118      {
 119      if ($this->rsz==0) $this->data='';    // Empty file
 120      else
 121          {
 122          $rbuf=$this->expand($this->fspace->readBlock($this->off,$this->csz));
 123          if (strlen($rbuf)!=$this->rsz) throw new \Exception('Wrong expanded size');
 124          $this->data=$rbuf;
 125          }
 126      }
 127  return $this->data;
 128  }
 129  
 130  //---
 131  
 132  private static function compressionRatio($rsz,$csz)
 133  {
 134  return ($rsz==0) ? '-' : (round(($csz/$rsz)*100));
 135  }
 136  
 137  //---
 138  
 139  public function flagString()
 140  {
 141  if ($ctype=$this->flags & self::COMPRESS_TYPE)
 142      return 'compress/'.self::$compression_method_names[$ctype]
 143          .' ('.self::compressionRatio($this->rsz,$this->csz).'%)';
 144  
 145  return '';
 146  }
 147  
 148  //---
 149  
 150  public function size() { return $this->rsz; }
 151  
 152  //---
 153  
 154  public function import($edata)
 155  {
 156  list($this->flags,$this->csz,$this->rsz,$this->off)
 157      =array_values(unpack('va/V3b',$edata));
 158      
 159  $this->data=null; // Must be reset as the object is created as an empty file
 160  }
 161  
 162  //---
 163  
 164  public function __construct()
 165  {
 166  $this->setFlags(0);
 167  $this->setData('');
 168  $this->csz=$this->off=null;
 169  }
 170  
 171  //---
 172  // Set only the DC flags
 173  
 174  public function setFlags($flags)
 175  {
 176  $this->flags=($flags & \PHK\Virtual\Node::TN_DC_FLAG_MASK);
 177  }
 178  
 179  //---
 180  
 181  public function setData($data)
 182  {
 183  $this->rsz=strlen($this->data=$data);
 184  }
 185  
 186  // <CREATOR> //---------------
 187  
 188  public function getNeededExtensions(\PHK\Build\Creator $phk
 189      ,\PHK\Tools\ItemLister $item_lister)
 190  {
 191  if (!is_null($ext=self::$compression_needed_extensions
 192      [$this->flags & self::COMPRESS_TYPE]))
 193          $item_lister->add($ext,true);
 194  }
 195  
 196  //---
 197  
 198  public function appendData($data)
 199  {
 200  $this->data.=$data;
 201  $this->rsz+=strlen($data);
 202  }
 203  
 204  //---
 205  
 206  public function export(\PHK\Build\Creator $phk,\PHK\Build\DataStacker $stacker)
 207  {
 208  $cbuf=$this->compress($this->data,$phk);
 209  $this->csz=strlen($cbuf);
 210  $this->off=$stacker->offset;
 211  $stacker->push($cbuf);
 212  return pack('vV3',$this->flags,$this->csz,$this->rsz,$this->off);
 213  }
 214  
 215  //------
 216  
 217  private function denyCompress($msg,$buf)
 218  {
 219  \PHK\Tools\Util::trace("    No compression: $msg");
 220  $this->flags &= ~self::COMPRESS_TYPE; // Set to COMPRESS_NONE
 221  return $buf;
 222  }
 223  
 224  //------
 225  
 226  private function compress($buf,\PHK\Build\Creator $phk)
 227  {
 228  if (!($ctype=$this->compressionType())) return $buf;
 229  
 230  $comp_min_size=$phk->option('compress_min_size');
 231  $comp_max_size=$phk->option('compress_max_size');
 232  $comp_ratio_limit=$phk->option('compress_ratio_limit');
 233  
 234  if ($buf==='') return $this->denyCompress('Empty file',$buf);
 235  if ((!is_null($comp_min_size)) && (strlen($buf) < $comp_min_size))
 236          return $this->denyCompress('File too small',$buf);
 237  if ((!is_null($comp_max_size)) && (strlen($buf) > $comp_max_size))
 238          return $this->denyCompress('File too large',$buf);
 239  
 240  switch($ctype)
 241      {
 242      case self::COMPRESS_BZIP2:
 243          \PHK\Tools\Util::loadExtension('bz2');
 244          \PHK\Tools\Util::trace("    Compressing (bzip2)");
 245          if(is_int($cbuf=bzcompress($buf,9)))
 246              throw new \Exception("Cannot bzcompress data - Error code $buf");
 247          break;
 248  
 249      case self::COMPRESS_GZIP:
 250          \PHK\Tools\Util::loadExtension('zlib');
 251          \PHK\Tools\Util::trace("    Compressing (gzip)");
 252          if(($cbuf=gzcompress($buf))===false) 
 253              throw new \Exception("Cannot gzcompress data");
 254          break;
 255  
 256      default:
 257          throw new \Exception("Unknown compression method : $ctype");
 258      }
 259  
 260  // Default: Deny if compressed buffer is larger than 90% of original
 261  
 262  if (is_null($comp_ratio_limit)) $comp_ratio_limit=90;
 263  if (($r=self::compressionRatio(strlen($buf),strlen($cbuf))) >$comp_ratio_limit)
 264      return $this->denyCompress("Compression ratio exceeded ($r%)",$buf);
 265  
 266  return $cbuf;
 267  }
 268  
 269  // </CREATOR> //---------------
 270  
 271  //---
 272  } // End of class
 273  //===========================================================================
 274  } // End of class_exists
 275  //===========================================================================
 276  } // End of namespace
 277  //===========================================================================
 278  ?>


Generated: Thu Jun 4 18:33:15 2015 Cross-referenced by PHPXref 0.7.1