| Mark Slee | 6e53644 | 2006-06-30 18:28:50 +0000 | [diff] [blame] | 1 | <?php | 
| David Reiss | ea2cba8 | 2009-03-30 21:35:00 +0000 | [diff] [blame] | 2 | /* | 
 | 3 |  * Licensed to the Apache Software Foundation (ASF) under one | 
 | 4 |  * or more contributor license agreements. See the NOTICE file | 
 | 5 |  * distributed with this work for additional information | 
 | 6 |  * regarding copyright ownership. The ASF licenses this file | 
 | 7 |  * to you under the Apache License, Version 2.0 (the | 
 | 8 |  * "License"); you may not use this file except in compliance | 
 | 9 |  * with the License. You may obtain a copy of the License at | 
| Mark Slee | 4902c05 | 2007-03-01 00:31:30 +0000 | [diff] [blame] | 10 |  * | 
| David Reiss | ea2cba8 | 2009-03-30 21:35:00 +0000 | [diff] [blame] | 11 |  *   http://www.apache.org/licenses/LICENSE-2.0 | 
 | 12 |  * | 
 | 13 |  * Unless required by applicable law or agreed to in writing, | 
 | 14 |  * software distributed under the License is distributed on an | 
 | 15 |  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | 
 | 16 |  * KIND, either express or implied. See the License for the | 
 | 17 |  * specific language governing permissions and limitations | 
 | 18 |  * under the License. | 
| Mark Slee | 4902c05 | 2007-03-01 00:31:30 +0000 | [diff] [blame] | 19 |  * | 
 | 20 |  * @package thrift | 
| Mark Slee | 4902c05 | 2007-03-01 00:31:30 +0000 | [diff] [blame] | 21 |  */ | 
 | 22 |  | 
| David Reiss | ea2cba8 | 2009-03-30 21:35:00 +0000 | [diff] [blame] | 23 |  | 
| Mark Slee | 4902c05 | 2007-03-01 00:31:30 +0000 | [diff] [blame] | 24 | /** | 
| Mark Slee | 1ecb1b0 | 2007-02-22 01:01:10 +0000 | [diff] [blame] | 25 |  * Data types that can be sent via Thrift | 
| Mark Slee | 99e2b26 | 2006-10-10 01:42:29 +0000 | [diff] [blame] | 26 |  */ | 
| Mark Slee | 1ecb1b0 | 2007-02-22 01:01:10 +0000 | [diff] [blame] | 27 | class TType { | 
 | 28 |   const STOP   = 0; | 
 | 29 |   const VOID   = 1; | 
 | 30 |   const BOOL   = 2; | 
 | 31 |   const BYTE   = 3; | 
 | 32 |   const I08    = 3; | 
 | 33 |   const DOUBLE = 4; | 
 | 34 |   const I16    = 6; | 
 | 35 |   const I32    = 8; | 
 | 36 |   const I64    = 10; | 
 | 37 |   const STRING = 11; | 
 | 38 |   const UTF7   = 11; | 
 | 39 |   const STRUCT = 12; | 
 | 40 |   const MAP    = 13; | 
 | 41 |   const SET    = 14; | 
 | 42 |   const LST    = 15;    // N.B. cannot use LIST keyword in PHP! | 
 | 43 |   const UTF8   = 16; | 
 | 44 |   const UTF16  = 17; | 
| Mark Slee | cfc0193 | 2006-09-01 22:18:16 +0000 | [diff] [blame] | 45 | } | 
| Mark Slee | 1ecb1b0 | 2007-02-22 01:01:10 +0000 | [diff] [blame] | 46 |  | 
 | 47 | /** | 
 | 48 |  * Message types for RPC | 
 | 49 |  */ | 
 | 50 | class TMessageType { | 
 | 51 |   const CALL  = 1; | 
 | 52 |   const REPLY = 2; | 
| Mark Slee | d395d57 | 2007-02-27 01:16:55 +0000 | [diff] [blame] | 53 |   const EXCEPTION = 3; | 
| David Reiss | deda141 | 2009-04-02 19:22:31 +0000 | [diff] [blame] | 54 |   const ONEWAY = 4; | 
| Mark Slee | 1ecb1b0 | 2007-02-22 01:01:10 +0000 | [diff] [blame] | 55 | } | 
| Mark Slee | 6e53644 | 2006-06-30 18:28:50 +0000 | [diff] [blame] | 56 |  | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 57 | /** | 
 | 58 |  * NOTE(mcslee): This currently contains a ton of duplicated code from TBase | 
 | 59 |  * because we need to save CPU cycles and this is not yet in an extension. | 
 | 60 |  * Ideally we'd multiply-inherit TException from both Exception and Base, but | 
 | 61 |  * that's not possible in PHP and there are no modules either, so for now we | 
 | 62 |  * apologetically take a trip to HackTown. | 
 | 63 |  * | 
 | 64 |  * Can be called with standard Exception constructor (message, code) or with | 
 | 65 |  * Thrift Base object constructor (spec, vals). | 
 | 66 |  * | 
 | 67 |  * @param mixed $p1 Message (string) or type-spec (array) | 
 | 68 |  * @param mixed $p2 Code (integer) or values (array) | 
 | 69 |  */ | 
| Mark Slee | dac7856 | 2007-02-21 07:35:03 +0000 | [diff] [blame] | 70 | class TException extends Exception { | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 71 |   function __construct($p1=null, $p2=0) { | 
 | 72 |     if (is_array($p1) && is_array($p2)) { | 
 | 73 |       $spec = $p1; | 
 | 74 |       $vals = $p2; | 
 | 75 |       foreach ($spec as $fid => $fspec) { | 
 | 76 |         $var = $fspec['var']; | 
 | 77 |         if (isset($vals[$var])) { | 
 | 78 |           $this->$var = $vals[$var]; | 
 | 79 |         } | 
 | 80 |       } | 
 | 81 |     } else { | 
 | 82 |       parent::__construct($p1, $p2); | 
 | 83 |     } | 
 | 84 |   } | 
 | 85 |  | 
 | 86 |   static $tmethod = array(TType::BOOL   => 'Bool', | 
 | 87 |                           TType::BYTE   => 'Byte', | 
 | 88 |                           TType::I16    => 'I16', | 
 | 89 |                           TType::I32    => 'I32', | 
 | 90 |                           TType::I64    => 'I64', | 
 | 91 |                           TType::DOUBLE => 'Double', | 
 | 92 |                           TType::STRING => 'String'); | 
 | 93 |  | 
 | 94 |   private function _readMap(&$var, $spec, $input) { | 
 | 95 |     $xfer = 0; | 
 | 96 |     $ktype = $spec['ktype']; | 
 | 97 |     $vtype = $spec['vtype']; | 
 | 98 |     $kread = $vread = null; | 
 | 99 |     if (isset(TBase::$tmethod[$ktype])) { | 
 | 100 |       $kread = 'read'.TBase::$tmethod[$ktype]; | 
 | 101 |     } else { | 
 | 102 |       $kspec = $spec['key']; | 
 | 103 |     } | 
 | 104 |     if (isset(TBase::$tmethod[$vtype])) { | 
 | 105 |       $vread = 'read'.TBase::$tmethod[$vtype]; | 
 | 106 |     } else { | 
 | 107 |       $vspec = $spec['val']; | 
 | 108 |     } | 
 | 109 |     $var = array(); | 
 | 110 |     $_ktype = $_vtype = $size = 0; | 
 | 111 |     $xfer += $input->readMapBegin($_ktype, $_vtype, $size); | 
 | 112 |     for ($i = 0; $i < $size; ++$i) { | 
 | 113 |       $key = $val = null; | 
 | 114 |       if ($kread !== null) { | 
 | 115 |         $xfer += $input->$kread($key); | 
 | 116 |       } else { | 
 | 117 |         switch ($ktype) { | 
 | 118 |         case TType::STRUCT: | 
 | 119 |           $class = $kspec['class']; | 
 | 120 |           $key = new $class(); | 
 | 121 |           $xfer += $key->read($input); | 
 | 122 |           break; | 
 | 123 |         case TType::MAP: | 
 | 124 |           $xfer += $this->_readMap($key, $kspec, $input); | 
 | 125 |           break; | 
 | 126 |         case TType::LST: | 
 | 127 |           $xfer += $this->_readList($key, $kspec, $input, false); | 
 | 128 |           break; | 
 | 129 |         case TType::SET: | 
 | 130 |           $xfer += $this->_readList($key, $kspec, $input, true); | 
 | 131 |           break; | 
 | 132 |         } | 
 | 133 |       } | 
 | 134 |       if ($vread !== null) { | 
 | 135 |         $xfer += $input->$vread($val); | 
 | 136 |       } else { | 
 | 137 |         switch ($vtype) { | 
 | 138 |         case TType::STRUCT: | 
 | 139 |           $class = $vspec['class']; | 
 | 140 |           $val = new $class(); | 
 | 141 |           $xfer += $val->read($input); | 
 | 142 |           break; | 
 | 143 |         case TType::MAP: | 
 | 144 |           $xfer += $this->_readMap($val, $vspec, $input); | 
 | 145 |           break; | 
 | 146 |         case TType::LST: | 
 | 147 |           $xfer += $this->_readList($val, $vspec, $input, false); | 
 | 148 |           break; | 
 | 149 |         case TType::SET: | 
 | 150 |           $xfer += $this->_readList($val, $vspec, $input, true); | 
 | 151 |           break; | 
 | 152 |         } | 
 | 153 |       } | 
 | 154 |       $var[$key] = $val; | 
 | 155 |     } | 
 | 156 |     $xfer += $input->readMapEnd(); | 
 | 157 |     return $xfer; | 
 | 158 |   } | 
 | 159 |  | 
 | 160 |   private function _readList(&$var, $spec, $input, $set=false) { | 
 | 161 |     $xfer = 0; | 
 | 162 |     $etype = $spec['etype']; | 
 | 163 |     $eread = $vread = null; | 
 | 164 |     if (isset(TBase::$tmethod[$etype])) { | 
 | 165 |       $eread = 'read'.TBase::$tmethod[$etype]; | 
 | 166 |     } else { | 
 | 167 |       $espec = $spec['elem']; | 
 | 168 |     } | 
 | 169 |     $var = array(); | 
 | 170 |     $_etype = $size = 0; | 
 | 171 |     if ($set) { | 
 | 172 |       $xfer += $input->readSetBegin($_etype, $size); | 
 | 173 |     } else { | 
 | 174 |       $xfer += $input->readListBegin($_etype, $size); | 
 | 175 |     } | 
 | 176 |     for ($i = 0; $i < $size; ++$i) { | 
 | 177 |       $elem = null; | 
 | 178 |       if ($eread !== null) { | 
 | 179 |         $xfer += $input->$eread($elem); | 
 | 180 |       } else { | 
 | 181 |         $espec = $spec['elem']; | 
 | 182 |         switch ($etype) { | 
 | 183 |         case TType::STRUCT: | 
 | 184 |           $class = $espec['class']; | 
 | 185 |           $elem = new $class(); | 
 | 186 |           $xfer += $elem->read($input); | 
 | 187 |           break; | 
 | 188 |         case TType::MAP: | 
| David Reiss | 465ccc0 | 2007-11-13 21:41:29 +0000 | [diff] [blame] | 189 |           $xfer += $this->_readMap($elem, $espec, $input); | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 190 |           break; | 
 | 191 |         case TType::LST: | 
| David Reiss | 465ccc0 | 2007-11-13 21:41:29 +0000 | [diff] [blame] | 192 |           $xfer += $this->_readList($elem, $espec, $input, false); | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 193 |           break; | 
 | 194 |         case TType::SET: | 
| David Reiss | 465ccc0 | 2007-11-13 21:41:29 +0000 | [diff] [blame] | 195 |           $xfer += $this->_readList($elem, $espec, $input, true); | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 196 |           break; | 
 | 197 |         } | 
 | 198 |       } | 
 | 199 |       if ($set) { | 
 | 200 |         $var[$elem] = true; | 
 | 201 |       } else { | 
 | 202 |         $var []= $elem; | 
 | 203 |       } | 
 | 204 |     } | 
 | 205 |     if ($set) { | 
 | 206 |       $xfer += $input->readSetEnd(); | 
 | 207 |     } else { | 
 | 208 |       $xfer += $input->readListEnd(); | 
 | 209 |     } | 
 | 210 |     return $xfer; | 
 | 211 |   } | 
 | 212 |  | 
 | 213 |   protected function _read($class, $spec, $input) { | 
 | 214 |     $xfer = 0; | 
 | 215 |     $fname = null; | 
 | 216 |     $ftype = 0; | 
 | 217 |     $fid = 0; | 
 | 218 |     $xfer += $input->readStructBegin($fname); | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 219 |     while (true) { | 
 | 220 |       $xfer += $input->readFieldBegin($fname, $ftype, $fid); | 
 | 221 |       if ($ftype == TType::STOP) { | 
 | 222 |         break; | 
 | 223 |       } | 
 | 224 |       if (isset($spec[$fid])) { | 
 | 225 |         $fspec = $spec[$fid]; | 
 | 226 |         $var = $fspec['var']; | 
 | 227 |         if ($ftype == $fspec['type']) { | 
 | 228 |           $xfer = 0; | 
| Mark Slee | 645ecea | 2007-11-28 02:46:24 +0000 | [diff] [blame] | 229 |           if (isset(TBase::$tmethod[$ftype])) { | 
 | 230 |             $func = 'read'.TBase::$tmethod[$ftype]; | 
 | 231 |             $xfer += $input->$func($this->$var); | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 232 |           } else { | 
| Mark Slee | 645ecea | 2007-11-28 02:46:24 +0000 | [diff] [blame] | 233 |             switch ($ftype) { | 
 | 234 |             case TType::STRUCT: | 
 | 235 |               $class = $fspec['class']; | 
 | 236 |               $this->$var = new $class(); | 
 | 237 |               $xfer += $this->$var->read($input); | 
 | 238 |               break; | 
 | 239 |             case TType::MAP: | 
 | 240 |               $xfer += $this->_readMap($this->$var, $fspec, $input); | 
 | 241 |               break; | 
 | 242 |             case TType::LST: | 
 | 243 |               $xfer += $this->_readList($this->$var, $fspec, $input, false); | 
 | 244 |               break; | 
 | 245 |             case TType::SET: | 
 | 246 |               $xfer += $this->_readList($this->$var, $fspec, $input, true); | 
 | 247 |               break; | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 248 |             } | 
 | 249 |           } | 
 | 250 |         } else { | 
 | 251 |           $xfer += $input->skip($ftype); | 
 | 252 |         } | 
 | 253 |       } else { | 
 | 254 |         $xfer += $input->skip($ftype); | 
 | 255 |       } | 
 | 256 |       $xfer += $input->readFieldEnd(); | 
 | 257 |     } | 
 | 258 |     $xfer += $input->readStructEnd(); | 
 | 259 |     return $xfer; | 
 | 260 |   } | 
 | 261 |  | 
 | 262 |   private function _writeMap($var, $spec, $output) { | 
 | 263 |     $xfer = 0; | 
 | 264 |     $ktype = $spec['ktype']; | 
 | 265 |     $vtype = $spec['vtype']; | 
 | 266 |     $kwrite = $vwrite = null; | 
 | 267 |     if (isset(TBase::$tmethod[$ktype])) { | 
 | 268 |       $kwrite = 'write'.TBase::$tmethod[$ktype]; | 
 | 269 |     } else { | 
 | 270 |       $kspec = $spec['key']; | 
 | 271 |     } | 
 | 272 |     if (isset(TBase::$tmethod[$vtype])) { | 
 | 273 |       $vwrite = 'write'.TBase::$tmethod[$vtype]; | 
 | 274 |     } else { | 
 | 275 |       $vspec = $spec['val']; | 
 | 276 |     } | 
 | 277 |     $xfer += $output->writeMapBegin($ktype, $vtype, count($var)); | 
 | 278 |     foreach ($var as $key => $val) { | 
 | 279 |       if (isset($kwrite)) { | 
 | 280 |         $xfer += $output->$kwrite($key); | 
 | 281 |       } else { | 
 | 282 |         switch ($ktype) { | 
 | 283 |         case TType::STRUCT: | 
 | 284 |           $xfer += $key->write($output); | 
 | 285 |           break; | 
 | 286 |         case TType::MAP: | 
 | 287 |           $xfer += $this->_writeMap($key, $kspec, $output); | 
 | 288 |           break; | 
 | 289 |         case TType::LST: | 
 | 290 |           $xfer += $this->_writeList($key, $kspec, $output, false); | 
 | 291 |           break; | 
 | 292 |         case TType::SET: | 
 | 293 |           $xfer += $this->_writeList($key, $kspec, $output, true); | 
 | 294 |           break; | 
 | 295 |         } | 
 | 296 |       } | 
 | 297 |       if (isset($vwrite)) { | 
 | 298 |         $xfer += $output->$vwrite($val); | 
 | 299 |       } else { | 
 | 300 |         switch ($vtype) { | 
 | 301 |         case TType::STRUCT: | 
 | 302 |           $xfer += $val->write($output); | 
 | 303 |           break; | 
 | 304 |         case TType::MAP: | 
 | 305 |           $xfer += $this->_writeMap($val, $vspec, $output); | 
 | 306 |           break; | 
 | 307 |         case TType::LST: | 
 | 308 |           $xfer += $this->_writeList($val, $vspec, $output, false); | 
 | 309 |           break; | 
 | 310 |         case TType::SET: | 
 | 311 |           $xfer += $this->_writeList($val, $vspec, $output, true); | 
 | 312 |           break; | 
 | 313 |         } | 
 | 314 |       } | 
 | 315 |     } | 
 | 316 |     $xfer += $output->writeMapEnd(); | 
 | 317 |     return $xfer; | 
 | 318 |   } | 
 | 319 |  | 
 | 320 |   private function _writeList($var, $spec, $output, $set=false) { | 
 | 321 |     $xfer = 0; | 
 | 322 |     $etype = $spec['etype']; | 
 | 323 |     $ewrite = null; | 
 | 324 |     if (isset(TBase::$tmethod[$etype])) { | 
 | 325 |       $ewrite = 'write'.TBase::$tmethod[$etype]; | 
 | 326 |     } else { | 
 | 327 |       $espec = $spec['elem']; | 
 | 328 |     } | 
 | 329 |     if ($set) { | 
 | 330 |       $xfer += $output->writeSetBegin($etype, count($var)); | 
 | 331 |     } else { | 
 | 332 |       $xfer += $output->writeListBegin($etype, count($var)); | 
 | 333 |     } | 
 | 334 |     foreach ($var as $key => $val) { | 
 | 335 |       $elem = $set ? $key : $val; | 
 | 336 |       if (isset($ewrite)) { | 
 | 337 |         $xfer += $output->$ewrite($elem); | 
 | 338 |       } else { | 
 | 339 |         switch ($etype) { | 
 | 340 |         case TType::STRUCT: | 
 | 341 |           $xfer += $elem->write($output); | 
 | 342 |           break; | 
 | 343 |         case TType::MAP: | 
 | 344 |           $xfer += $this->_writeMap($elem, $espec, $output); | 
 | 345 |           break; | 
 | 346 |         case TType::LST: | 
 | 347 |           $xfer += $this->_writeList($elem, $espec, $output, false); | 
 | 348 |           break; | 
 | 349 |         case TType::SET: | 
 | 350 |           $xfer += $this->_writeList($elem, $espec, $output, true); | 
 | 351 |           break; | 
 | 352 |         } | 
 | 353 |       } | 
 | 354 |     } | 
 | 355 |     if ($set) { | 
 | 356 |       $xfer += $output->writeSetEnd(); | 
 | 357 |     } else { | 
 | 358 |       $xfer += $output->writeListEnd(); | 
 | 359 |     } | 
 | 360 |     return $xfer; | 
 | 361 |   } | 
 | 362 |  | 
 | 363 |   protected function _write($class, $spec, $output) { | 
 | 364 |     $xfer = 0; | 
 | 365 |     $xfer += $output->writeStructBegin($class); | 
 | 366 |     foreach ($spec as $fid => $fspec) { | 
 | 367 |       $var = $fspec['var']; | 
 | 368 |       if ($this->$var !== null) { | 
 | 369 |         $ftype = $fspec['type']; | 
 | 370 |         $xfer += $output->writeFieldBegin($var, $ftype, $fid); | 
 | 371 |         if (isset(TBase::$tmethod[$ftype])) { | 
 | 372 |           $func = 'write'.TBase::$tmethod[$ftype]; | 
| Mark Slee | 2b78622 | 2007-11-13 05:35:34 +0000 | [diff] [blame] | 373 |           $xfer += $output->$func($this->$var); | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 374 |         } else { | 
 | 375 |           switch ($ftype) { | 
 | 376 |           case TType::STRUCT: | 
 | 377 |             $xfer += $this->$var->write($output); | 
 | 378 |             break; | 
 | 379 |           case TType::MAP: | 
 | 380 |             $xfer += $this->_writeMap($this->$var, $fspec, $output); | 
 | 381 |             break; | 
 | 382 |           case TType::LST: | 
 | 383 |             $xfer += $this->_writeList($this->$var, $fspec, $output, false); | 
 | 384 |             break; | 
 | 385 |           case TType::SET: | 
 | 386 |             $xfer += $this->_writeList($this->$var, $fspec, $output, true); | 
 | 387 |             break; | 
 | 388 |           } | 
 | 389 |         } | 
 | 390 |         $xfer += $output->writeFieldEnd(); | 
 | 391 |       } | 
 | 392 |     } | 
 | 393 |     $xfer += $output->writeFieldStop(); | 
 | 394 |     $xfer += $output->writeStructEnd(); | 
 | 395 |     return $xfer; | 
 | 396 |   } | 
 | 397 |  | 
 | 398 | } | 
 | 399 |  | 
 | 400 | /** | 
 | 401 |  * Base class from which other Thrift structs extend. This is so that we can | 
 | 402 |  * cut back on the size of the generated code which is turning out to have a | 
 | 403 |  * nontrivial cost just to load thanks to the wondrously abysmal implementation | 
 | 404 |  * of PHP. Note that code is intentionally duplicated in here to avoid making | 
 | 405 |  * function calls for every field or member of a container.. | 
 | 406 |  */ | 
 | 407 | abstract class TBase { | 
 | 408 |  | 
 | 409 |   static $tmethod = array(TType::BOOL   => 'Bool', | 
 | 410 |                           TType::BYTE   => 'Byte', | 
 | 411 |                           TType::I16    => 'I16', | 
 | 412 |                           TType::I32    => 'I32', | 
 | 413 |                           TType::I64    => 'I64', | 
 | 414 |                           TType::DOUBLE => 'Double', | 
 | 415 |                           TType::STRING => 'String'); | 
 | 416 |  | 
 | 417 |   abstract function read($input); | 
 | 418 |  | 
 | 419 |   abstract function write($output); | 
 | 420 |  | 
 | 421 |   public function __construct($spec=null, $vals=null) { | 
 | 422 |     if (is_array($spec) && is_array($vals)) { | 
 | 423 |       foreach ($spec as $fid => $fspec) { | 
 | 424 |         $var = $fspec['var']; | 
 | 425 |         if (isset($vals[$var])) { | 
 | 426 |           $this->$var = $vals[$var]; | 
 | 427 |         } | 
 | 428 |       } | 
 | 429 |     } | 
 | 430 |   } | 
 | 431 |  | 
 | 432 |   private function _readMap(&$var, $spec, $input) { | 
 | 433 |     $xfer = 0; | 
 | 434 |     $ktype = $spec['ktype']; | 
 | 435 |     $vtype = $spec['vtype']; | 
 | 436 |     $kread = $vread = null; | 
 | 437 |     if (isset(TBase::$tmethod[$ktype])) { | 
 | 438 |       $kread = 'read'.TBase::$tmethod[$ktype]; | 
 | 439 |     } else { | 
 | 440 |       $kspec = $spec['key']; | 
 | 441 |     } | 
 | 442 |     if (isset(TBase::$tmethod[$vtype])) { | 
 | 443 |       $vread = 'read'.TBase::$tmethod[$vtype]; | 
 | 444 |     } else { | 
 | 445 |       $vspec = $spec['val']; | 
 | 446 |     } | 
 | 447 |     $var = array(); | 
 | 448 |     $_ktype = $_vtype = $size = 0; | 
 | 449 |     $xfer += $input->readMapBegin($_ktype, $_vtype, $size); | 
 | 450 |     for ($i = 0; $i < $size; ++$i) { | 
 | 451 |       $key = $val = null; | 
 | 452 |       if ($kread !== null) { | 
 | 453 |         $xfer += $input->$kread($key); | 
 | 454 |       } else { | 
 | 455 |         switch ($ktype) { | 
 | 456 |         case TType::STRUCT: | 
 | 457 |           $class = $kspec['class']; | 
 | 458 |           $key = new $class(); | 
 | 459 |           $xfer += $key->read($input); | 
 | 460 |           break; | 
 | 461 |         case TType::MAP: | 
| David Reiss | bef54c0 | 2007-11-28 20:15:11 +0000 | [diff] [blame] | 462 |           $xfer += $this->_readMap($key, $kspec, $input); | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 463 |           break; | 
 | 464 |         case TType::LST: | 
| David Reiss | bef54c0 | 2007-11-28 20:15:11 +0000 | [diff] [blame] | 465 |           $xfer += $this->_readList($key, $kspec, $input, false); | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 466 |           break; | 
 | 467 |         case TType::SET: | 
| David Reiss | bef54c0 | 2007-11-28 20:15:11 +0000 | [diff] [blame] | 468 |           $xfer += $this->_readList($key, $kspec, $input, true); | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 469 |           break; | 
 | 470 |         } | 
 | 471 |       } | 
 | 472 |       if ($vread !== null) { | 
 | 473 |         $xfer += $input->$vread($val); | 
 | 474 |       } else { | 
 | 475 |         switch ($vtype) { | 
 | 476 |         case TType::STRUCT: | 
 | 477 |           $class = $vspec['class']; | 
 | 478 |           $val = new $class(); | 
 | 479 |           $xfer += $val->read($input); | 
 | 480 |           break; | 
 | 481 |         case TType::MAP: | 
 | 482 |           $xfer += $this->_readMap($val, $vspec, $input); | 
 | 483 |           break; | 
 | 484 |         case TType::LST: | 
 | 485 |           $xfer += $this->_readList($val, $vspec, $input, false); | 
 | 486 |           break; | 
 | 487 |         case TType::SET: | 
 | 488 |           $xfer += $this->_readList($val, $vspec, $input, true); | 
 | 489 |           break; | 
 | 490 |         } | 
 | 491 |       } | 
 | 492 |       $var[$key] = $val; | 
 | 493 |     } | 
 | 494 |     $xfer += $input->readMapEnd(); | 
 | 495 |     return $xfer; | 
 | 496 |   } | 
 | 497 |  | 
 | 498 |   private function _readList(&$var, $spec, $input, $set=false) { | 
 | 499 |     $xfer = 0; | 
 | 500 |     $etype = $spec['etype']; | 
 | 501 |     $eread = $vread = null; | 
 | 502 |     if (isset(TBase::$tmethod[$etype])) { | 
 | 503 |       $eread = 'read'.TBase::$tmethod[$etype]; | 
 | 504 |     } else { | 
 | 505 |       $espec = $spec['elem']; | 
 | 506 |     } | 
 | 507 |     $var = array(); | 
 | 508 |     $_etype = $size = 0; | 
 | 509 |     if ($set) { | 
 | 510 |       $xfer += $input->readSetBegin($_etype, $size); | 
 | 511 |     } else { | 
 | 512 |       $xfer += $input->readListBegin($_etype, $size); | 
 | 513 |     } | 
 | 514 |     for ($i = 0; $i < $size; ++$i) { | 
 | 515 |       $elem = null; | 
 | 516 |       if ($eread !== null) { | 
 | 517 |         $xfer += $input->$eread($elem); | 
 | 518 |       } else { | 
 | 519 |         $espec = $spec['elem']; | 
 | 520 |         switch ($etype) { | 
 | 521 |         case TType::STRUCT: | 
 | 522 |           $class = $espec['class']; | 
 | 523 |           $elem = new $class(); | 
 | 524 |           $xfer += $elem->read($input); | 
 | 525 |           break; | 
 | 526 |         case TType::MAP: | 
| David Reiss | bef54c0 | 2007-11-28 20:15:11 +0000 | [diff] [blame] | 527 |           $xfer += $this->_readMap($elem, $espec, $input); | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 528 |           break; | 
 | 529 |         case TType::LST: | 
| David Reiss | bef54c0 | 2007-11-28 20:15:11 +0000 | [diff] [blame] | 530 |           $xfer += $this->_readList($elem, $espec, $input, false); | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 531 |           break; | 
 | 532 |         case TType::SET: | 
| David Reiss | bef54c0 | 2007-11-28 20:15:11 +0000 | [diff] [blame] | 533 |           $xfer += $this->_readList($elem, $espec, $input, true); | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 534 |           break; | 
 | 535 |         } | 
 | 536 |       } | 
 | 537 |       if ($set) { | 
 | 538 |         $var[$elem] = true; | 
 | 539 |       } else { | 
 | 540 |         $var []= $elem; | 
 | 541 |       } | 
 | 542 |     } | 
 | 543 |     if ($set) { | 
 | 544 |       $xfer += $input->readSetEnd(); | 
 | 545 |     } else { | 
 | 546 |       $xfer += $input->readListEnd(); | 
 | 547 |     } | 
 | 548 |     return $xfer; | 
 | 549 |   } | 
 | 550 |  | 
 | 551 |   protected function _read($class, $spec, $input) { | 
 | 552 |     $xfer = 0; | 
 | 553 |     $fname = null; | 
 | 554 |     $ftype = 0; | 
 | 555 |     $fid = 0; | 
 | 556 |     $xfer += $input->readStructBegin($fname); | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 557 |     while (true) { | 
 | 558 |       $xfer += $input->readFieldBegin($fname, $ftype, $fid); | 
 | 559 |       if ($ftype == TType::STOP) { | 
 | 560 |         break; | 
 | 561 |       } | 
 | 562 |       if (isset($spec[$fid])) { | 
 | 563 |         $fspec = $spec[$fid]; | 
 | 564 |         $var = $fspec['var']; | 
 | 565 |         if ($ftype == $fspec['type']) { | 
 | 566 |           $xfer = 0; | 
| Mark Slee | 645ecea | 2007-11-28 02:46:24 +0000 | [diff] [blame] | 567 |           if (isset(TBase::$tmethod[$ftype])) { | 
 | 568 |             $func = 'read'.TBase::$tmethod[$ftype]; | 
 | 569 |             $xfer += $input->$func($this->$var); | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 570 |           } else { | 
| Mark Slee | 645ecea | 2007-11-28 02:46:24 +0000 | [diff] [blame] | 571 |             switch ($ftype) { | 
 | 572 |             case TType::STRUCT: | 
 | 573 |               $class = $fspec['class']; | 
 | 574 |               $this->$var = new $class(); | 
 | 575 |               $xfer += $this->$var->read($input); | 
 | 576 |               break; | 
 | 577 |             case TType::MAP: | 
 | 578 |               $xfer += $this->_readMap($this->$var, $fspec, $input); | 
 | 579 |               break; | 
 | 580 |             case TType::LST: | 
 | 581 |               $xfer += $this->_readList($this->$var, $fspec, $input, false); | 
 | 582 |               break; | 
 | 583 |             case TType::SET: | 
 | 584 |               $xfer += $this->_readList($this->$var, $fspec, $input, true); | 
 | 585 |               break; | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 586 |             } | 
 | 587 |           } | 
 | 588 |         } else { | 
 | 589 |           $xfer += $input->skip($ftype); | 
 | 590 |         } | 
 | 591 |       } else { | 
 | 592 |         $xfer += $input->skip($ftype); | 
 | 593 |       } | 
 | 594 |       $xfer += $input->readFieldEnd(); | 
 | 595 |     } | 
 | 596 |     $xfer += $input->readStructEnd(); | 
 | 597 |     return $xfer; | 
 | 598 |   } | 
 | 599 |  | 
 | 600 |   private function _writeMap($var, $spec, $output) { | 
 | 601 |     $xfer = 0; | 
 | 602 |     $ktype = $spec['ktype']; | 
 | 603 |     $vtype = $spec['vtype']; | 
 | 604 |     $kwrite = $vwrite = null; | 
 | 605 |     if (isset(TBase::$tmethod[$ktype])) { | 
 | 606 |       $kwrite = 'write'.TBase::$tmethod[$ktype]; | 
 | 607 |     } else { | 
 | 608 |       $kspec = $spec['key']; | 
 | 609 |     } | 
 | 610 |     if (isset(TBase::$tmethod[$vtype])) { | 
 | 611 |       $vwrite = 'write'.TBase::$tmethod[$vtype]; | 
 | 612 |     } else { | 
 | 613 |       $vspec = $spec['val']; | 
 | 614 |     } | 
 | 615 |     $xfer += $output->writeMapBegin($ktype, $vtype, count($var)); | 
 | 616 |     foreach ($var as $key => $val) { | 
 | 617 |       if (isset($kwrite)) { | 
 | 618 |         $xfer += $output->$kwrite($key); | 
 | 619 |       } else { | 
 | 620 |         switch ($ktype) { | 
 | 621 |         case TType::STRUCT: | 
 | 622 |           $xfer += $key->write($output); | 
 | 623 |           break; | 
 | 624 |         case TType::MAP: | 
 | 625 |           $xfer += $this->_writeMap($key, $kspec, $output); | 
 | 626 |           break; | 
 | 627 |         case TType::LST: | 
 | 628 |           $xfer += $this->_writeList($key, $kspec, $output, false); | 
 | 629 |           break; | 
 | 630 |         case TType::SET: | 
 | 631 |           $xfer += $this->_writeList($key, $kspec, $output, true); | 
 | 632 |           break; | 
 | 633 |         } | 
 | 634 |       } | 
 | 635 |       if (isset($vwrite)) { | 
 | 636 |         $xfer += $output->$vwrite($val); | 
 | 637 |       } else { | 
 | 638 |         switch ($vtype) { | 
 | 639 |         case TType::STRUCT: | 
 | 640 |           $xfer += $val->write($output); | 
 | 641 |           break; | 
 | 642 |         case TType::MAP: | 
 | 643 |           $xfer += $this->_writeMap($val, $vspec, $output); | 
 | 644 |           break; | 
 | 645 |         case TType::LST: | 
 | 646 |           $xfer += $this->_writeList($val, $vspec, $output, false); | 
 | 647 |           break; | 
 | 648 |         case TType::SET: | 
 | 649 |           $xfer += $this->_writeList($val, $vspec, $output, true); | 
 | 650 |           break; | 
 | 651 |         } | 
 | 652 |       } | 
 | 653 |     } | 
 | 654 |     $xfer += $output->writeMapEnd(); | 
 | 655 |     return $xfer; | 
 | 656 |   } | 
 | 657 |  | 
 | 658 |   private function _writeList($var, $spec, $output, $set=false) { | 
 | 659 |     $xfer = 0; | 
 | 660 |     $etype = $spec['etype']; | 
 | 661 |     $ewrite = null; | 
 | 662 |     if (isset(TBase::$tmethod[$etype])) { | 
 | 663 |       $ewrite = 'write'.TBase::$tmethod[$etype]; | 
 | 664 |     } else { | 
 | 665 |       $espec = $spec['elem']; | 
 | 666 |     } | 
 | 667 |     if ($set) { | 
 | 668 |       $xfer += $output->writeSetBegin($etype, count($var)); | 
 | 669 |     } else { | 
 | 670 |       $xfer += $output->writeListBegin($etype, count($var)); | 
 | 671 |     } | 
 | 672 |     foreach ($var as $key => $val) { | 
 | 673 |       $elem = $set ? $key : $val; | 
 | 674 |       if (isset($ewrite)) { | 
 | 675 |         $xfer += $output->$ewrite($elem); | 
 | 676 |       } else { | 
 | 677 |         switch ($etype) { | 
 | 678 |         case TType::STRUCT: | 
 | 679 |           $xfer += $elem->write($output); | 
 | 680 |           break; | 
 | 681 |         case TType::MAP: | 
 | 682 |           $xfer += $this->_writeMap($elem, $espec, $output); | 
 | 683 |           break; | 
 | 684 |         case TType::LST: | 
 | 685 |           $xfer += $this->_writeList($elem, $espec, $output, false); | 
 | 686 |           break; | 
 | 687 |         case TType::SET: | 
 | 688 |           $xfer += $this->_writeList($elem, $espec, $output, true); | 
 | 689 |           break; | 
 | 690 |         } | 
 | 691 |       } | 
 | 692 |     } | 
 | 693 |     if ($set) { | 
 | 694 |       $xfer += $output->writeSetEnd(); | 
 | 695 |     } else { | 
 | 696 |       $xfer += $output->writeListEnd(); | 
 | 697 |     } | 
 | 698 |     return $xfer; | 
 | 699 |   } | 
 | 700 |  | 
 | 701 |   protected function _write($class, $spec, $output) { | 
 | 702 |     $xfer = 0; | 
 | 703 |     $xfer += $output->writeStructBegin($class); | 
 | 704 |     foreach ($spec as $fid => $fspec) { | 
 | 705 |       $var = $fspec['var']; | 
 | 706 |       if ($this->$var !== null) { | 
 | 707 |         $ftype = $fspec['type']; | 
 | 708 |         $xfer += $output->writeFieldBegin($var, $ftype, $fid); | 
 | 709 |         if (isset(TBase::$tmethod[$ftype])) { | 
 | 710 |           $func = 'write'.TBase::$tmethod[$ftype]; | 
| Mark Slee | 2b78622 | 2007-11-13 05:35:34 +0000 | [diff] [blame] | 711 |           $xfer += $output->$func($this->$var); | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 712 |         } else { | 
 | 713 |           switch ($ftype) { | 
 | 714 |           case TType::STRUCT: | 
 | 715 |             $xfer += $this->$var->write($output); | 
 | 716 |             break; | 
 | 717 |           case TType::MAP: | 
 | 718 |             $xfer += $this->_writeMap($this->$var, $fspec, $output); | 
 | 719 |             break; | 
 | 720 |           case TType::LST: | 
 | 721 |             $xfer += $this->_writeList($this->$var, $fspec, $output, false); | 
 | 722 |             break; | 
 | 723 |           case TType::SET: | 
 | 724 |             $xfer += $this->_writeList($this->$var, $fspec, $output, true); | 
 | 725 |             break; | 
 | 726 |           } | 
 | 727 |         } | 
 | 728 |         $xfer += $output->writeFieldEnd(); | 
 | 729 |       } | 
 | 730 |     } | 
 | 731 |     $xfer += $output->writeFieldStop(); | 
 | 732 |     $xfer += $output->writeStructEnd(); | 
 | 733 |     return $xfer; | 
| Mark Slee | dac7856 | 2007-02-21 07:35:03 +0000 | [diff] [blame] | 734 |   } | 
 | 735 | } | 
 | 736 |  | 
 | 737 | class TApplicationException extends TException { | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 738 |   static $_TSPEC = | 
 | 739 |     array(1 => array('var' => 'message', | 
 | 740 |                      'type' => TType::STRING), | 
 | 741 |           2 => array('var' => 'code', | 
 | 742 |                      'type' => TType::I32)); | 
 | 743 |  | 
| Mark Slee | dac7856 | 2007-02-21 07:35:03 +0000 | [diff] [blame] | 744 |   const UNKNOWN = 0; | 
 | 745 |   const UNKNOWN_METHOD = 1; | 
 | 746 |   const INVALID_MESSAGE_TYPE = 2; | 
 | 747 |   const WRONG_METHOD_NAME = 3; | 
 | 748 |   const BAD_SEQUENCE_ID = 4; | 
 | 749 |   const MISSING_RESULT = 5; | 
| Bryan Duxbury | d26cb9b | 2011-04-11 17:59:27 +0000 | [diff] [blame] | 750 |   const INTERNAL_ERROR = 6; | 
 | 751 |   const PROTOCOL_ERROR = 7; | 
| Mark Slee | dac7856 | 2007-02-21 07:35:03 +0000 | [diff] [blame] | 752 |  | 
 | 753 |   function __construct($message=null, $code=0) { | 
 | 754 |     parent::__construct($message, $code); | 
 | 755 |   } | 
 | 756 |  | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 757 |   public function read($output) { | 
 | 758 |     return $this->_read('TApplicationException', self::$_TSPEC, $output); | 
| Mark Slee | dac7856 | 2007-02-21 07:35:03 +0000 | [diff] [blame] | 759 |   } | 
 | 760 |  | 
 | 761 |   public function write($output) { | 
 | 762 |     $xfer = 0; | 
 | 763 |     $xfer += $output->writeStructBegin('TApplicationException'); | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 764 |     if ($message = $this->getMessage()) { | 
| Mark Slee | dac7856 | 2007-02-21 07:35:03 +0000 | [diff] [blame] | 765 |       $xfer += $output->writeFieldBegin('message', TType::STRING, 1); | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 766 |       $xfer += $output->writeString($message); | 
| Mark Slee | dac7856 | 2007-02-21 07:35:03 +0000 | [diff] [blame] | 767 |       $xfer += $output->writeFieldEnd(); | 
 | 768 |     } | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 769 |     if ($code = $this->getCode()) { | 
| Mark Slee | dac7856 | 2007-02-21 07:35:03 +0000 | [diff] [blame] | 770 |       $xfer += $output->writeFieldBegin('type', TType::I32, 2); | 
| Mark Slee | 5b74307 | 2007-11-13 04:00:29 +0000 | [diff] [blame] | 771 |       $xfer += $output->writeI32($code); | 
| Mark Slee | dac7856 | 2007-02-21 07:35:03 +0000 | [diff] [blame] | 772 |       $xfer += $output->writeFieldEnd(); | 
 | 773 |     } | 
 | 774 |     $xfer += $output->writeFieldStop(); | 
 | 775 |     $xfer += $output->writeStructEnd(); | 
 | 776 |     return $xfer; | 
 | 777 |   } | 
 | 778 | } | 
 | 779 |  | 
| Mark Slee | 1ecb1b0 | 2007-02-22 01:01:10 +0000 | [diff] [blame] | 780 | /** | 
 | 781 |  * Set global THRIFT ROOT automatically via inclusion here | 
 | 782 |  */ | 
 | 783 | if (!isset($GLOBALS['THRIFT_ROOT'])) { | 
 | 784 |   $GLOBALS['THRIFT_ROOT'] = dirname(__FILE__); | 
 | 785 | } | 
 | 786 | include_once $GLOBALS['THRIFT_ROOT'].'/protocol/TProtocol.php'; | 
 | 787 | include_once $GLOBALS['THRIFT_ROOT'].'/transport/TTransport.php'; |