<s> """<STR_LIT>""" <EOL> import sys <EOL> import decimal <EOL> import re <EOL> import json <EOL> import logging <EOL> from . import util <EOL> if sys . version_info [ <NUM_LIT:0> ] == <NUM_LIT:2> : <EOL> from StringIO import StringIO <EOL> else : <EOL> from io import StringIO <EOL> logger = logging . getLogger ( __name__ ) <EOL> OBJECT = "<STR_LIT>" <EOL> ARRAY = "<STR_LIT>" <EOL> FIELD = "<STR_LIT>" <EOL> STRING = "<STR_LIT>" <EOL> NUMBER = "<STR_LIT>" <EOL> BOOLEAN = "<STR_LIT>" <EOL> NULL = "<STR_LIT:null>" <EOL> TRUE = "<STR_LIT:true>" <EOL> FALSE = "<STR_LIT:false>" <EOL> START_OBJECT = "<STR_LIT>" <EOL> START_ARRAY = "<STR_LIT>" <EOL> FIELD_NAME = "<STR_LIT>" <EOL> FIELD_VALUE = "<STR_LIT>" <EOL> ARRAY_VALUE = "<STR_LIT>" <EOL> END_OBJECT = "<STR_LIT>" <EOL> END_ARRAY = "<STR_LIT>" <EOL> JSON_SYNTAX_ERROR = "<STR_LIT>" <EOL> JSON_INCOMPLETE_ERROR = "<STR_LIT>" <EOL> JSON_UNEXPECTED_ELEMENT_ERROR = "<STR_LIT>" <EOL> class JSONPullParser ( object ) : <EOL> def __init__ ( self , stream , size = <NUM_LIT:2> ** <NUM_LIT:16> ) : <EOL> """<STR_LIT>""" <EOL> self . stream = stream <EOL> self . size = size <EOL> self . node = None <EOL> self . value = "<STR_LIT>" <EOL> self . valueType = None <EOL> self . tokens = [ ] <EOL> self . tokenIndex = <NUM_LIT:0> <EOL> self . halfToken = "<STR_LIT>" <EOL> self . pattern = re . compile ( '<STR_LIT>' ) <EOL> def expectObject ( self ) : <EOL> """<STR_LIT>""" <EOL> event = self . nextEvent ( ) <EOL> if event . type != START_OBJECT : <EOL> raise JSONParseError ( <EOL> JSON_UNEXPECTED_ELEMENT_ERROR , <EOL> "<STR_LIT>" + str ( event ) ) <EOL> def expectArray ( self ) : <EOL> """<STR_LIT>""" <EOL> event = self . nextEvent ( ) <EOL> if event . type != START_ARRAY : <EOL> raise JSONParseError ( <EOL> JSON_UNEXPECTED_ELEMENT_ERROR , <EOL> "<STR_LIT>" + str ( event ) ) <EOL> return JSONArrayIterator ( self ) <EOL> def expectField ( self , expectedName , expectedType = None , allowNull = False , <EOL> readAll = False ) : <EOL> """<STR_LIT>""" <EOL> event = self . nextEvent ( ) <EOL> if event . type != FIELD_NAME : <EOL> raise JSONParseError ( <EOL> JSON_UNEXPECTED_ELEMENT_ERROR , <EOL> "<STR_LIT>" + str ( event ) ) <EOL> if event . value != expectedName : <EOL> raise JSONParseError ( JSON_UNEXPECTED_ELEMENT_ERROR , "<STR_LIT>" + <EOL> expectedName + "<STR_LIT>" + <EOL> event . value + "<STR_LIT>" ) <EOL> return self . _expectValue ( FIELD_VALUE , expectedType , allowNull , readAll ) <EOL> def expectArrayValue ( self , expectedType = None , allowNull = False , <EOL> readAll = False ) : <EOL> """<STR_LIT>""" <EOL> return self . _expectValue ( ARRAY_VALUE , expectedType , allowNull , readAll ) <EOL> def _expectValue ( self , eventType , expectedType , allowNull , readAll ) : <EOL> event = self . nextEvent ( ) <EOL> if event . type == eventType : <EOL> if allowNull and event . valueType == NULL : <EOL> return None <EOL> elif expectedType is not None and event . valueType != expectedType : <EOL> raise JSONParseError ( <EOL> JSON_UNEXPECTED_ELEMENT_ERROR , "<STR_LIT>" + expectedType + <EOL> "<STR_LIT>" + event . valueType + "<STR_LIT>" ) <EOL> else : <EOL> return event . value <EOL> else : <EOL> if eventType == ARRAY_VALUE : <EOL> if event . node . parent is None or event . node . parent != ARRAY : <EOL> raise JSONParseError ( <EOL> JSON_UNEXPECTED_ELEMENT_ERROR , <EOL> "<STR_LIT>" ) <EOL> if event . type == START_OBJECT : <EOL> if expectedType is not None and expectedType != OBJECT : <EOL> raise JSONParseError ( <EOL> JSON_UNEXPECTED_ELEMENT_ERROR , "<STR_LIT>" + <EOL> expectedType + "<STR_LIT>" ) <EOL> elif expectedType is None or readAll : <EOL> return self . readObject ( event ) <EOL> elif event . type == START_ARRAY : <EOL> if expectedType is not None and expectedType != ARRAY : <EOL> raise JSONParseError ( <EOL> JSON_UNEXPECTED_ELEMENT_ERROR , "<STR_LIT>" + <EOL> expectedType + "<STR_LIT>" ) <EOL> if expectedType is None or readAll : <EOL> return self . readArray ( event ) <EOL> else : <EOL> return JSONArrayIterator ( self ) <EOL> else : <EOL> raise JSONParseError ( <EOL> JSON_UNEXPECTED_ELEMENT_ERROR , <EOL> "<STR_LIT>" + str ( event ) ) <EOL> def readObject ( self , event = None ) : <EOL> """<STR_LIT>""" <EOL> if event is None : <EOL> event = self . nextEvent ( ) <EOL> popRequired = False <EOL> else : <EOL> popRequired = True <EOL> if event is None : <EOL> return None <EOL> if event . type != START_OBJECT : <EOL> raise JSONParseError ( <EOL> JSON_UNEXPECTED_ELEMENT_ERROR , <EOL> "<STR_LIT>" + event . type + "<STR_LIT>" ) <EOL> obj = self . _load ( event ) <EOL> if popRequired : <EOL> self . _pop ( ) <EOL> return obj <EOL> def readArray ( self , event = None ) : <EOL> """<STR_LIT>""" <EOL> if event is None : <EOL> event = self . nextEvent ( ) <EOL> popRequired = False <EOL> else : <EOL> popRequired = True <EOL> if event is None : <EOL> return None <EOL> if event . type != START_ARRAY : <EOL> raise JSONParseError ( <EOL> JSON_UNEXPECTED_ELEMENT_ERROR , <EOL> "<STR_LIT>" + event . type + "<STR_LIT>" ) <EOL> arr = self . _load ( event ) <EOL> if popRequired : <EOL> self . _pop ( ) <EOL> return arr <EOL> def nextEvent ( self ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> return self . __next__ ( ) <EOL> except StopIteration : <EOL> return None <EOL> def next ( self ) : <EOL> """<STR_LIT>""" <EOL> return self . __next__ ( ) <EOL> def __next__ ( self ) : <EOL> """<STR_LIT>""" <EOL> while True : <EOL> try : <EOL> token = self . tokens [ self . tokenIndex ] <EOL> self . tokenIndex += <NUM_LIT:1> <EOL> if token == "<STR_LIT>" or token . isspace ( ) : <EOL> pass <EOL> elif token == '<STR_LIT:{>' : <EOL> return self . _push ( OBJECT ) <EOL> elif token == '<STR_LIT:}>' : <EOL> if self . node . type == FIELD : <EOL> self . tokenIndex -= <NUM_LIT:1> <EOL> event = self . _pop ( ) <EOL> if event is not None : <EOL> return event <EOL> elif self . node . type == OBJECT : <EOL> return self . _pop ( ) <EOL> else : <EOL> raise JSONParseError ( <EOL> JSON_SYNTAX_ERROR , <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> elif token == '<STR_LIT:[>' : <EOL> if self . node is not None and self . node . type == OBJECT : <EOL> raise JSONParseError ( <EOL> JSON_SYNTAX_ERROR , "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> return self . _push ( ARRAY ) <EOL> elif token == '<STR_LIT:]>' : <EOL> if self . valueType is not None : <EOL> self . tokenIndex -= <NUM_LIT:1> <EOL> event = self . _arrayValue ( ) <EOL> if event is not None : <EOL> return event <EOL> elif self . node . type == ARRAY : <EOL> if self . node . lastIndex == self . node . arrayLength : <EOL> self . node . arrayLength += <NUM_LIT:1> <EOL> return self . _pop ( ) <EOL> else : <EOL> raise JSONParseError ( <EOL> JSON_SYNTAX_ERROR , "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> elif token == '<STR_LIT::>' : <EOL> if self . node . type == OBJECT : <EOL> if self . value != "<STR_LIT>" and self . valueType == STRING : <EOL> event = self . _push ( FIELD , self . value ) <EOL> self . value = "<STR_LIT>" <EOL> self . valueType = None <EOL> return event <EOL> else : <EOL> raise JSONParseError ( <EOL> JSON_SYNTAX_ERROR , <EOL> "<STR_LIT>" ) <EOL> else : <EOL> raise JSONParseError ( <EOL> JSON_SYNTAX_ERROR , <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> elif token == '<STR_LIT:U+002C>' : <EOL> if self . node . type == ARRAY : <EOL> event = self . _arrayValue ( ) <EOL> self . node . arrayLength += <NUM_LIT:1> <EOL> elif self . node . type == FIELD : <EOL> event = self . _pop ( ) <EOL> else : <EOL> raise JSONParseError ( <EOL> JSON_SYNTAX_ERROR , <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> if event is not None : <EOL> return event <EOL> else : <EOL> if self . valueType is not None : <EOL> raise JSONParseError ( <EOL> JSON_SYNTAX_ERROR , "<STR_LIT>" <EOL> "<STR_LIT>" + str ( self . value ) ) <EOL> elif self . node is None : <EOL> raise JSONParseError ( <EOL> JSON_SYNTAX_ERROR , <EOL> "<STR_LIT>" <EOL> "<STR_LIT>" + token + <EOL> "<STR_LIT>" ) <EOL> elif token == '<STR_LIT:">' : <EOL> escape = False <EOL> while True : <EOL> try : <EOL> token = self . tokens [ self . tokenIndex ] <EOL> self . tokenIndex += <NUM_LIT:1> <EOL> if token == "<STR_LIT>" : <EOL> pass <EOL> elif escape : <EOL> escape = False <EOL> self . value += token <EOL> elif token == '<STR_LIT:">' : <EOL> break <EOL> elif token == '<STR_LIT:\\>' : <EOL> escape = True <EOL> else : <EOL> self . value += token <EOL> except IndexError : <EOL> data = self . stream . read ( self . size ) <EOL> if data == "<STR_LIT>" : <EOL> raise JSONParseError ( <EOL> JSON_INCOMPLETE_ERROR , <EOL> "<STR_LIT>" + <EOL> "<STR_LIT>" ) <EOL> self . tokens = self . pattern . split ( data ) <EOL> self . tokenIndex = <NUM_LIT:0> <EOL> self . valueType = STRING <EOL> else : <EOL> token = token . strip ( ) <EOL> if self . tokenIndex == len ( self . tokens ) : <EOL> self . halfToken = token <EOL> raise IndexError <EOL> elif token [ <NUM_LIT:0> ] . isdigit ( ) or token [ <NUM_LIT:0> ] == '<STR_LIT:->' : <EOL> self . value = decimal . Decimal ( token ) <EOL> self . valueType = NUMBER <EOL> elif token == "<STR_LIT:null>" : <EOL> self . value = None <EOL> self . valueType = NULL <EOL> elif token == "<STR_LIT:true>" : <EOL> self . value = True <EOL> self . valueType = BOOLEAN <EOL> elif token == "<STR_LIT:false>" : <EOL> self . value = False <EOL> self . valueType = BOOLEAN <EOL> else : <EOL> raise JSONParseError ( <EOL> JSON_SYNTAX_ERROR , <EOL> "<STR_LIT>" + token ) <EOL> except IndexError : <EOL> data = self . stream . read ( self . size ) <EOL> if data == "<STR_LIT>" : <EOL> if self . node is not None : <EOL> raise JSONParseError ( <EOL> JSON_INCOMPLETE_ERROR , "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> else : <EOL> raise StopIteration ( ) <EOL> return None <EOL> logger . trace ( data ) <EOL> self . tokens = self . pattern . split ( data ) <EOL> self . tokenIndex = <NUM_LIT:0> <EOL> if self . halfToken is not None : <EOL> self . tokens [ <NUM_LIT:0> ] = self . halfToken + self . tokens [ <NUM_LIT:0> ] <EOL> self . halfToken = None <EOL> def _load ( self , event ) : <EOL> if event . type == START_OBJECT : <EOL> value = start = "<STR_LIT:{>" <EOL> end = "<STR_LIT:}>" <EOL> elif event . type == START_ARRAY : <EOL> value = start = "<STR_LIT:[>" <EOL> end = "<STR_LIT:]>" <EOL> else : <EOL> raise JSONParseError ( <EOL> JSON_UNEXPECTED_ELEMENT_ERROR , <EOL> "<STR_LIT>" + event . type ) <EOL> count = <NUM_LIT:1> <EOL> tokens = self . tokens <EOL> tokenIndex = self . tokenIndex <EOL> inString = False <EOL> inEscape = False <EOL> try : <EOL> while True : <EOL> startIndex = tokenIndex <EOL> for token in tokens [ startIndex : ] : <EOL> tokenIndex += <NUM_LIT:1> <EOL> if token == "<STR_LIT>" : <EOL> pass <EOL> elif inString : <EOL> if inEscape : <EOL> inEscape = False <EOL> elif token == '<STR_LIT:">' : <EOL> inString = False <EOL> elif token == '<STR_LIT:\\>' : <EOL> inEscape = True <EOL> elif token == '<STR_LIT:">' : <EOL> inString = True <EOL> elif token == start : <EOL> count += <NUM_LIT:1> <EOL> elif token == end : <EOL> count -= <NUM_LIT:1> <EOL> if count == <NUM_LIT:0> : <EOL> value += "<STR_LIT>" . join ( tokens [ startIndex : tokenIndex ] ) <EOL> raise StopIteration ( ) <EOL> value += "<STR_LIT>" . join ( tokens [ startIndex : ] ) <EOL> data = self . stream . read ( self . size ) <EOL> if data == "<STR_LIT>" : <EOL> raise JSONParseError ( <EOL> JSON_INCOMPLETE_ERROR , "<STR_LIT>" <EOL> "<STR_LIT>" ) <EOL> tokens = self . pattern . split ( data ) <EOL> tokenIndex = <NUM_LIT:0> <EOL> except StopIteration : <EOL> pass <EOL> self . tokens = tokens <EOL> self . tokenIndex = tokenIndex <EOL> try : <EOL> return json . loads ( value , parse_float = decimal . Decimal , <EOL> parse_int = decimal . Decimal ) <EOL> except ValueError as e : <EOL> raise JSONParseError ( JSON_SYNTAX_ERROR , "<STR_LIT>" . join ( e . args ) ) <EOL> def _push ( self , nodeType , value = None ) : <EOL> if self . node is not None and self . node . type == FIELD : <EOL> self . node . valueType = nodeType <EOL> self . node = JSONNode ( self . node , nodeType , value ) <EOL> if self . node . parent is not None and self . node . parent . type == ARRAY : <EOL> self . node . arrayIndex = self . node . parent . arrayLength <EOL> if self . node . parent . lastIndex == self . node . parent . arrayLength : <EOL> raise JSONParseError ( <EOL> JSON_SYNTAX_ERROR , <EOL> "<STR_LIT>" ) <EOL> self . node . parent . lastIndex = self . node . parent . arrayLength <EOL> return self . node . startEvent ( ) <EOL> def _pop ( self ) : <EOL> node = self . node <EOL> self . node = self . node . parent <EOL> if node . valueType is None : <EOL> node . valueType = self . valueType <EOL> node . value = self . value <EOL> self . value = "<STR_LIT>" <EOL> self . valueType = None <EOL> if node . type == FIELD and node . valueType is None : <EOL> raise JSONParseError ( <EOL> JSON_SYNTAX_ERROR , "<STR_LIT>" + node . name ) <EOL> return node . endEvent ( ) <EOL> def _arrayValue ( self ) : <EOL> endOfArray = self . node . lastIndex == self . node . arrayLength <EOL> if self . valueType is None and endOfArray : <EOL> pass <EOL> elif self . valueType is None : <EOL> raise JSONParseError ( <EOL> JSON_SYNTAX_ERROR , <EOL> "<STR_LIT>" + <EOL> str ( self . node . arrayLength ) ) <EOL> else : <EOL> event = JSONEvent ( <EOL> self . node , ARRAY_VALUE , self . value , self . valueType , <EOL> self . node . arrayLength ) <EOL> self . node . lastIndex = self . node . arrayLength <EOL> self . value = "<STR_LIT>" <EOL> self . valueType = None <EOL> return event <EOL> def __iter__ ( self ) : <EOL> return self <EOL> class JSONParseError ( Exception ) : <EOL> def __init__ ( self , code , msg ) : <EOL> self . args = ( code , msg ) <EOL> self . code = code <EOL> self . msg = msg <EOL> class JSONNode ( object ) : <EOL> def __init__ ( self , parent , nodeType , name = None , value = None , <EOL> valueType = None ) : <EOL> self . parent = parent <EOL> self . type = nodeType <EOL> self . name = name <EOL> self . value = value <EOL> self . valueType = valueType <EOL> self . arrayIndex = None <EOL> self . arrayLength = None <EOL> self . lastIndex = - <NUM_LIT:1> <EOL> if nodeType == ARRAY : <EOL> self . arrayLength = <NUM_LIT:0> <EOL> def startEvent ( self ) : <EOL> if self . type == ARRAY : <EOL> return JSONEvent ( self , START_ARRAY , arrayIndex = self . arrayIndex ) <EOL> elif self . type == OBJECT : <EOL> return JSONEvent ( self , START_OBJECT , arrayIndex = self . arrayIndex ) <EOL> elif self . type == FIELD : <EOL> return JSONEvent ( self , FIELD_NAME , self . name ) <EOL> def endEvent ( self ) : <EOL> if self . type == ARRAY : <EOL> return JSONEvent ( self , END_ARRAY , arrayIndex = self . arrayIndex , <EOL> arrayLength = self . arrayLength ) <EOL> elif self . type == OBJECT : <EOL> return JSONEvent ( self , END_OBJECT , arrayIndex = self . arrayIndex ) <EOL> elif self . type == FIELD and self . valueType not in ( OBJECT , ARRAY ) : <EOL> return JSONEvent ( self , FIELD_VALUE , self . value , self . valueType ) <EOL> class JSONEvent ( object ) : <EOL> def __init__ ( self , node , eventType , value = None , valueType = None , <EOL> arrayIndex = None , arrayLength = None ) : <EOL> self . node = node <EOL> self . type = eventType <EOL> self . value = value <EOL> self . valueType = valueType <EOL> self . arrayIndex = arrayIndex <EOL> self . arrayLength = arrayLength <EOL> def __repr__ ( self ) : <EOL> text = "<STR_LIT>" + self . type <EOL> if self . value is not None : <EOL> text += "<STR_LIT>" + str ( self . value ) <EOL> if self . valueType is not None : <EOL> text += "<STR_LIT>" + str ( self . valueType ) <EOL> if self . arrayIndex is not None : <EOL> text += "<STR_LIT>" + str ( self . arrayIndex ) <EOL> if self . arrayLength is not None : <EOL> text += "<STR_LIT>" + str ( self . arrayLength ) <EOL> text += "<STR_LIT:)>" <EOL> return text <EOL> class JSONArrayIterator ( object ) : <EOL> def __init__ ( self , parser ) : <EOL> self . parser = parser <EOL> self . complete = False <EOL> def __iter__ ( self ) : <EOL> return self <EOL> def __next__ ( self ) : <EOL> if self . complete : <EOL> raise StopIteration ( ) <EOL> else : <EOL> event = self . parser . nextEvent ( ) <EOL> if event . type == START_OBJECT : <EOL> return self . parser . readObject ( event ) <EOL> elif event . type == START_ARRAY : <EOL> return self . parser . readArray ( event ) <EOL> elif event . type == ARRAY_VALUE : <EOL> return event . value <EOL> elif event . type == END_ARRAY : <EOL> self . complete = True <EOL> raise StopIteration ( ) <EOL> else : <EOL> raise JSONParseError ( <EOL> JSON_UNEXPECTED_ELEMENT_ERROR , <EOL> "<STR_LIT>" + str ( event ) ) <EOL> def next ( self ) : <EOL> return self . __next__ ( ) </s>
