/gdata/tlslite/FileObject.py

http://radioappz.googlecode.com/ · Python · 220 lines · 183 code · 17 blank · 20 comment · 49 complexity · 93390e9c7cfc3e234cdff86642714395 MD5 · raw file

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