@@ -18,15 +18,37 @@ _ipaddr = ipaddress.ip_address
1818_ipnet = ipaddress.ip_network
1919
2020
21- cdef inline _net_encode(WriteBuffer buf, int32_t version, uint8_t bits,
21+ cdef inline uint8_t _ip_max_prefix_len(int32_t family):
22+ # Maximum number of bits in the network prefix of the specified
23+ # IP protocol version.
24+ if family == PGSQL_AF_INET:
25+ return 32
26+ else :
27+ return 128
28+
29+
30+ cdef inline int32_t _ip_addr_len(int32_t family):
31+ # Length of address in bytes for the specified IP protocol version.
32+ if family == PGSQL_AF_INET:
33+ return 4
34+ else :
35+ return 16
36+
37+
38+ cdef inline int8_t _ver_to_family(int32_t version):
39+ if version == 4 :
40+ return PGSQL_AF_INET
41+ else :
42+ return PGSQL_AF_INET6
43+
44+
45+ cdef inline _net_encode(WriteBuffer buf, int8_t family, uint32_t bits,
2246 int8_t is_cidr, bytes addr):
2347
2448 cdef:
2549 char * addrbytes
2650 ssize_t addrlen
27- int8_t family
2851
29- family = PGSQL_AF_INET if version == 4 else PGSQL_AF_INET6
3052 cpython.PyBytes_AsStringAndSize(addr, & addrbytes, & addrlen)
3153
3254 buf.write_int32(4 + < int32_t> addrlen)
@@ -41,28 +63,31 @@ cdef net_decode(ConnectionSettings settings, FastReadBuffer buf):
4163 cdef:
4264 int32_t family = < int32_t> buf.read(1 )[0 ]
4365 uint8_t bits = < uint8_t> buf.read(1 )[0 ]
44- uint32_t is_cidr = < uint32_t > buf.read(1 )[0 ]
45- uint32_t addrlen = < uint32_t > buf.read(1 )[0 ]
66+ int32_t is_cidr = < int32_t > buf.read(1 )[0 ]
67+ int32_t addrlen = < int32_t > buf.read(1 )[0 ]
4668 bytes addr
69+ uint8_t max_prefix_len = _ip_max_prefix_len(family)
4770
4871 if family != PGSQL_AF_INET and family != PGSQL_AF_INET6:
4972 raise ValueError (' invalid address family in "{}" value' .format(
5073 ' cidr' if is_cidr else ' inet'
5174 ))
5275
53- if bits > (32 if family == PGSQL_AF_INET else 128 ):
54- raise ValueError (' invalid bits in "{}" value' .format(
76+ max_prefix_len = _ip_max_prefix_len(family)
77+
78+ if bits > max_prefix_len:
79+ raise ValueError (' invalid network prefix length in "{}" value' .format(
5580 ' cidr' if is_cidr else ' inet'
5681 ))
5782
58- if addrlen != ( 4 if family == PGSQL_AF_INET else 16 ):
59- raise ValueError (' invalid length in "{}" value' .format(
83+ if addrlen != _ip_addr_len( family):
84+ raise ValueError (' invalid address length in "{}" value' .format(
6085 ' cidr' if is_cidr else ' inet'
6186 ))
6287
6388 addr = cpython.PyBytes_FromStringAndSize(buf.read(addrlen), addrlen)
6489
65- if is_cidr or bits > 0 :
90+ if is_cidr or bits ! = max_prefix_len :
6691 return _ipnet(addr).supernet(new_prefix = cpython.PyLong_FromLong(bits))
6792 else :
6893 return _ipaddr(addr)
@@ -71,15 +96,17 @@ cdef net_decode(ConnectionSettings settings, FastReadBuffer buf):
7196cdef cidr_encode(ConnectionSettings settings, WriteBuffer buf, obj):
7297 cdef:
7398 object ipnet
99+ int8_t family
74100
75101 ipnet = _ipnet(obj)
76- _net_encode(buf, ipnet.version, ipnet.prefixlen, 1 ,
77- ipnet.network_address.packed)
102+ family = _ver_to_family( ipnet.version)
103+ _net_encode(buf, family, ipnet.prefixlen, 1 , ipnet.network_address.packed)
78104
79105
80106cdef inet_encode(ConnectionSettings settings, WriteBuffer buf, obj):
81107 cdef:
82108 object ipaddr
109+ int8_t family
83110
84111 try :
85112 ipaddr = _ipaddr(obj)
@@ -88,7 +115,8 @@ cdef inet_encode(ConnectionSettings settings, WriteBuffer buf, obj):
88115 # for the host datatype.
89116 cidr_encode(settings, buf, obj)
90117 else :
91- _net_encode(buf, ipaddr.version, 0 , 0 , ipaddr.packed)
118+ family = _ver_to_family(ipaddr.version)
119+ _net_encode(buf, family, _ip_max_prefix_len(family), 0 , ipaddr.packed)
92120
93121
94122cdef init_network_codecs():
0 commit comments