Пример #1
0
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()
Пример #2
0
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()
Пример #3
0
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
Пример #4
0
    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
Пример #5
0
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])
Пример #6
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])
Пример #7
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])
Пример #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])
Пример #9
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])
Пример #10
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])
Пример #11
0
 def _r( i ):
     l = _rah( i )
     return TAG_Byte_Array( _r( i, l ) )