From 4ae2344dec4bc5066aa689c6bba80c277b2fac5d Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Tue, 13 Oct 2026 13:34:36 +0800 Subject: [PATCH] =?UTF-8?q?test(endiantest):=20=E6=96=B0=E5=A2=9E=E5=A4=A7?= =?UTF-8?q?=E5=B0=8F=E7=AB=AF=E5=AD=97=E8=8A=82=E5=BA=8F=E4=B8=93=E9=A1=B9?= =?UTF-8?q?=E2=80=94=E2=80=94=E5=86=85=E5=AD=98=E5=AD=97=E8=8A=82=E5=BA=8F?= =?UTF-8?q?=E5=88=97=E6=A0=A1=E9=AA=8C=20+=20=E8=AF=BB=E5=86=99=E6=88=90?= =?UTF-8?q?=E5=AF=B9=E5=9B=9E=E7=8E=AF=EF=BC=88=E5=B1=80=E9=83=A8=E5=8F=98?= =?UTF-8?q?=E9=87=8F/=E7=BB=93=E6=9E=84=E4=BD=93=E6=88=90=E5=91=98?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- EndianTest/App/main.vp | 96 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 EndianTest/App/main.vp diff --git a/EndianTest/App/main.vp b/EndianTest/App/main.vp new file mode 100644 index 0000000..46daa8b --- /dev/null +++ b/EndianTest/App/main.vp @@ -0,0 +1,96 @@ +import testcheck +import t + + +# 大小端字节序专项: +# · 标记 `t.BigEndian` 的槽位,在(默认的)小端目标上必须以**大端字节序列**存放; +# · 标记 `t.LittleEndian` 的槽位与目标序一致,按目标序存放; +# · 无标记 = native,不参与任何交换。 +# 因此本测试既校验「读写成对交换」的语义不变式(round-trip), +# 又**直接检查内存里的字节序列** —— 只有后者能真正证明交换发生了 +# (纯 round-trip 即使不交换也会通过,因为读写交换会互相抵消)。 + + +def read_byte(p: rawptr, i: int) -> int: + """读指针第 i 个字节;i8 按有符号解释,这里只取低 8 位。""" + return int(p[i]) & 0xFF + + +def test_big_endian_local() -> None: + """大端局部变量:内存字节必须是 12 34 56 78(MSB 在前),读回值不变。""" + testcheck.section("BigEndian local variable") + x: t.CInt32T | t.BigEndian = 0x12345678 + px: rawptr = rawptr(&x) + testcheck.check(read_byte(px, 0) == 0x12, "BigEndian memory byte[0] = 0x12 (MSB first)", "expect 0x12") + testcheck.check(read_byte(px, 1) == 0x34, "BigEndian memory byte[1] = 0x34", "expect 0x34") + testcheck.check(read_byte(px, 2) == 0x56, "BigEndian memory byte[2] = 0x56", "expect 0x56") + testcheck.check(read_byte(px, 3) == 0x78, "BigEndian memory byte[3] = 0x78 (LSB last)", "expect 0x78") + testcheck.check(x == 0x12345678, "BigEndian local round-trip", "expect 0x12345678") + + +def test_little_endian_local() -> None: + """小端局部变量:小端目标上与目标序一致,内存字节是 78 56 34 12(LSB 在前)。""" + testcheck.section("LittleEndian local variable") + y: t.CInt32T | t.LittleEndian = 0x12345678 + py: rawptr = rawptr(&y) + testcheck.check(read_byte(py, 0) == 0x78, "LittleEndian memory byte[0] = 0x78 (LSB first)", "expect 0x78") + testcheck.check(read_byte(py, 3) == 0x12, "LittleEndian memory byte[3] = 0x12", "expect 0x12") + testcheck.check(y == 0x12345678, "LittleEndian local round-trip", "expect 0x12345678") + + +def test_be_le_differ() -> None: + """同一值分别按大端/小端存放,内存字节序列必须互为反转。""" + testcheck.section("BigEndian vs LittleEndian memory layout") + a: t.CInt32T | t.BigEndian = 0x22334455 + b: t.CInt32T | t.LittleEndian = 0x22334455 + pa: rawptr = rawptr(&a) + pb: rawptr = rawptr(&b) + testcheck.check(read_byte(pa, 0) == read_byte(pb, 3), "BE byte[0] == LE byte[3]", "expect reversed byte order") + testcheck.check(read_byte(pa, 1) == read_byte(pb, 2), "BE byte[1] == LE byte[2]", "expect reversed byte order") + testcheck.check(read_byte(pa, 0) == 0x22, "BigEndian starts with MSB (0x22)", "expect 0x22") + + +class NetHeader: + """经典用法:结构体成员带字节序标记(对齐 TransPyC 文档里的 NetHeader)。""" + + magic: t.CInt32T | t.BigEndian + length: t.CInt16T | t.BigEndian + body: t.CInt32T + + +def test_struct_field_roundtrip() -> None: + """结构体成员:带标记的字段读写必须相等(读写成对交换的语义不变式)。""" + testcheck.section("Byte-order struct fields") + h: NetHeader = NetHeader() + h.magic = 0x11223344 + h.length = 0x5566 + h.body = 0x778899AA + testcheck.check(h.magic == 0x11223344, "BigEndian field magic round-trip", "expect 0x11223344") + testcheck.check(h.length == 0x5566, "BigEndian field length round-trip", "expect 0x5566") + testcheck.check(h.body == 0x778899AA, "native field body round-trip", "expect 0x778899AA") + # 赋值后再读第二次,确保交换是成对的、不会逐次累积 + testcheck.check(h.magic == 0x11223344, "BigEndian field second read unchanged", "expect 0x11223344") + + +def test_repeated_write() -> None: + """反复写入不同值,读回始终正确(交换必须成对且不残留)。""" + testcheck.section("Repeated writes") + x: t.CInt32T | t.BigEndian = 0 + i: int = 0 + ok: int = 1 + for i in range(int(4)): + v: t.CInt32T = t.CInt32T(0x10000000 * (i + 1)) + x = v + if x != v: + ok = 0 + testcheck.check(ok == 1, "BigEndian repeated writes stay consistent", "expect all round-trips to match") + + +def main() -> int: + testcheck.begin("EndianTest: BigEndian / LittleEndian byte order") + test_big_endian_local() + test_little_endian_local() + test_be_le_differ() + test_struct_field_roundtrip() + test_repeated_write() + return testcheck.end()