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