Fri, 21 Oct 2016 18:29:26 +0200
Merged with changes of Tobias.
--- a/DebugClients/Python/AsyncFile.py Fri Oct 21 18:25:23 2016 +0200 +++ b/DebugClients/Python/AsyncFile.py Fri Oct 21 18:29:26 2016 +0200 @@ -23,8 +23,10 @@ """ Module function to check for data to be written. - @param file The file object to be checked (file) - @return Flag indicating if there is data wating (int) + @param file The file object to be checked + @type file + @return Flag indicating if there is data waiting + @rtype int """ try: pending = file.pendingWrite() @@ -39,15 +41,17 @@ Class wrapping a socket object with a file interface. """ maxtries = 10 - maxbuffersize = 1024 * 1024 * 4 def __init__(self, sock, mode, name): """ Constructor @param sock the socket object being wrapped - @param mode mode of this file (string) - @param name name of this file (string) + @type socket + @param mode mode of this file + @type str + @param name name of this file + @type str """ # Initialise the attributes. self.closed = False @@ -57,7 +61,7 @@ self.nWriteErrors = 0 self.encoding = "utf-8" - self.wpending = unicode('') + self.wpending = [] def __checkMode(self, mode): """ @@ -66,47 +70,28 @@ This method checks, if an operation is permitted according to the mode of the file. If it is not, an IOError is raised. - @param mode the mode to be checked (string) + @param mode the mode to be checked + @type string @exception IOError raised to indicate a bad file descriptor """ if mode != self.mode: raise IOError((9, '[Errno 9] Bad file descriptor')) - def __nWrite(self, n): - """ - Private method to write a specific number of pending bytes. - - @param n the number of bytes to be written (int) - """ - if n: - try: - buf = self.wpending[:n] - try: - buf = buf.encode('utf-8', 'backslashreplace') - except (UnicodeEncodeError, UnicodeDecodeError): - pass - self.sock.sendall(buf) - self.wpending = self.wpending[n:] - self.nWriteErrors = 0 - except socket.error: - self.nWriteErrors += 1 - if self.nWriteErrors > self.maxtries: - self.wpending = unicode('') # delete all output - def pendingWrite(self): """ - Public method that returns the number of bytes waiting to be written. + Public method that returns the number of strings waiting to be written. - @return the number of bytes to be written (int) + @return the number of strings to be written + @rtype int """ - return self.wpending.rfind('\n') + 1 + return len(self.wpending) def close(self, closeit=False): """ Public method to close the file. @param closeit flag to indicate a close ordered by the debugger code - (boolean) + @type bool """ if closeit and not self.closed: self.flush() @@ -115,15 +100,28 @@ def flush(self): """ - Public method to write all pending bytes. + Public method to write all pending entries. """ - self.__nWrite(len(self.wpending)) + while self.wpending: + buf = self.wpending.pop(0) + try: + try: + buf = buf.encode('utf-8', 'backslashreplace') + except (UnicodeEncodeError, UnicodeDecodeError): + pass + self.sock.sendall(buf) + self.nWriteErrors = 0 + except socket.error: + self.nWriteErrors += 1 + if self.nWriteErrors > self.maxtries: + self.wpending = [] # delete all output def isatty(self): """ Public method to indicate whether a tty interface is supported. @return always false + @rtype bool """ return False @@ -131,7 +129,8 @@ """ Public method returning the file number. - @return file number (int) + @return file number + @rtype int """ try: return self.sock.fileno() @@ -142,7 +141,8 @@ """ Public method to check, if the stream is readable. - @return flag indicating a readable stream (boolean) + @return flag indicating a readable stream + @rtype bool """ return self.mode == "r" @@ -150,8 +150,10 @@ """ Public method to read bytes from this file. - @param size maximum number of bytes to be read (int) - @return the bytes read (any) + @param size maximum number of bytes to be read + @type int + @return the bytes read + @rtype str """ self.__checkMode('r') @@ -164,8 +166,10 @@ """ Public method to read bytes from this file. - @param size maximum number of bytes to be read (int) - @return the bytes read (any) + @param size maximum number of bytes to be read + @type int + @return the bytes read + @rtype str """ self.__checkMode('r') @@ -181,8 +185,10 @@ <b>Note</b>: This method will not block and may return only a part of a line if that is all that is available. - @param size maximum number of bytes to be read (int) - @return one line of text up to size bytes (string) + @param size maximum number of bytes to be read + @type int + @return one line of text up to size bytes + @rtype str """ self.__checkMode('r') @@ -209,8 +215,10 @@ """ Public method to read all lines from this file. - @param sizehint hint of the numbers of bytes to be read (int) - @return list of lines read (list of strings) + @param sizehint hint of the numbers of bytes to be read + @type int + @return list of lines read + @rtype list of str """ self.__checkMode('r') @@ -238,8 +246,10 @@ """ Public method to read one line from this file. - @param sizehint hint of the numbers of bytes to be read (int) - @return one line read (string) + @param sizehint hint of the numbers of bytes to be read + @type int + @return one line read + @rtype str """ self.__checkMode('r') @@ -252,7 +262,8 @@ """ Public method to check, if the stream is seekable. - @return flag indicating a seekable stream (boolean) + @return flag indicating a seekable stream + @rtype bool """ return False @@ -260,8 +271,10 @@ """ Public method to move the filepointer. - @param offset offset to move the filepointer to (integer) + @param offset offset to move the filepointer to + @type int @param whence position the offset relates to + @type int @exception IOError This method is not supported and always raises an IOError. """ @@ -280,7 +293,8 @@ """ Public method to truncate the file. - @param size size to truncate to (integer) + @param size size to truncate to + @type int @exception IOError This method is not supported and always raises an IOError. """ @@ -290,7 +304,8 @@ """ Public method to check, if a stream is writable. - @return flag indicating a writable stream (boolean) + @return flag indicating a writable stream + @rtype bool """ return self.mode == "w" @@ -298,45 +313,35 @@ """ Public method to write a string to the file. - @param s text to be written (string) + @param s text to be written + @type str """ self.__checkMode('w') cmd = prepareJsonCommand("ClientOutput", { "text": s, }) - self.write_p(cmd) + self.wpending.append(cmd) + self.flush() def write_p(self, s): """ - Public method to write a string to the file. + Public method to write a json-rpc 2.0 coded string to the file. - @param s text to be written (string) - @exception socket.error raised to indicate too many send attempts + @param s text to be written + @type str """ self.__checkMode('w') - tries = 0 - if not self.wpending: - self.wpending = s - elif len(self.wpending) + len(s) > self.maxbuffersize: - # flush wpending if it is too big - while self.wpending: - # if we have a persistent error in sending the data, an - # exception will be raised in __nWrite - self.flush() - tries += 1 - if tries > self.maxtries: - raise socket.error("Too many attempts to send data") - self.wpending = s - else: - self.wpending += s - self.__nWrite(self.pendingWrite()) + + self.wpending.append(s) + self.flush() def writelines(self, lines): """ Public method to write a list of strings to the file. - @param lines list of texts to be written (list of string) + @param lines list of texts to be written + @type list of str """ self.write("".join(lines))
--- a/DebugClients/Python/DebugUtilities.py Fri Oct 21 18:25:23 2016 +0200 +++ b/DebugClients/Python/DebugUtilities.py Fri Oct 21 18:29:26 2016 +0200 @@ -7,6 +7,8 @@ Module implementing utilities functions for the debug client. """ +import json + # # Taken from inspect.py of Python 3.4 # @@ -136,8 +138,6 @@ @return prepared JSON command or response string @rtype str """ - import json - commandDict = { "jsonrpc": "2.0", "method": method,