Lenard Lindstrom avatar Lenard Lindstrom committed dea97ec

populate testtools subproject

Comments (0)

Files changed (6)

+from ctypes import *
+
+class PyArrayInterface(Structure):
+    _fields_ = [('two', c_int), ('nd', c_int), ('typekind', c_char),
+                ('itemsize', c_int), ('flags', c_int),
+                ('shape', POINTER(c_int)),
+                ('strides', POINTER(c_int)),
+                ('data', c_void_p), ('descr', py_object)]
+
+PAI_Ptr = POINTER(PyArrayInterface)
+PyCObject_AsVoidPtr = pythonapi.PyCObject_AsVoidPtr
+PyCObject_AsVoidPtr.restype = c_void_p
+PyCObject_AsVoidPtr.argtypes = [py_object]
+
+PAI_CONTIGUOUS = 0x01
+PAI_FORTRAN = 0x02
+PAI_ALIGNED = 0x100
+PAI_NOTSWAPPED = 0x200
+PAI_WRITEABLE = 0x400
+PAI_ARR_HAS_DESCR = 0x800
+
+class Inter(object):
+    def __init__(self, arr):
+        self._cobj = arr.__array_struct__
+        vp = PyCObject_AsVoidPtr(self._cobj)
+        self._inter = cast(vp, PAI_Ptr)[0]
+
+    def __getattr__(self, name):
+        return getattr(self._inter, name)
+
+    def __str__(self):
+        return ("nd: %i\n"
+                "typekind: %s\n"
+                "itemsize: %i\n"
+                "flags: %s\n"
+                "shape: %s\n"
+                "strides: %s\n" %
+                (self.nd, self.typekind, self.itemsize,
+                 format_flags(self.flags),
+                 format_shape(self.nd, self.shape),
+                 format_strides(self.nd, self.strides)))
+
+def format_flags(flags):
+    names = []
+    for flag, name in [(PAI_CONTIGUOUS, 'CONTIGUOUS'),
+                       (PAI_FORTRAN, 'FORTRAN'),
+                       (PAI_ALIGNED, 'ALIGNED'),
+                       (PAI_NOTSWAPPED, 'NOTSWAPPED'),
+                       (PAI_WRITEABLE, 'WRITEABLE'),
+                       (PAI_ARR_HAS_DESCR, 'ARR_HAS_DESCR')]:
+        if flag & flags:
+            names.append(name)
+    return ', '.join(names)
+
+def format_shape(nd, shape):
+    return ', '.join([str(shape[i]) for i in range(nd)])
+
+def format_strides(nd, strides):
+    return ', '.join([str(strides[i]) for i in range(nd)])

blitting/alphablit.py

