Esempio n. 1
0
def _float_adjust(v, encode):
    if encode and six.indexbytes(v, 0) & 0x80 != 0x00:
        return b''.join(map(lambda x: six.int2byte(x ^ 0xff), six.iterbytes(v)))
    elif not encode and six.indexbytes(v, 0) & 0x80 != 0x80:
        return b''.join(map(lambda x: six.int2byte(x ^ 0xff), six.iterbytes(v)))
    else:
        return six.int2byte(six.indexbytes(v, 0) ^ 0x80) + v[1:]
Esempio n. 2
0
 def from_bytes(cls, v, start=0):
     if not isinstance(v, bytes):
         raise TypeError("Cannot parse versionstamp from non-byte string")
     elif len(v) - start < cls.LENGTH:
         raise ValueError("Versionstamp byte string is too short (only " +
                          str(len(v) - start) + " bytes to read from")
     else:
         tr_version = v[start:start + cls._TR_VERSION_LEN]
         if tr_version == cls._UNSET_TR_VERSION:
             tr_version = None
         user_version = six.indexbytes(v, start + cls._TR_VERSION_LEN) * (
             1 << 8) + six.indexbytes(v, start + cls._TR_VERSION_LEN + 1)
         return Versionstamp(tr_version, user_version)
Esempio n. 3
0
def _decode(v, pos):
    code = six.indexbytes(v, pos)
    if code == NULL_CODE:
        return None, pos + 1
    elif code == BYTES_CODE:
        end = _find_terminator(v, pos + 1)
        return v[pos + 1:end].replace(b"\x00\xFF", b"\x00"), end + 1
    elif code == STRING_CODE:
        end = _find_terminator(v, pos + 1)
        return v[pos + 1:end].replace(b"\x00\xFF",
                                      b"\x00").decode("utf-8"), end + 1
    elif code >= INT_ZERO_CODE and code < POS_INT_END:
        n = code - 20
        end = pos + 1 + n
        return struct.unpack(">Q", b'\x00' * (8 - n) + v[pos + 1:end])[0], end
    elif code > NEG_INT_START and code < INT_ZERO_CODE:
        n = 20 - code
        end = pos + 1 + n
        return struct.unpack(
            ">Q", b'\x00' * (8 - n) + v[pos + 1:end])[0] - _size_limits[n], end
    elif code == POS_INT_END:  # 0x1d; Positive 9-255 byte integer
        length = six.indexbytes(v, pos + 1)
        val = 0
        for i in _range(length):
            val = val << 8
            val += six.indexbytes(v, pos + 2 + i)
        return val, pos + 2 + length
    elif code == NEG_INT_START:  # 0x0b; Negative 9-255 byte integer
        length = six.indexbytes(v, pos + 1) ^ 0xff
        val = 0
        for i in _range(length):
            val = val << 8
            val += six.indexbytes(v, pos + 2 + i)
        return val - (1 << (length * 8)) + 1, pos + 2 + length
    elif code == FLOAT_CODE:
        return SingleFloat(
            struct.unpack(">f", _float_adjust(v[pos + 1:pos + 5],
                                              False))[0]), pos + 5
    elif code == DOUBLE_CODE:
        return struct.unpack(">d", _float_adjust(v[pos + 1:pos + 9],
                                                 False))[0], pos + 9
    elif code == UUID_CODE:
        return uuid.UUID(bytes=v[pos + 1:pos + 17]), pos + 17
    elif code == FALSE_CODE:
        if fdb.is_api_version_selected() and fdb.get_api_version() < 500:
            raise ValueError("Invalid API version " + str(fdb._version) +
                             " for boolean types")
        return False, pos + 1
    elif code == TRUE_CODE:
        if fdb.is_api_version_selected() and fdb.get_api_version() < 500:
            raise ValueError("Invalid API version " + str(fdb._version) +
                             " for boolean types")
        return True, pos + 1
    elif code == VERSIONSTAMP_CODE:
        return Versionstamp.from_bytes(v,
                                       pos + 1), pos + 1 + Versionstamp.LENGTH
    elif code == NESTED_CODE:
        ret = []
        end_pos = pos + 1
        while end_pos < len(v):
            if six.indexbytes(v, end_pos) == 0x00:
                if end_pos + 1 < len(v) and six.indexbytes(
                        v, end_pos + 1) == 0xff:
                    ret.append(None)
                    end_pos += 2
                else:
                    break
            else:
                val, end_pos = _decode(v, end_pos)
                ret.append(val)
        return tuple(ret), end_pos + 1
    else:
        raise ValueError("Unknown data type in DB: " + repr(v))