terom@49: cimport qmsk.net.libc as libc terom@24: cimport qmsk.net.py as py terom@24: terom@24: cdef class sockaddr_in (sockaddr) : terom@24: terom@24: def __init__ (self, object addr=None, platform.in_port_t port=0) : terom@24: """ terom@24: Construct using given literal IPv4 address and TCP/UDP port terom@24: terom@24: addr - IPv4 address, defaults to INADDR_ANY (0.0.0.0) terom@24: port - TCP/UDP port, defaults to 0 (ephemeral) terom@24: """ terom@24: terom@24: # zero terom@24: libc.memset(&self.sockaddr, 0, sizeof(self.sockaddr)) terom@24: terom@24: # store our family terom@24: # XXX: this should be a class attribute... terom@24: self._init_family(platform.AF_INET) terom@24: terom@24: # constant af terom@24: self.sockaddr.sin_family = self.family terom@24: terom@24: # set the sin_port terom@24: self.sockaddr.sin_port = platform.htons(port) terom@24: terom@24: if addr : terom@24: # set the sin_addr terom@24: # this automatically converts the addr from str -> char * terom@24: platform.inet_pton(self.family, addr, &self.sockaddr.sin_addr) terom@24: terom@24: else : terom@24: # set as INADDR_ANY terom@24: self.sockaddr.sin_addr.s_addr = platform.INADDR_ANY terom@24: terom@24: cdef int _get_sockaddr (self, platform.sockaddr **sa_ptr, platform.socklen_t *sa_len) except -1 : terom@24: if sa_ptr : terom@24: sa_ptr[0] = &self.sockaddr terom@24: terom@24: if sa_len : terom@24: sa_len[0] = sizeof(self.sockaddr) terom@24: terom@24: return 0 terom@24: terom@24: cdef int _set_sockaddr (self, platform.sockaddr *sa, size_t sa_len) except -1 : terom@24: assert sa_len == sizeof(self.sockaddr) terom@24: terom@24: libc.memcpy(&self.sockaddr, sa, sa_len) terom@24: terom@24: property port : terom@24: """ terom@24: The integer port number terom@24: terom@24: >>> sockaddr_in(port=1234).port terom@24: 1234 terom@24: """ terom@24: terom@24: def __get__ (self) : terom@24: return platform.ntohs(self.sockaddr.sin_port) terom@24: terom@24: def __cmp__ (self, other_obj) : terom@24: """ terom@24: A sockaddr_in is equal to any other sockaddr_in which has the same addr and port terom@24: terom@24: >>> assert sockaddr_in() == sockaddr_in() terom@24: >>> assert sockaddr_in('127.0.0.1', 80) == sockaddr_in('127.0.0.1', 80) terom@24: >>> addr = sockaddr_in(); assert addr == addr terom@24: """ terom@24: terom@24: if not isinstance(other_obj, sockaddr_in) : terom@24: return py.Py_NotImplemented terom@24: terom@24: cdef sockaddr_in other = other_obj terom@24: cdef platform.sockaddr_in *sa1 = &self.sockaddr, *sa2 = &other.sockaddr terom@24: terom@24: if other is self : terom@24: return 0 terom@24: terom@24: return ( terom@24: libc.memcmp( &sa1.sin_port, &sa2.sin_port, sizeof(sa1.sin_port)) terom@24: or libc.memcmp( &sa1.sin_addr, &sa2.sin_addr, sizeof(sa1.sin_addr)) terom@24: ) terom@24: terom@24: def __str__ (self) : terom@24: """ terom@24: Return the literal ASCII representation for this sockaddr as an ': string terom@24: terom@24: >>> str(sockaddr_in()) terom@24: '0.0.0.0:0' terom@24: """ terom@24: terom@24: # format terom@24: return "%s:%s" % self.getnameinfo() terom@24: terom@24: