1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
22:
23:
24: 25: 26:
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;
43: const UTF8 = 16;
44: const UTF16 = 17;
45: }
46:
47: 48: 49:
50: class TMessageType {
51: const CALL = 1;
52: const REPLY = 2;
53: const EXCEPTION = 3;
54: const ONEWAY = 4;
55: }
56:
57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69:
70: class TException extends Exception {
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:
189: $xfer += $this->_readMap($elem, $espec, $input);
190: break;
191: case TType::LST:
192: $xfer += $this->_readList($elem, $espec, $input, false);
193: break;
194: case TType::SET:
195: $xfer += $this->_readList($elem, $espec, $input, true);
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);
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;
229: if (isset(TBase::$tmethod[$ftype])) {
230: $func = 'read'.TBase::$tmethod[$ftype];
231: $xfer += $input->$func($this->$var);
232: } else {
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;
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];
373: $xfer += $output->$func($this->$var);
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: 402: 403: 404: 405: 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:
462: $xfer += $this->_readMap($key, $kspec, $input);
463: break;
464: case TType::LST:
465: $xfer += $this->_readList($key, $kspec, $input, false);
466: break;
467: case TType::SET:
468: $xfer += $this->_readList($key, $kspec, $input, true);
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:
527: $xfer += $this->_readMap($elem, $espec, $input);
528: break;
529: case TType::LST:
530: $xfer += $this->_readList($elem, $espec, $input, false);
531: break;
532: case TType::SET:
533: $xfer += $this->_readList($elem, $espec, $input, true);
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);
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;
567: if (isset(TBase::$tmethod[$ftype])) {
568: $func = 'read'.TBase::$tmethod[$ftype];
569: $xfer += $input->$func($this->$var);
570: } else {
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;
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];
711: $xfer += $output->$func($this->$var);
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;
734: }
735: }
736:
737: class TApplicationException extends TException {
738: static $_TSPEC =
739: array(1 => array('var' => 'message',
740: 'type' => TType::STRING),
741: 2 => array('var' => 'code',
742: 'type' => TType::I32));
743:
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;
750: const INTERNAL_ERROR = 6;
751: const PROTOCOL_ERROR = 7;
752:
753: function __construct($message=null, $code=0) {
754: parent::__construct($message, $code);
755: }
756:
757: public function read($output) {
758: return $this->_read('TApplicationException', self::$_TSPEC, $output);
759: }
760:
761: public function write($output) {
762: $xfer = 0;
763: $xfer += $output->writeStructBegin('TApplicationException');
764: if ($message = $this->getMessage()) {
765: $xfer += $output->writeFieldBegin('message', TType::STRING, 1);
766: $xfer += $output->writeString($message);
767: $xfer += $output->writeFieldEnd();
768: }
769: if ($code = $this->getCode()) {
770: $xfer += $output->writeFieldBegin('type', TType::I32, 2);
771: $xfer += $output->writeI32($code);
772: $xfer += $output->writeFieldEnd();
773: }
774: $xfer += $output->writeFieldStop();
775: $xfer += $output->writeStructEnd();
776: return $xfer;
777: }
778: }
779:
780: 781: 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';
788: