[ Index ] |
PHP Cross Reference of PHK Manager |
[Summary view] [Print] [Text view]
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 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Jun 4 18:33:15 2015 | Cross-referenced by PHPXref 0.7.1 |