+"""Python implemetation of Pygame blitters for pointer bounds checking"""
+
+# Requires Python 2.5 or latter.
+
+SDL_SRCALPHA = 0x00010000
+SDL_SRCCOLORKEY = 0x00001000
+
+PYGAME_BLEND_RGBA_ADD = 1
+
+from mockc import (int_, posint_, Uint8, Uint16, Sint16, Uint32,
+                   VoidP, Uint8P, Struct, Ref, undef, malloc)
+
+
+class SDL_Rect(Struct):
+    def __init__(self, x=undef, y=undef, w=undef, h=undef):
+        Struct.__init__(self,
+                        x=Sint16(x),
+                        y=Sint16(y),
+                        w=Uint16(w),
+                        h=Uint16(h))
+
+class SDL_PixelFormat(Struct):
+    def __init__(self, BytesPerPixel, ppa):
+        if BytesPerPixel == 2:
+            BitsPerPixel = 16
+            Amask = 0x000F if ppa else 0
+        elif BytesPerPixel == 3:
+            BitsPerPixel = 24
+            Amask = 0
+        elif BytesPerPixel == 4:
+            BitsPerPixel = 32
+            Amask = 0xFF if ppa else 0
+        else:
+            raise ValueError("Unsupported pixel depth %i" % BytesPerPixel)
+        Struct.__init__(self,
+                        BitsPerPixel=Uint8(BitsPerPixel),
+                        BytesPerPixel=Uint8(BytesPerPixel),
+                        Rmask=Uint32(0xFF),
+                        Gmask=Uint32(0xFF00),
+                        Bmask=Uint32(0xFF0000),
+                        Amask=Uint32(Amask),
+                        colorkey=Uint32(),
+                        alpha=Uint8())
+
+class SDL_Surface(Struct):
+    def __init__(self, bytes_per_pixel, width, height,
+                 flags=0, pixels=None, offset=None, clip_rect=None):
+        ppa = flags & SDL_SRCALPHA
+        format = SDL_PixelFormat(bytes_per_pixel, ppa)
+        pitch = (width * bytes_per_pixel + 3) & 0xFFFC
+        if clip_rect is None:
+            clip_rect = SDL_Rect(0, 0, width, height)
+        else:
+            clip_rect = clip_rect.copy()
+        size = height * pitch
+        if pixels is None:
+            pixels = malloc(size)
+        else:
+            pixels = VoidP(pixels, pixels + size, pixels)
+        if offset is None:
+            offset = 0
+        Struct.__init__(self,
+                        flags=Uint32(flags),
+                        format=Ref(format),
+                        w=posint_(width),
+                        h=posint_(height),
+                        pitch=Uint16(pitch),
+                        pixels=pixels,
+                        offset=int_(-0xFFFF, 0xFFFF, offset),
+                        clip_rect=clip_rect)
+    def set_colorkey(self, color=None):
+        if color is None:
+            self.flags &= SDL_SRCALPHA
+        else:
+            self.flags |= SDL_SRCCOLORKEY
+            self.format.colorkey = color
+    def set_alpha(self, alpha=None):
+        if alpha is None:
+            self.flags &= SDL_SRCCOLORKEY
+        else:
+            self.flags |= SDL_SRCALPHA
+            self.format.alpha = alpha
+    
+def LOOP_UNROLLED4(block, n, width):
+    n.set_value((width + 3) // 4)
+    switch = int_(0, 3, width & 3)
+    while 1:
+        if switch == 0:
+            block()
+        if switch == 3 or switch == 0:
+            block()
+        if switch >= 2 or switch == 0:
+            block()
+        if switch >= 0:
+            block()
+        n -= 1
+        if not (n > 0):
+            break
+        switch.set_value(0)
+
+def REPEAT_4(block):
+    block()
+    block()
+    block()
+    block()
+
+def GET_PIXEL(pxl, bpp, source):
+    source[0]
+    if bpp == 2:
+        source[1]
+        pxl.set_value(0xFFFF)
+    elif bpp == 4:
+        source[3]
+        pxl.set_value(0xFFFFFFFFL)
+    else:
+        source[2]
+        pxl.set_value(0xFFFFFF)
+
+def GET_PIXELVALS(_sR, _sG, _sB, _sA, px, fmt, ppa):
+    _sR.set_value(0xFF)
+    _sG.set_value(0xFF)
+    _sB.set_value(0xFF)
+    if ppa:
+        _sA.set_value(0xF0)
+    else:
+        _sA.set_value(0xFF)
+
+def BLEND_RGBA_ADD(tmp, sR, sG, sB, sA, dR, dG, dB, dA):
+    dR.set_value(sR)
+    dG.set_value(sG)
+    dB.set_value(sB)
+    dA.set_value(sA)
+    tmp.set_value(0)
+    
+def ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB, dA):
+    dR.set_value(sR)
+    dG.set_value(sG)
+    dB.set_value(sB)
+    dA.set_value(sA)
+
+def CREATE_PIXEL(buf, r, g, b, a, bp, ft):
+    # Begin stats
+    global CREATE_PIXEL_ncalls
+    CREATE_PIXEL_ncalls += 1
+    # End stats
+    buf[0]
+    r.get_value()
+    g.get_value()
+    b.get_value()
+    a.get_value()
+    if bp == 2:
+        buf[1]
+    elif bp == 4:
+        buf[3]
+
+class Info(Struct):
+    def __init__(self):
+        Struct.__init__(self,
+                        width = posint_(),
+                        height = posint_(),
+                        s_pixels=Uint8P(0, 0xFFFFFFFFL),
+                        s_pxskip=int_(-4, 4),
+                        s_skip=int_(-0xFFFF, 0xFFFF),
+                        d_pixels=Uint8P(0, 0xFFFFFFFFL),
+                        d_pxskip=int_(-4, 4),
+                        d_skip=int_(-0xFFFF, 0xFFFF),
+                        src=Ref(),
+                        dst=Ref(),
+                        src_flags=Uint32(),
+                        dst_flags=Uint32())
+
+def blit_blend_rgba_add(info):
+    global src, dst
+
+    n = int_(0, info.width)
+    width = info.width
+    height = int_(-1, info.height, info.height)
+    src = info.s_pixels
+    srcpxskip = info.s_pxskip
+    srcskip = info.s_skip
+    dst = info.d_pixels
+    dstpxskip = info.d_pxskip
+    dstskip = info.d_skip
+    srcfmt = info.src
+    dstfmt = info.dst
+    srcbpp = srcfmt.BytesPerPixel
+    dstbpp = dstfmt.BytesPerPixel
+    dR = Uint8()
+    dG = Uint8()
+    dB = Uint8()
+    dA = Uint8()
+    sR = Uint8()
+    sG = Uint8()
+    sB = Uint8()
+    sA = Uint8()
+    alpha = srcfmt.alpha
+    pixel = Uint32()
+    tmp = Uint32()
+    srcppa = (info.src_flags & SDL_SRCALPHA and srcfmt.Amask)
+    dstppa = (info.dst_flags & SDL_SRCALPHA and dstfmt.Amask)
+
+    if (not dstppa):
+        blit_blend_add(info)
+        return
+
+    if (srcbpp == 4 and dstbpp == 4 and
+        srcfmt.Rmask == dstfmt.Rmask and
+        srcfmt.Gmask == dstfmt.Gmask and
+        srcfmt.Bmask == dstfmt.Bmask and
+        srcfmt.Amask == dstfmt.Amask and
+        info.src_flags & SDL_SRCALPHA):
+        incr = 1 if srcpxskip > 0 else -1
+        if incr < 0:
+            src += 3
+            dst += 3
+        while (height):
+            height -= 1
+            def block4x4_repeat_4():
+                global src, dst
+                
+                src[0]
+                dst[0]
+                src += incr
+                dst += incr
+            def block4x4():
+                REPEAT_4(block4x4_repeat_4)
+            LOOP_UNROLLED4(block4x4, n, width)
+        height -= 1
+        return
+
+    if srcbpp == 1:
+        if dstbpp == 1:
+            raise NotImplementedError("No 8 to 8")
+        else:
+            raise NotImplementedError("No anything to 8")
+    else:
+        if dstbpp == 1:
+            raise NotImplementedError("No 8 bit support, period")
+        else:
+            def blockx4():
+                global src, dst
+                
+                GET_PIXEL(pixel, srcbpp, src)
+                GET_PIXELVALS (sR, sG, sB, sA, pixel, srcfmt, srcppa)
+                GET_PIXEL (pixel, dstbpp, dst)
+                GET_PIXELVALS(dR, dG, dB, dA, pixel, dstfmt, dstppa)
+                BLEND_RGBA_ADD(tmp, sR, sG, sB, sA, dR, dG, dB, dA)
+                CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt)
+                src += srcpxskip
+                dst += dstpxskip
+            while height:
+                height -= 1
+                LOOP_UNROLLED4(blockx4, n, width)
+                src += srcskip
+                dst += dstskip
+            height -= 1
+
+def blit_blend_add(info):
+    raise NotImplementedError("blit_blend_add unavailable")
+
+def alphablit_solid(info):
+    global src, dst
+
+    n = int_(0, info.width)
+    width = info.width
+    height = int_(-1, info.height, info.height)
+    src = info.s_pixels
+    srcpxskip = info.s_pxskip
+    srcskip = info.s_skip
+    dst = info.d_pixels
+    dstpxskip = info.d_pxskip
+    dstskip = info.d_skip
+    srcfmt = info.src
+    dstfmt = info.dst
+    srcbpp = srcfmt.BytesPerPixel
+    dstbpp = dstfmt.BytesPerPixel
+    dR = Uint8()
+    dG = Uint8()
+    dB = Uint8()
+    dA = Uint8()
+    sR = Uint8()
+    sG = Uint8()
+    sB = Uint8()
+    sA = Uint8()
+    alpha = srcfmt.alpha
+    pixel = Uint32()
+    srcppa = (info.src_flags & SDL_SRCALPHA and srcfmt.Amask)
+    dstppa = (info.dst_flags & SDL_SRCALPHA and dstfmt.Amask)
+
+    if srcbpp == 1:
+        if dstbpp == 1:
+            raise NotImplementedError("No 8 to 8")
+        else:
+            raise NotImplementedError("No anything to 8")
+    else:
+        if dstbpp == 1:
+            raise NotImplementedError("No 8 bit support, period")
+        elif dstbpp == 3:
+            raise NotImplementedError("No 24 bit support")
+        else:
+            def blockx4():
+                global src, dst
+                
+                GET_PIXEL(pixel, srcbpp, src)
+                GET_PIXELVALS(sR, sG, sB, sA, pixel, srcfmt, srcppa)
+                GET_PIXEL(pixel, dstbpp, dst)
+                GET_PIXELVALS(dR, dG, dB, dA, pixel, dstfmt, dstppa)
+                ALPHA_BLEND(sR, sG, sB, alpha, dR, dG, dB, dA)
+                CREATE_PIXEL(dst, dR, dG, dB, dA, dstbpp, dstfmt)
+                src += srcpxskip
+                dst += dstpxskip
+                
+            while height:
+                height -= 1
+                LOOP_UNROLLED4(blockx4, n, width)
+            height -= 1
+
+def SoftBlitPyGame(src, srcrect, dst, dstrect, the_args):
+    # Begin stats
+    global was_reversed
+    # End stats
+    okay = 1
+
+    if (okay and srcrect.w and srcrect.h):
+        info = Info()
+
+        info.width = srcrect.w
+        info.height = srcrect.h
+        info.s_pixels = (
+            Uint8P.cast(src.pixels) + src.offset +
+            Uint16(srcrect.y) * src.pitch +
+            Uint16(srcrect.x) * src.format.BytesPerPixel).clamped_lower()
+        info.s_pxskip = src.format.BytesPerPixel
+        info.s_skip = src.pitch - info.width * src.format.BytesPerPixel
+        info.d_pixels = (
+            Uint8P.cast(dst.pixels) + dst.offset +
+            Uint16(dstrect.y) * dst.pitch +
+            Uint16(dstrect.x) * dst.format.BytesPerPixel).clamped_lower()
+        info.d_pxskip = dst.format.BytesPerPixel
+        info.d_skip = dst.pitch - info.width * dst.format.BytesPerPixel
+        info.src = src.format
+        info.dst = dst.format
+        info.src_flags = src.flags
+        info.dst_flags = dst.flags
+
+        if (info.d_pixels > info.s_pixels):
+            span = info.width * info.src.BytesPerPixel
+            srcpixend = info.s_pixels + (info.height - 1) * src.pitch + span
+
+            if (info.d_pixels < srcpixend):
+                dstoffset = (info.d_pixels - info.s_pixels) % src.pitch
+
+                if (dstoffset < span or dstoffset > src.pitch - span):
+                    # Begin stats
+                    was_reversed = True
+                    # End stats
+                    info.s_pixels = srcpixend - info.s_pxskip
+                    info.s_pxskip = -info.s_pxskip
+                    info.d_pixels = (info.d_pixels +
+                                     (info.height - 1) * dst.pitch +
+                                     span - info.d_pxskip)
+                    info.d_pxskip = -info.d_pxskip
+                    info.d_skip = -info.d_skip
+
+        if the_args == 0:
+            if (src.flags & SDL_SRCALPHA and src.format.Amask):
+                return
+            elif (src.flags & SDL_SRCCOLORKEY):
+                return
+            else:
+                alphablit_solid(info)
+        elif the_args == PYGAME_BLEND_RGBA_ADD:
+            blit_blend_rgba_add(info)
+        else:
+            raise NotImplementedError("Not done yet")
+
+        return 0 if okay else -1
+            
+def pygame_Blit(src, srcrect, dst, dstrect, the_args):
+    # Begin stats
+    global CREATE_PIXEL_ncalls, was_reversed
+    CREATE_PIXEL_ncalls = 0
+    was_reversed = False
+    # End stats
+    fulldst = SDL_Rect()
+    
+    if dstrect is None:
+        fulldst.x = fulldst.y = 0
+        dstrect = fulldst
+
+    if srcrect:
+        srcx = srcrect.x
+        w = srcrect.w
+        if (srcx < 0):
+            w += srcx
+            dstrect.x -= srcx
+            srcx = 0
+        maxw = src.w - srcx
+        if (maxw < w):
+            w = maxw
+
+        srcy = srcrect.y
+        h = srcrect.h
+        if srcy < 0:
+            h += srcy
+            dstrect.y -= srcy
+            srcy = 0
+        maxh = src.h - srcy
+        if (maxh < h):
+            h = maxh
+    else:
+        srcx = srcy = 0
+        w = src.w
+        h = src.h
+
+    # clip the destinatin rectangle against the clip rectangle
+    clip = dst.clip_rect
+
+    dx = clip.x - dstrect.x
+    if (dx > 0):
+        w -= dx
+        dstrect.x += dx
+        srcx += dx
+    dx = dstrect.x + w - clip.x - clip.w
+    if (dx > 0):
+        w -= dx
+
+    dy = clip.y - dstrect.y
+    if (dy > 0):
+        h -= dy
+        dstrect.y += dy
+        srcy += dy
+    dy = dstrect.y + h - clip.y - clip.h
+    if (dy > 0):
+        h -= dy
+    # -- end clip --
+
+    if (w > 0 and h > 0):
+        sr = SDL_Rect()
+
+        sr.x = srcx
+        sr.y = srcy
+        sr.w = dstrect.w = w
+        sr.h = dstrect.h = h
+        return SoftBlitPyGame(src, sr, dst, dstrect, the_args)
+    dstrect.w = dstrect.h = 0
+    return 0
+
+def pygame_AlphaBlit(src, srcrect, dst, dstrect, the_args):
+    return pygame_Blit(src, srcrect, dst, dstrect, the_args)

blitting/blittest.py

+"""Exercise the alphablit module
+
+This runs self blit tests on alphablit to check for invalid memory
+accesses and that the self blit check in SoftBlitPyGame works properly.
+
+"""
+
+# Requires Python 2.5
+
+import alphablit
+from alphablit import (SDL_Surface, pygame_AlphaBlit, SDL_SRCALPHA,
+                       SDL_Rect, PYGAME_BLEND_RGBA_ADD)
+
+def testcase(bpp, w, sx, sy, w2, h2, dx, dy, do_overlap):
+    surf = SDL_Surface(bpp, w, 300, flags=SDL_SRCALPHA)
+    pygame_AlphaBlit(surf, SDL_Rect(sx, sy, w2, h2),
+                     surf, SDL_Rect(dx, dy, w2, h2),
+                     PYGAME_BLEND_RGBA_ADD)
+    if alphablit.was_reversed:
+        if do_overlap:
+            return
+    else:
+        if not do_overlap:
+            return
+    # fail
+    if do_overlap:
+        print "** False negative for"
+    else:
+        print "** False positive for"
+    print "   parent width %i," % w
+    print "   source rect (%i, %i, %i, %i)," % (sx, sy, w2, h2)
+    print "   destination rect (%i, %i, %i, %i)" % (dx, dy, w2, h2)
+
+def test():
+    for bpp in [2, 4]:
+        # dstpx < srcpx
+        testcase(bpp, 51, 1, 0, 50, 50, 0, 0, False)
+        # dstpx == srcpx
+        testcase(bpp, 50, 0, 0, 50, 50, 0, 0, False)
+        # srcpx < dstpx < srcpx + rect_width * BytesPerPixel
+        testcase(bpp, 51, 0, 0, 50, 50, 1, 0, True)
+        # dst rect outside src rect
+        testcase(bpp, 100, 0, 0, 40, 40, 50, 0, False) #
+        testcase(bpp, 100, 0, 0, 40, 40, 50, 48, False)
+        # dst rect next to src rect
+        testcase(bpp, 100, 0, 0, 50, 50, 50, 0, False) #
+        testcase(bpp, 100, 0, 0, 50, 50, 50, 10, False) #
+        # dst rect overlaps src rect on right
+        testcase(bpp, 100, 0, 0, 50, 50, 49, 1, True)
+        testcase(bpp, 100, 0, 0, 50, 50, 49, 49, True)
+        # dst rect overlaps src rect on left
+        testcase(bpp, 100, 49, 0, 50, 50, 0, 1, True)
+        testcase(bpp, 100, 49, 0, 50, 50, 0, 49, True)
+        # last pixel of src is first pixel of dst
+        testcase(bpp, 100, 0, 0, 40, 40, 39, 39, True)
+        # start of dst is just pass source
+        testcase(bpp, 100, 0, 0, 40, 40, 39, 40, False)
+
+
+if __name__ == '__main__':
+    print "Go"
+    test()
+    print "End"

