1: <?php
2: include_once $GLOBALS['THRIFT_ROOT'].'/transport/TBufferedTransport.php';
3:
4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
14:
15: 16: 17: 18: 19: 20:
21: class TBinaryProtocol extends TProtocol {
22:
23: const VERSION_MASK = 0xffff0000;
24: const VERSION_1 = 0x80010000;
25:
26: protected $strictRead_ = false;
27: protected $strictWrite_ = true;
28:
29: public function __construct($trans, $strictRead=false, $strictWrite=true) {
30: parent::__construct($trans);
31: $this->strictRead_ = $strictRead;
32: $this->strictWrite_ = $strictWrite;
33: }
34:
35: public function writeMessageBegin($name, $type, $seqid) {
36: if ($this->strictWrite_) {
37: $version = self::VERSION_1 | $type;
38: return
39: $this->writeI32($version) +
40: $this->writeString($name) +
41: $this->writeI32($seqid);
42: } else {
43: return
44: $this->writeString($name) +
45: $this->writeByte($type) +
46: $this->writeI32($seqid);
47: }
48: }
49:
50: public function writeMessageEnd() {
51: return 0;
52: }
53:
54: public function writeStructBegin($name) {
55: return 0;
56: }
57:
58: public function writeStructEnd() {
59: return 0;
60: }
61:
62: public function writeFieldBegin($fieldName, $fieldType, $fieldId) {
63: return
64: $this->writeByte($fieldType) +
65: $this->writeI16($fieldId);
66: }
67:
68: public function writeFieldEnd() {
69: return 0;
70: }
71:
72: public function writeFieldStop() {
73: return
74: $this->writeByte(TType::STOP);
75: }
76:
77: public function writeMapBegin($keyType, $valType, $size) {
78: return
79: $this->writeByte($keyType) +
80: $this->writeByte($valType) +
81: $this->writeI32($size);
82: }
83:
84: public function writeMapEnd() {
85: return 0;
86: }
87:
88: public function writeListBegin($elemType, $size) {
89: return
90: $this->writeByte($elemType) +
91: $this->writeI32($size);
92: }
93:
94: public function writeListEnd() {
95: return 0;
96: }
97:
98: public function writeSetBegin($elemType, $size) {
99: return
100: $this->writeByte($elemType) +
101: $this->writeI32($size);
102: }
103:
104: public function writeSetEnd() {
105: return 0;
106: }
107:
108: public function writeBool($value) {
109: $data = pack('c', $value ? 1 : 0);
110: $this->trans_->write($data, 1);
111: return 1;
112: }
113:
114: public function writeByte($value) {
115: $data = pack('c', $value);
116: $this->trans_->write($data, 1);
117: return 1;
118: }
119:
120: public function writeI16($value) {
121: $data = pack('n', $value);
122: $this->trans_->write($data, 2);
123: return 2;
124: }
125:
126: public function writeI32($value) {
127: $data = pack('N', $value);
128: $this->trans_->write($data, 4);
129: return 4;
130: }
131:
132: public function writeI64($value) {
133:
134:
135:
136: if (PHP_INT_SIZE == 4) {
137: $neg = $value < 0;
138:
139: if ($neg) {
140: $value *= -1;
141: }
142:
143: $hi = (int)($value / 4294967296);
144: $lo = (int)$value;
145:
146: if ($neg) {
147: $hi = ~$hi;
148: $lo = ~$lo;
149: if (($lo & (int)0xffffffff) == (int)0xffffffff) {
150: $lo = 0;
151: $hi++;
152: } else {
153: $lo++;
154: }
155: }
156: $data = pack('N2', $hi, $lo);
157:
158: } else {
159: $hi = $value >> 32;
160: $lo = $value & 0xFFFFFFFF;
161: $data = pack('N2', $hi, $lo);
162: }
163:
164: $this->trans_->write($data, 8);
165: return 8;
166: }
167:
168: public function writeDouble($value) {
169: $data = pack('d', $value);
170: $this->trans_->write(strrev($data), 8);
171: return 8;
172: }
173:
174: public function writeString($value) {
175: $len = strlen($value);
176: $result = $this->writeI32($len);
177: if ($len) {
178: $this->trans_->write($value, $len);
179: }
180: return $result + $len;
181: }
182:
183: public function readMessageBegin(&$name, &$type, &$seqid) {
184: $result = $this->readI32($sz);
185: if ($sz < 0) {
186: $version = (int) ($sz & self::VERSION_MASK);
187: if ($version != (int) self::VERSION_1) {
188: throw new TProtocolException('Bad version identifier: '.$sz, TProtocolException::BAD_VERSION);
189: }
190: $type = $sz & 0x000000ff;
191: $result +=
192: $this->readString($name) +
193: $this->readI32($seqid);
194: } else {
195: if ($this->strictRead_) {
196: throw new TProtocolException('No version identifier, old protocol client?', TProtocolException::BAD_VERSION);
197: } else {
198:
199: $name = $this->trans_->readAll($sz);
200: $result +=
201: $sz +
202: $this->readByte($type) +
203: $this->readI32($seqid);
204: }
205: }
206: return $result;
207: }
208:
209: public function readMessageEnd() {
210: return 0;
211: }
212:
213: public function readStructBegin(&$name) {
214: $name = '';
215: return 0;
216: }
217:
218: public function readStructEnd() {
219: return 0;
220: }
221:
222: public function readFieldBegin(&$name, &$fieldType, &$fieldId) {
223: $result = $this->readByte($fieldType);
224: if ($fieldType == TType::STOP) {
225: $fieldId = 0;
226: return $result;
227: }
228: $result += $this->readI16($fieldId);
229: return $result;
230: }
231:
232: public function readFieldEnd() {
233: return 0;
234: }
235:
236: public function readMapBegin(&$keyType, &$valType, &$size) {
237: return
238: $this->readByte($keyType) +
239: $this->readByte($valType) +
240: $this->readI32($size);
241: }
242:
243: public function readMapEnd() {
244: return 0;
245: }
246:
247: public function readListBegin(&$elemType, &$size) {
248: return
249: $this->readByte($elemType) +
250: $this->readI32($size);
251: }
252:
253: public function readListEnd() {
254: return 0;
255: }
256:
257: public function readSetBegin(&$elemType, &$size) {
258: return
259: $this->readByte($elemType) +
260: $this->readI32($size);
261: }
262:
263: public function readSetEnd() {
264: return 0;
265: }
266:
267: public function readBool(&$value) {
268: $data = $this->trans_->readAll(1);
269: $arr = unpack('c', $data);
270: $value = $arr[1] == 1;
271: return 1;
272: }
273:
274: public function readByte(&$value) {
275: $data = $this->trans_->readAll(1);
276: $arr = unpack('c', $data);
277: $value = $arr[1];
278: return 1;
279: }
280:
281: public function readI16(&$value) {
282: $data = $this->trans_->readAll(2);
283: $arr = unpack('n', $data);
284: $value = $arr[1];
285: if ($value > 0x7fff) {
286: $value = 0 - (($value - 1) ^ 0xffff);
287: }
288: return 2;
289: }
290:
291: public function readI32(&$value) {
292: $data = $this->trans_->readAll(4);
293: $arr = unpack('N', $data);
294: $value = $arr[1];
295: if ($value > 0x7fffffff) {
296: $value = 0 - (($value - 1) ^ 0xffffffff);
297: }
298: return 4;
299: }
300:
301: public function readI64(&$value) {
302: $data = $this->trans_->readAll(8);
303:
304: $arr = unpack('N2', $data);
305:
306:
307:
308:
309: if (PHP_INT_SIZE == 4) {
310:
311: $hi = $arr[1];
312: $lo = $arr[2];
313: $isNeg = $hi < 0;
314:
315:
316: if ($isNeg) {
317: $hi = ~$hi & (int)0xffffffff;
318: $lo = ~$lo & (int)0xffffffff;
319:
320: if ($lo == (int)0xffffffff) {
321: $hi++;
322: $lo = 0;
323: } else {
324: $lo++;
325: }
326: }
327:
328:
329:
330:
331: if ($hi & (int)0x80000000) {
332: $hi &= (int)0x7fffffff;
333: $hi += 0x80000000;
334: }
335:
336: if ($lo & (int)0x80000000) {
337: $lo &= (int)0x7fffffff;
338: $lo += 0x80000000;
339: }
340:
341: $value = $hi * 4294967296 + $lo;
342:
343: if ($isNeg) {
344: $value = 0 - $value;
345: }
346: } else {
347:
348:
349: if ($arr[2] & 0x80000000) {
350: $arr[2] = $arr[2] & 0xffffffff;
351: }
352:
353:
354: if ($arr[1] & 0x80000000) {
355: $arr[1] = $arr[1] & 0xffffffff;
356: $arr[1] = $arr[1] ^ 0xffffffff;
357: $arr[2] = $arr[2] ^ 0xffffffff;
358: $value = 0 - $arr[1]*4294967296 - $arr[2] - 1;
359: } else {
360: $value = $arr[1]*4294967296 + $arr[2];
361: }
362: }
363:
364: return 8;
365: }
366:
367: public function readDouble(&$value) {
368: $data = strrev($this->trans_->readAll(8));
369: $arr = unpack('d', $data);
370: $value = $arr[1];
371: return 8;
372: }
373:
374: public function readString(&$value) {
375: $result = $this->readI32($len);
376: if ($len) {
377: $value = $this->trans_->readAll($len);
378: } else {
379: $value = '';
380: }
381: return $result + $len;
382: }
383: }
384:
385: 386: 387:
388: class TBinaryProtocolFactory implements TProtocolFactory {
389: private $strictRead_ = false;
390: private $strictWrite_ = false;
391:
392: public function __construct($strictRead=false, $strictWrite=false) {
393: $this->strictRead_ = $strictRead;
394: $this->strictWrite_ = $strictWrite;
395: }
396:
397: public function getProtocol($trans) {
398: return new TBinaryProtocol($trans, $this->strictRead, $this->strictWrite);
399: }
400: }
401:
402: 403: 404: 405:
406: class TBinaryProtocolAccelerated extends TBinaryProtocol {
407: public function __construct($trans, $strictRead=false, $strictWrite=true) {
408:
409:
410: if (!method_exists($trans, 'putBack')) {
411: $trans = new TBufferedTransport($trans);
412: }
413: parent::__construct($trans, $strictRead, $strictWrite);
414: }
415: public function isStrictRead() {
416: return $this->strictRead_;
417: }
418: public function isStrictWrite() {
419: return $this->strictWrite_;
420: }
421: }
422:
423: ?>
424: