|
1 """ |
|
2 Abstract byte-stream transport interface. |
|
3 """ |
|
4 |
|
5 from qmsk.net.transport import transport |
|
6 |
|
7 class Stream (transport.Transport) : |
|
8 """ |
|
9 A byte stream oriented transport. |
|
10 |
|
11 This provides a sequenced, reliable, full-duplex, connection-oriented byte stream. |
|
12 """ |
|
13 |
|
14 def read (self, iov) : |
|
15 """ |
|
16 Read and return up to `iov` bytes from this stream. This may return fewer bytes than requested. |
|
17 |
|
18 If the stream does not contain any more data (i.e. EOF), an empty string is returned. |
|
19 """ |
|
20 |
|
21 raise NotImplementedError() |
|
22 |
|
23 def readv (self, iovecs) : |
|
24 """ |
|
25 Attempt to read data into a sequence of iov's, returning a sequence of buffers with the read data. |
|
26 |
|
27 This may return fewer buffers than specified if there was not sufficient data to fill all buffers. |
|
28 |
|
29 By default, this is simply implemented using read(), but an implementation may also provide a more |
|
30 efficient version. |
|
31 """ |
|
32 |
|
33 ret = [] |
|
34 |
|
35 for iovec in iovecs : |
|
36 buf = self.read(iovec) |
|
37 |
|
38 if buf : |
|
39 ret.append(buf) |
|
40 |
|
41 else : |
|
42 # EOF! This should not be returned by readv! |
|
43 break |
|
44 |
|
45 return ret |
|
46 |
|
47 def write (self, buf) : |
|
48 """ |
|
49 Attempt to write the given data to this stream, returning the number of bytes written, which may be less |
|
50 than the length of the buffer given. |
|
51 """ |
|
52 |
|
53 raise NotImplementedError() |
|
54 |
|
55 def writev (self, iovecs) : |
|
56 """ |
|
57 Attempt to write data from the given sequence of buffers to this stream, returning the total number of |
|
58 bytes written, which may be less than the total length of the buffers given. |
|
59 |
|
60 By default, this is simply implemented using write(), but an implementation may also provide a more |
|
61 efficient version. |
|
62 """ |
|
63 |
|
64 ret = 0 |
|
65 |
|
66 for buf in iovec : |
|
67 # send this buffer |
|
68 buf_len = self.write(buf) |
|
69 |
|
70 # count total bytes sent |
|
71 ret += buf_len |
|
72 |
|
73 if buf_len < len(buf) : |
|
74 # buffer was sent incompletely, do not try and send any more |
|
75 break |
|
76 |
|
77 return ret |
|
78 |
|
79 def close (eslf) : |
|
80 """ |
|
81 Close this stream, disallowing any more read/write operations. |
|
82 |
|
83 This discards any unread data, but written data that has been buffered will still be sent. |
|
84 """ |
|
85 |
|
86 raise NotImplementedError() |
|
87 |
|
88 def abort (self) : |
|
89 """ |
|
90 Close this stream immediately, invalidating it for future use. |
|
91 |
|
92 This discards any unread data, and may discard written data that has been buffered and not yet sent. This |
|
93 should also ignore any close-related errors. |
|
94 |
|
95 By default, this is implemented using close(), but an implementation may also provide a more efficient |
|
96 version. |
|
97 |
|
98 XXX: remove default implementation? |
|
99 """ |
|
100 |
|
101 # XXX: ignore close-related errors? |
|
102 self.close() |
|
103 |