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