コード例 #1
0
    def descr_int(self, space):  # TODO
        index = self.nbits - 1
        bigval = self.bigval
        wordpos = index / SHIFT
        if wordpos > bigval.numdigits(
        ):  # msb must be zero, number is positive
            return self.descr_uint(space)

        bitpos = index - wordpos * SHIFT
        word = bigval.digit(wordpos)
        msb = (word >> bitpos) & 1
        if not msb:
            return newlong(space, bigval)

        # calculate self.nbits's index
        bitpos += 1
        if bitpos == SHIFT:
            wordpos += 1
            bitpos = 0

        # manually assemble (1 << (index+1))
        shift = rbigint([NULLDIGIT] * wordpos + [_store_digit(1 << bitpos)], 1,
                        wordpos + 1)

        res = bigval.sub(shift)
        return newlong(space, res)
コード例 #2
0
 def test__kmul_split(self):
     split = 5
     diglo = [0] * split
     dighi = [lobj.MASK] * split
     f1 = bigint(diglo + dighi, 1)
     hi, lo = lobj._kmul_split(f1, split)
     assert lo._digits == [_store_digit(0)]
     assert hi._digits == map(_store_digit, dighi)
コード例 #3
0
def _rbigint_setidx(value, index, other):
    size = value.numdigits()
    wordpos = index / SHIFT

    if wordpos >= size:
        if not other:
            return value

        bitpos = index - wordpos * SHIFT
        shift = 1 << bitpos
        return rbigint( value._digits[:size] + \
                        [NULLDIGIT]*(wordpos-size) + \
                        [_store_digit(shift)], 1, wordpos + 1 )

    # wordpos < size
    digit = value.digit(wordpos)
    bitpos = index - wordpos * SHIFT
    shift = 1 << bitpos

    if other == 1:
        if digit & shift:  # already 1
            return value
        # the value is changed
        ret = rbigint(value._digits[:size], 1, size)
        ret.setdigit(wordpos, digit | shift)
        return ret
    # other == 0

    if not (digit & shift):  # already 0
        return value
    # the value is changed
    digit ^= shift
    if digit == 0 and wordpos == size - 1:
        assert wordpos >= 0
        return rbigint(value._digits[:wordpos] + [NULLDIGIT], 1, wordpos)

    ret = rbigint(value._digits[:size], 1, size)
    ret.setdigit(wordpos, digit)
    return ret
コード例 #4
0
def read_bytearray_bits_impl(space, w_arr, w_addr, w_nbytes):
    # We directly manipulate bytearray here
    assert isinstance(w_arr, W_BytearrayObject)
    ba_data = w_arr._data
    ba_len = len(ba_data)
    ba_offset = w_arr._offset

    nbytes = 0
    if isinstance(w_nbytes, W_SmallBits):
        nbytes = w_nbytes.intval
    elif type(w_nbytes) is W_IntObject:
        nbytes = w_nbytes.intval
    elif isinstance(w_nbytes, W_BigBits):
        tmp = w_nbytes.bigval
        if tmp.numdigits() > 1:
            raise oefmt(space.w_ValueError,
                        "nbytes [%s] too big for bytearray read Bits%d",
                        rbigint.str(tmp), w_nbytes.nbits)
        nbytes = tmp.digit(0)
    elif type(w_nbytes) is W_LongObject:
        nbytes = w_nbytes.num.toint()
    else:
        raise oefmt(space.w_TypeError, "Please pass in int/Bits")

    addr = 0
    if isinstance(w_addr, W_SmallBits):
        addr = w_addr.intval
    elif type(w_addr) is W_IntObject:
        addr = w_addr.intval
    elif isinstance(w_addr, W_BigBits):
        tmp = w_addr.bigval
        if tmp.numdigits() > 1:
            raise oefmt(space.w_ValueError,
                        "Index [%s] too big for bytearray read Bits%d",
                        rbigint.str(tmp), w_addr.nbits)
        addr = tmp.digit(0)
    elif type(w_addr) is W_LongObject:
        addr = w_addr.num.toint()
    else:
        raise oefmt(space.w_TypeError, "Please pass in int/Bits")

    if addr < 0:
        raise oefmt(space.w_ValueError,
                    "read_bytearray_bits only accept positive addr.")

    begin = addr + ba_offset
    end = begin + nbytes

    if end > ba_len:
        raise OperationError(space.w_IndexError,
                             space.newtext("bytearray index out of range"))

    if nbytes < 8:
        intval = 0
        while end > begin:
            end -= 1
            intval = (intval << 8) + ord(ba_data[end])

        return W_SmallBits(nbytes << 3, intval)

    else:
        digits = []
        current_word = 0
        bitstart = 0

        while begin < end:
            item = ord(ba_data[begin])

            bitend = bitstart + 8

            if bitend <= SHIFT:  # we are good
                current_word |= item << bitstart
                bitstart = bitend
            else:
                bitend -= SHIFT
                this_nbits = 8 - bitend
                current_word |= (item & get_int_mask(this_nbits)) << bitstart
                digits.append(_store_digit(current_word))

                current_word = item >> this_nbits
                bitstart = 8 - this_nbits

            begin += 1

        digits.append(_store_digit(current_word))

        bigval = rbigint(digits[:], sign=1)  # 1 is positive!!!
        bigval._normalize()

        return W_BigBits(nbytes << 3, bigval)
