blob: a42aaa6315d56fb03586085650ec9b3838584854 [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 Sukegawa10308cb2016-02-03 01:57:03 +090020from .TProtocol import (TType, TProtocolBase, TProtocolException,
James E. King IIIe44f6a92019-02-07 17:11:21 -050021 TProtocolFactory, checkIntegerLimits)
Roger Meier0895dfe2012-12-26 22:09:55 +010022import base64
Roger Meier0895dfe2012-12-26 22:09:55 +010023import math
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +090024import sys
25
Roger Meier85fb6de2012-11-02 00:05:42 +000026
Roger Meier0895dfe2012-12-26 22:09:55 +010027__all__ = ['TJSONProtocol',
28 'TJSONProtocolFactory',
29 'TSimpleJSONProtocol',
30 'TSimpleJSONProtocolFactory']
Roger Meier85fb6de2012-11-02 00:05:42 +000031
32VERSION = 1
33
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +090034COMMA = b','
35COLON = b':'
36LBRACE = b'{'
37RBRACE = b'}'
38LBRACKET = b'['
39RBRACKET = b']'
40QUOTE = b'"'
41BACKSLASH = b'\\'
42ZERO = b'0'
Roger Meier85fb6de2012-11-02 00:05:42 +000043
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +090044ESCSEQ0 = ord('\\')
45ESCSEQ1 = ord('u')
46ESCAPE_CHAR_VALS = {
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090047 '"': '\\"',
48 '\\': '\\\\',
49 '\b': '\\b',
50 '\f': '\\f',
51 '\n': '\\n',
52 '\r': '\\r',
53 '\t': '\\t',
54 # '/': '\\/',
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +090055}
56ESCAPE_CHARS = {
57 b'"': '"',
58 b'\\': '\\',
59 b'b': '\b',
60 b'f': '\f',
61 b'n': '\n',
62 b'r': '\r',
63 b't': '\t',
64 b'/': '/',
65}
66NUMERIC_CHAR = b'+-.0123456789Ee'
Roger Meier85fb6de2012-11-02 00:05:42 +000067
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090068CTYPES = {
69 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',
76 TType.STRUCT: 'rec',
77 TType.LIST: 'lst',
78 TType.SET: 'set',
79 TType.MAP: 'map',
80}
Roger Meier85fb6de2012-11-02 00:05:42 +000081
82JTYPES = {}
83for key in CTYPES.keys():
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090084 JTYPES[CTYPES[key]] = key
Roger Meier85fb6de2012-11-02 00:05:42 +000085
86
Roger Meierad8154a2012-12-18 21:02:16 +010087class JSONBaseContext(object):
Roger Meier85fb6de2012-11-02 00:05:42 +000088
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090089 def __init__(self, protocol):
90 self.protocol = protocol
91 self.first = True
Roger Meier85fb6de2012-11-02 00:05:42 +000092
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090093 def doIO(self, function):
94 pass
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +090095
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090096 def write(self):
97 pass
Roger Meier85fb6de2012-11-02 00:05:42 +000098
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090099 def read(self):
100 pass
Roger Meier85fb6de2012-11-02 00:05:42 +0000101
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900102 def escapeNum(self):
103 return False
Roger Meier85fb6de2012-11-02 00:05:42 +0000104
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900105 def __str__(self):
106 return self.__class__.__name__
Roger Meier0895dfe2012-12-26 22:09:55 +0100107
Roger Meier85fb6de2012-11-02 00:05:42 +0000108
109class JSONListContext(JSONBaseContext):
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900110
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900111 def doIO(self, function):
112 if self.first is True:
113 self.first = False
114 else:
115 function(COMMA)
Roger Meier85fb6de2012-11-02 00:05:42 +0000116
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900117 def write(self):
118 self.doIO(self.protocol.trans.write)
Roger Meier85fb6de2012-11-02 00:05:42 +0000119
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900120 def read(self):
121 self.doIO(self.protocol.readJSONSyntaxChar)
Roger Meier85fb6de2012-11-02 00:05:42 +0000122
123
124class JSONPairContext(JSONBaseContext):
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900125
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900126 def __init__(self, protocol):
127 super(JSONPairContext, self).__init__(protocol)
128 self.colon = True
Roger Meier85fb6de2012-11-02 00:05:42 +0000129
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900130 def doIO(self, function):
131 if self.first:
132 self.first = False
133 self.colon = True
134 else:
135 function(COLON if self.colon else COMMA)
136 self.colon = not self.colon
Roger Meier85fb6de2012-11-02 00:05:42 +0000137
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900138 def write(self):
139 self.doIO(self.protocol.trans.write)
Roger Meier85fb6de2012-11-02 00:05:42 +0000140
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900141 def read(self):
142 self.doIO(self.protocol.readJSONSyntaxChar)
Roger Meier85fb6de2012-11-02 00:05:42 +0000143
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900144 def escapeNum(self):
145 return self.colon
Roger Meier85fb6de2012-11-02 00:05:42 +0000146
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900147 def __str__(self):
148 return '%s, colon=%s' % (self.__class__.__name__, self.colon)
Roger Meier0895dfe2012-12-26 22:09:55 +0100149
Roger Meier85fb6de2012-11-02 00:05:42 +0000150
151class LookaheadReader():
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900152 hasData = False
153 data = ''
Roger Meier85fb6de2012-11-02 00:05:42 +0000154
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900155 def __init__(self, protocol):
156 self.protocol = protocol
Roger Meier85fb6de2012-11-02 00:05:42 +0000157
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900158 def read(self):
159 if self.hasData is True:
160 self.hasData = False
161 else:
162 self.data = self.protocol.trans.read(1)
163 return self.data
Roger Meier85fb6de2012-11-02 00:05:42 +0000164
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900165 def peek(self):
166 if self.hasData is False:
167 self.data = self.protocol.trans.read(1)
168 self.hasData = True
169 return self.data
Roger Meier85fb6de2012-11-02 00:05:42 +0000170
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900171
Roger Meier85fb6de2012-11-02 00:05:42 +0000172class TJSONProtocolBase(TProtocolBase):
173
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900174 def __init__(self, trans):
175 TProtocolBase.__init__(self, trans)
176 self.resetWriteContext()
177 self.resetReadContext()
Roger Meier85fb6de2012-11-02 00:05:42 +0000178
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900179 # We don't have length limit implementation for JSON protocols
180 @property
181 def string_length_limit(senf):
182 return None
Nobuaki Sukegawa7b545b52016-01-11 13:46:04 +0900183
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900184 @property
185 def container_length_limit(senf):
186 return None
Nobuaki Sukegawa7b545b52016-01-11 13:46:04 +0900187
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900188 def resetWriteContext(self):
189 self.context = JSONBaseContext(self)
190 self.contextStack = [self.context]
Roger Meier85fb6de2012-11-02 00:05:42 +0000191
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900192 def resetReadContext(self):
193 self.resetWriteContext()
194 self.reader = LookaheadReader(self)
Roger Meier85fb6de2012-11-02 00:05:42 +0000195
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900196 def pushContext(self, ctx):
197 self.contextStack.append(ctx)
198 self.context = ctx
Roger Meier85fb6de2012-11-02 00:05:42 +0000199
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900200 def popContext(self):
201 self.contextStack.pop()
202 if self.contextStack:
203 self.context = self.contextStack[-1]
Roger Meier85fb6de2012-11-02 00:05:42 +0000204 else:
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900205 self.context = JSONBaseContext(self)
206
207 def writeJSONString(self, string):
208 self.context.write()
209 json_str = ['"']
210 for s in string:
211 escaped = ESCAPE_CHAR_VALS.get(s, s)
212 json_str.append(escaped)
213 json_str.append('"')
Alexandre Detiste3494e1c2025-02-19 21:53:40 +0100214 self.trans.write(bytes(''.join(json_str), 'utf-8'))
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900215
216 def writeJSONNumber(self, number, formatter='{0}'):
217 self.context.write()
218 jsNumber = str(formatter.format(number)).encode('ascii')
219 if self.context.escapeNum():
220 self.trans.write(QUOTE)
221 self.trans.write(jsNumber)
222 self.trans.write(QUOTE)
223 else:
224 self.trans.write(jsNumber)
225
226 def writeJSONBase64(self, binary):
227 self.context.write()
228 self.trans.write(QUOTE)
229 self.trans.write(base64.b64encode(binary))
230 self.trans.write(QUOTE)
231
232 def writeJSONObjectStart(self):
233 self.context.write()
234 self.trans.write(LBRACE)
235 self.pushContext(JSONPairContext(self))
236
237 def writeJSONObjectEnd(self):
238 self.popContext()
239 self.trans.write(RBRACE)
240
241 def writeJSONArrayStart(self):
242 self.context.write()
243 self.trans.write(LBRACKET)
244 self.pushContext(JSONListContext(self))
245
246 def writeJSONArrayEnd(self):
247 self.popContext()
248 self.trans.write(RBRACKET)
249
250 def readJSONSyntaxChar(self, character):
251 current = self.reader.read()
252 if character != current:
Roger Meier85fb6de2012-11-02 00:05:42 +0000253 raise TProtocolException(TProtocolException.INVALID_DATA,
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900254 "Unexpected character: %s" % current)
Phongphan Phuttha7f01e2a2015-11-06 15:46:50 +0700255
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900256 def _isHighSurrogate(self, codeunit):
257 return codeunit >= 0xd800 and codeunit <= 0xdbff
Roger Meier85fb6de2012-11-02 00:05:42 +0000258
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900259 def _isLowSurrogate(self, codeunit):
260 return codeunit >= 0xdc00 and codeunit <= 0xdfff
Roger Meier85fb6de2012-11-02 00:05:42 +0000261
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900262 def _toChar(self, high, low=None):
263 if not low:
Alexandre Detisted0787212024-12-26 02:44:13 +0100264 return chr(high)
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900265 else:
266 codepoint = (1 << 16) + ((high & 0x3ff) << 10)
267 codepoint += low & 0x3ff
Alexandre Detisted0787212024-12-26 02:44:13 +0100268 return chr(codepoint)
Roger Meier85fb6de2012-11-02 00:05:42 +0000269
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900270 def readJSONString(self, skipContext):
271 highSurrogate = None
272 string = []
273 if skipContext is False:
274 self.context.read()
Roger Meier85fb6de2012-11-02 00:05:42 +0000275 self.readJSONSyntaxChar(QUOTE)
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900276 while True:
277 character = self.reader.read()
278 if character == QUOTE:
279 break
280 if ord(character) == ESCSEQ0:
281 character = self.reader.read()
282 if ord(character) == ESCSEQ1:
283 character = self.trans.read(4).decode('ascii')
284 codeunit = int(character, 16)
285 if self._isHighSurrogate(codeunit):
286 if highSurrogate:
287 raise TProtocolException(
288 TProtocolException.INVALID_DATA,
289 "Expected low surrogate char")
290 highSurrogate = codeunit
291 continue
292 elif self._isLowSurrogate(codeunit):
293 if not highSurrogate:
294 raise TProtocolException(
295 TProtocolException.INVALID_DATA,
296 "Expected high surrogate char")
297 character = self._toChar(highSurrogate, codeunit)
298 highSurrogate = None
299 else:
300 character = self._toChar(codeunit)
301 else:
302 if character not in ESCAPE_CHARS:
303 raise TProtocolException(
304 TProtocolException.INVALID_DATA,
305 "Expected control char")
306 character = ESCAPE_CHARS[character]
307 elif character in ESCAPE_CHAR_VALS:
308 raise TProtocolException(TProtocolException.INVALID_DATA,
309 "Unescaped control char")
Alexandre Detisted0787212024-12-26 02:44:13 +0100310 else:
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900311 utf8_bytes = bytearray([ord(character)])
312 while ord(self.reader.peek()) >= 0x80:
313 utf8_bytes.append(ord(self.reader.read()))
Alexandre Detiste3494e1c2025-02-19 21:53:40 +0100314 character = utf8_bytes.decode('utf-8')
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900315 string.append(character)
Roger Meier85fb6de2012-11-02 00:05:42 +0000316
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900317 if highSurrogate:
318 raise TProtocolException(TProtocolException.INVALID_DATA,
319 "Expected low surrogate char")
320 return ''.join(string)
Roger Meier85fb6de2012-11-02 00:05:42 +0000321
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900322 def isJSONNumeric(self, character):
323 return (True if NUMERIC_CHAR.find(character) != - 1 else False)
Roger Meier85fb6de2012-11-02 00:05:42 +0000324
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900325 def readJSONQuotes(self):
326 if (self.context.escapeNum()):
327 self.readJSONSyntaxChar(QUOTE)
Roger Meier85fb6de2012-11-02 00:05:42 +0000328
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900329 def readJSONNumericChars(self):
330 numeric = []
331 while True:
332 character = self.reader.peek()
333 if self.isJSONNumeric(character) is False:
334 break
335 numeric.append(self.reader.read())
336 return b''.join(numeric).decode('ascii')
Roger Meier85fb6de2012-11-02 00:05:42 +0000337
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900338 def readJSONInteger(self):
339 self.context.read()
340 self.readJSONQuotes()
341 numeric = self.readJSONNumericChars()
342 self.readJSONQuotes()
343 try:
344 return int(numeric)
345 except ValueError:
346 raise TProtocolException(TProtocolException.INVALID_DATA,
347 "Bad data encounted in numeric data")
348
349 def readJSONDouble(self):
350 self.context.read()
351 if self.reader.peek() == QUOTE:
352 string = self.readJSONString(True)
353 try:
354 double = float(string)
355 if (self.context.escapeNum is False and
356 not math.isinf(double) and
357 not math.isnan(double)):
358 raise TProtocolException(
359 TProtocolException.INVALID_DATA,
360 "Numeric data unexpectedly quoted")
361 return double
362 except ValueError:
363 raise TProtocolException(TProtocolException.INVALID_DATA,
364 "Bad data encounted in numeric data")
365 else:
366 if self.context.escapeNum() is True:
367 self.readJSONSyntaxChar(QUOTE)
368 try:
369 return float(self.readJSONNumericChars())
370 except ValueError:
371 raise TProtocolException(TProtocolException.INVALID_DATA,
372 "Bad data encounted in numeric data")
373
374 def readJSONBase64(self):
375 string = self.readJSONString(False)
376 size = len(string)
377 m = size % 4
378 # Force padding since b64encode method does not allow it
379 if m != 0:
380 for i in range(4 - m):
381 string += '='
382 return base64.b64decode(string)
383
384 def readJSONObjectStart(self):
385 self.context.read()
386 self.readJSONSyntaxChar(LBRACE)
387 self.pushContext(JSONPairContext(self))
388
389 def readJSONObjectEnd(self):
390 self.readJSONSyntaxChar(RBRACE)
391 self.popContext()
392
393 def readJSONArrayStart(self):
394 self.context.read()
395 self.readJSONSyntaxChar(LBRACKET)
396 self.pushContext(JSONListContext(self))
397
398 def readJSONArrayEnd(self):
399 self.readJSONSyntaxChar(RBRACKET)
400 self.popContext()
Roger Meier85fb6de2012-11-02 00:05:42 +0000401
402
403class TJSONProtocol(TJSONProtocolBase):
404
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900405 def readMessageBegin(self):
406 self.resetReadContext()
407 self.readJSONArrayStart()
408 if self.readJSONInteger() != VERSION:
409 raise TProtocolException(TProtocolException.BAD_VERSION,
410 "Message contained bad version.")
411 name = self.readJSONString(False)
412 typen = self.readJSONInteger()
413 seqid = self.readJSONInteger()
414 return (name, typen, seqid)
Roger Meier85fb6de2012-11-02 00:05:42 +0000415
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900416 def readMessageEnd(self):
417 self.readJSONArrayEnd()
Roger Meier85fb6de2012-11-02 00:05:42 +0000418
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900419 def readStructBegin(self):
420 self.readJSONObjectStart()
Roger Meier85fb6de2012-11-02 00:05:42 +0000421
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900422 def readStructEnd(self):
423 self.readJSONObjectEnd()
Roger Meier85fb6de2012-11-02 00:05:42 +0000424
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900425 def readFieldBegin(self):
426 character = self.reader.peek()
427 ttype = 0
428 id = 0
429 if character == RBRACE:
430 ttype = TType.STOP
431 else:
432 id = self.readJSONInteger()
433 self.readJSONObjectStart()
434 ttype = JTYPES[self.readJSONString(False)]
435 return (None, ttype, id)
Roger Meier85fb6de2012-11-02 00:05:42 +0000436
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900437 def readFieldEnd(self):
438 self.readJSONObjectEnd()
Roger Meier85fb6de2012-11-02 00:05:42 +0000439
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900440 def readMapBegin(self):
441 self.readJSONArrayStart()
442 keyType = JTYPES[self.readJSONString(False)]
443 valueType = JTYPES[self.readJSONString(False)]
444 size = self.readJSONInteger()
445 self.readJSONObjectStart()
446 return (keyType, valueType, size)
Roger Meier85fb6de2012-11-02 00:05:42 +0000447
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900448 def readMapEnd(self):
449 self.readJSONObjectEnd()
450 self.readJSONArrayEnd()
Roger Meier85fb6de2012-11-02 00:05:42 +0000451
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900452 def readCollectionBegin(self):
453 self.readJSONArrayStart()
454 elemType = JTYPES[self.readJSONString(False)]
455 size = self.readJSONInteger()
456 return (elemType, size)
457 readListBegin = readCollectionBegin
458 readSetBegin = readCollectionBegin
Roger Meier85fb6de2012-11-02 00:05:42 +0000459
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900460 def readCollectionEnd(self):
461 self.readJSONArrayEnd()
462 readSetEnd = readCollectionEnd
463 readListEnd = readCollectionEnd
Roger Meier85fb6de2012-11-02 00:05:42 +0000464
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900465 def readBool(self):
466 return (False if self.readJSONInteger() == 0 else True)
Roger Meier85fb6de2012-11-02 00:05:42 +0000467
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900468 def readNumber(self):
469 return self.readJSONInteger()
470 readByte = readNumber
471 readI16 = readNumber
472 readI32 = readNumber
473 readI64 = readNumber
Roger Meier85fb6de2012-11-02 00:05:42 +0000474
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900475 def readDouble(self):
476 return self.readJSONDouble()
Roger Meier85fb6de2012-11-02 00:05:42 +0000477
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900478 def readString(self):
479 return self.readJSONString(False)
Roger Meier85fb6de2012-11-02 00:05:42 +0000480
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900481 def readBinary(self):
482 return self.readJSONBase64()
Roger Meier85fb6de2012-11-02 00:05:42 +0000483
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900484 def writeMessageBegin(self, name, request_type, seqid):
485 self.resetWriteContext()
486 self.writeJSONArrayStart()
487 self.writeJSONNumber(VERSION)
488 self.writeJSONString(name)
489 self.writeJSONNumber(request_type)
490 self.writeJSONNumber(seqid)
Roger Meier85fb6de2012-11-02 00:05:42 +0000491
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900492 def writeMessageEnd(self):
493 self.writeJSONArrayEnd()
Roger Meier85fb6de2012-11-02 00:05:42 +0000494
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900495 def writeStructBegin(self, name):
496 self.writeJSONObjectStart()
Roger Meier85fb6de2012-11-02 00:05:42 +0000497
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900498 def writeStructEnd(self):
499 self.writeJSONObjectEnd()
Roger Meier85fb6de2012-11-02 00:05:42 +0000500
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900501 def writeFieldBegin(self, name, ttype, id):
502 self.writeJSONNumber(id)
503 self.writeJSONObjectStart()
504 self.writeJSONString(CTYPES[ttype])
Roger Meier85fb6de2012-11-02 00:05:42 +0000505
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900506 def writeFieldEnd(self):
507 self.writeJSONObjectEnd()
Roger Meier85fb6de2012-11-02 00:05:42 +0000508
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900509 def writeFieldStop(self):
510 pass
Roger Meier85fb6de2012-11-02 00:05:42 +0000511
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900512 def writeMapBegin(self, ktype, vtype, size):
513 self.writeJSONArrayStart()
514 self.writeJSONString(CTYPES[ktype])
515 self.writeJSONString(CTYPES[vtype])
516 self.writeJSONNumber(size)
517 self.writeJSONObjectStart()
Roger Meier85fb6de2012-11-02 00:05:42 +0000518
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900519 def writeMapEnd(self):
520 self.writeJSONObjectEnd()
521 self.writeJSONArrayEnd()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900522
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900523 def writeListBegin(self, etype, size):
524 self.writeJSONArrayStart()
525 self.writeJSONString(CTYPES[etype])
526 self.writeJSONNumber(size)
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900527
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900528 def writeListEnd(self):
529 self.writeJSONArrayEnd()
Roger Meier85fb6de2012-11-02 00:05:42 +0000530
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900531 def writeSetBegin(self, etype, size):
532 self.writeJSONArrayStart()
533 self.writeJSONString(CTYPES[etype])
534 self.writeJSONNumber(size)
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900535
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900536 def writeSetEnd(self):
537 self.writeJSONArrayEnd()
Roger Meier85fb6de2012-11-02 00:05:42 +0000538
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900539 def writeBool(self, boolean):
540 self.writeJSONNumber(1 if boolean is True else 0)
Roger Meier85fb6de2012-11-02 00:05:42 +0000541
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900542 def writeByte(self, byte):
543 checkIntegerLimits(byte, 8)
544 self.writeJSONNumber(byte)
Konrad Grochowski93fea152014-10-02 16:29:14 +0200545
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900546 def writeI16(self, i16):
547 checkIntegerLimits(i16, 16)
548 self.writeJSONNumber(i16)
Konrad Grochowski93fea152014-10-02 16:29:14 +0200549
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900550 def writeI32(self, i32):
551 checkIntegerLimits(i32, 32)
552 self.writeJSONNumber(i32)
Konrad Grochowski93fea152014-10-02 16:29:14 +0200553
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900554 def writeI64(self, i64):
555 checkIntegerLimits(i64, 64)
556 self.writeJSONNumber(i64)
Roger Meier85fb6de2012-11-02 00:05:42 +0000557
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900558 def writeDouble(self, dbl):
559 # 17 significant digits should be just enough for any double precision
560 # value.
561 self.writeJSONNumber(dbl, '{0:.17g}')
Roger Meier85fb6de2012-11-02 00:05:42 +0000562
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900563 def writeString(self, string):
564 self.writeJSONString(string)
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900565
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900566 def writeBinary(self, binary):
567 self.writeJSONBase64(binary)
Roger Meier85fb6de2012-11-02 00:05:42 +0000568
Roger Meier0895dfe2012-12-26 22:09:55 +0100569
James E. King IIIe44f6a92019-02-07 17:11:21 -0500570class TJSONProtocolFactory(TProtocolFactory):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900571 def getProtocol(self, trans):
572 return TJSONProtocol(trans)
Roger Meier0895dfe2012-12-26 22:09:55 +0100573
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900574 @property
575 def string_length_limit(senf):
576 return None
Nobuaki Sukegawa7b545b52016-01-11 13:46:04 +0900577
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900578 @property
579 def container_length_limit(senf):
580 return None
Nobuaki Sukegawa7b545b52016-01-11 13:46:04 +0900581
Roger Meier0895dfe2012-12-26 22:09:55 +0100582
583class TSimpleJSONProtocol(TJSONProtocolBase):
584 """Simple, readable, write-only JSON protocol.
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900585
Roger Meier0895dfe2012-12-26 22:09:55 +0100586 Useful for interacting with scripting languages.
587 """
588
589 def readMessageBegin(self):
590 raise NotImplementedError()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900591
Roger Meier0895dfe2012-12-26 22:09:55 +0100592 def readMessageEnd(self):
593 raise NotImplementedError()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900594
Roger Meier0895dfe2012-12-26 22:09:55 +0100595 def readStructBegin(self):
596 raise NotImplementedError()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900597
Roger Meier0895dfe2012-12-26 22:09:55 +0100598 def readStructEnd(self):
599 raise NotImplementedError()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900600
Roger Meier0895dfe2012-12-26 22:09:55 +0100601 def writeMessageBegin(self, name, request_type, seqid):
602 self.resetWriteContext()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900603
Roger Meier0895dfe2012-12-26 22:09:55 +0100604 def writeMessageEnd(self):
605 pass
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900606
Roger Meier0895dfe2012-12-26 22:09:55 +0100607 def writeStructBegin(self, name):
608 self.writeJSONObjectStart()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900609
Roger Meier0895dfe2012-12-26 22:09:55 +0100610 def writeStructEnd(self):
611 self.writeJSONObjectEnd()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900612
Roger Meier0895dfe2012-12-26 22:09:55 +0100613 def writeFieldBegin(self, name, ttype, fid):
614 self.writeJSONString(name)
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900615
Roger Meier0895dfe2012-12-26 22:09:55 +0100616 def writeFieldEnd(self):
617 pass
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900618
Roger Meier0895dfe2012-12-26 22:09:55 +0100619 def writeMapBegin(self, ktype, vtype, size):
620 self.writeJSONObjectStart()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900621
Roger Meier0895dfe2012-12-26 22:09:55 +0100622 def writeMapEnd(self):
623 self.writeJSONObjectEnd()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900624
Roger Meier0895dfe2012-12-26 22:09:55 +0100625 def _writeCollectionBegin(self, etype, size):
626 self.writeJSONArrayStart()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900627
Roger Meier0895dfe2012-12-26 22:09:55 +0100628 def _writeCollectionEnd(self):
629 self.writeJSONArrayEnd()
630 writeListBegin = _writeCollectionBegin
631 writeListEnd = _writeCollectionEnd
632 writeSetBegin = _writeCollectionBegin
633 writeSetEnd = _writeCollectionEnd
634
Konrad Grochowski93fea152014-10-02 16:29:14 +0200635 def writeByte(self, byte):
636 checkIntegerLimits(byte, 8)
637 self.writeJSONNumber(byte)
638
639 def writeI16(self, i16):
640 checkIntegerLimits(i16, 16)
641 self.writeJSONNumber(i16)
642
643 def writeI32(self, i32):
644 checkIntegerLimits(i32, 32)
645 self.writeJSONNumber(i32)
646
647 def writeI64(self, i64):
648 checkIntegerLimits(i64, 64)
649 self.writeJSONNumber(i64)
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900650
Roger Meier0895dfe2012-12-26 22:09:55 +0100651 def writeBool(self, boolean):
652 self.writeJSONNumber(1 if boolean is True else 0)
653
654 def writeDouble(self, dbl):
655 self.writeJSONNumber(dbl)
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900656
Roger Meier0895dfe2012-12-26 22:09:55 +0100657 def writeString(self, string):
658 self.writeJSONString(string)
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900659
Roger Meier0895dfe2012-12-26 22:09:55 +0100660 def writeBinary(self, binary):
661 self.writeJSONBase64(binary)
662
663
James E. King IIIe44f6a92019-02-07 17:11:21 -0500664class TSimpleJSONProtocolFactory(TProtocolFactory):
Roger Meier0895dfe2012-12-26 22:09:55 +0100665
666 def getProtocol(self, trans):
667 return TSimpleJSONProtocol(trans)