def parseTagCompound(input, handler): """ Reads a TAG_Compound from input. Calls handler.startCompound(). For each entry in the TAG_Compound: 1. Reads the type and name of the entry from input and calls handler.name() 2. Calls an appropriate parse*() function (e.g. parseInt) to read the payload of the tag Finally, calls handler.endCompound(). """ handler.startCompound() #Read first named tag header tagType = _B.unpack(_r(input, 1))[0] while tagType != TAG_END: #Check that tagType is valid. _avtt(tagType) #Now that we know the named tag isn't TAG_End, read the name. #Call .name() on handler, passing tagType and the name string. handler.name(tagType, _rst(input)) #Call appropriate parse() function for the type of tag we're reading TAG_PARSERS[tagType](input, handler) #Read next named tag header tagType = _B.unpack(_r(input, 1))[0] handler.endCompound()
def parseTagByteArray(input, handler): """ Reads a TAG_Byte_Array from input. Calls handler.startByteArray(), passing the length of the array. Repeatedly reads up to 4KB from the array and calls handler.bytes(), passing the bytes that were read as an argument. Finally, calls handler.endByteArray(). """ length = _rah(input) handler.startByteArray(length) #Read at most 4096 bytes at a time if length > 0: while length > 4096: handler.bytes(_r(input, 4096)) length -= 4096 handler.bytes(_r(input, length)) handler.endByteArray()
def _parseImpl(input, handler): """ Implementation of parse(). input is expected to be a readable file-like object containing uncompressed NBT data. See help( parse ) for further documentation. """ #Read root tag type and name length at same time tagType, length = _NT.unpack(_r(input, 3)) #Check that tagType and name length are valid. if tagType != TAG_COMPOUND: raise WrongTagError(TAG_COMPOUND, tagType) if length < 0: raise OutOfBoundsError(length, 0, 32768) #Call .name() on handler, passing tagType and length. try: handler.start() handler.name(tagType, _r(input, length).decode()) parseTagCompound(input, handler) handler.end() except _StopParsingNBT: return False return True
def _read( self, file ): """Read chunk contents from the given readable file-like object, file.""" #Read chunk header file.seek( self.offset, os.SEEK_SET ) size = _rui( file ) - 1 compression = _rub( file ) if compression == 2: #TODO: Don't read entire file into memory; use zlib decompression objects source = BytesIO( zlib.decompress( _r( file, size ) ) ) elif compression == 1: source = gzip.GzipFile( fileobj=file ) else: raise NBTFormatError( "Unrecognized compression type: {:d}.".format( compression ) ) #Read chunk data nbt = tag.read( source, None ) self.size = size self.compression = compression self.nbt = nbt
def parseTagShort(input, handler): """ Reads a TAG_Short from input as a python int. Calls handler.short() and passes the value as an argument. """ handler.short(_S.unpack(_r(input, 2))[0])
def parseTagByte(input, handler): """ Reads a TAG_Byte from input as a python int. Calls handler.byte() and passes the value as an argument. """ handler.byte(_B.unpack(_r(input, 1))[0])
def parseTagDouble(input, handler): """ Reads a TAG_Double from input as a python float (i.e. a double) Calls handler.double() and passes the value as an argument. """ handler.double(_D.unpack(_r(input, 8))[0])
def parseTagFloat(input, handler): """ Reads a TAG_Float from input as a python float (i.e. a float) Calls handler.float() and passes the value as an argument. """ handler.float(_F.unpack(_r(input, 4))[0])
def parseTagLong(input, handler): """ Reads a TAG_Long from input as a python int. Calls handler.long() and passes the value as an argument. """ handler.long(_L.unpack(_r(input, 8))[0])
def parseTagInt(input, handler): """ Reads a TAG_Int from input as a python int. Calls handler.int() and passes the value as an argument. """ handler.int(_I.unpack(_r(input, 4))[0])
def _r( i ): l = _rah( i ) return TAG_Byte_Array( _r( i, l ) )