def sendEvent(self): #called to send data out of the outbound queue - triggered when the sam bridge allows further sending assert self.state == 'connected', 'wrong state, expected "connected", got "%s"' % (self.state,) self.sendable = True if self.outQueueSize == 0: #nothing to send data = None if self.waitingForClose: #was waiting for close and done sending, so close it now self._close() elif self.outQueueSize <= 32768: #fits into a single message data = ''.join(self.outQueue) dataSize = len(data) self.outQueue.clear() self.outQueueSize = 0 else: #too much data for a single message data = deque() dataSize = 0 while dataSize < 32768: #add chunks until the limit is reached dataChunk = self.outQueue.popleft() dataChunkLen = len(dataChunk) if dataSize + dataChunkLen < 32768: #take entire chunk data.append(dataChunk) dataSize += dataChunkLen self.outQueueSize -= dataChunkLen else: #only take a part of the chunk useableDataChunkLen = 32768 - dataSize data.append(dataChunk[:useableDataChunkLen]) self.outQueue.appendleft(dataChunk[useableDataChunkLen:]) self.outQueueSize -= useableDataChunkLen dataSize += useableDataChunkLen data = ''.join(data) if data is not None: #something to send if (not self.waitingForClose) and \ self.outQueueSize < self.outMaxQueueSize and \ (self.outQueueSize + dataSize) >= self.outMaxQueueSize: #buffer was full and is not full anymore self.i2pSockStatus.setSendable(True, self.connId) #send data to the sam bridge self.sendFunc(SamMessages.streamSendMessage(self.samId, data)) #remember data, in case sam rejects it self.outMessage = data #don't send anything until the sam bridge send us its status self.sendable = False