/gdata/tlslite/FileObject.py
Python | 220 lines | 208 code | 3 blank | 9 comment | 3 complexity | 93390e9c7cfc3e234cdff86642714395 MD5 | raw file
1"""Class returned by TLSConnection.makefile().""" 2 3class FileObject: 4 """This class provides a file object interface to a 5 L{tlslite.TLSConnection.TLSConnection}. 6 7 Call makefile() on a TLSConnection to create a FileObject instance. 8 9 This class was copied, with minor modifications, from the 10 _fileobject class in socket.py. Note that fileno() is not 11 implemented.""" 12 13 default_bufsize = 16384 #TREV: changed from 8192 14 15 def __init__(self, sock, mode='rb', bufsize=-1): 16 self._sock = sock 17 self.mode = mode # Not actually used in this version 18 if bufsize < 0: 19 bufsize = self.default_bufsize 20 self.bufsize = bufsize 21 self.softspace = False 22 if bufsize == 0: 23 self._rbufsize = 1 24 elif bufsize == 1: 25 self._rbufsize = self.default_bufsize 26 else: 27 self._rbufsize = bufsize 28 self._wbufsize = bufsize 29 self._rbuf = "" # A string 30 self._wbuf = [] # A list of strings 31 32 def _getclosed(self): 33 return self._sock is not None 34 closed = property(_getclosed, doc="True if the file is closed") 35 36 def close(self): 37 try: 38 if self._sock: 39 for result in self._sock._decrefAsync(): #TREV 40 pass 41 finally: 42 self._sock = None 43 44 def __del__(self): 45 try: 46 self.close() 47 except: 48 # close() may fail if __init__ didn't complete 49 pass 50 51 def flush(self): 52 if self._wbuf: 53 buffer = "".join(self._wbuf) 54 self._wbuf = [] 55 self._sock.sendall(buffer) 56 57 #def fileno(self): 58 # raise NotImplementedError() #TREV 59 60 def write(self, data): 61 data = str(data) # XXX Should really reject non-string non-buffers 62 if not data: 63 return 64 self._wbuf.append(data) 65 if (self._wbufsize == 0 or 66 self._wbufsize == 1 and '\n' in data or 67 self._get_wbuf_len() >= self._wbufsize): 68 self.flush() 69 70 def writelines(self, list): 71 # XXX We could do better here for very long lists 72 # XXX Should really reject non-string non-buffers 73 self._wbuf.extend(filter(None, map(str, list))) 74 if (self._wbufsize <= 1 or 75 self._get_wbuf_len() >= self._wbufsize): 76 self.flush() 77 78 def _get_wbuf_len(self): 79 buf_len = 0 80 for x in self._wbuf: 81 buf_len += len(x) 82 return buf_len 83 84 def read(self, size=-1): 85 data = self._rbuf 86 if size < 0: 87 # Read until EOF 88 buffers = [] 89 if data: 90 buffers.append(data) 91 self._rbuf = "" 92 if self._rbufsize <= 1: 93 recv_size = self.default_bufsize 94 else: 95 recv_size = self._rbufsize 96 while True: 97 data = self._sock.recv(recv_size) 98 if not data: 99 break 100 buffers.append(data) 101 return "".join(buffers) 102 else: 103 # Read until size bytes or EOF seen, whichever comes first 104 buf_len = len(data) 105 if buf_len >= size: 106 self._rbuf = data[size:] 107 return data[:size] 108 buffers = [] 109 if data: 110 buffers.append(data) 111 self._rbuf = "" 112 while True: 113 left = size - buf_len 114 recv_size = max(self._rbufsize, left) 115 data = self._sock.recv(recv_size) 116 if not data: 117 break 118 buffers.append(data) 119 n = len(data) 120 if n >= left: 121 self._rbuf = data[left:] 122 buffers[-1] = data[:left] 123 break 124 buf_len += n 125 return "".join(buffers) 126 127 def readline(self, size=-1): 128 data = self._rbuf 129 if size < 0: 130 # Read until \n or EOF, whichever comes first 131 if self._rbufsize <= 1: 132 # Speed up unbuffered case 133 assert data == "" 134 buffers = [] 135 recv = self._sock.recv 136 while data != "\n": 137 data = recv(1) 138 if not data: 139 break 140 buffers.append(data) 141 return "".join(buffers) 142 nl = data.find('\n') 143 if nl >= 0: 144 nl += 1 145 self._rbuf = data[nl:] 146 return data[:nl] 147 buffers = [] 148 if data: 149 buffers.append(data) 150 self._rbuf = "" 151 while True: 152 data = self._sock.recv(self._rbufsize) 153 if not data: 154 break 155 buffers.append(data) 156 nl = data.find('\n') 157 if nl >= 0: 158 nl += 1 159 self._rbuf = data[nl:] 160 buffers[-1] = data[:nl] 161 break 162 return "".join(buffers) 163 else: 164 # Read until size bytes or \n or EOF seen, whichever comes first 165 nl = data.find('\n', 0, size) 166 if nl >= 0: 167 nl += 1 168 self._rbuf = data[nl:] 169 return data[:nl] 170 buf_len = len(data) 171 if buf_len >= size: 172 self._rbuf = data[size:] 173 return data[:size] 174 buffers = [] 175 if data: 176 buffers.append(data) 177 self._rbuf = "" 178 while True: 179 data = self._sock.recv(self._rbufsize) 180 if not data: 181 break 182 buffers.append(data) 183 left = size - buf_len 184 nl = data.find('\n', 0, left) 185 if nl >= 0: 186 nl += 1 187 self._rbuf = data[nl:] 188 buffers[-1] = data[:nl] 189 break 190 n = len(data) 191 if n >= left: 192 self._rbuf = data[left:] 193 buffers[-1] = data[:left] 194 break 195 buf_len += n 196 return "".join(buffers) 197 198 def readlines(self, sizehint=0): 199 total = 0 200 list = [] 201 while True: 202 line = self.readline() 203 if not line: 204 break 205 list.append(line) 206 total += len(line) 207 if sizehint and total >= sizehint: 208 break 209 return list 210 211 # Iterator protocols 212 213 def __iter__(self): 214 return self 215 216 def next(self): 217 line = self.readline() 218 if not line: 219 raise StopIteration 220 return line