blitting/mockc.py

+"""Mock C data types for range checking
+
+This module contains integer and fake C pointer types as well as
+a struct. The integer types can be used to check for overflow
+and underflow. The pointer types do bounds checking on addresses.
+
+"""
+
+# Requires Python 2.5
+
+class Undef(object):
+    pass
+undef = Undef()
+
+class UndefinedError(ValueError):
+    pass
+
+class Cell(object):
+    def __init__(self, value=undef):
+        if value is undef:
+            self._value = undef
+        else:
+            self.set_value(value)
+    def get_value(self):
+        if self._value is undef:
+            raise UndefinedError("Undefined value")
+        return self._value
+    def set_value(self, value):
+        if isinstance(value, Cell):
+            value = value.get_value()
+        self._value = value
+    def del_value(self):
+        self._value = undef
+    def copy(self):
+        cls = self.__class__
+        obj = cls.__new__(cls)
+        obj.__dict__.update(self.__dict__)
+        return obj
+
+class RangeError(ValueError):
+    pass
+
+class Range(Cell):
+    def __init__(self, minimum, maximum, value=undef):
+        if isinstance(minimum, Range):
+            minimum = minimum.get_value()
+        if isinstance(maximum, Range):
+            maximum = maximum.get_value()
+        if maximum < minimum:
+            return ValueError("upper limit is less than minimum: %i", maximum)
+        self._minimum = minimum
+        self._maximum = maximum
+        if value is undef:
+            Cell.__init__(self)
+        else:
+            self.set_value(value)
+    def set_value(self, value):
+        if isinstance(value, Cell):
+            value = value.get_value()
+        if not (self._minimum <= value <= self._maximum):
+            raise RangeError("%s value %i out of range (%i, %i)" %
+                             (self.__class__.__name__,
+                              value, self._minimum, self._maximum))
+        Cell.set_value(self, value)
+    def __str__(self):
+        try:
+            return str(self.get_value())
+        except UndefinedError:
+            return "**undefined**"
+    def __repr__(self):
+        try:
+            return ("%s(%i, %i, %i)" %
+                    (self.__class__.__name__,
+                     self._minimum, self._maximum, self.get_value()))
+        except UndefinedError:
+            return ("%s(%i, %i)" %
+                    (self.__class__.__name__, self._minimum, self._maximum))
+
+class int_(Range):
+    def __iadd__(self, other):
+        if isinstance(other, int_):
+            other = other.get_value()
+        if not isinstance(other, (int, long)):
+            return NotImplemented
+        self.set_value(self.get_value() + other)
+        return self
+    def __add__(self, other):
+        return self.copy().__iadd__(other)
+    def __radd__(self, other):
+        return self.__add__(other)
+    def __imul__(self, other):
+        if isinstance(other, int_):
+            other = other.get_value()
+        if not isinstance(other, (int, long)):
+            return NotImplemented
+        self.set_value(self.get_value() * other)
+        return self
+    def __mul__(self, other):
+        return self.copy().__imul__(other)
+    def __rmul__(self, other):
+        return self.__mul__(other)
+    def __nonzero__(self):
+        return bool(self.get_value())
+    def __floordiv__(self, other):
+        if isinstance(other, int_):
+            other = other.get_value()
+        if not isinstance(other, (int, long)):
+            return NotImplemented
+        obj = self.copy()
+        obj.set_value(self.get_value() // other)
+        return obj
+    def __rfloordiv__(self, other):
+        if isinstance(other, int_):
+            other = other.get_value()
+        if not isinstance(other, (int, long)):
+            return NotImplemented
+        obj = self.copy()
+        obj.set_value(other // self.get_value())
+        return obj
+    def __iand__(self, other):
+        if isinstance(other, int_):
+            other = other.get_value()
+        if not isinstance(other, (int, long)):
+            return NotImplemented
+        self.set_value(self.get_value() & other)
+        return self
+    def __and__(self, other):
+        return self.copy().__iand__(other)
+    def __ior__(self, other):
+        if isinstance(other, int_):
+            other = other.get_value()
+        if not isinstance(other, (int, long)):
+            return NotImplemented
+        self.set_value(self.get_value() | other)
+        return self
+    def __or__(self, other):
+        return self.copy().__ior__(other)
+    def __rand__(self, other):
+        return self.__and__(other)
+    def __eq__(self, other):
+        if isinstance(other, int_):
+            other = other.get_value()
+        return self.get_value() == other
+    def __gt__(self, other):
+        if isinstance(other, int_):
+            other = other.get_value()
+        return self.get_value() > other
+    def __ge__(self, other):
+        if isinstance(other, int_):
+            other = other.get_value()
+        return self.get_value() >= other
+    def __isub__(self, other):
+        if isinstance(other, int_):
+            other = other.get_value()
+        if not isinstance(other, (int, long)):
+            return NotImplemented
+        self.set_value(self.get_value() - other)
+        return self
+    def __sub__(self, other):
+        return self.copy().__isub__(other)
+    def __rsub__(self, other):
+        if isinstance(other, int_):
+            other = other.get_value()
+        if not isinstance(other, (int, long)):
+            return NotImplemented
+        obj = self.copy()
+        obj.set_value(other - self.get_value())
+        return obj
+    def __neg__(self):
+        obj = self.copy()
+        obj.set_value(-self.get_value())
+        return obj
+    def __imod__(self, other):
+        if isinstance(other, int_):
+            other = other.get_value()
+        if not isinstance(other, (int, long)):
+            return NotImplemented
+        self.set_value(self.get_value % other)
+        return self
+    def __mod__(self, other):
+        return self.copy().__imod__(other)
+    def __rmod__(self, other):
+        if isinstance(other, int_):
+            other = other.get_value()
+        if not isinstance(other, (int, long)):
+            return NotImplemented
+        obj = self.copy()
+        obj.set_value(other % self.get_value())
+        return obj
+    def __index__(self):
+        return self.get_value()
+
+class intX(int_):
+    def __repr__(self):
+        try:
+            return "%s(%i)" % (self.__class__.__name__, self.get_value())
+        except UndefinedError:
+            return "%s()" % self.__class__.__name__
+
+class Uint8(intX):
+    def __init__(self, value=undef):
+        intX.__init__(self, 0, 255, value)
+
+class Sint16(intX):
+    def __init__(self, value=undef):
+        intX.__init__(self, -0x8000, 0x7FFF, value)
+
+class Uint16(intX):
+    def __init__(self, value=undef):
+        intX.__init__(self, 0, 0xFFFF, value)
+
+class Uint32(intX):
+    def __init__(self, value=undef):
+        intX.__init__(self, 0, 0xFFFFFFFFL, value)
+
+class posint_(intX):
+    def __init__(self, value=undef):
+        intX.__init__(self, 0, 0x7FFFFFFF, value)
+
+class VoidP(Range):
+    def __init__(self, lower, upper, address=undef):
+        if not (0 <= lower <= 0xFFFFFFFFL):
+            raise ValueError("lower bounds out of range: %i" % lower)
+        if not (lower <= upper <= 0xFFFFFFFFL):
+            raise ValueError("Upper bounds out of range: %i" % upper)
+        Range.__init__(self, 0, 0xFFFFFFFFL, address)
+        self._lower = lower
+        self._upper = upper
+    def clamped_lower(self):
+        obj = self.copy()
+        obj._lower = self.get_value()
+        return obj
+    def clamped_upper(self):
+        obj = self.copy()
+        obj._upper = self.get_value()
+        return obj
+    def set_value(self, value):
+        Range.set_value(self, value)
+        if isinstance(value, VoidP):
+            lower = value._lower
+            upper = value._upper
+            if lower > self._lower:
+                self._lower = lower
+            if upper < self._upper:
+                self._upper = upper
+    @classmethod
+    def cast(cls, other):
+        return cls(other._lower, other._upper, other.get_value())
+    def __getitem__(self, index):
+        if index != 0:
+            raise IndexError("Void pointer doesn't support non-zero index")
+        if not (self._lower <= self.get_value() <= self._upper):
+            raise RangeError("address %i outside of range (%i, %i)" %
+                             (self._value, self._lower, self._value))
+    def __repr__(self):
+        try:
+            return ("%s(%i, %i, %i)" %
+                    (self.__class__.__name__,
+                     self._lower, self._upper, self.get_value()))
+        except UndefinedError:
+            return ("%s(%i, %i)" %
+                    (self.__class__.__name__, self._lower, self._upper))
+    def __eq__(self, other):
+        if isinstance(other, VoidP):
+            other = other.get_value()
+        return self.get_value() == other
+    def __gt__(self, other):
+        if isinstance(other, VoidP):
+            other = other.get_value()
+        return self.get_value() > other
+    def __ge__(self, other):
+        if isinstance(other, VoidP):
+            other = other.get_value()
+        return self.get_value() >= other
+
+class Uint8P(VoidP):
+    item_size = 1
+    def __iadd__(self, other):
+        try:
+            i = other.__index__()
+        except AttributeError:
+            return NotImplemented
+        self.set_value(self.get_value() + (self.item_size * i))
+        return self
+    def __add__(self, other):
+        return self.copy().__iadd__(other)
+    def __radd__(self, other):
+        return self.__add__(other)
+    def __isub__(self, other):
+        try:
+            i = other.__index__()
+        except AttributeError:
+            return NotImplemented
+        self.set_value(self.get_value() - (self.item_size * i))
+        return self
+    def __sub__(self, other):
+        if isinstance(other, Uint8P):
+            if other.item_size != self.item_size:
+                raise TypeError("Other pointer has different item size")
+            return (self.get_value() - other.get_value()) // self.item_size
+        return self.copy().__isub__(other)
+    def __getitem__(self, index):
+        address = self.get_value() + self.item_size * index.__index__()
+        if not (self._lower <= address <= self._upper):
+            raise RangeError("address %i outside of range (%i, %i)" %
+                             (address, self._lower, self._upper))
+        return 1L << (8 * self.item_size - 2)
+
+class Ref(Cell):
+    def copy(self):
+        return self.get_value()
+    def __str__(self):
+        return "&%s" % str(self.get_value())
+    def __repr__(self):
+        return "%s(%s)" % (self.__class__.__name__, repr(self.get_value()))
+
+class Struct(object):
+    class Substruct(object):
+        def __init__(self, struct):
+            self._struct = struct
+        def copy(self):
+            return self._struct
+        def set_value(self, value):
+            self._struct.set_value(value)
+        def __str__(self):
+            return str(self._struct)
+        def __repr__(self):
+            return repr(self._struct)
+    def __init__(self, **kwds):
+        for name, value in kwds.items():
+            if isinstance(value, Struct):
+                value = self.Substruct(value)
+            object.__setattr__(self, '_%s' % name, value)
+    def set_value(self, other):
+        for key, val in other.__dict__.iteritems():
+            setattr(self, key, val)
+    def copy(self):
+        kwds = {}
+        for name, attr in self.__dict__.iteritems():
+            if isinstance(attr, self.Substruct):
+                attr = attr.copy().copy()
+            elif isinstance(attr, Ref):
+                attr = Ref(attr.copy())
+            kwds[name[1:]] = attr.copy()
+        return self.__class__(**kwds)
+    def __getattr__(self, name):
+        return object.__getattribute__(self, '_%s' % name).copy()
+    def __setattr__(self, name, value):
+        object.__getattribute__(self, '_%s' % name).set_value(value)
+    def __str__(self):
+        return ("[%s]" %
+                ", ".join("%s: %s" % (name[1:], val)
+                          for name, val in self.__dict__.iteritems()))
+    def __repr__(self):
+        return ("Struct(%s)" %
+                ", ".join("%s=%s" % (name[1:], repr(val))
+                            for name, val in self.__dict__.iteritems()))
+
+def malloc(size):
+    address = 0x01000000
+    return VoidP(address, address + size - 1, address)
+

blitting/mockctest.py

+"""Do some confirmation of the mock C data types module"""
+
+# Requires Python 2.5
+
+from mockc import Uint8, RangeError, Uint8P, malloc
+
+a = Uint8()
+try:
+    a.get_value()
+except ValueError:
+    pass
+else:
+    assert False
+
+a.set_value(42)
+assert a == 42
+
+b = a
+a += 2
+assert a is b
+assert a == 44
+
+a -= 10
+assert a is b
+assert a == 34
+
+assert isinstance(a + 1, Uint8)
+assert (a + 8) == 42
+assert (8 + a) == 42
+
+assert isinstance(a - 1, Uint8)
+assert (a - 18) == 16
+assert isinstance(100 - a, Uint8)
+assert (34 - a) == 0
+
+p = Uint8P.cast(malloc(2048))
+
+p[0]
+p[2047]
+try:
+    p[2048]
+except RangeError:
+    pass
+else:
+    assert False
+
+q = p - 10
+assert isinstance(q, Uint8P)
+try:
+    q[0]
+except RangeError:
+    pass
+else:
+    assert False
+
+q = p + 1024
+q[0]
+try:
+    q[1024]
+except RangeError:
+    pass
+else:
+    assert False
+These are some tools used to validate parts of Pygame.
+
+arrinter.py is a ctypes based module that wraps an objects array struct
+interface in a Python class. It was useful in developing the
+_arraysurfarray module.
+
+Directory blitting contains several modules and programs used to check
+Pygame's blitter algorithms. It contains mockc.py, a module of types
+that emulate C integers and pointer, alphablit.py, a partial implementation
+of alphablit.c using mockc, and blittest.py, a program that runs some
+tests on alphablit.py.
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.