summaryrefslogtreecommitdiffstats
path: root/Lib/plat-win/socket.py
blob: 7e1b3727b22d353dbb6ddf4e0f53bde4bc28b22a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
"Socket wrapper for Windows, which does not support dup()."

# (And hence, fromfd() and makefile() are unimplemented in C....)

# XXX Living dangerously here -- close() is implemented by deleting a
# reference.  Thus we rely on the real _socket module to close on
# deallocation, and also hope that nobody keeps a reference to our _sock
# member.



try:
    from _socket import *
except ImportError:
    from socket import *

_realsocketcall = socket


def socket(family, type, proto=0):
    return _socketobject(_realsocketcall(family, type, proto))


class _socketobject:

    def __init__(self, sock):
	self._sock = sock

    def close(self):
	self._sock = None

    def __del__(self):
	self.close()

    def accept(self):
	sock, addr = self._sock.accept()
	return _socketobject(sock), addr

    def dup(self):
	return _socketobject(self._sock)

    def makefile(self, mode='r', bufsize=-1):
	return _fileobject(self._sock, mode, bufsize)

    _s = "def %s(self, *args): return apply(self._sock.%s, args)\n\n"
    for _m in ('bind', 'connect', 'fileno', 'listen',
	       'getpeername', 'getsockname',
	       'getsockopt', 'setsockopt',
	       'recv', 'recvfrom', 'send', 'sendto',
	       'setblocking',
	       'shutdown'):
	exec _s % (_m, _m)


class _fileobject:

    def __init__(self, sock, mode, bufsize):
	self._sock = sock
	self._mode = mode
	if bufsize < 0:
	    bufsize = 512
	self._rbufsize = max(1, bufsize)
	self._wbufsize = bufsize
	self._wbuf = self._rbuf = ""

    def close(self):
	try:
	    if self._sock:
		self.flush()
	finally:
	    self._sock = None

    def __del__(self):
	self.close()

    def flush(self):
	if self._wbuf:
	    self._sock.send(self._wbuf)
	    self._wbuf = ""

    def fileno(self):
	return self._sock.fileno()

    def write(self, data):
	self._wbuf = self._wbuf + data
	if self._wbufsize == 1:
	    if '\n' in data:
		self.flush()
	else:
	    if len(self._wbuf) >= self._wbufsize:
		self.flush()

    def writelines(self, list):
	filter(self._sock.send, list)
	self.flush()

    def read(self, n=-1):
	if n >= 0:
	    while len(self._rbuf) < n:
		new = self._sock.recv(self._rbufsize)
		if not new: break
		self._rbuf = self._rbuf + new
	    data, self._rbuf = self._rbuf[:n], self._rbuf[n:]
	    return data
	while 1:
	    new = self._sock.recv(self._rbufsize)
	    if not new: break
	    self._rbuf = self._rbuf + new
	data, self._rbuf = self._rbuf, ""
	return data

    def readline(self):
	import string
	data = ""
	i = string.find(self._rbuf, '\n')
	while i < 0:
	    new = self._sock.recv(self._rbufsize)
	    if not new: break
	    i = string.find(new, '\n')
	    if i >= 0: i = i + len(self._rbuf)
	    self._rbuf = self._rbuf + new
	if i < 0: i = len(self._rbuf)
	else: i = i+1
	data, self._rbuf = self._rbuf[:i], self._rbuf[i:]
	return data

    def readlines(self):
	list = []
	while 1:
	    line = self.readline()
	    if not line: break
	    list.append(line)
	return list