c2ephp
|
00001 <?php 00002 require_once(dirname(__FILE__).'/../support/IReader.php'); 00003 require_once(dirname(__FILE__).'/../support/StringReader.php'); 00004 require_once(dirname(__FILE__).'/COB/AgentBlock.php'); 00005 require_once(dirname(__FILE__).'/COB/FileBlock.php'); 00006 require_once(dirname(__FILE__).'/COB/AuthorBlock.php'); 00007 require_once(dirname(__FILE__).'/COB/UnknownBlock.php'); 00008 00010 00014 define('COB_FORMAT_C1','C1'); 00019 define('COB_FORMAT_C2','C2'); 00021 00023 class COB { 00024 00026 00027 private $format; 00028 private $blocks; 00029 00031 00033 00045 public function COB(IReader $reader=null) { 00046 if($reader != null) { 00047 $this->LoadCOB($reader); 00048 } 00049 } 00050 00052 00054 00060 private function LoadCOB(IReader $reader) { 00061 if($reader->Read(4) == 'cob2') { 00062 $reader->Seek(0); 00063 $this->LoadC2COB($reader); 00064 } else { 00065 $string = $reader->GetSubString(0); 00066 $data = @gzuncompress($string); 00067 if($data===false) { 00068 $reader->Seek(0); 00069 $this->LoadC1COB($reader); 00070 } else { 00071 $this->LoadC2COB(new StringReader($data)); 00072 } 00073 } 00074 } 00075 00077 00079 00084 public function LoadC2COB(IReader $reader) { 00085 $this->format = COB_FORMAT_C2; 00086 if($reader->Read(4) == 'cob2') { 00087 while($block = $this->ReadBlock($reader)) { 00088 $this->blocks[] = $block; 00089 } 00090 } else { 00091 throw new Exception('Not a valid C2 COB file!'); 00092 } 00093 } 00094 00096 00101 public function LoadC1COB(IReader $reader) { 00102 $this->format = COB_FORMAT_C1; 00103 $version = $reader->ReadInt(2); 00104 if($version > 4) { 00105 throw new Exception('Invalid cob file.'); 00106 } else { 00107 $this->blocks[] = COBAgentBlock::CreateFromReaderC1($reader); 00108 } 00109 } 00111 00114 public function AddBlock(COBBlock $block) { 00115 //TODO: Check that this block works for this COB type? 00116 $this->blocks[] = $block; 00117 } 00118 00120 00122 00126 private function ReadBlock(IReader $reader) { 00127 if(!($type = $reader->Read(4))) { 00128 return false; 00129 } 00130 $size = $reader->ReadInt(4); 00131 switch($type) { 00132 case 'agnt': 00133 //we read the entire thing so that if there are errors we can still go on with the other blocks. 00134 return COBAgentBlock::CreateFromReaderC2($reader); 00135 break; 00136 case 'auth': 00137 return COBAuthorBlock::CreateFromReader(new StringReader($reader->Read($size))); 00138 break; 00139 case 'file': 00140 return COBFileBlock::CreateFromReader(new StringReader($reader->Read($size))); 00141 break; 00142 default: 00143 //throw new Exception('Invalid block type: Probably a bug or an invalid COB file: '.$type); 00144 //simply ignore unknown block types, in case people add their own 00145 return new COBUnknownBlock($type,$reader->Read($size)); 00146 break; 00147 } 00148 } 00149 00151 00153 00160 public function GetBlocks($type=false) { 00161 $blocks = array(); 00162 foreach($this->blocks as $block) { 00163 if($type === false || $type == $block->GetType()) { 00164 $blocks[] = $block; 00165 } 00166 } 00167 return $blocks; 00168 } 00169 00171 00175 public function Compile($format = null) { 00176 if($format == null) { 00177 $format = $this->GetType(); 00178 } 00179 if($format != FORMAT_C1) { 00180 $format = FORMAT_C2 00181 } 00182 switch($format) { 00183 case FORMAT_C1: 00184 $this->CompileC1(); 00185 case FORMAT_C2: 00186 $this->CompileC2(); 00187 default: 00188 throw new Exception('Non-understood COB format - sorry!'); 00189 } 00190 } 00191 00193 // TODO: implement this. 00194 public function CompileC1() { 00195 throw new Exception('C1 COB Compilation not yet ready.') 00196 } 00198 // TODO: Check accuracy 00199 public function CompileC2() { 00200 $data = 'cob2'; 00201 foreach($this->blocks as $block) { 00202 $data .= $block->Compile(); 00203 } 00204 } 00205 } 00206 ?>