blob: 004a40a0834ca034314e2b374194980b6ca1cf24 [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 +090024
Roger Meier85fb6de2012-11-02 00:05:42 +000025
Roger Meier0895dfe2012-12-26 22:09:55 +010026__all__ = ['TJSONProtocol',
27 'TJSONProtocolFactory',
28 'TSimpleJSONProtocol',
29 'TSimpleJSONProtocolFactory']
Roger Meier85fb6de2012-11-02 00:05:42 +000030
31VERSION = 1
32
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +090033COMMA = b','
34COLON = b':'
35LBRACE = b'{'
36RBRACE = b'}'
37LBRACKET = b'['
38RBRACKET = b']'
39QUOTE = b'"'
40BACKSLASH = b'\\'
41ZERO = b'0'
Roger Meier85fb6de2012-11-02 00:05:42 +000042
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +090043ESCSEQ0 = ord('\\')
44ESCSEQ1 = ord('u')
45ESCAPE_CHAR_VALS = {
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090046 '"': '\\"',
47 '\\': '\\\\',
48 '\b': '\\b',
49 '\f': '\\f',
50 '\n': '\\n',
51 '\r': '\\r',
52 '\t': '\\t',
53 # '/': '\\/',
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +090054}
55ESCAPE_CHARS = {
56 b'"': '"',
57 b'\\': '\\',
58 b'b': '\b',
59 b'f': '\f',
60 b'n': '\n',
61 b'r': '\r',
62 b't': '\t',
63 b'/': '/',
64}
65NUMERIC_CHAR = b'+-.0123456789Ee'
Roger Meier85fb6de2012-11-02 00:05:42 +000066
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090067CTYPES = {
68 TType.BOOL: 'tf',
69 TType.BYTE: 'i8',
70 TType.I16: 'i16',
71 TType.I32: 'i32',
72 TType.I64: 'i64',
73 TType.DOUBLE: 'dbl',
74 TType.STRING: 'str',
75 TType.STRUCT: 'rec',
76 TType.LIST: 'lst',
77 TType.SET: 'set',
78 TType.MAP: 'map',
79}
Roger Meier85fb6de2012-11-02 00:05:42 +000080
81JTYPES = {}
82for key in CTYPES.keys():
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090083 JTYPES[CTYPES[key]] = key
Roger Meier85fb6de2012-11-02 00:05:42 +000084
85
Roger Meierad8154a2012-12-18 21:02:16 +010086class JSONBaseContext(object):
Roger Meier85fb6de2012-11-02 00:05:42 +000087
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090088 def __init__(self, protocol):
89 self.protocol = protocol
90 self.first = True
Roger Meier85fb6de2012-11-02 00:05:42 +000091
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090092 def doIO(self, function):
93 pass
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +090094
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090095 def write(self):
96 pass
Roger Meier85fb6de2012-11-02 00:05:42 +000097
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +090098 def read(self):
99 pass
Roger Meier85fb6de2012-11-02 00:05:42 +0000100
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900101 def escapeNum(self):
102 return False
Roger Meier85fb6de2012-11-02 00:05:42 +0000103
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900104 def __str__(self):
105 return self.__class__.__name__
Roger Meier0895dfe2012-12-26 22:09:55 +0100106
Roger Meier85fb6de2012-11-02 00:05:42 +0000107
108class JSONListContext(JSONBaseContext):
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900109
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900110 def doIO(self, function):
111 if self.first is True:
112 self.first = False
113 else:
114 function(COMMA)
Roger Meier85fb6de2012-11-02 00:05:42 +0000115
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900116 def write(self):
117 self.doIO(self.protocol.trans.write)
Roger Meier85fb6de2012-11-02 00:05:42 +0000118
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900119 def read(self):
120 self.doIO(self.protocol.readJSONSyntaxChar)
Roger Meier85fb6de2012-11-02 00:05:42 +0000121
122
123class JSONPairContext(JSONBaseContext):
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900124
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900125 def __init__(self, protocol):
126 super(JSONPairContext, self).__init__(protocol)
127 self.colon = True
Roger Meier85fb6de2012-11-02 00:05:42 +0000128
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900129 def doIO(self, function):
130 if self.first:
131 self.first = False
132 self.colon = True
133 else:
134 function(COLON if self.colon else COMMA)
135 self.colon = not self.colon
Roger Meier85fb6de2012-11-02 00:05:42 +0000136
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900137 def write(self):
138 self.doIO(self.protocol.trans.write)
Roger Meier85fb6de2012-11-02 00:05:42 +0000139
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900140 def read(self):
141 self.doIO(self.protocol.readJSONSyntaxChar)
Roger Meier85fb6de2012-11-02 00:05:42 +0000142
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900143 def escapeNum(self):
144 return self.colon
Roger Meier85fb6de2012-11-02 00:05:42 +0000145
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900146 def __str__(self):
147 return '%s, colon=%s' % (self.__class__.__name__, self.colon)
Roger Meier0895dfe2012-12-26 22:09:55 +0100148
Roger Meier85fb6de2012-11-02 00:05:42 +0000149
150class LookaheadReader():
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900151 hasData = False
152 data = ''
Roger Meier85fb6de2012-11-02 00:05:42 +0000153
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900154 def __init__(self, protocol):
155 self.protocol = protocol
Roger Meier85fb6de2012-11-02 00:05:42 +0000156
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900157 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
Roger Meier85fb6de2012-11-02 00:05:42 +0000163
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900164 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
Roger Meier85fb6de2012-11-02 00:05:42 +0000169
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900170
Roger Meier85fb6de2012-11-02 00:05:42 +0000171class TJSONProtocolBase(TProtocolBase):
172
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900173 def __init__(self, trans):
174 TProtocolBase.__init__(self, trans)
175 self.resetWriteContext()
176 self.resetReadContext()
Roger Meier85fb6de2012-11-02 00:05:42 +0000177
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900178 # We don't have length limit implementation for JSON protocols
179 @property
180 def string_length_limit(senf):
181 return None
Nobuaki Sukegawa7b545b52016-01-11 13:46:04 +0900182
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900183 @property
184 def container_length_limit(senf):
185 return None
Nobuaki Sukegawa7b545b52016-01-11 13:46:04 +0900186
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900187 def resetWriteContext(self):
188 self.context = JSONBaseContext(self)
189 self.contextStack = [self.context]
Roger Meier85fb6de2012-11-02 00:05:42 +0000190
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900191 def resetReadContext(self):
192 self.resetWriteContext()
193 self.reader = LookaheadReader(self)
Roger Meier85fb6de2012-11-02 00:05:42 +0000194
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900195 def pushContext(self, ctx):
196 self.contextStack.append(ctx)
197 self.context = ctx
Roger Meier85fb6de2012-11-02 00:05:42 +0000198
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900199 def popContext(self):
200 self.contextStack.pop()
201 if self.contextStack:
202 self.context = self.contextStack[-1]
Roger Meier85fb6de2012-11-02 00:05:42 +0000203 else:
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900204 self.context = JSONBaseContext(self)
205
206 def writeJSONString(self, string):
207 self.context.write()
208 json_str = ['"']
209 for s in string:
210 escaped = ESCAPE_CHAR_VALS.get(s, s)
211 json_str.append(escaped)
212 json_str.append('"')
Alexandre Detiste3494e1c2025-02-19 21:53:40 +0100213 self.trans.write(bytes(''.join(json_str), 'utf-8'))
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900214
215 def writeJSONNumber(self, number, formatter='{0}'):
216 self.context.write()
217 jsNumber = str(formatter.format(number)).encode('ascii')
218 if self.context.escapeNum():
219 self.trans.write(QUOTE)
220 self.trans.write(jsNumber)
221 self.trans.write(QUOTE)
222 else:
223 self.trans.write(jsNumber)
224
225 def writeJSONBase64(self, binary):
226 self.context.write()
227 self.trans.write(QUOTE)
228 self.trans.write(base64.b64encode(binary))
229 self.trans.write(QUOTE)
230
231 def writeJSONObjectStart(self):
232 self.context.write()
233 self.trans.write(LBRACE)
234 self.pushContext(JSONPairContext(self))
235
236 def writeJSONObjectEnd(self):
237 self.popContext()
238 self.trans.write(RBRACE)
239
240 def writeJSONArrayStart(self):
241 self.context.write()
242 self.trans.write(LBRACKET)
243 self.pushContext(JSONListContext(self))
244
245 def writeJSONArrayEnd(self):
246 self.popContext()
247 self.trans.write(RBRACKET)
248
249 def readJSONSyntaxChar(self, character):
250 current = self.reader.read()
251 if character != current:
Roger Meier85fb6de2012-11-02 00:05:42 +0000252 raise TProtocolException(TProtocolException.INVALID_DATA,
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900253 "Unexpected character: %s" % current)
Phongphan Phuttha7f01e2a2015-11-06 15:46:50 +0700254
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900255 def _isHighSurrogate(self, codeunit):
256 return codeunit >= 0xd800 and codeunit <= 0xdbff
Roger Meier85fb6de2012-11-02 00:05:42 +0000257
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900258 def _isLowSurrogate(self, codeunit):
259 return codeunit >= 0xdc00 and codeunit <= 0xdfff
Roger Meier85fb6de2012-11-02 00:05:42 +0000260
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900261 def _toChar(self, high, low=None):
262 if not low:
Alexandre Detisted0787212024-12-26 02:44:13 +0100263 return chr(high)
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900264 else:
265 codepoint = (1 << 16) + ((high & 0x3ff) << 10)
266 codepoint += low & 0x3ff
Alexandre Detisted0787212024-12-26 02:44:13 +0100267 return chr(codepoint)
Roger Meier85fb6de2012-11-02 00:05:42 +0000268
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900269 def readJSONString(self, skipContext):
270 highSurrogate = None
271 string = []
272 if skipContext is False:
273 self.context.read()
Roger Meier85fb6de2012-11-02 00:05:42 +0000274 self.readJSONSyntaxChar(QUOTE)
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900275 while True:
276 character = self.reader.read()
277 if character == QUOTE:
278 break
279 if ord(character) == ESCSEQ0:
280 character = self.reader.read()
281 if ord(character) == ESCSEQ1:
282 character = self.trans.read(4).decode('ascii')
283 codeunit = int(character, 16)
284 if self._isHighSurrogate(codeunit):
285 if highSurrogate:
286 raise TProtocolException(
287 TProtocolException.INVALID_DATA,
288 "Expected low surrogate char")
289 highSurrogate = codeunit
290 continue
291 elif self._isLowSurrogate(codeunit):
292 if not highSurrogate:
293 raise TProtocolException(
294 TProtocolException.INVALID_DATA,
295 "Expected high surrogate char")
296 character = self._toChar(highSurrogate, codeunit)
297 highSurrogate = None
298 else:
299 character = self._toChar(codeunit)
300 else:
301 if character not in ESCAPE_CHARS:
302 raise TProtocolException(
303 TProtocolException.INVALID_DATA,
304 "Expected control char")
305 character = ESCAPE_CHARS[character]
306 elif character in ESCAPE_CHAR_VALS:
307 raise TProtocolException(TProtocolException.INVALID_DATA,
308 "Unescaped control char")
Alexandre Detisted0787212024-12-26 02:44:13 +0100309 else:
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900310 utf8_bytes = bytearray([ord(character)])
311 while ord(self.reader.peek()) >= 0x80:
312 utf8_bytes.append(ord(self.reader.read()))
Alexandre Detiste3494e1c2025-02-19 21:53:40 +0100313 character = utf8_bytes.decode('utf-8')
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900314 string.append(character)
Roger Meier85fb6de2012-11-02 00:05:42 +0000315
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900316 if highSurrogate:
317 raise TProtocolException(TProtocolException.INVALID_DATA,
318 "Expected low surrogate char")
319 return ''.join(string)
Roger Meier85fb6de2012-11-02 00:05:42 +0000320
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900321 def isJSONNumeric(self, character):
322 return (True if NUMERIC_CHAR.find(character) != - 1 else False)
Roger Meier85fb6de2012-11-02 00:05:42 +0000323
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900324 def readJSONQuotes(self):
325 if (self.context.escapeNum()):
326 self.readJSONSyntaxChar(QUOTE)
Roger Meier85fb6de2012-11-02 00:05:42 +0000327
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900328 def readJSONNumericChars(self):
329 numeric = []
330 while True:
331 character = self.reader.peek()
332 if self.isJSONNumeric(character) is False:
333 break
334 numeric.append(self.reader.read())
335 return b''.join(numeric).decode('ascii')
Roger Meier85fb6de2012-11-02 00:05:42 +0000336
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900337 def readJSONInteger(self):
338 self.context.read()
339 self.readJSONQuotes()
340 numeric = self.readJSONNumericChars()
341 self.readJSONQuotes()
342 try:
343 return int(numeric)
344 except ValueError:
345 raise TProtocolException(TProtocolException.INVALID_DATA,
346 "Bad data encounted in numeric data")
347
348 def readJSONDouble(self):
349 self.context.read()
350 if self.reader.peek() == QUOTE:
351 string = self.readJSONString(True)
352 try:
353 double = float(string)
354 if (self.context.escapeNum is False and
355 not math.isinf(double) and
356 not math.isnan(double)):
357 raise TProtocolException(
358 TProtocolException.INVALID_DATA,
359 "Numeric data unexpectedly quoted")
360 return double
361 except ValueError:
362 raise TProtocolException(TProtocolException.INVALID_DATA,
363 "Bad data encounted in numeric data")
364 else:
365 if self.context.escapeNum() is True:
366 self.readJSONSyntaxChar(QUOTE)
367 try:
368 return float(self.readJSONNumericChars())
369 except ValueError:
370 raise TProtocolException(TProtocolException.INVALID_DATA,
371 "Bad data encounted in numeric data")
372
373 def readJSONBase64(self):
374 string = self.readJSONString(False)
375 size = len(string)
376 m = size % 4
377 # Force padding since b64encode method does not allow it
378 if m != 0:
379 for i in range(4 - m):
380 string += '='
381 return base64.b64decode(string)
382
383 def readJSONObjectStart(self):
384 self.context.read()
385 self.readJSONSyntaxChar(LBRACE)
386 self.pushContext(JSONPairContext(self))
387
388 def readJSONObjectEnd(self):
389 self.readJSONSyntaxChar(RBRACE)
390 self.popContext()
391
392 def readJSONArrayStart(self):
393 self.context.read()
394 self.readJSONSyntaxChar(LBRACKET)
395 self.pushContext(JSONListContext(self))
396
397 def readJSONArrayEnd(self):
398 self.readJSONSyntaxChar(RBRACKET)
399 self.popContext()
Roger Meier85fb6de2012-11-02 00:05:42 +0000400
401
402class TJSONProtocol(TJSONProtocolBase):
403
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900404 def readMessageBegin(self):
405 self.resetReadContext()
406 self.readJSONArrayStart()
407 if self.readJSONInteger() != VERSION:
408 raise TProtocolException(TProtocolException.BAD_VERSION,
409 "Message contained bad version.")
410 name = self.readJSONString(False)
411 typen = self.readJSONInteger()
412 seqid = self.readJSONInteger()
413 return (name, typen, seqid)
Roger Meier85fb6de2012-11-02 00:05:42 +0000414
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900415 def readMessageEnd(self):
416 self.readJSONArrayEnd()
Roger Meier85fb6de2012-11-02 00:05:42 +0000417
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900418 def readStructBegin(self):
419 self.readJSONObjectStart()
Roger Meier85fb6de2012-11-02 00:05:42 +0000420
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900421 def readStructEnd(self):
422 self.readJSONObjectEnd()
Roger Meier85fb6de2012-11-02 00:05:42 +0000423
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900424 def readFieldBegin(self):
425 character = self.reader.peek()
426 ttype = 0
427 id = 0
428 if character == RBRACE:
429 ttype = TType.STOP
430 else:
431 id = self.readJSONInteger()
432 self.readJSONObjectStart()
433 ttype = JTYPES[self.readJSONString(False)]
434 return (None, ttype, id)
Roger Meier85fb6de2012-11-02 00:05:42 +0000435
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900436 def readFieldEnd(self):
437 self.readJSONObjectEnd()
Roger Meier85fb6de2012-11-02 00:05:42 +0000438
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900439 def readMapBegin(self):
440 self.readJSONArrayStart()
441 keyType = JTYPES[self.readJSONString(False)]
442 valueType = JTYPES[self.readJSONString(False)]
443 size = self.readJSONInteger()
444 self.readJSONObjectStart()
445 return (keyType, valueType, size)
Roger Meier85fb6de2012-11-02 00:05:42 +0000446
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900447 def readMapEnd(self):
448 self.readJSONObjectEnd()
449 self.readJSONArrayEnd()
Roger Meier85fb6de2012-11-02 00:05:42 +0000450
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900451 def readCollectionBegin(self):
452 self.readJSONArrayStart()
453 elemType = JTYPES[self.readJSONString(False)]
454 size = self.readJSONInteger()
455 return (elemType, size)
456 readListBegin = readCollectionBegin
457 readSetBegin = readCollectionBegin
Roger Meier85fb6de2012-11-02 00:05:42 +0000458
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900459 def readCollectionEnd(self):
460 self.readJSONArrayEnd()
461 readSetEnd = readCollectionEnd
462 readListEnd = readCollectionEnd
Roger Meier85fb6de2012-11-02 00:05:42 +0000463
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900464 def readBool(self):
465 return (False if self.readJSONInteger() == 0 else True)
Roger Meier85fb6de2012-11-02 00:05:42 +0000466
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900467 def readNumber(self):
468 return self.readJSONInteger()
469 readByte = readNumber
470 readI16 = readNumber
471 readI32 = readNumber
472 readI64 = readNumber
Roger Meier85fb6de2012-11-02 00:05:42 +0000473
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900474 def readDouble(self):
475 return self.readJSONDouble()
Roger Meier85fb6de2012-11-02 00:05:42 +0000476
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900477 def readString(self):
478 return self.readJSONString(False)
Roger Meier85fb6de2012-11-02 00:05:42 +0000479
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900480 def readBinary(self):
481 return self.readJSONBase64()
Roger Meier85fb6de2012-11-02 00:05:42 +0000482
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900483 def writeMessageBegin(self, name, request_type, seqid):
484 self.resetWriteContext()
485 self.writeJSONArrayStart()
486 self.writeJSONNumber(VERSION)
487 self.writeJSONString(name)
488 self.writeJSONNumber(request_type)
489 self.writeJSONNumber(seqid)
Roger Meier85fb6de2012-11-02 00:05:42 +0000490
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900491 def writeMessageEnd(self):
492 self.writeJSONArrayEnd()
Roger Meier85fb6de2012-11-02 00:05:42 +0000493
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900494 def writeStructBegin(self, name):
495 self.writeJSONObjectStart()
Roger Meier85fb6de2012-11-02 00:05:42 +0000496
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900497 def writeStructEnd(self):
498 self.writeJSONObjectEnd()
Roger Meier85fb6de2012-11-02 00:05:42 +0000499
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900500 def writeFieldBegin(self, name, ttype, id):
501 self.writeJSONNumber(id)
502 self.writeJSONObjectStart()
503 self.writeJSONString(CTYPES[ttype])
Roger Meier85fb6de2012-11-02 00:05:42 +0000504
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900505 def writeFieldEnd(self):
506 self.writeJSONObjectEnd()
Roger Meier85fb6de2012-11-02 00:05:42 +0000507
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900508 def writeFieldStop(self):
509 pass
Roger Meier85fb6de2012-11-02 00:05:42 +0000510
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900511 def writeMapBegin(self, ktype, vtype, size):
512 self.writeJSONArrayStart()
513 self.writeJSONString(CTYPES[ktype])
514 self.writeJSONString(CTYPES[vtype])
515 self.writeJSONNumber(size)
516 self.writeJSONObjectStart()
Roger Meier85fb6de2012-11-02 00:05:42 +0000517
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900518 def writeMapEnd(self):
519 self.writeJSONObjectEnd()
520 self.writeJSONArrayEnd()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900521
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900522 def writeListBegin(self, etype, size):
523 self.writeJSONArrayStart()
524 self.writeJSONString(CTYPES[etype])
525 self.writeJSONNumber(size)
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900526
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900527 def writeListEnd(self):
528 self.writeJSONArrayEnd()
Roger Meier85fb6de2012-11-02 00:05:42 +0000529
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900530 def writeSetBegin(self, etype, size):
531 self.writeJSONArrayStart()
532 self.writeJSONString(CTYPES[etype])
533 self.writeJSONNumber(size)
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900534
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900535 def writeSetEnd(self):
536 self.writeJSONArrayEnd()
Roger Meier85fb6de2012-11-02 00:05:42 +0000537
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900538 def writeBool(self, boolean):
539 self.writeJSONNumber(1 if boolean is True else 0)
Roger Meier85fb6de2012-11-02 00:05:42 +0000540
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900541 def writeByte(self, byte):
542 checkIntegerLimits(byte, 8)
543 self.writeJSONNumber(byte)
Konrad Grochowski93fea152014-10-02 16:29:14 +0200544
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900545 def writeI16(self, i16):
546 checkIntegerLimits(i16, 16)
547 self.writeJSONNumber(i16)
Konrad Grochowski93fea152014-10-02 16:29:14 +0200548
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900549 def writeI32(self, i32):
550 checkIntegerLimits(i32, 32)
551 self.writeJSONNumber(i32)
Konrad Grochowski93fea152014-10-02 16:29:14 +0200552
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900553 def writeI64(self, i64):
554 checkIntegerLimits(i64, 64)
555 self.writeJSONNumber(i64)
Roger Meier85fb6de2012-11-02 00:05:42 +0000556
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900557 def writeDouble(self, dbl):
558 # 17 significant digits should be just enough for any double precision
559 # value.
560 self.writeJSONNumber(dbl, '{0:.17g}')
Roger Meier85fb6de2012-11-02 00:05:42 +0000561
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900562 def writeString(self, string):
563 self.writeJSONString(string)
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900564
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900565 def writeBinary(self, binary):
566 self.writeJSONBase64(binary)
Roger Meier85fb6de2012-11-02 00:05:42 +0000567
Roger Meier0895dfe2012-12-26 22:09:55 +0100568
James E. King IIIe44f6a92019-02-07 17:11:21 -0500569class TJSONProtocolFactory(TProtocolFactory):
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900570 def getProtocol(self, trans):
571 return TJSONProtocol(trans)
Roger Meier0895dfe2012-12-26 22:09:55 +0100572
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900573 @property
574 def string_length_limit(senf):
575 return None
Nobuaki Sukegawa7b545b52016-01-11 13:46:04 +0900576
Nobuaki Sukegawa10308cb2016-02-03 01:57:03 +0900577 @property
578 def container_length_limit(senf):
579 return None
Nobuaki Sukegawa7b545b52016-01-11 13:46:04 +0900580
Roger Meier0895dfe2012-12-26 22:09:55 +0100581
582class TSimpleJSONProtocol(TJSONProtocolBase):
583 """Simple, readable, write-only JSON protocol.
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900584
Roger Meier0895dfe2012-12-26 22:09:55 +0100585 Useful for interacting with scripting languages.
586 """
587
588 def readMessageBegin(self):
589 raise NotImplementedError()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900590
Roger Meier0895dfe2012-12-26 22:09:55 +0100591 def readMessageEnd(self):
592 raise NotImplementedError()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900593
Roger Meier0895dfe2012-12-26 22:09:55 +0100594 def readStructBegin(self):
595 raise NotImplementedError()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900596
Roger Meier0895dfe2012-12-26 22:09:55 +0100597 def readStructEnd(self):
598 raise NotImplementedError()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900599
Roger Meier0895dfe2012-12-26 22:09:55 +0100600 def writeMessageBegin(self, name, request_type, seqid):
601 self.resetWriteContext()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900602
Roger Meier0895dfe2012-12-26 22:09:55 +0100603 def writeMessageEnd(self):
604 pass
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900605
Roger Meier0895dfe2012-12-26 22:09:55 +0100606 def writeStructBegin(self, name):
607 self.writeJSONObjectStart()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900608
Roger Meier0895dfe2012-12-26 22:09:55 +0100609 def writeStructEnd(self):
610 self.writeJSONObjectEnd()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900611
Roger Meier0895dfe2012-12-26 22:09:55 +0100612 def writeFieldBegin(self, name, ttype, fid):
613 self.writeJSONString(name)
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900614
Roger Meier0895dfe2012-12-26 22:09:55 +0100615 def writeFieldEnd(self):
616 pass
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900617
Roger Meier0895dfe2012-12-26 22:09:55 +0100618 def writeMapBegin(self, ktype, vtype, size):
619 self.writeJSONObjectStart()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900620
Roger Meier0895dfe2012-12-26 22:09:55 +0100621 def writeMapEnd(self):
622 self.writeJSONObjectEnd()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900623
Roger Meier0895dfe2012-12-26 22:09:55 +0100624 def _writeCollectionBegin(self, etype, size):
625 self.writeJSONArrayStart()
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900626
Roger Meier0895dfe2012-12-26 22:09:55 +0100627 def _writeCollectionEnd(self):
628 self.writeJSONArrayEnd()
629 writeListBegin = _writeCollectionBegin
630 writeListEnd = _writeCollectionEnd
631 writeSetBegin = _writeCollectionBegin
632 writeSetEnd = _writeCollectionEnd
633
Konrad Grochowski93fea152014-10-02 16:29:14 +0200634 def writeByte(self, byte):
635 checkIntegerLimits(byte, 8)
636 self.writeJSONNumber(byte)
637
638 def writeI16(self, i16):
639 checkIntegerLimits(i16, 16)
640 self.writeJSONNumber(i16)
641
642 def writeI32(self, i32):
643 checkIntegerLimits(i32, 32)
644 self.writeJSONNumber(i32)
645
646 def writeI64(self, i64):
647 checkIntegerLimits(i64, 64)
648 self.writeJSONNumber(i64)
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900649
Roger Meier0895dfe2012-12-26 22:09:55 +0100650 def writeBool(self, boolean):
651 self.writeJSONNumber(1 if boolean is True else 0)
652
653 def writeDouble(self, dbl):
654 self.writeJSONNumber(dbl)
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900655
Roger Meier0895dfe2012-12-26 22:09:55 +0100656 def writeString(self, string):
657 self.writeJSONString(string)
Nobuaki Sukegawa760511f2015-11-06 21:24:16 +0900658
Roger Meier0895dfe2012-12-26 22:09:55 +0100659 def writeBinary(self, binary):
660 self.writeJSONBase64(binary)
661
662
James E. King IIIe44f6a92019-02-07 17:11:21 -0500663class TSimpleJSONProtocolFactory(TProtocolFactory):
Roger Meier0895dfe2012-12-26 22:09:55 +0100664
665 def getProtocol(self, trans):
666 return TSimpleJSONProtocol(trans)