blob: 7d5654531298406589c54c8af2442dc61988f19f [file] [log] [blame]
Roger Meier85fb6de2012-11-02 00:05:42 +00001#
2# Licensed to the Apache Software Foundation (ASF) under one
3# or more contributor license agreements. See the NOTICE file
4# distributed with this work for additional information
5# regarding copyright ownership. The ASF licenses this file
6# to you under the Apache License, Version 2.0 (the
7# "License"); you may not use this file except in compliance
8# with the License. You may obtain a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing,
13# software distributed under the License is distributed on an
14# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15# KIND, either express or implied. See the License for the
16# specific language governing permissions and limitations
17# under the License.
18#
19
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +090020from .TProtocol import TType, TProtocolBase, TProtocolException, checkIntegerLimits
Roger Meier0895dfe2012-12-26 22:09:55 +010021import base64
Roger Meier0895dfe2012-12-26 22:09:55 +010022import math
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +090023import sys
24
25from ..compat import str_to_binary
26
Roger Meier85fb6de2012-11-02 00:05:42 +000027
Roger Meier0895dfe2012-12-26 22:09:55 +010028__all__ = ['TJSONProtocol',
29 'TJSONProtocolFactory',
30 'TSimpleJSONProtocol',
31 'TSimpleJSONProtocolFactory']
Roger Meier85fb6de2012-11-02 00:05:42 +000032
33VERSION = 1
34
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +090035COMMA = b','
36COLON = b':'
37LBRACE = b'{'
38RBRACE = b'}'
39LBRACKET = b'['
40RBRACKET = b']'
41QUOTE = b'"'
42BACKSLASH = b'\\'
43ZERO = b'0'
Roger Meier85fb6de2012-11-02 00:05:42 +000044
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +090045ESCSEQ0 = ord('\\')
46ESCSEQ1 = ord('u')
47ESCAPE_CHAR_VALS = {
48 '"': '\\"',
49 '\\': '\\\\',
50 '\b': '\\b',
51 '\f': '\\f',
52 '\n': '\\n',
53 '\r': '\\r',
54 '\t': '\\t',
55 # '/': '\\/',
56}
57ESCAPE_CHARS = {
58 b'"': '"',
59 b'\\': '\\',
60 b'b': '\b',
61 b'f': '\f',
62 b'n': '\n',
63 b'r': '\r',
64 b't': '\t',
65 b'/': '/',
66}
67NUMERIC_CHAR = b'+-.0123456789Ee'
Roger Meier85fb6de2012-11-02 00:05:42 +000068
69CTYPES = {TType.BOOL: 'tf',
70 TType.BYTE: 'i8',
71 TType.I16: 'i16',
72 TType.I32: 'i32',
73 TType.I64: 'i64',
74 TType.DOUBLE: 'dbl',
75 TType.STRING: 'str',
Roger Meier05ab89a2012-11-02 10:36:59 +000076 TType.STRUCT: 'rec',
Roger Meier85fb6de2012-11-02 00:05:42 +000077 TType.LIST: 'lst',
78 TType.SET: 'set',
79 TType.MAP: 'map'}
80
81JTYPES = {}
82for key in CTYPES.keys():
83 JTYPES[CTYPES[key]] = key
84
85
Roger Meierad8154a2012-12-18 21:02:16 +010086class JSONBaseContext(object):
Roger Meier85fb6de2012-11-02 00:05:42 +000087
88 def __init__(self, protocol):
89 self.protocol = protocol
90 self.first = True
91
92 def doIO(self, function):
93 pass
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +090094
Roger Meier85fb6de2012-11-02 00:05:42 +000095 def write(self):
96 pass
97
98 def read(self):
99 pass
100
101 def escapeNum(self):
102 return False
103
Roger Meier0895dfe2012-12-26 22:09:55 +0100104 def __str__(self):
105 return self.__class__.__name__
106
Roger Meier85fb6de2012-11-02 00:05:42 +0000107
108class JSONListContext(JSONBaseContext):
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900109
Roger Meier85fb6de2012-11-02 00:05:42 +0000110 def doIO(self, function):
111 if self.first is True:
112 self.first = False
113 else:
114 function(COMMA)
115
116 def write(self):
117 self.doIO(self.protocol.trans.write)
118
119 def read(self):
120 self.doIO(self.protocol.readJSONSyntaxChar)
121
122
123class JSONPairContext(JSONBaseContext):
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900124
Roger Meier0895dfe2012-12-26 22:09:55 +0100125 def __init__(self, protocol):
126 super(JSONPairContext, self).__init__(protocol)
127 self.colon = True
Roger Meier85fb6de2012-11-02 00:05:42 +0000128
129 def doIO(self, function):
Roger Meier0895dfe2012-12-26 22:09:55 +0100130 if self.first:
Roger Meier85fb6de2012-11-02 00:05:42 +0000131 self.first = False
132 self.colon = True
133 else:
Roger Meier0895dfe2012-12-26 22:09:55 +0100134 function(COLON if self.colon else COMMA)
Roger Meier85fb6de2012-11-02 00:05:42 +0000135 self.colon = not self.colon
136
137 def write(self):
138 self.doIO(self.protocol.trans.write)
139
140 def read(self):
141 self.doIO(self.protocol.readJSONSyntaxChar)
142
143 def escapeNum(self):
144 return self.colon
145
Roger Meier0895dfe2012-12-26 22:09:55 +0100146 def __str__(self):
147 return '%s, colon=%s' % (self.__class__.__name__, self.colon)
148
Roger Meier85fb6de2012-11-02 00:05:42 +0000149
150class LookaheadReader():
151 hasData = False
152 data = ''
153
154 def __init__(self, protocol):
155 self.protocol = protocol
156
157 def read(self):
158 if self.hasData is True:
159 self.hasData = False
160 else:
161 self.data = self.protocol.trans.read(1)
162 return self.data
163
164 def peek(self):
165 if self.hasData is False:
166 self.data = self.protocol.trans.read(1)
167 self.hasData = True
168 return self.data
169
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900170
Roger Meier85fb6de2012-11-02 00:05:42 +0000171class TJSONProtocolBase(TProtocolBase):
172
173 def __init__(self, trans):
174 TProtocolBase.__init__(self, trans)
Roger Meierad8154a2012-12-18 21:02:16 +0100175 self.resetWriteContext()
176 self.resetReadContext()
Roger Meier85fb6de2012-11-02 00:05:42 +0000177
178 def resetWriteContext(self):
Roger Meier0895dfe2012-12-26 22:09:55 +0100179 self.context = JSONBaseContext(self)
180 self.contextStack = [self.context]
Roger Meier85fb6de2012-11-02 00:05:42 +0000181
182 def resetReadContext(self):
183 self.resetWriteContext()
184 self.reader = LookaheadReader(self)
185
186 def pushContext(self, ctx):
187 self.contextStack.append(ctx)
188 self.context = ctx
189
190 def popContext(self):
191 self.contextStack.pop()
Roger Meier0895dfe2012-12-26 22:09:55 +0100192 if self.contextStack:
193 self.context = self.contextStack[-1]
194 else:
195 self.context = JSONBaseContext(self)
Roger Meier85fb6de2012-11-02 00:05:42 +0000196
197 def writeJSONString(self, string):
198 self.context.write()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900199 json_str = ['"']
200 for s in string:
201 escaped = ESCAPE_CHAR_VALS.get(s, s)
202 json_str.append(escaped)
203 json_str.append('"')
204 self.trans.write(str_to_binary(''.join(json_str)))
Roger Meier85fb6de2012-11-02 00:05:42 +0000205
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900206 def writeJSONNumber(self, number, formatter='{}'):
Roger Meier85fb6de2012-11-02 00:05:42 +0000207 self.context.write()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900208 jsNumber = str(formatter.format(number)).encode('ascii')
Roger Meier85fb6de2012-11-02 00:05:42 +0000209 if self.context.escapeNum():
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900210 self.trans.write(QUOTE)
211 self.trans.write(jsNumber)
212 self.trans.write(QUOTE)
213 else:
214 self.trans.write(jsNumber)
Roger Meier85fb6de2012-11-02 00:05:42 +0000215
216 def writeJSONBase64(self, binary):
217 self.context.write()
218 self.trans.write(QUOTE)
219 self.trans.write(base64.b64encode(binary))
220 self.trans.write(QUOTE)
221
222 def writeJSONObjectStart(self):
223 self.context.write()
224 self.trans.write(LBRACE)
225 self.pushContext(JSONPairContext(self))
226
227 def writeJSONObjectEnd(self):
228 self.popContext()
229 self.trans.write(RBRACE)
230
231 def writeJSONArrayStart(self):
232 self.context.write()
233 self.trans.write(LBRACKET)
234 self.pushContext(JSONListContext(self))
235
236 def writeJSONArrayEnd(self):
237 self.popContext()
238 self.trans.write(RBRACKET)
239
240 def readJSONSyntaxChar(self, character):
241 current = self.reader.read()
242 if character != current:
243 raise TProtocolException(TProtocolException.INVALID_DATA,
244 "Unexpected character: %s" % current)
245
Phongphan Phuttha7f01e2a2015-11-06 15:46:50 +0700246 def _isHighSurrogate(self, codeunit):
247 return codeunit >= 0xd800 and codeunit <= 0xdbff
248
249 def _isLowSurrogate(self, codeunit):
250 return codeunit >= 0xdc00 and codeunit <= 0xdfff
251
Phongphan Phuttha369d62e2015-11-09 02:05:09 +0700252 def _toChar(self, high, low=None):
253 if not low:
Nobuaki Sukegawa7f404fd2015-11-14 17:05:42 +0900254 codepoint = high
Phongphan Phuttha369d62e2015-11-09 02:05:09 +0700255 else:
256 codepoint = (1 << 16) + ((high & 0x3ff) << 10)
257 codepoint += low & 0x3ff
Nobuaki Sukegawa7f404fd2015-11-14 17:05:42 +0900258 if sys.version_info[0] == 2:
259 return unichr(codepoint).encode('utf-8')
260 else:
261 return chr(codepoint)
Phongphan Phuttha369d62e2015-11-09 02:05:09 +0700262
Roger Meier85fb6de2012-11-02 00:05:42 +0000263 def readJSONString(self, skipContext):
Phongphan Phuttha7f01e2a2015-11-06 15:46:50 +0700264 highSurrogate = None
Roger Meier85fb6de2012-11-02 00:05:42 +0000265 string = []
266 if skipContext is False:
267 self.context.read()
268 self.readJSONSyntaxChar(QUOTE)
269 while True:
270 character = self.reader.read()
271 if character == QUOTE:
272 break
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900273 if ord(character) == ESCSEQ0:
Roger Meier85fb6de2012-11-02 00:05:42 +0000274 character = self.reader.read()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900275 if ord(character) == ESCSEQ1:
Phongphan Phuttha369d62e2015-11-09 02:05:09 +0700276 character = self.trans.read(4).decode('ascii')
277 codeunit = int(character, 16)
278 if self._isHighSurrogate(codeunit):
279 if highSurrogate:
280 raise TProtocolException(TProtocolException.INVALID_DATA,
281 "Expected low surrogate char")
282 highSurrogate = codeunit
283 continue
284 elif self._isLowSurrogate(codeunit):
285 if not highSurrogate:
286 raise TProtocolException(TProtocolException.INVALID_DATA,
287 "Expected high surrogate char")
288 character = self._toChar(highSurrogate, codeunit)
289 highSurrogate = None
Phongphan Phuttha7f01e2a2015-11-06 15:46:50 +0700290 else:
Phongphan Phuttha369d62e2015-11-09 02:05:09 +0700291 character = self._toChar(codeunit)
Roger Meier85fb6de2012-11-02 00:05:42 +0000292 else:
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900293 if character not in ESCAPE_CHARS:
Roger Meier85fb6de2012-11-02 00:05:42 +0000294 raise TProtocolException(TProtocolException.INVALID_DATA,
295 "Expected control char")
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900296 character = ESCAPE_CHARS[character]
297 elif character in ESCAPE_CHAR_VALS:
298 raise TProtocolException(TProtocolException.INVALID_DATA,
299 "Unescaped control char")
300 elif sys.version_info[0] > 2:
301 utf8_bytes = bytearray([ord(character)])
302 while ord(self.reader.peek()) >= 0x80:
303 utf8_bytes.append(ord(self.reader.read()))
304 character = utf8_bytes.decode('utf8')
Roger Meier85fb6de2012-11-02 00:05:42 +0000305 string.append(character)
Phongphan Phuttha7f01e2a2015-11-06 15:46:50 +0700306
307 if highSurrogate:
308 raise TProtocolException(TProtocolException.INVALID_DATA,
309 "Expected low surrogate char")
Roger Meier85fb6de2012-11-02 00:05:42 +0000310 return ''.join(string)
311
312 def isJSONNumeric(self, character):
313 return (True if NUMERIC_CHAR.find(character) != - 1 else False)
314
315 def readJSONQuotes(self):
316 if (self.context.escapeNum()):
317 self.readJSONSyntaxChar(QUOTE)
318
319 def readJSONNumericChars(self):
320 numeric = []
321 while True:
322 character = self.reader.peek()
323 if self.isJSONNumeric(character) is False:
324 break
325 numeric.append(self.reader.read())
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900326 return b''.join(numeric).decode('ascii')
Roger Meier85fb6de2012-11-02 00:05:42 +0000327
328 def readJSONInteger(self):
329 self.context.read()
330 self.readJSONQuotes()
331 numeric = self.readJSONNumericChars()
332 self.readJSONQuotes()
333 try:
334 return int(numeric)
335 except ValueError:
336 raise TProtocolException(TProtocolException.INVALID_DATA,
337 "Bad data encounted in numeric data")
338
339 def readJSONDouble(self):
340 self.context.read()
341 if self.reader.peek() == QUOTE:
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900342 string = self.readJSONString(True)
Roger Meier85fb6de2012-11-02 00:05:42 +0000343 try:
344 double = float(string)
Roger Meier0895dfe2012-12-26 22:09:55 +0100345 if (self.context.escapeNum is False and
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900346 not math.isinf(double) and
347 not math.isnan(double)):
Roger Meier85fb6de2012-11-02 00:05:42 +0000348 raise TProtocolException(TProtocolException.INVALID_DATA,
349 "Numeric data unexpectedly quoted")
350 return double
351 except ValueError:
352 raise TProtocolException(TProtocolException.INVALID_DATA,
353 "Bad data encounted in numeric data")
354 else:
355 if self.context.escapeNum() is True:
356 self.readJSONSyntaxChar(QUOTE)
357 try:
358 return float(self.readJSONNumericChars())
Roger Meierad8154a2012-12-18 21:02:16 +0100359 except ValueError:
Roger Meier85fb6de2012-11-02 00:05:42 +0000360 raise TProtocolException(TProtocolException.INVALID_DATA,
361 "Bad data encounted in numeric data")
362
363 def readJSONBase64(self):
364 string = self.readJSONString(False)
Nobuaki Sukegawabc7e4802015-11-14 19:23:27 +0900365 size = len(string)
366 m = size % 4
367 # Force padding since b64encode method does not allow it
368 if m != 0:
369 for i in range(4 - m):
370 string += '='
Roger Meier85fb6de2012-11-02 00:05:42 +0000371 return base64.b64decode(string)
372
373 def readJSONObjectStart(self):
374 self.context.read()
375 self.readJSONSyntaxChar(LBRACE)
376 self.pushContext(JSONPairContext(self))
377
378 def readJSONObjectEnd(self):
379 self.readJSONSyntaxChar(RBRACE)
380 self.popContext()
381
382 def readJSONArrayStart(self):
383 self.context.read()
384 self.readJSONSyntaxChar(LBRACKET)
385 self.pushContext(JSONListContext(self))
386
387 def readJSONArrayEnd(self):
388 self.readJSONSyntaxChar(RBRACKET)
389 self.popContext()
390
391
392class TJSONProtocol(TJSONProtocolBase):
393
394 def readMessageBegin(self):
395 self.resetReadContext()
396 self.readJSONArrayStart()
397 if self.readJSONInteger() != VERSION:
398 raise TProtocolException(TProtocolException.BAD_VERSION,
399 "Message contained bad version.")
400 name = self.readJSONString(False)
401 typen = self.readJSONInteger()
402 seqid = self.readJSONInteger()
403 return (name, typen, seqid)
404
405 def readMessageEnd(self):
406 self.readJSONArrayEnd()
407
408 def readStructBegin(self):
409 self.readJSONObjectStart()
410
411 def readStructEnd(self):
412 self.readJSONObjectEnd()
413
414 def readFieldBegin(self):
415 character = self.reader.peek()
Roger Meierad8154a2012-12-18 21:02:16 +0100416 ttype = 0
Roger Meier85fb6de2012-11-02 00:05:42 +0000417 id = 0
418 if character == RBRACE:
Roger Meierad8154a2012-12-18 21:02:16 +0100419 ttype = TType.STOP
Roger Meier85fb6de2012-11-02 00:05:42 +0000420 else:
421 id = self.readJSONInteger()
422 self.readJSONObjectStart()
Roger Meierad8154a2012-12-18 21:02:16 +0100423 ttype = JTYPES[self.readJSONString(False)]
424 return (None, ttype, id)
Roger Meier85fb6de2012-11-02 00:05:42 +0000425
426 def readFieldEnd(self):
427 self.readJSONObjectEnd()
428
429 def readMapBegin(self):
430 self.readJSONArrayStart()
431 keyType = JTYPES[self.readJSONString(False)]
432 valueType = JTYPES[self.readJSONString(False)]
433 size = self.readJSONInteger()
434 self.readJSONObjectStart()
435 return (keyType, valueType, size)
436
437 def readMapEnd(self):
438 self.readJSONObjectEnd()
439 self.readJSONArrayEnd()
440
441 def readCollectionBegin(self):
442 self.readJSONArrayStart()
443 elemType = JTYPES[self.readJSONString(False)]
444 size = self.readJSONInteger()
Roger Meierad8154a2012-12-18 21:02:16 +0100445 return (elemType, size)
Roger Meier85fb6de2012-11-02 00:05:42 +0000446 readListBegin = readCollectionBegin
447 readSetBegin = readCollectionBegin
448
449 def readCollectionEnd(self):
450 self.readJSONArrayEnd()
451 readSetEnd = readCollectionEnd
452 readListEnd = readCollectionEnd
453
454 def readBool(self):
455 return (False if self.readJSONInteger() == 0 else True)
456
457 def readNumber(self):
458 return self.readJSONInteger()
459 readByte = readNumber
460 readI16 = readNumber
461 readI32 = readNumber
462 readI64 = readNumber
463
464 def readDouble(self):
465 return self.readJSONDouble()
466
467 def readString(self):
468 return self.readJSONString(False)
469
470 def readBinary(self):
471 return self.readJSONBase64()
472
473 def writeMessageBegin(self, name, request_type, seqid):
474 self.resetWriteContext()
475 self.writeJSONArrayStart()
476 self.writeJSONNumber(VERSION)
477 self.writeJSONString(name)
478 self.writeJSONNumber(request_type)
479 self.writeJSONNumber(seqid)
480
481 def writeMessageEnd(self):
482 self.writeJSONArrayEnd()
483
484 def writeStructBegin(self, name):
485 self.writeJSONObjectStart()
486
487 def writeStructEnd(self):
488 self.writeJSONObjectEnd()
489
Roger Meierad8154a2012-12-18 21:02:16 +0100490 def writeFieldBegin(self, name, ttype, id):
Roger Meier85fb6de2012-11-02 00:05:42 +0000491 self.writeJSONNumber(id)
492 self.writeJSONObjectStart()
Roger Meierad8154a2012-12-18 21:02:16 +0100493 self.writeJSONString(CTYPES[ttype])
Roger Meier85fb6de2012-11-02 00:05:42 +0000494
495 def writeFieldEnd(self):
496 self.writeJSONObjectEnd()
497
498 def writeFieldStop(self):
499 pass
500
501 def writeMapBegin(self, ktype, vtype, size):
502 self.writeJSONArrayStart()
503 self.writeJSONString(CTYPES[ktype])
504 self.writeJSONString(CTYPES[vtype])
505 self.writeJSONNumber(size)
506 self.writeJSONObjectStart()
507
508 def writeMapEnd(self):
509 self.writeJSONObjectEnd()
510 self.writeJSONArrayEnd()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900511
Roger Meier85fb6de2012-11-02 00:05:42 +0000512 def writeListBegin(self, etype, size):
513 self.writeJSONArrayStart()
514 self.writeJSONString(CTYPES[etype])
515 self.writeJSONNumber(size)
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900516
Roger Meier85fb6de2012-11-02 00:05:42 +0000517 def writeListEnd(self):
518 self.writeJSONArrayEnd()
519
520 def writeSetBegin(self, etype, size):
521 self.writeJSONArrayStart()
522 self.writeJSONString(CTYPES[etype])
523 self.writeJSONNumber(size)
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900524
Roger Meier85fb6de2012-11-02 00:05:42 +0000525 def writeSetEnd(self):
526 self.writeJSONArrayEnd()
527
528 def writeBool(self, boolean):
529 self.writeJSONNumber(1 if boolean is True else 0)
530
Konrad Grochowski93fea152014-10-02 16:29:14 +0200531 def writeByte(self, byte):
532 checkIntegerLimits(byte, 8)
533 self.writeJSONNumber(byte)
534
535 def writeI16(self, i16):
536 checkIntegerLimits(i16, 16)
537 self.writeJSONNumber(i16)
538
539 def writeI32(self, i32):
540 checkIntegerLimits(i32, 32)
541 self.writeJSONNumber(i32)
542
543 def writeI64(self, i64):
544 checkIntegerLimits(i64, 64)
545 self.writeJSONNumber(i64)
Roger Meier85fb6de2012-11-02 00:05:42 +0000546
547 def writeDouble(self, dbl):
Nobuaki Sukegawa228b3282015-10-10 03:11:49 +0900548 # 17 significant digits should be just enough for any double precision value.
549 self.writeJSONNumber(dbl, '{:.17g}')
Roger Meier85fb6de2012-11-02 00:05:42 +0000550
551 def writeString(self, string):
552 self.writeJSONString(string)
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900553
Roger Meier85fb6de2012-11-02 00:05:42 +0000554 def writeBinary(self, binary):
555 self.writeJSONBase64(binary)
556
Roger Meier0895dfe2012-12-26 22:09:55 +0100557
Roger Meier85fb6de2012-11-02 00:05:42 +0000558class TJSONProtocolFactory:
Roger Meier85fb6de2012-11-02 00:05:42 +0000559
560 def getProtocol(self, trans):
561 return TJSONProtocol(trans)
Roger Meier0895dfe2012-12-26 22:09:55 +0100562
563
564class TSimpleJSONProtocol(TJSONProtocolBase):
565 """Simple, readable, write-only JSON protocol.
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900566
Roger Meier0895dfe2012-12-26 22:09:55 +0100567 Useful for interacting with scripting languages.
568 """
569
570 def readMessageBegin(self):
571 raise NotImplementedError()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900572
Roger Meier0895dfe2012-12-26 22:09:55 +0100573 def readMessageEnd(self):
574 raise NotImplementedError()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900575
Roger Meier0895dfe2012-12-26 22:09:55 +0100576 def readStructBegin(self):
577 raise NotImplementedError()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900578
Roger Meier0895dfe2012-12-26 22:09:55 +0100579 def readStructEnd(self):
580 raise NotImplementedError()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900581
Roger Meier0895dfe2012-12-26 22:09:55 +0100582 def writeMessageBegin(self, name, request_type, seqid):
583 self.resetWriteContext()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900584
Roger Meier0895dfe2012-12-26 22:09:55 +0100585 def writeMessageEnd(self):
586 pass
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900587
Roger Meier0895dfe2012-12-26 22:09:55 +0100588 def writeStructBegin(self, name):
589 self.writeJSONObjectStart()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900590
Roger Meier0895dfe2012-12-26 22:09:55 +0100591 def writeStructEnd(self):
592 self.writeJSONObjectEnd()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900593
Roger Meier0895dfe2012-12-26 22:09:55 +0100594 def writeFieldBegin(self, name, ttype, fid):
595 self.writeJSONString(name)
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900596
Roger Meier0895dfe2012-12-26 22:09:55 +0100597 def writeFieldEnd(self):
598 pass
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900599
Roger Meier0895dfe2012-12-26 22:09:55 +0100600 def writeMapBegin(self, ktype, vtype, size):
601 self.writeJSONObjectStart()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900602
Roger Meier0895dfe2012-12-26 22:09:55 +0100603 def writeMapEnd(self):
604 self.writeJSONObjectEnd()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900605
Roger Meier0895dfe2012-12-26 22:09:55 +0100606 def _writeCollectionBegin(self, etype, size):
607 self.writeJSONArrayStart()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900608
Roger Meier0895dfe2012-12-26 22:09:55 +0100609 def _writeCollectionEnd(self):
610 self.writeJSONArrayEnd()
611 writeListBegin = _writeCollectionBegin
612 writeListEnd = _writeCollectionEnd
613 writeSetBegin = _writeCollectionBegin
614 writeSetEnd = _writeCollectionEnd
615
Konrad Grochowski93fea152014-10-02 16:29:14 +0200616 def writeByte(self, byte):
617 checkIntegerLimits(byte, 8)
618 self.writeJSONNumber(byte)
619
620 def writeI16(self, i16):
621 checkIntegerLimits(i16, 16)
622 self.writeJSONNumber(i16)
623
624 def writeI32(self, i32):
625 checkIntegerLimits(i32, 32)
626 self.writeJSONNumber(i32)
627
628 def writeI64(self, i64):
629 checkIntegerLimits(i64, 64)
630 self.writeJSONNumber(i64)
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900631
Roger Meier0895dfe2012-12-26 22:09:55 +0100632 def writeBool(self, boolean):
633 self.writeJSONNumber(1 if boolean is True else 0)
634
635 def writeDouble(self, dbl):
636 self.writeJSONNumber(dbl)
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900637
Roger Meier0895dfe2012-12-26 22:09:55 +0100638 def writeString(self, string):
639 self.writeJSONString(string)
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900640
Roger Meier0895dfe2012-12-26 22:09:55 +0100641 def writeBinary(self, binary):
642 self.writeJSONBase64(binary)
643
644
645class TSimpleJSONProtocolFactory(object):
646
647 def getProtocol(self, trans):
648 return TSimpleJSONProtocol(trans)