blob: cfd3c8b2b53598e737e283920d87ab48721efead [file] [log] [blame]
Roger Meier21c0a852012-09-05 19:47:14 +00001<?php
2
3/*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 *
21 * @package thrift.protocol
22 */
23
24namespace Thrift\Protocol;
25
Volodymyr Panivko68139d12024-03-19 23:14:07 +010026use Thrift\Exception\TException;
Roger Meier21c0a852012-09-05 19:47:14 +000027use Thrift\Type\TType;
28use Thrift\Exception\TProtocolException;
29use Thrift\Protocol\JSON\BaseContext;
30use Thrift\Protocol\JSON\LookaheadReader;
31use Thrift\Protocol\JSON\PairContext;
32use Thrift\Protocol\JSON\ListContext;
33
34/**
35 * JSON implementation of thrift protocol, ported from Java.
36 */
37class TJSONProtocol extends TProtocol
38{
39 const COMMA = ',';
40 const COLON = ':';
41 const LBRACE = '{';
42 const RBRACE = '}';
43 const LBRACKET = '[';
44 const RBRACKET = ']';
45 const QUOTE = '"';
46 const BACKSLASH = '\\';
47 const ZERO = '0';
48 const ESCSEQ = '\\';
49 const DOUBLEESC = '__DOUBLE_ESCAPE_SEQUENCE__';
50
51 const VERSION = 1;
52
53 public static $JSON_CHAR_TABLE = array(
54 /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
55 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, // 0
56 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1
57 1, 1, '"', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2
58 );
59
Jens Geyer79759502013-12-26 18:56:54 +010060 public static $ESCAPE_CHARS = array('"', '\\', '/', "b", "f", "n", "r", "t");
Roger Meier21c0a852012-09-05 19:47:14 +000061
62 public static $ESCAPE_CHAR_VALS = array(
Jens Geyer79759502013-12-26 18:56:54 +010063 '"', '\\', '/', "\x08", "\f", "\n", "\r", "\t",
Roger Meier21c0a852012-09-05 19:47:14 +000064 );
65
66 const NAME_BOOL = "tf";
67 const NAME_BYTE = "i8";
68 const NAME_I16 = "i16";
69 const NAME_I32 = "i32";
70 const NAME_I64 = "i64";
71 const NAME_DOUBLE = "dbl";
72 const NAME_STRUCT = "rec";
73 const NAME_STRING = "str";
74 const NAME_MAP = "map";
75 const NAME_LIST = "lst";
76 const NAME_SET = "set";
77
78 private function getTypeNameForTypeID($typeID)
79 {
80 switch ($typeID) {
81 case TType::BOOL:
82 return self::NAME_BOOL;
83 case TType::BYTE:
84 return self::NAME_BYTE;
85 case TType::I16:
86 return self::NAME_I16;
87 case TType::I32:
88 return self::NAME_I32;
89 case TType::I64:
90 return self::NAME_I64;
91 case TType::DOUBLE:
92 return self::NAME_DOUBLE;
93 case TType::STRING:
94 return self::NAME_STRING;
95 case TType::STRUCT:
96 return self::NAME_STRUCT;
97 case TType::MAP:
98 return self::NAME_MAP;
99 case TType::SET:
100 return self::NAME_SET;
101 case TType::LST:
102 return self::NAME_LIST;
103 default:
104 throw new TProtocolException("Unrecognized type", TProtocolException::UNKNOWN);
105 }
106 }
107
108 private function getTypeIDForTypeName($name)
109 {
110 $result = TType::STOP;
111
Pavel Kvach82383642024-01-14 15:53:17 +0200112 if (strlen((string) $name) > 1) {
Roger Meier21c0a852012-09-05 19:47:14 +0000113 switch (substr($name, 0, 1)) {
114 case 'd':
115 $result = TType::DOUBLE;
116 break;
117 case 'i':
118 switch (substr($name, 1, 1)) {
119 case '8':
120 $result = TType::BYTE;
121 break;
122 case '1':
123 $result = TType::I16;
124 break;
125 case '3':
126 $result = TType::I32;
127 break;
128 case '6':
129 $result = TType::I64;
130 break;
131 }
132 break;
133 case 'l':
134 $result = TType::LST;
135 break;
136 case 'm':
137 $result = TType::MAP;
138 break;
139 case 'r':
140 $result = TType::STRUCT;
141 break;
142 case 's':
143 if (substr($name, 1, 1) == 't') {
144 $result = TType::STRING;
Roger Thomas6fb59232014-11-04 10:09:23 +0000145 } elseif (substr($name, 1, 1) == 'e') {
Roger Meier21c0a852012-09-05 19:47:14 +0000146 $result = TType::SET;
147 }
148 break;
149 case 't':
150 $result = TType::BOOL;
151 break;
152 }
153 }
154 if ($result == TType::STOP) {
155 throw new TProtocolException("Unrecognized type", TProtocolException::INVALID_DATA);
156 }
Roger Thomas6fb59232014-11-04 10:09:23 +0000157
Roger Meier21c0a852012-09-05 19:47:14 +0000158 return $result;
159 }
160
161 public $contextStack_ = array();
162 public $context_;
163 public $reader_;
164
Roger Thomas6fb59232014-11-04 10:09:23 +0000165 private function pushContext($c)
166 {
Roger Meier21c0a852012-09-05 19:47:14 +0000167 array_push($this->contextStack_, $this->context_);
168 $this->context_ = $c;
169 }
170
Roger Thomas6fb59232014-11-04 10:09:23 +0000171 private function popContext()
172 {
Roger Meier21c0a852012-09-05 19:47:14 +0000173 $this->context_ = array_pop($this->contextStack_);
174 }
175
Roger Thomas6fb59232014-11-04 10:09:23 +0000176 public function __construct($trans)
177 {
Roger Meier21c0a852012-09-05 19:47:14 +0000178 parent::__construct($trans);
179 $this->context_ = new BaseContext();
180 $this->reader_ = new LookaheadReader($this);
181 }
182
Roger Thomas6fb59232014-11-04 10:09:23 +0000183 public function reset()
184 {
Roger Meier21c0a852012-09-05 19:47:14 +0000185 $this->contextStack_ = array();
186 $this->context_ = new BaseContext();
187 $this->reader_ = new LookaheadReader($this);
188 }
189
Roger Thomas6fb59232014-11-04 10:09:23 +0000190 public function readJSONSyntaxChar($b)
191 {
Roger Meier21c0a852012-09-05 19:47:14 +0000192 $ch = $this->reader_->read();
193
194 if (substr($ch, 0, 1) != $b) {
195 throw new TProtocolException("Unexpected character: " . $ch, TProtocolException::INVALID_DATA);
196 }
197 }
198
Roger Thomas6fb59232014-11-04 10:09:23 +0000199 private function writeJSONString($b)
200 {
Roger Meier21c0a852012-09-05 19:47:14 +0000201 $this->context_->write();
202
203 if (is_numeric($b) && $this->context_->escapeNum()) {
204 $this->trans_->write(self::QUOTE);
205 }
206
Volodymyr Panivko68139d12024-03-19 23:14:07 +0100207 $this->trans_->write(json_encode($b, JSON_UNESCAPED_UNICODE));
Roger Meier21c0a852012-09-05 19:47:14 +0000208
209 if (is_numeric($b) && $this->context_->escapeNum()) {
210 $this->trans_->write(self::QUOTE);
211 }
212 }
213
Roger Thomas6fb59232014-11-04 10:09:23 +0000214 private function writeJSONInteger($num)
215 {
Roger Meier21c0a852012-09-05 19:47:14 +0000216 $this->context_->write();
217
218 if ($this->context_->escapeNum()) {
219 $this->trans_->write(self::QUOTE);
220 }
221
222 $this->trans_->write($num);
223
224 if ($this->context_->escapeNum()) {
225 $this->trans_->write(self::QUOTE);
226 }
227 }
228
Roger Thomas6fb59232014-11-04 10:09:23 +0000229 private function writeJSONDouble($num)
230 {
Roger Meier21c0a852012-09-05 19:47:14 +0000231 $this->context_->write();
232
233 if ($this->context_->escapeNum()) {
234 $this->trans_->write(self::QUOTE);
235 }
236
Volodymyr Panivko68139d12024-03-19 23:14:07 +0100237 #TODO add compatibility with NAN and INF
Roger Meier21c0a852012-09-05 19:47:14 +0000238 $this->trans_->write(json_encode($num));
239
240 if ($this->context_->escapeNum()) {
241 $this->trans_->write(self::QUOTE);
242 }
243 }
244
Roger Thomas6fb59232014-11-04 10:09:23 +0000245 private function writeJSONObjectStart()
246 {
Robert Lub03ca012018-01-18 19:06:39 +0800247 $this->context_->write();
248 $this->trans_->write(self::LBRACE);
249 $this->pushContext(new PairContext($this));
Roger Meier21c0a852012-09-05 19:47:14 +0000250 }
251
Roger Thomas6fb59232014-11-04 10:09:23 +0000252 private function writeJSONObjectEnd()
253 {
Robert Lub03ca012018-01-18 19:06:39 +0800254 $this->popContext();
255 $this->trans_->write(self::RBRACE);
Roger Meier21c0a852012-09-05 19:47:14 +0000256 }
257
Roger Thomas6fb59232014-11-04 10:09:23 +0000258 private function writeJSONArrayStart()
259 {
Robert Lub03ca012018-01-18 19:06:39 +0800260 $this->context_->write();
261 $this->trans_->write(self::LBRACKET);
262 $this->pushContext(new ListContext($this));
Roger Meier21c0a852012-09-05 19:47:14 +0000263 }
264
Roger Thomas6fb59232014-11-04 10:09:23 +0000265 private function writeJSONArrayEnd()
266 {
Robert Lub03ca012018-01-18 19:06:39 +0800267 $this->popContext();
268 $this->trans_->write(self::RBRACKET);
Roger Meier21c0a852012-09-05 19:47:14 +0000269 }
270
Roger Thomas6fb59232014-11-04 10:09:23 +0000271 private function readJSONString($skipContext)
272 {
Robert Lub03ca012018-01-18 19:06:39 +0800273 if (!$skipContext) {
274 $this->context_->read();
Roger Meier21c0a852012-09-05 19:47:14 +0000275 }
Roger Thomas6fb59232014-11-04 10:09:23 +0000276
Robert Lub03ca012018-01-18 19:06:39 +0800277 $jsonString = '';
278 $lastChar = null;
279 while (true) {
280 $ch = $this->reader_->read();
281 $jsonString .= $ch;
282 if ($ch == self::QUOTE &&
283 $lastChar !== null &&
284 $lastChar !== self::ESCSEQ) {
285 break;
286 }
287 if ($ch == self::ESCSEQ && $lastChar == self::ESCSEQ) {
288 $lastChar = self::DOUBLEESC;
289 } else {
290 $lastChar = $ch;
291 }
292 }
293
294 return json_decode($jsonString);
Roger Meier21c0a852012-09-05 19:47:14 +0000295 }
296
Roger Thomas6fb59232014-11-04 10:09:23 +0000297 private function isJSONNumeric($b)
298 {
Roger Meier21c0a852012-09-05 19:47:14 +0000299 switch ($b) {
300 case '+':
301 case '-':
302 case '.':
303 case '0':
304 case '1':
305 case '2':
306 case '3':
307 case '4':
308 case '5':
309 case '6':
310 case '7':
311 case '8':
312 case '9':
313 case 'E':
314 case 'e':
Robert Lub03ca012018-01-18 19:06:39 +0800315 return true;
316 }
Roger Thomas6fb59232014-11-04 10:09:23 +0000317
Roger Meier21c0a852012-09-05 19:47:14 +0000318 return false;
319 }
320
Roger Thomas6fb59232014-11-04 10:09:23 +0000321 private function readJSONNumericChars()
322 {
Roger Meier21c0a852012-09-05 19:47:14 +0000323 $strbld = array();
324
325 while (true) {
326 $ch = $this->reader_->peek();
327
328 if (!$this->isJSONNumeric($ch)) {
329 break;
330 }
331
332 $strbld[] = $this->reader_->read();
333 }
334
335 return implode("", $strbld);
336 }
337
Roger Thomas6fb59232014-11-04 10:09:23 +0000338 private function readJSONInteger()
339 {
Roger Meier21c0a852012-09-05 19:47:14 +0000340 $this->context_->read();
341
342 if ($this->context_->escapeNum()) {
343 $this->readJSONSyntaxChar(self::QUOTE);
344 }
345
346 $str = $this->readJSONNumericChars();
347
348 if ($this->context_->escapeNum()) {
349 $this->readJSONSyntaxChar(self::QUOTE);
350 }
351
352 if (!is_numeric($str)) {
353 throw new TProtocolException("Invalid data in numeric: " . $str, TProtocolException::INVALID_DATA);
354 }
355
356 return intval($str);
357 }
358
359 /**
360 * Identical to readJSONInteger but without the final cast.
361 * Needed for proper handling of i64 on 32 bit machines. Why a
362 * separate function? So we don't have to force the rest of the
363 * use cases through the extra conditional.
364 */
Roger Thomas6fb59232014-11-04 10:09:23 +0000365 private function readJSONIntegerAsString()
366 {
Roger Meier21c0a852012-09-05 19:47:14 +0000367 $this->context_->read();
368
369 if ($this->context_->escapeNum()) {
370 $this->readJSONSyntaxChar(self::QUOTE);
371 }
372
373 $str = $this->readJSONNumericChars();
374
375 if ($this->context_->escapeNum()) {
376 $this->readJSONSyntaxChar(self::QUOTE);
377 }
378
379 if (!is_numeric($str)) {
380 throw new TProtocolException("Invalid data in numeric: " . $str, TProtocolException::INVALID_DATA);
381 }
382
383 return $str;
384 }
385
Roger Thomas6fb59232014-11-04 10:09:23 +0000386 private function readJSONDouble()
387 {
Roger Meier21c0a852012-09-05 19:47:14 +0000388 $this->context_->read();
389
390 if (substr($this->reader_->peek(), 0, 1) == self::QUOTE) {
391 $arr = $this->readJSONString(true);
392
393 if ($arr == "NaN") {
394 return NAN;
Roger Thomas6fb59232014-11-04 10:09:23 +0000395 } elseif ($arr == "Infinity") {
Roger Meier21c0a852012-09-05 19:47:14 +0000396 return INF;
Roger Thomas6fb59232014-11-04 10:09:23 +0000397 } elseif (!$this->context_->escapeNum()) {
Robert Lub03ca012018-01-18 19:06:39 +0800398 throw new TProtocolException(
399 "Numeric data unexpectedly quoted " . $arr,
400 TProtocolException::INVALID_DATA
401 );
Roger Meier21c0a852012-09-05 19:47:14 +0000402 }
403
404 return floatval($arr);
405 } else {
406 if ($this->context_->escapeNum()) {
407 $this->readJSONSyntaxChar(self::QUOTE);
408 }
409
410 return floatval($this->readJSONNumericChars());
411 }
412 }
413
Roger Thomas6fb59232014-11-04 10:09:23 +0000414 private function readJSONObjectStart()
415 {
Roger Meier21c0a852012-09-05 19:47:14 +0000416 $this->context_->read();
417 $this->readJSONSyntaxChar(self::LBRACE);
418 $this->pushContext(new PairContext($this));
419 }
420
Roger Thomas6fb59232014-11-04 10:09:23 +0000421 private function readJSONObjectEnd()
422 {
Roger Meier21c0a852012-09-05 19:47:14 +0000423 $this->readJSONSyntaxChar(self::RBRACE);
424 $this->popContext();
425 }
426
427 private function readJSONArrayStart()
428 {
429 $this->context_->read();
430 $this->readJSONSyntaxChar(self::LBRACKET);
431 $this->pushContext(new ListContext($this));
432 }
433
Roger Thomas6fb59232014-11-04 10:09:23 +0000434 private function readJSONArrayEnd()
435 {
Roger Meier21c0a852012-09-05 19:47:14 +0000436 $this->readJSONSyntaxChar(self::RBRACKET);
437 $this->popContext();
438 }
439
440 /**
441 * Writes the message header
442 *
Robert Lub03ca012018-01-18 19:06:39 +0800443 * @param string $name Function name
444 * @param int $type message type TMessageType::CALL or TMessageType::REPLY
445 * @param int $seqid The sequence id of this message
Roger Meier21c0a852012-09-05 19:47:14 +0000446 */
Roger Thomas6fb59232014-11-04 10:09:23 +0000447 public function writeMessageBegin($name, $type, $seqid)
448 {
Roger Meier21c0a852012-09-05 19:47:14 +0000449 $this->writeJSONArrayStart();
450 $this->writeJSONInteger(self::VERSION);
451 $this->writeJSONString($name);
452 $this->writeJSONInteger($type);
453 $this->writeJSONInteger($seqid);
454 }
455
456 /**
457 * Close the message
458 */
Roger Thomas6fb59232014-11-04 10:09:23 +0000459 public function writeMessageEnd()
460 {
Roger Meier21c0a852012-09-05 19:47:14 +0000461 $this->writeJSONArrayEnd();
462 }
463
464 /**
465 * Writes a struct header.
466 *
Robert Lub03ca012018-01-18 19:06:39 +0800467 * @param string $name Struct name
Roger Meier21c0a852012-09-05 19:47:14 +0000468 * @throws TException on write error
Roger Thomas6fb59232014-11-04 10:09:23 +0000469 * @return int How many bytes written
Roger Meier21c0a852012-09-05 19:47:14 +0000470 */
Roger Thomas6fb59232014-11-04 10:09:23 +0000471 public function writeStructBegin($name)
472 {
Roger Meier21c0a852012-09-05 19:47:14 +0000473 $this->writeJSONObjectStart();
474 }
475
476 /**
477 * Close a struct.
478 *
479 * @throws TException on write error
Roger Thomas6fb59232014-11-04 10:09:23 +0000480 * @return int How many bytes written
Roger Meier21c0a852012-09-05 19:47:14 +0000481 */
Roger Thomas6fb59232014-11-04 10:09:23 +0000482 public function writeStructEnd()
483 {
Roger Meier21c0a852012-09-05 19:47:14 +0000484 $this->writeJSONObjectEnd();
485 }
486
Roger Thomas6fb59232014-11-04 10:09:23 +0000487 public function writeFieldBegin($fieldName, $fieldType, $fieldId)
488 {
Roger Meier21c0a852012-09-05 19:47:14 +0000489 $this->writeJSONInteger($fieldId);
490 $this->writeJSONObjectStart();
491 $this->writeJSONString($this->getTypeNameForTypeID($fieldType));
492 }
493
Roger Thomas6fb59232014-11-04 10:09:23 +0000494 public function writeFieldEnd()
495 {
Roger Meier21c0a852012-09-05 19:47:14 +0000496 $this->writeJsonObjectEnd();
497 }
498
Roger Thomas6fb59232014-11-04 10:09:23 +0000499 public function writeFieldStop()
500 {
Roger Meier21c0a852012-09-05 19:47:14 +0000501 }
502
Roger Thomas6fb59232014-11-04 10:09:23 +0000503 public function writeMapBegin($keyType, $valType, $size)
504 {
Roger Meier21c0a852012-09-05 19:47:14 +0000505 $this->writeJSONArrayStart();
506 $this->writeJSONString($this->getTypeNameForTypeID($keyType));
507 $this->writeJSONString($this->getTypeNameForTypeID($valType));
508 $this->writeJSONInteger($size);
509 $this->writeJSONObjectStart();
510 }
511
Roger Thomas6fb59232014-11-04 10:09:23 +0000512 public function writeMapEnd()
513 {
Roger Meier21c0a852012-09-05 19:47:14 +0000514 $this->writeJSONObjectEnd();
515 $this->writeJSONArrayEnd();
516 }
517
Roger Thomas6fb59232014-11-04 10:09:23 +0000518 public function writeListBegin($elemType, $size)
519 {
Roger Meier21c0a852012-09-05 19:47:14 +0000520 $this->writeJSONArrayStart();
521 $this->writeJSONString($this->getTypeNameForTypeID($elemType));
522 $this->writeJSONInteger($size);
523 }
524
Roger Thomas6fb59232014-11-04 10:09:23 +0000525 public function writeListEnd()
526 {
Roger Meier21c0a852012-09-05 19:47:14 +0000527 $this->writeJSONArrayEnd();
528 }
529
Roger Thomas6fb59232014-11-04 10:09:23 +0000530 public function writeSetBegin($elemType, $size)
531 {
Roger Meier21c0a852012-09-05 19:47:14 +0000532 $this->writeJSONArrayStart();
533 $this->writeJSONString($this->getTypeNameForTypeID($elemType));
534 $this->writeJSONInteger($size);
535 }
536
Roger Thomas6fb59232014-11-04 10:09:23 +0000537 public function writeSetEnd()
538 {
Roger Meier21c0a852012-09-05 19:47:14 +0000539 $this->writeJSONArrayEnd();
540 }
541
Roger Thomas6fb59232014-11-04 10:09:23 +0000542 public function writeBool($bool)
543 {
Roger Meier21c0a852012-09-05 19:47:14 +0000544 $this->writeJSONInteger($bool ? 1 : 0);
545 }
546
Roger Thomas6fb59232014-11-04 10:09:23 +0000547 public function writeByte($byte)
548 {
Roger Meier21c0a852012-09-05 19:47:14 +0000549 $this->writeJSONInteger($byte);
550 }
551
Roger Thomas6fb59232014-11-04 10:09:23 +0000552 public function writeI16($i16)
553 {
Roger Meier21c0a852012-09-05 19:47:14 +0000554 $this->writeJSONInteger($i16);
555 }
556
Roger Thomas6fb59232014-11-04 10:09:23 +0000557 public function writeI32($i32)
558 {
Roger Meier21c0a852012-09-05 19:47:14 +0000559 $this->writeJSONInteger($i32);
560 }
561
Roger Thomas6fb59232014-11-04 10:09:23 +0000562 public function writeI64($i64)
563 {
Roger Meier21c0a852012-09-05 19:47:14 +0000564 $this->writeJSONInteger($i64);
565 }
566
Roger Thomas6fb59232014-11-04 10:09:23 +0000567 public function writeDouble($dub)
568 {
Roger Meier21c0a852012-09-05 19:47:14 +0000569 $this->writeJSONDouble($dub);
570 }
571
Roger Thomas6fb59232014-11-04 10:09:23 +0000572 public function writeString($str)
573 {
Roger Meier21c0a852012-09-05 19:47:14 +0000574 $this->writeJSONString($str);
575 }
576
577 /**
578 * Reads the message header
579 *
580 * @param string $name Function name
Robert Lub03ca012018-01-18 19:06:39 +0800581 * @param int $type message type TMessageType::CALL or TMessageType::REPLY
Roger Meier21c0a852012-09-05 19:47:14 +0000582 * @parem int $seqid The sequence id of this message
583 */
Roger Thomas6fb59232014-11-04 10:09:23 +0000584 public function readMessageBegin(&$name, &$type, &$seqid)
585 {
Roger Meier21c0a852012-09-05 19:47:14 +0000586 $this->readJSONArrayStart();
587
588 if ($this->readJSONInteger() != self::VERSION) {
589 throw new TProtocolException("Message contained bad version", TProtocolException::BAD_VERSION);
590 }
591
592 $name = $this->readJSONString(false);
593 $type = $this->readJSONInteger();
594 $seqid = $this->readJSONInteger();
595
596 return true;
597 }
598
599 /**
600 * Read the close of message
601 */
Roger Thomas6fb59232014-11-04 10:09:23 +0000602 public function readMessageEnd()
603 {
Roger Meier21c0a852012-09-05 19:47:14 +0000604 $this->readJSONArrayEnd();
605 }
606
Roger Thomas6fb59232014-11-04 10:09:23 +0000607 public function readStructBegin(&$name)
608 {
Roger Meier21c0a852012-09-05 19:47:14 +0000609 $this->readJSONObjectStart();
Roger Thomas6fb59232014-11-04 10:09:23 +0000610
Roger Meier21c0a852012-09-05 19:47:14 +0000611 return 0;
612 }
613
Roger Thomas6fb59232014-11-04 10:09:23 +0000614 public function readStructEnd()
615 {
Roger Meier21c0a852012-09-05 19:47:14 +0000616 $this->readJSONObjectEnd();
617 }
618
Roger Thomas6fb59232014-11-04 10:09:23 +0000619 public function readFieldBegin(&$name, &$fieldType, &$fieldId)
620 {
Roger Meier21c0a852012-09-05 19:47:14 +0000621 $ch = $this->reader_->peek();
622 $name = "";
623
624 if (substr($ch, 0, 1) == self::RBRACE) {
625 $fieldType = TType::STOP;
626 } else {
627 $fieldId = $this->readJSONInteger();
628 $this->readJSONObjectStart();
629 $fieldType = $this->getTypeIDForTypeName($this->readJSONString(false));
630 }
631 }
632
Roger Thomas6fb59232014-11-04 10:09:23 +0000633 public function readFieldEnd()
634 {
Roger Meier21c0a852012-09-05 19:47:14 +0000635 $this->readJSONObjectEnd();
636 }
637
Roger Thomas6fb59232014-11-04 10:09:23 +0000638 public function readMapBegin(&$keyType, &$valType, &$size)
639 {
Roger Meier21c0a852012-09-05 19:47:14 +0000640 $this->readJSONArrayStart();
641 $keyType = $this->getTypeIDForTypeName($this->readJSONString(false));
642 $valType = $this->getTypeIDForTypeName($this->readJSONString(false));
643 $size = $this->readJSONInteger();
644 $this->readJSONObjectStart();
645 }
646
Roger Thomas6fb59232014-11-04 10:09:23 +0000647 public function readMapEnd()
648 {
Roger Meier21c0a852012-09-05 19:47:14 +0000649 $this->readJSONObjectEnd();
650 $this->readJSONArrayEnd();
651 }
652
Roger Thomas6fb59232014-11-04 10:09:23 +0000653 public function readListBegin(&$elemType, &$size)
654 {
Roger Meier21c0a852012-09-05 19:47:14 +0000655 $this->readJSONArrayStart();
656 $elemType = $this->getTypeIDForTypeName($this->readJSONString(false));
657 $size = $this->readJSONInteger();
Roger Thomas6fb59232014-11-04 10:09:23 +0000658
Roger Meier21c0a852012-09-05 19:47:14 +0000659 return true;
660 }
661
Roger Thomas6fb59232014-11-04 10:09:23 +0000662 public function readListEnd()
663 {
Roger Meier21c0a852012-09-05 19:47:14 +0000664 $this->readJSONArrayEnd();
665 }
666
Roger Thomas6fb59232014-11-04 10:09:23 +0000667 public function readSetBegin(&$elemType, &$size)
668 {
Roger Meier21c0a852012-09-05 19:47:14 +0000669 $this->readJSONArrayStart();
670 $elemType = $this->getTypeIDForTypeName($this->readJSONString(false));
671 $size = $this->readJSONInteger();
Roger Thomas6fb59232014-11-04 10:09:23 +0000672
Roger Meier21c0a852012-09-05 19:47:14 +0000673 return true;
674 }
675
Roger Thomas6fb59232014-11-04 10:09:23 +0000676 public function readSetEnd()
677 {
Roger Meier21c0a852012-09-05 19:47:14 +0000678 $this->readJSONArrayEnd();
679 }
680
Roger Thomas6fb59232014-11-04 10:09:23 +0000681 public function readBool(&$bool)
682 {
Roger Meier21c0a852012-09-05 19:47:14 +0000683 $bool = $this->readJSONInteger() == 0 ? false : true;
Roger Thomas6fb59232014-11-04 10:09:23 +0000684
Roger Meier21c0a852012-09-05 19:47:14 +0000685 return true;
686 }
687
Roger Thomas6fb59232014-11-04 10:09:23 +0000688 public function readByte(&$byte)
689 {
Roger Meier21c0a852012-09-05 19:47:14 +0000690 $byte = $this->readJSONInteger();
Roger Thomas6fb59232014-11-04 10:09:23 +0000691
Roger Meier21c0a852012-09-05 19:47:14 +0000692 return true;
693 }
694
Roger Thomas6fb59232014-11-04 10:09:23 +0000695 public function readI16(&$i16)
696 {
Roger Meier21c0a852012-09-05 19:47:14 +0000697 $i16 = $this->readJSONInteger();
Roger Thomas6fb59232014-11-04 10:09:23 +0000698
Roger Meier21c0a852012-09-05 19:47:14 +0000699 return true;
700 }
701
Roger Thomas6fb59232014-11-04 10:09:23 +0000702 public function readI32(&$i32)
703 {
Roger Meier21c0a852012-09-05 19:47:14 +0000704 $i32 = $this->readJSONInteger();
Roger Thomas6fb59232014-11-04 10:09:23 +0000705
Roger Meier21c0a852012-09-05 19:47:14 +0000706 return true;
707 }
708
Roger Thomas6fb59232014-11-04 10:09:23 +0000709 public function readI64(&$i64)
710 {
711 if (PHP_INT_SIZE === 4) {
Roger Meier21c0a852012-09-05 19:47:14 +0000712 $i64 = $this->readJSONIntegerAsString();
713 } else {
714 $i64 = $this->readJSONInteger();
715 }
Roger Thomas6fb59232014-11-04 10:09:23 +0000716
Roger Meier21c0a852012-09-05 19:47:14 +0000717 return true;
718 }
719
Roger Thomas6fb59232014-11-04 10:09:23 +0000720 public function readDouble(&$dub)
721 {
Roger Meier21c0a852012-09-05 19:47:14 +0000722 $dub = $this->readJSONDouble();
Roger Thomas6fb59232014-11-04 10:09:23 +0000723
Roger Meier21c0a852012-09-05 19:47:14 +0000724 return true;
725 }
726
Roger Thomas6fb59232014-11-04 10:09:23 +0000727 public function readString(&$str)
728 {
Roger Meier21c0a852012-09-05 19:47:14 +0000729 $str = $this->readJSONString(false);
Roger Thomas6fb59232014-11-04 10:09:23 +0000730
Roger Meier21c0a852012-09-05 19:47:14 +0000731 return true;
732 }
733}