from ctypes import *
import unittest

# IMPORTANT INFO:
#
# Consider this call:
#    func.restype = c_char_p
#    func(c_char_p("123"))
# It returns
#    "123"
#
# WHY IS THIS SO?
#
# argument tuple (c_char_p("123"), ) is destroyed after the function
# func is called, but NOT before the result is actually built.
#
# If the arglist would be destroyed BEFORE the result has been built,
# the c_char_p("123") object would already have a zero refcount,
# and the pointer passed to (and returned by) the function would
# probably point to deallocated space.
#
# In this case, there would have to be an additional reference to the argument...

import _ctypes_test
testdll = CDLL(_ctypes_test.__file__)

# Return machine address `a` as a (possibly long) non-negative integer.
# Starting with Python 2.5, id(anything) is always non-negative, and
# the ctypes addressof() inherits that via PyLong_FromVoidPtr().
def positive_address(a):
    if a >= 0:
        return a
    # View the bits in `a` as unsigned instead.
    import struct
    num_bits = struct.calcsize("P") * 8 # num bits in native machine address
    a += 1L << num_bits
    assert a >= 0
    return a

def c_wbuffer(init):
    n = len(init) + 1
    return (c_wchar * n)(*init)

class CharPointersTestCase(unittest.TestCase):

    def setUp(self):
        func = testdll._testfunc_p_p
        func.restype = c_long
        func.argtypes = None

    def test_paramflags(self):
        # function returns c_void_p result,
        # and has a required parameter named 'input'
        prototype = CFUNCTYPE(c_void_p, c_void_p)
        func = prototype(("_testfunc_p_p", testdll),
                         ((1, "input"),))

        try:
            func()
        except TypeError, details:
            self.assertEqual(str(details), "required argument 'input' missing")
        else:
            self.fail("TypeError not raised")

        self.assertEqual(func(None), None)
        self.assertEqual(func(input=None), None)


    def test_int_pointer_arg(self):
        func = testdll._testfunc_p_p
        func.restype = c_long
        self.assertEqual(0, func(0))

        ci = c_int(0)

        func.argtypes = POINTER(c_int),
        self.assertEqual(positive_address(addressof(ci)),
                             positive_address(func(byref(ci))))

        func.argtypes = c_char_p,
        self.assertRaises(ArgumentError, func, byref(ci))

        func.argtypes = POINTER(c_short),
        self.assertRaises(ArgumentError, func, byref(ci))

        func.argtypes = POINTER(c_double),
        self.assertRaises(ArgumentError, func, byref(ci))

    def test_POINTER_c_char_arg(self):
        func = testdll._testfunc_p_p
        func.restype = c_char_p
        func.argtypes = POINTER(c_char),

        self.assertEqual(None, func(None))
        self.assertEqual("123", func("123"))
        self.assertEqual(None, func(c_char_p(None)))
        self.assertEqual("123", func(c_char_p("123")))

        self.assertEqual("123", func(c_buffer("123")))
        ca = c_char("a")
        self.assertEqual("a", func(pointer(ca))[0])
        self.assertEqual("a", func(byref(ca))[0])

    def test_c_char_p_arg(self):
        func = testdll._testfunc_p_p
        func.restype = c_char_p
        func.argtypes = c_char_p,

        self.assertEqual(None, func(None))
        self.assertEqual("123", func("123"))
        self.assertEqual(None, func(c_char_p(None)))
        self.assertEqual("123", func(c_char_p("123")))

        self.assertEqual("123", func(c_buffer("123")))
        ca = c_char("a")
        self.assertEqual("a", func(pointer(ca))[0])
        self.assertEqual("a", func(byref(ca))[0])

    def test_c_void_p_arg(self):
        func = testdll._testfunc_p_p
        func.restype = c_char_p
        func.argtypes = c_void_p,

        self.assertEqual(None, func(None))
        self.assertEqual("123", func("123"))
        self.assertEqual("123", func(c_char_p("123")))
        self.assertEqual(None, func(c_char_p(None)))

        self.assertEqual("123", func(c_buffer("123")))
        ca = c_char("a")
        self.assertEqual("a", func(pointer(ca))[0])
        self.assertEqual("a", func(byref(ca))[0])

        func(byref(c_int()))
        func(pointer(c_int()))
        func((c_int * 3)())

        try:
            func.restype = c_wchar_p
        except NameError:
            pass
        else:
            self.assertEqual(None, func(c_wchar_p(None)))
            self.assertEqual(u"123", func(c_wchar_p(u"123")))

    def test_instance(self):
        func = testdll._testfunc_p_p
        func.restype = c_void_p

        class X:
            _as_parameter_ = None

        func.argtypes = c_void_p,
        self.assertEqual(None, func(X()))

        func.argtypes = None
        self.assertEqual(None, func(X()))

try:
    c_wchar
except NameError:
    pass
else:
    class WCharPointersTestCase(unittest.TestCase):

        def setUp(self):
            func = testdll._testfunc_p_p
            func.restype = c_int
            func.argtypes = None


        def test_POINTER_c_wchar_arg(self):
            func = testdll._testfunc_p_p
            func.restype = c_wchar_p
            func.argtypes = POINTER(c_wchar),

            self.assertEqual(None, func(None))
            self.assertEqual(u"123", func(u"123"))
            self.assertEqual(None, func(c_wchar_p(None)))
            self.assertEqual(u"123", func(c_wchar_p(u"123")))

            self.assertEqual(u"123", func(c_wbuffer(u"123")))
            ca = c_wchar("a")
            self.assertEqual(u"a", func(pointer(ca))[0])
            self.assertEqual(u"a", func(byref(ca))[0])

        def test_c_wchar_p_arg(self):
            func = testdll._testfunc_p_p
            func.restype = c_wchar_p
            func.argtypes = c_wchar_p,

            c_wchar_p.from_param(u"123")

            self.assertEqual(None, func(None))
            self.assertEqual("123", func(u"123"))
            self.assertEqual(None, func(c_wchar_p(None)))
            self.assertEqual("123", func(c_wchar_p("123")))

            # XXX Currently, these raise TypeErrors, although they shouldn't:
            self.assertEqual("123", func(c_wbuffer("123")))
            ca = c_wchar("a")
            self.assertEqual("a", func(pointer(ca))[0])
            self.assertEqual("a", func(byref(ca))[0])

class ArrayTest(unittest.TestCase):
    def test(self):
        func = testdll._testfunc_ai8
        func.restype = POINTER(c_int)
        func.argtypes = c_int * 8,

        func((c_int * 8)(1, 2, 3, 4, 5, 6, 7, 8))

        # This did crash before:

        def func(): pass
        CFUNCTYPE(None, c_int * 3)(func)

################################################################

if __name__ == '__main__':
    unittest.main()
