42 @param sock the socket object being wrapped |
42 @param sock the socket object being wrapped |
43 @param mode mode of this file (string) |
43 @param mode mode of this file (string) |
44 @param name name of this file (string) |
44 @param name name of this file (string) |
45 """ |
45 """ |
46 # Initialise the attributes. |
46 # Initialise the attributes. |
47 self.closed = 0 |
47 self.closed = False |
48 self.sock = sock |
48 self.sock = sock |
49 self.mode = mode |
49 self.mode = mode |
50 self.name = name |
50 self.name = name |
51 self.nWriteErrors = 0 |
51 self.nWriteErrors = 0 |
52 self.encoding = "utf-8" |
52 self.encoding = "utf-8" |
72 |
72 |
73 @param n the number of bytes to be written (int) |
73 @param n the number of bytes to be written (int) |
74 """ |
74 """ |
75 if n: |
75 if n: |
76 try: |
76 try: |
77 buf = "%s%s" % (self.wpending[:n], EOT) |
77 buf = self.wpending[:n] |
78 try: |
78 try: |
79 buf = buf.encode('utf-8') |
79 buf = buf.encode('utf-8', 'backslashreplace') |
80 except (UnicodeEncodeError, UnicodeDecodeError): |
80 except (UnicodeEncodeError, UnicodeDecodeError): |
81 pass |
81 pass |
82 self.sock.sendall(buf) |
82 self.sock.sendall(buf) |
83 self.wpending = self.wpending[n:] |
83 self.wpending = self.wpending[n:] |
84 self.nWriteErrors = 0 |
84 self.nWriteErrors = 0 |
93 |
93 |
94 @return the number of bytes to be written (int) |
94 @return the number of bytes to be written (int) |
95 """ |
95 """ |
96 return self.wpending.rfind('\n') + 1 |
96 return self.wpending.rfind('\n') + 1 |
97 |
97 |
98 def close(self, closeit=0): |
98 def close(self, closeit=False): |
99 """ |
99 """ |
100 Public method to close the file. |
100 Public method to close the file. |
101 |
101 |
102 @param closeit flag to indicate a close ordered by the debugger code |
102 @param closeit flag to indicate a close ordered by the debugger code |
103 (boolean) |
103 (boolean) |
104 """ |
104 """ |
105 if closeit and not self.closed: |
105 if closeit and not self.closed: |
106 self.flush() |
106 self.flush() |
107 self.sock.close() |
107 self.sock.close() |
108 self.closed = 1 |
108 self.closed = True |
109 |
109 |
110 def flush(self): |
110 def flush(self): |
111 """ |
111 """ |
112 Public method to write all pending bytes. |
112 Public method to write all pending bytes. |
113 """ |
113 """ |
130 try: |
130 try: |
131 return self.sock.fileno() |
131 return self.sock.fileno() |
132 except socket.error: |
132 except socket.error: |
133 return -1 |
133 return -1 |
134 |
134 |
|
135 def readable(self): |
|
136 """ |
|
137 Public method to check, if the stream is readable. |
|
138 |
|
139 @return flag indicating a readable stream (boolean) |
|
140 """ |
|
141 return self.mode == "r" |
|
142 |
135 def read_p(self, size=-1): |
143 def read_p(self, size=-1): |
136 """ |
144 """ |
137 Public method to read bytes from this file. |
145 Public method to read bytes from this file. |
138 |
146 |
139 @param size maximum number of bytes to be read (int) |
147 @param size maximum number of bytes to be read (int) |
179 # to the debugger relies on the two lines of the debugger command being |
187 # to the debugger relies on the two lines of the debugger command being |
180 # delivered as two separate events. Therefore we make sure we only |
188 # delivered as two separate events. Therefore we make sure we only |
181 # read a line at a time. |
189 # read a line at a time. |
182 line = self.sock.recv(size, socket.MSG_PEEK) |
190 line = self.sock.recv(size, socket.MSG_PEEK) |
183 |
191 |
184 eol = line.find('\n') |
192 eol = line.find(b'\n') |
185 |
193 |
186 if eol >= 0: |
194 if eol >= 0: |
187 size = eol + 1 |
195 size = eol + 1 |
188 else: |
196 else: |
189 size = len(line) |
197 size = len(line) |
190 |
198 |
191 # Now we know how big the line is, read it for real. |
199 # Now we know how big the line is, read it for real. |
192 return self.sock.recv(size).decode('utf8') |
200 return self.sock.recv(size).decode('utf8', 'backslashreplace') |
193 |
201 |
194 def readlines(self, sizehint=-1): |
202 def readlines(self, sizehint=-1): |
195 """ |
203 """ |
196 Public method to read all lines from this file. |
204 Public method to read all lines from this file. |
197 |
205 |
232 line = raw_input() + '\n' |
240 line = raw_input() + '\n' |
233 if sizehint >= 0: |
241 if sizehint >= 0: |
234 line = line[:sizehint] |
242 line = line[:sizehint] |
235 return line |
243 return line |
236 |
244 |
|
245 def seekable(self): |
|
246 """ |
|
247 Public method to check, if the stream is seekable. |
|
248 |
|
249 @return flag indicating a seekable stream (boolean) |
|
250 """ |
|
251 return False |
|
252 |
237 def seek(self, offset, whence=0): |
253 def seek(self, offset, whence=0): |
238 """ |
254 """ |
239 Public method to move the filepointer. |
255 Public method to move the filepointer. |
240 |
256 |
241 @param offset offset to seek for |
257 @param offset offset to seek for |
262 @exception IOError This method is not supported and always raises an |
278 @exception IOError This method is not supported and always raises an |
263 IOError. |
279 IOError. |
264 """ |
280 """ |
265 raise IOError('[Errno 29] Illegal seek') |
281 raise IOError('[Errno 29] Illegal seek') |
266 |
282 |
|
283 def writable(self): |
|
284 """ |
|
285 Public method to check, if a stream is writable. |
|
286 |
|
287 @return flag indicating a writable stream (boolean) |
|
288 """ |
|
289 return self.mode == "w" |
|
290 |
267 def write(self, s): |
291 def write(self, s): |
268 """ |
292 """ |
269 Public method to write a string to the file. |
293 Public method to write a string to the file. |
270 |
294 |
271 @param s bytes to be written (string) |
295 @param s bytes to be written (string) |
|
296 """ |
|
297 self.__checkMode('w') |
|
298 |
|
299 cmd = prepareJsonCommand("ClientOutput", { |
|
300 "text": s, |
|
301 }) |
|
302 self.write_p(cmd) |
|
303 |
|
304 def write_p(self, s): |
|
305 """ |
|
306 Public method to write a string to the file. |
|
307 |
|
308 @param s text to be written (string) |
272 @exception socket.error raised to indicate too many send attempts |
309 @exception socket.error raised to indicate too many send attempts |
273 """ |
310 """ |
274 self.__checkMode('w') |
311 self.__checkMode('w') |
275 tries = 0 |
312 tries = 0 |
276 if not self.wpending: |
313 if not self.wpending: |
277 self.wpending = s |
314 self.wpending = s |
278 elif type(self.wpending) != type(s) or \ |
315 elif len(self.wpending) + len(s) > self.maxbuffersize: |
279 len(self.wpending) + len(s) > self.maxbuffersize: |
316 # flush wpending if it is too big |
280 # flush wpending so that different string types are not |
|
281 # concatenated |
|
282 while self.wpending: |
317 while self.wpending: |
283 # if we have a persistent error in sending the data, an |
318 # if we have a persistent error in sending the data, an |
284 # exception will be raised in __nWrite |
319 # exception will be raised in __nWrite |
285 self.flush() |
320 self.flush() |
286 tries += 1 |
321 tries += 1 |
289 self.wpending = s |
324 self.wpending = s |
290 else: |
325 else: |
291 self.wpending += s |
326 self.wpending += s |
292 self.__nWrite(self.pendingWrite()) |
327 self.__nWrite(self.pendingWrite()) |
293 |
328 |
294 def writelines(self, list): |
329 def writelines(self, lines): |
295 """ |
330 """ |
296 Public method to write a list of strings to the file. |
331 Public method to write a list of strings to the file. |
297 |
332 |
298 @param list the list to be written (list of string) |
333 @param lines list of texts to be written (list of string) |
299 """ |
334 """ |
300 map(self.write, list) |
335 self.write("".join(lines)) |
301 |
336 |
302 # |
337 # |
303 # eflag: FileType = Python2 |
338 # eflag: FileType = Python2 |
304 # eflag: noqa = M601, M702 |
339 # eflag: noqa = M601, M702 |