コード例 #5
0
def setitem_long_int_helper(value, other, start, stop):
    vsize = value.numdigits()
    if other < 0:
        slice_nbits = stop - start
        if slice_nbits < SHIFT:
            other &= get_int_mask(slice_nbits)
        else:
            tmp = get_long_mask(slice_nbits).int_and_(other)
            return setitem_long_long_helper(value, tmp, start, stop)

    # wordstart must < wordstop
    wordstart = start / SHIFT
    bitstart = start - wordstart * SHIFT

    # vsize <= wordstart < wordstop, concatenate
    if wordstart >= vsize:
        if not other: return value  # if other is zero, do nothing

        if not bitstart:  # aha, not chopped into two parts
            return rbigint( value._digits[:vsize] + \
                            [NULLDIGIT]*(wordstart-vsize) + \
                            [_store_digit(other)], 1, wordstart+1 )

        # split into two parts
        lo = SHIFT - bitstart
        val1 = other & get_int_mask(lo)
        if val1 == other:  # aha, the higher part is zero
            return rbigint( value._digits[:vsize] + \
                            [NULLDIGIT]*(wordstart-vsize) + \
                            [_store_digit(val1 << bitstart)], 1, wordstart+1 )
        return rbigint( value._digits[:vsize] + \
                        [NULLDIGIT]*(wordstart-vsize) + \
                        [_store_digit(val1 << bitstart)] + \
                        [_store_digit(other >> lo)], 1, wordstart+2 )

    wordstop = stop / SHIFT
    bitstop = stop - wordstop * SHIFT
    # (wordstart <=) wordstop < vsize
    if wordstop < vsize:
        ret = rbigint(value._digits[:vsize], 1, vsize)
        maskstop = get_int_mask(bitstop)
        valstop = ret.digit(wordstop)

        if wordstop == wordstart:  # valstop is ret.digit(wordstart)
            valuemask = ~(maskstop - get_int_mask(bitstart))
            ret.setdigit(wordstop, (valstop & valuemask) | (other << bitstart))

        # span multiple words
        # wordstart < wordstop
        else:
            # do start
            if not bitstart:
                ret.setdigit(wordstart, other)
                i = wordstart + 1
                while i < wordstop:
                    ret._digits[i] = NULLDIGIT
                    i += 1
                ret.setdigit(wordstop, valstop & ~maskstop)
            else:
                lo = SHIFT - bitstart
                val1 = other & get_int_mask(lo)
                word = (ret.digit(wordstart)
                        & get_int_mask(bitstart)) | (val1 << bitstart)
                ret.setdigit(wordstart, word)

                val2 = other >> lo
                i = wordstart + 1
                if i == wordstop:
                    ret.setdigit(i, val2 | (valstop & ~maskstop))
                else:  # i < wordstop
                    ret.setdigit(i, val2)
                    i += 1
                    while i < wordstop:
                        ret._digits[i] = NULLDIGIT
                        i += 1
                    ret.setdigit(wordstop, valstop & ~maskstop)
        ret._normalize()
        return ret

    # wordstart < vsize <= wordstop, highest bits will be cleared
    newsize = wordstart + 2  #
    assert wordstart >= 0
    ret = rbigint( value._digits[:wordstart] + \
                  [NULLDIGIT, NULLDIGIT], 1, newsize )

    bitstart = start - wordstart * SHIFT
    if not bitstart:
        ret.setdigit(wordstart, other)
    else:
        lo = SHIFT - bitstart
        val1 = other & get_int_mask(lo)
        word = (value.digit(wordstart)
                & get_int_mask(bitstart)) | (val1 << bitstart)
        ret.setdigit(wordstart, word)

        if val1 != other:
            ret.setdigit(wordstart + 1, other >> lo)

    ret._normalize()
    return ret