|
1 cimport qmsk.net.py as py |
|
2 |
|
3 cdef class sockaddr_in (sockaddr) : |
|
4 |
|
5 def __init__ (self, object addr=None, platform.in_port_t port=0) : |
|
6 """ |
|
7 Construct using given literal IPv4 address and TCP/UDP port |
|
8 |
|
9 addr - IPv4 address, defaults to INADDR_ANY (0.0.0.0) |
|
10 port - TCP/UDP port, defaults to 0 (ephemeral) |
|
11 """ |
|
12 |
|
13 # zero |
|
14 libc.memset(&self.sockaddr, 0, sizeof(self.sockaddr)) |
|
15 |
|
16 # store our family |
|
17 # XXX: this should be a class attribute... |
|
18 self._init_family(platform.AF_INET) |
|
19 |
|
20 # constant af |
|
21 self.sockaddr.sin_family = self.family |
|
22 |
|
23 # set the sin_port |
|
24 self.sockaddr.sin_port = platform.htons(port) |
|
25 |
|
26 if addr : |
|
27 # set the sin_addr |
|
28 # this automatically converts the addr from str -> char * |
|
29 platform.inet_pton(self.family, addr, &self.sockaddr.sin_addr) |
|
30 |
|
31 else : |
|
32 # set as INADDR_ANY |
|
33 self.sockaddr.sin_addr.s_addr = platform.INADDR_ANY |
|
34 |
|
35 cdef int _get_sockaddr (self, platform.sockaddr **sa_ptr, platform.socklen_t *sa_len) except -1 : |
|
36 if sa_ptr : |
|
37 sa_ptr[0] = <platform.sockaddr *> &self.sockaddr |
|
38 |
|
39 if sa_len : |
|
40 sa_len[0] = sizeof(self.sockaddr) |
|
41 |
|
42 return 0 |
|
43 |
|
44 cdef int _set_sockaddr (self, platform.sockaddr *sa, size_t sa_len) except -1 : |
|
45 assert sa_len == sizeof(self.sockaddr) |
|
46 |
|
47 libc.memcpy(&self.sockaddr, sa, sa_len) |
|
48 |
|
49 property port : |
|
50 """ |
|
51 The integer port number |
|
52 |
|
53 >>> sockaddr_in(port=1234).port |
|
54 1234 |
|
55 """ |
|
56 |
|
57 def __get__ (self) : |
|
58 return platform.ntohs(self.sockaddr.sin_port) |
|
59 |
|
60 def __cmp__ (self, other_obj) : |
|
61 """ |
|
62 A sockaddr_in is equal to any other sockaddr_in which has the same addr and port |
|
63 |
|
64 >>> assert sockaddr_in() == sockaddr_in() |
|
65 >>> assert sockaddr_in('127.0.0.1', 80) == sockaddr_in('127.0.0.1', 80) |
|
66 >>> addr = sockaddr_in(); assert addr == addr |
|
67 """ |
|
68 |
|
69 if not isinstance(other_obj, sockaddr_in) : |
|
70 return <object> py.Py_NotImplemented |
|
71 |
|
72 cdef sockaddr_in other = other_obj |
|
73 cdef platform.sockaddr_in *sa1 = &self.sockaddr, *sa2 = &other.sockaddr |
|
74 |
|
75 if other is self : |
|
76 return 0 |
|
77 |
|
78 return ( |
|
79 libc.memcmp(<void *> &sa1.sin_port, <void *> &sa2.sin_port, sizeof(sa1.sin_port)) |
|
80 or libc.memcmp(<void *> &sa1.sin_addr, <void *> &sa2.sin_addr, sizeof(sa1.sin_addr)) |
|
81 ) |
|
82 |
|
83 def __str__ (self) : |
|
84 """ |
|
85 Return the literal ASCII representation for this sockaddr as an '<addr>:<port> string |
|
86 |
|
87 >>> str(sockaddr_in()) |
|
88 '0.0.0.0:0' |
|
89 """ |
|
90 |
|
91 # format |
|
92 return "%s:%s" % self.getnameinfo() |
|
93 |
|
94 |