• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1import unittest
2from ctypes import *
3from ctypes.test import need_symbol
4
5class StringArrayTestCase(unittest.TestCase):
6    def test(self):
7        BUF = c_char * 4
8
9        buf = BUF(b"a", b"b", b"c")
10        self.assertEqual(buf.value, b"abc")
11        self.assertEqual(buf.raw, b"abc\000")
12
13        buf.value = b"ABCD"
14        self.assertEqual(buf.value, b"ABCD")
15        self.assertEqual(buf.raw, b"ABCD")
16
17        buf.value = b"x"
18        self.assertEqual(buf.value, b"x")
19        self.assertEqual(buf.raw, b"x\000CD")
20
21        buf[1] = b"Z"
22        self.assertEqual(buf.value, b"xZCD")
23        self.assertEqual(buf.raw, b"xZCD")
24
25        self.assertRaises(ValueError, setattr, buf, "value", b"aaaaaaaa")
26        self.assertRaises(TypeError, setattr, buf, "value", 42)
27
28    def test_c_buffer_value(self):
29        buf = c_buffer(32)
30
31        buf.value = b"Hello, World"
32        self.assertEqual(buf.value, b"Hello, World")
33
34        self.assertRaises(TypeError, setattr, buf, "value", memoryview(b"Hello, World"))
35        self.assertRaises(TypeError, setattr, buf, "value", memoryview(b"abc"))
36        self.assertRaises(ValueError, setattr, buf, "raw", memoryview(b"x" * 100))
37
38    def test_c_buffer_raw(self):
39        buf = c_buffer(32)
40
41        buf.raw = memoryview(b"Hello, World")
42        self.assertEqual(buf.value, b"Hello, World")
43        self.assertRaises(TypeError, setattr, buf, "value", memoryview(b"abc"))
44        self.assertRaises(ValueError, setattr, buf, "raw", memoryview(b"x" * 100))
45
46    def test_param_1(self):
47        BUF = c_char * 4
48        buf = BUF()
49##        print c_char_p.from_param(buf)
50
51    def test_param_2(self):
52        BUF = c_char * 4
53        buf = BUF()
54##        print BUF.from_param(c_char_p("python"))
55##        print BUF.from_param(BUF(*"pyth"))
56
57    def test_del_segfault(self):
58        BUF = c_char * 4
59        buf = BUF()
60        with self.assertRaises(AttributeError):
61            del buf.raw
62
63
64@need_symbol('c_wchar')
65class WStringArrayTestCase(unittest.TestCase):
66    def test(self):
67        BUF = c_wchar * 4
68
69        buf = BUF("a", "b", "c")
70        self.assertEqual(buf.value, "abc")
71
72        buf.value = "ABCD"
73        self.assertEqual(buf.value, "ABCD")
74
75        buf.value = "x"
76        self.assertEqual(buf.value, "x")
77
78        buf[1] = "Z"
79        self.assertEqual(buf.value, "xZCD")
80
81    @unittest.skipIf(sizeof(c_wchar) < 4,
82                     "sizeof(wchar_t) is smaller than 4 bytes")
83    def test_nonbmp(self):
84        u = chr(0x10ffff)
85        w = c_wchar(u)
86        self.assertEqual(w.value, u)
87
88class StringTestCase(unittest.TestCase):
89    @unittest.skip('test disabled')
90    def test_basic_strings(self):
91        cs = c_string("abcdef")
92
93        # Cannot call len on a c_string any longer
94        self.assertRaises(TypeError, len, cs)
95        self.assertEqual(sizeof(cs), 7)
96
97        # The value property is the string up to the first terminating NUL.
98        self.assertEqual(cs.value, "abcdef")
99        self.assertEqual(c_string("abc\000def").value, "abc")
100
101        # The raw property is the total buffer contents:
102        self.assertEqual(cs.raw, "abcdef\000")
103        self.assertEqual(c_string("abc\000def").raw, "abc\000def\000")
104
105        # We can change the value:
106        cs.value = "ab"
107        self.assertEqual(cs.value, "ab")
108        self.assertEqual(cs.raw, "ab\000\000\000\000\000")
109
110        cs.raw = "XY"
111        self.assertEqual(cs.value, "XY")
112        self.assertEqual(cs.raw, "XY\000\000\000\000\000")
113
114        self.assertRaises(TypeError, c_string, "123")
115
116    @unittest.skip('test disabled')
117    def test_sized_strings(self):
118
119        # New in releases later than 0.4.0:
120        self.assertRaises(TypeError, c_string, None)
121
122        # New in releases later than 0.4.0:
123        # c_string(number) returns an empty string of size number
124        self.assertEqual(len(c_string(32).raw), 32)
125        self.assertRaises(ValueError, c_string, -1)
126        self.assertRaises(ValueError, c_string, 0)
127
128        # These tests fail, because it is no longer initialized
129##        self.assertEqual(c_string(2).value, "")
130##        self.assertEqual(c_string(2).raw, "\000\000")
131        self.assertEqual(c_string(2).raw[-1], "\000")
132        self.assertEqual(len(c_string(2).raw), 2)
133
134    @unittest.skip('test disabled')
135    def test_initialized_strings(self):
136
137        self.assertEqual(c_string("ab", 4).raw[:2], "ab")
138        self.assertEqual(c_string("ab", 4).raw[:2:], "ab")
139        self.assertEqual(c_string("ab", 4).raw[:2:-1], "ba")
140        self.assertEqual(c_string("ab", 4).raw[:2:2], "a")
141        self.assertEqual(c_string("ab", 4).raw[-1], "\000")
142        self.assertEqual(c_string("ab", 2).raw, "a\000")
143
144    @unittest.skip('test disabled')
145    def test_toolong(self):
146        cs = c_string("abcdef")
147        # Much too long string:
148        self.assertRaises(ValueError, setattr, cs, "value", "123456789012345")
149
150        # One char too long values:
151        self.assertRaises(ValueError, setattr, cs, "value", "1234567")
152
153    @unittest.skip('test disabled')
154    def test_perf(self):
155        check_perf()
156
157@need_symbol('c_wchar')
158class WStringTestCase(unittest.TestCase):
159    def test_wchar(self):
160        c_wchar("x")
161        repr(byref(c_wchar("x")))
162        c_wchar("x")
163
164
165    @unittest.skip('test disabled')
166    def test_basic_wstrings(self):
167        cs = c_wstring("abcdef")
168
169        # XXX This behaviour is about to change:
170        # len returns the size of the internal buffer in bytes.
171        # This includes the terminating NUL character.
172        self.assertEqual(sizeof(cs), 14)
173
174        # The value property is the string up to the first terminating NUL.
175        self.assertEqual(cs.value, "abcdef")
176        self.assertEqual(c_wstring("abc\000def").value, "abc")
177
178        self.assertEqual(c_wstring("abc\000def").value, "abc")
179
180        # The raw property is the total buffer contents:
181        self.assertEqual(cs.raw, "abcdef\000")
182        self.assertEqual(c_wstring("abc\000def").raw, "abc\000def\000")
183
184        # We can change the value:
185        cs.value = "ab"
186        self.assertEqual(cs.value, "ab")
187        self.assertEqual(cs.raw, "ab\000\000\000\000\000")
188
189        self.assertRaises(TypeError, c_wstring, "123")
190        self.assertRaises(ValueError, c_wstring, 0)
191
192    @unittest.skip('test disabled')
193    def test_toolong(self):
194        cs = c_wstring("abcdef")
195        # Much too long string:
196        self.assertRaises(ValueError, setattr, cs, "value", "123456789012345")
197
198        # One char too long values:
199        self.assertRaises(ValueError, setattr, cs, "value", "1234567")
200
201
202def run_test(rep, msg, func, arg):
203    items = range(rep)
204    from time import perf_counter as clock
205    start = clock()
206    for i in items:
207        func(arg); func(arg); func(arg); func(arg); func(arg)
208    stop = clock()
209    print("%20s: %.2f us" % (msg, ((stop-start)*1e6/5/rep)))
210
211def check_perf():
212    # Construct 5 objects
213
214    REP = 200000
215
216    run_test(REP, "c_string(None)", c_string, None)
217    run_test(REP, "c_string('abc')", c_string, 'abc')
218
219# Python 2.3 -OO, win2k, P4 700 MHz:
220#
221#      c_string(None): 1.75 us
222#     c_string('abc'): 2.74 us
223
224# Python 2.2 -OO, win2k, P4 700 MHz:
225#
226#      c_string(None): 2.95 us
227#     c_string('abc'): 3.67 us
228
229
230if __name__ == '__main__':
231##    check_perf()
232    unittest.main()
233