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