src/eric7/DebugClients/Python/AsyncFile.py

branch
eric7
changeset 10552
c5b0c8a5fa7d
parent 10439
21c28b0f9e41
child 10652
f788c1657f91
equal deleted inserted replaced
10544:70762114c59a 10552:c5b0c8a5fa7d
8 debugger. 8 debugger.
9 """ 9 """
10 10
11 import contextlib 11 import contextlib
12 import socket 12 import socket
13 import struct
13 import threading 14 import threading
15 import zlib
14 16
15 from DebugUtilities import prepareJsonCommand 17 from DebugUtilities import prepareJsonCommand
16 18
17 19
18 def AsyncPendingWrite(file): 20 def AsyncPendingWrite(file):
107 Public method to write all pending entries. 109 Public method to write all pending entries.
108 """ 110 """
109 self.writeLock.acquire() 111 self.writeLock.acquire()
110 while self.wpending: 112 while self.wpending:
111 try: 113 try:
112 buf = self.wpending.pop(0) 114 data = self.wpending.pop(0)
113 except IndexError: 115 except IndexError:
114 break 116 break
115 117
116 try: 118 try:
117 with contextlib.suppress(UnicodeEncodeError, UnicodeDecodeError): 119 with contextlib.suppress(UnicodeEncodeError, UnicodeDecodeError):
118 buf = buf.encode("utf-8", "backslashreplace") 120 data = data.encode("utf-8", "backslashreplace")
119 self.sock.sendall(buf) 121 header = struct.pack(b"!II", len(data), zlib.adler32(data) & 0xFFFFFFFF)
122 self.sock.sendall(header)
123 self.sock.sendall(data)
120 self.nWriteErrors = 0 124 self.nWriteErrors = 0
121 except OSError: 125 except OSError:
122 self.nWriteErrors += 1 126 self.nWriteErrors += 1
123 if self.nWriteErrors > AsyncFile.MAX_TRIES: 127 if self.nWriteErrors > AsyncFile.MAX_TRIES:
124 self.wpending = [] # delete all output 128 self.wpending = [] # delete all output
186 buf = buf[:size] 190 buf = buf[:size]
187 return buf 191 return buf
188 192
189 def readCommand(self): 193 def readCommand(self):
190 """ 194 """
191 Public method to read a length prefixed command string. 195 Public method to read a command string prefixed by a command header.
192 196
193 @return command string 197 @return command string
194 @rtype str 198 @rtype str
195 """ 199 """
196 # The command string is prefixed by a 9 character long length field. 200 header = self.sock.recv(struct.calcsize(b"!II"))
197 length = self.sock.recv(9) 201 if header:
198 length = int(length) 202 length, datahash = struct.unpack(b"!II", header)
199 data = b"" 203
200 while len(data) < length: 204 length = int(length)
201 remaining = length - len(data) 205 data = bytearray()
202 newBytes = self.sock.recv(min(remaining, AsyncFile.CMD_BUFSIZE)) 206 while len(data) < length:
203 data += newBytes 207 newData = self.sock.recv(length - len(data))
204 if newBytes[-1] == b"\n": 208 data += newData
205 break 209 if not newData:
206 210 break
207 # step 2: convert the data 211
208 return data.decode("utf8", "backslashreplace") 212 if data and zlib.adler32(data) & 0xFFFFFFFF == datahash:
213 return data.decode("utf8", "backslashreplace")
214
215 return ""
209 216
210 def readline_p(self, size=-1): 217 def readline_p(self, size=-1):
211 """ 218 """
212 Public method to read a line from this file. 219 Public method to read a line from this file.
213 220
346 self.writeLock.acquire() 353 self.writeLock.acquire()
347 if isinstance(s, (bytes, bytearray)): 354 if isinstance(s, (bytes, bytearray)):
348 # convert to string to send it 355 # convert to string to send it
349 s = repr(s) 356 s = repr(s)
350 357
351 cmd = prepareJsonCommand( 358 jsonCommand = prepareJsonCommand(
352 "ClientOutput", 359 "ClientOutput",
353 { 360 {
354 "text": s, 361 "text": s,
355 "debuggerId": "", 362 "debuggerId": "",
356 }, 363 },
357 ) 364 )
358 self.wpending.append(cmd) 365 self.wpending.append(jsonCommand)
359 self.flush() 366 self.flush()
360 self.writeLock.release() 367 self.writeLock.release()
361 368
362 def write_p(self, s): 369 def write_p(self, s):
363 """ 370 """

eric ide

mercurial