def setup(self): src = self._src = SocketEventSource(self._sock) src.stop_writing() # We'll start writing when we need to. self.mainloop.add_event_source(src) self._wbuf = StringBuffer() spec = [ # state, source, event_class, new_state, callback ('reading', src, SocketReadable, 'reading', self._fill), ('reading', self, _WriteBufferNotEmpty, 'rw', self._start_writing), ('reading', self, SocketBufferEof, 'idle', None), ('reading', self, _Close, None, self._really_close), ('rw', src, SocketReadable, 'rw', self._fill), ('rw', src, SocketWriteable, 'rw', self._flush), ('rw', self, _WriteBufferIsEmpty, 'reading', self._stop_writing), ('rw', self, SocketBufferEof, 'w', None), ('rw', self, _Close, 'wc', None), ('idle', self, _WriteBufferNotEmpty, 'w', self._start_writing), ('idle', self, _Close, None, self._really_close), ('w', src, SocketWriteable, 'w', self._flush), ('w', self, _WriteBufferIsEmpty, 'idle', self._stop_writing), ('wc', src, SocketWriteable, 'wc', self._flush), ('wc', self, _WriteBufferIsEmpty, None, self._really_close), ] self.add_transitions(spec)
def parseValue(self, *args): if len(args) is 0: valtype = self.buffer.readUInt8() else: valtype = args[0] if valtype < OBJECT: return self.buffer.readValue(valtype) elif valtype is VARARRAY: valtype = self.buffer.readUInt8() length = self.buffer.readValue(valtype) ret = [] i = 0 while i < length: ret.append(self.parseValue()) i += 1 return ret elif valtype is OBJECT: index = self.objectLayoutIndex[self.buffer.readValue(self.OLItype)] ret = {} i = 0 while i < len(index): ret[self.stringIndex[index[i]]] = self.parseValue() i += 1 elif valtype is STRING: return self.stringIndex[self.buffer.readValue(self.stringIndexType)] elif valtype is UNDEFINED: return None elif valtype is NULL: return Null(); elif valtype is TRUE: return True elif valtype is FALSE: return False elif valtype is DATE: return date.fromtimestamp(self.buffer.readUInt32()) elif valtype is REGEXP: return re.compile(self.readString()) elif valtype is NAN: return float("nan"); elif valtype is POSITIVE_INFINITY: return float("inf"); elif valtype is MINUS_INFINITY: return float("-inf"); elif valtype is BUFFER: ret = StringBuffer(); length = self.parseValue(self.buffer.readUInt8()); i = 0; while i < length: ret.writeUInt8(self.buffer.readUInt8(), i); i += 1 return ret else: raise Exception('Invalid LEON.') return ret
def setup(self): sockbuf = self.sockbuf = SocketBuffer(self.conn, self.max_buffer) self.mainloop.add_state_machine(sockbuf) self._eof = False self.receive_buf = StringBuffer() spec = [ # state, source, event_class, new_state, callback ('rw', sockbuf, SocketBufferNewData, 'rw', self._parse), ('rw', sockbuf, SocketBufferEof, 'w', self._send_eof), ('rw', self, _Close2, None, self._really_close), ('w', self, _Close2, None, self._really_close), ] self.add_transitions(spec)
class JsonMachine(StateMachine): '''A state machine for sending/receiving JSON messages across TCP.''' max_buffer = 16 * 1024 def __init__(self, conn): StateMachine.__init__(self, 'rw') self.conn = conn self.debug_json = False def __repr__(self): return '<JsonMachine at 0x%x: socket %s, max_buffer %s>' % \ (id(self), self.conn, self.max_buffer) def setup(self): sockbuf = self.sockbuf = SocketBuffer(self.conn, self.max_buffer) self.mainloop.add_state_machine(sockbuf) self._eof = False self.receive_buf = StringBuffer() spec = [ # state, source, event_class, new_state, callback ('rw', sockbuf, SocketBufferNewData, 'rw', self._parse), ('rw', sockbuf, SocketBufferEof, 'w', self._send_eof), ('rw', self, _Close2, None, self._really_close), ('w', self, _Close2, None, self._really_close), ] self.add_transitions(spec) def send(self, msg): '''Send a message to the other side.''' if self.debug_json: logging.debug('JsonMachine: Sending message %s' % repr(msg)) s = json.dumps(yaml.safe_dump(msg)) if self.debug_json: logging.debug('JsonMachine: As %s' % repr(s)) self.sockbuf.write('%s\n' % s) def close(self): '''Tell state machine it should shut down. The state machine will vanish once it has flushed any pending writes. ''' self.mainloop.queue_event(self, _Close2()) def _parse(self, event_source, event): data = event.data self.receive_buf.add(data) if self.debug_json: logging.debug('JsonMachine: Received: %s' % repr(data)) while True: line = self.receive_buf.readline() if line is None: break line = line.rstrip() if self.debug_json: logging.debug('JsonMachine: line: %s' % repr(line)) msg = yaml.load(json.loads(line)) self.mainloop.queue_event(self, JsonNewMessage(msg)) def _send_eof(self, event_source, event): self.mainloop.queue_event(self, JsonEof()) def _really_close(self, event_source, event): self.sockbuf.close() self._send_eof(event_source, event)
def writeString(self, string): buf = StringBuffer() for c in string: buf.writeUInt8(ord(c), -1) buf.writeUInt8(0, -1) self.append(buf)
def writeValue(self, *args): if len(args) < 3: implicit = False else: implicit = args[2] valtype = args[1] val = args[0] typeByte = StringBuffer() typeByte.writeUInt8(valtype, 0) if not implicit: self.append(typeByte) if valtype is UNDEFINED or valtype is TRUE or valtype is FALSE or valtype is NULL or valtype is NAN: return 1 if valtype is STRING: if len(self.stringIndex) is 0: self.writeString(val) return 2 + len(val) self.writeValue(self.stringIndex.index(val), self.stringIndexType, True) return 2 if valtype is SIGNED | CHAR: buf = StringBuffer() buf.writeInt8(val, 0) self.append(buf) return 2 if valtype is CHAR: buf = StringBuffer() buf.writeUInt8(val, 0) self.append(buf) return 2 if valtype is SIGNED | SHORT: buf = StringBuffer() buf.writeInt16LE(val, 0) self.append(buf) return 3 if valtype is SHORT: buf = StringBuffer() buf.writeInt16LE(val, 0) self.append(buf) return 5 if valtype is SIGNED | INT: buf = StringBuffer() buf.writeInt32LE(val, 0) self.append(buf) return 5 if valtype is INT: buf = StringBuffer() buf.writeUInt32LE(val, 0) self.append(buf) return 5 if valtype is FLOAT: buf = StringBuffer() buf.writeFloatLE(val, 0) self.append(buf) return 5 if valtype is DOUBLE: buf = StringBuffer() buf.writeDoubleLE(val, 0) self.append(buf) return 9 if valtype is VARARRAY: self.writeValue(len(val), typeCheck(len(val))) i = 0 while i < len(val): self.writeValue(val[i], typeCheck(val[i])) i += 1 if valtype is OBJECT: index = matchLayout(val, self.stringIndex, self.OLI) if not implicit: self.writeValue(index, self.OLItype, True) i = 0 while i < len(self.OLI[index]): tmp = val[self.stringIndex[self.OLI[index][i]]] self.writeValue(tmp, typeCheck(tmp)) i += 1 if valtype is DATE: self.writeValue(val.timestamp(), INT, true) if valtype is REGEXP: self.writeString(val.pattern)
def toDotString(self, attributes = False, fill = None): cr = r'\n' sb = StringBuffer() has_attribute = False highlight = 'yellow' sb.append(self.nid).append(' [label="').append(self.name) if attributes: if isinstance(attributes, list): for key in self.attributes: if key in attributes: has_attribute = True sb.append(cr).append(key).append(' = ').append(self.attributes[key]) else: for key in self.attributes: #has_attribute = True sb.append(cr).append(key).append(' = ').append(self.attributes[key]) sb.append('"') if fill: sb.append(', color=').append(fill).append(',style=filled') elif has_attribute: sb.append(', color=').append(highlight).append(',style=filled') sb.append('];') return str(sb)
def toDotString(self, nodes = None, attributes = False, highlights = None, fill = None): """produces the dot for either the entire graph, or just restricted to the nodes passed in. """ highighted_nids = set() if highlights is None else self.toNidSet(highlights) nids = set(self.nid_to_node.keys()) if nodes is None else self.toNidSet(nodes) sb = StringBuffer() sb.append('digraph ').append(self.gname).append(' {\n') #sb.append('\tnode [shape=box];\n') for name in self.name_to_node: node = self.name_to_node[name] node_id = node.nid if node_id not in nids: continue if fill and (node_id in highighted_nids): sb.append('\t').append(node.toDotString(attributes, fill)).append('\n') else: sb.append('\t').append(node.toDotString(attributes)).append('\n') for edge in self.edges: src_id = edge[0] tgt_id = edge[1] if src_id not in nids: continue if tgt_id not in nids: continue sb.append('\t').append(src_id).append(' -> ').append(tgt_id).append(';\n') sb.append('}\n') return str(sb)
class SocketBuffer(StateMachine): def __init__(self, sock, max_buffer): StateMachine.__init__(self, 'reading') self._sock = sock self._max_buffer = max_buffer def __repr__(self): return '<SocketBuffer at 0x%x: socket %s max_buffer %i>' % ( id(self), self._sock, self._max_buffer) def setup(self): src = self._src = SocketEventSource(self._sock) src.stop_writing() # We'll start writing when we need to. self.mainloop.add_event_source(src) self._wbuf = StringBuffer() spec = [ # state, source, event_class, new_state, callback ('reading', src, SocketReadable, 'reading', self._fill), ('reading', self, _WriteBufferNotEmpty, 'rw', self._start_writing), ('reading', self, SocketBufferEof, 'idle', None), ('reading', self, _Close, None, self._really_close), ('rw', src, SocketReadable, 'rw', self._fill), ('rw', src, SocketWriteable, 'rw', self._flush), ('rw', self, _WriteBufferIsEmpty, 'reading', self._stop_writing), ('rw', self, SocketBufferEof, 'w', None), ('rw', self, _Close, 'wc', None), ('idle', self, _WriteBufferNotEmpty, 'w', self._start_writing), ('idle', self, _Close, None, self._really_close), ('w', src, SocketWriteable, 'w', self._flush), ('w', self, _WriteBufferIsEmpty, 'idle', self._stop_writing), ('wc', src, SocketWriteable, 'wc', self._flush), ('wc', self, _WriteBufferIsEmpty, None, self._really_close), ] self.add_transitions(spec) def write(self, data): '''Put data into write queue.''' was_empty = len(self._wbuf) == 0 self._wbuf.add(data) if was_empty and len(self._wbuf) > 0: self._start_writing(None, None) self.mainloop.queue_event(self, _WriteBufferNotEmpty()) def close(self): '''Tell state machine to terminate.''' self.mainloop.queue_event(self, _Close()) def _report_error(self, event_source, event): logging.error(str(event)) def _fill(self, event_source, event): try: data = event.sock.read(self._max_buffer) except (IOError, OSError), e: logging.debug( '%s: _fill(): Exception %s from sock.read()', self, e) return [SocketError(event.sock, e)] if data: self.mainloop.queue_event(self, SocketBufferNewData(data)) else: event_source.stop_reading() self.mainloop.queue_event(self, SocketBufferEof())
class SocketBuffer(StateMachine): def __init__(self, sock, max_buffer): StateMachine.__init__(self, 'reading') self._sock = sock self._max_buffer = max_buffer def __repr__(self): return '<SocketBuffer at 0x%x: socket %s max_buffer %i>' % ( id(self), self._sock, self._max_buffer) def setup(self): src = self._src = SocketEventSource(self._sock) src.stop_writing() # We'll start writing when we need to. self.mainloop.add_event_source(src) self._wbuf = StringBuffer() spec = [ # state, source, event_class, new_state, callback ('reading', src, SocketReadable, 'reading', self._fill), ('reading', self, _WriteBufferNotEmpty, 'rw', self._start_writing), ('reading', self, SocketBufferEof, 'idle', None), ('reading', self, _Close, None, self._really_close), ('rw', src, SocketReadable, 'rw', self._fill), ('rw', src, SocketWriteable, 'rw', self._flush), ('rw', self, _WriteBufferIsEmpty, 'reading', self._stop_writing), ('rw', self, SocketBufferEof, 'w', None), ('rw', self, _Close, 'wc', None), ('idle', self, _WriteBufferNotEmpty, 'w', self._start_writing), ('idle', self, _Close, None, self._really_close), ('w', src, SocketWriteable, 'w', self._flush), ('w', self, _WriteBufferIsEmpty, 'idle', self._stop_writing), ('wc', src, SocketWriteable, 'wc', self._flush), ('wc', self, _WriteBufferIsEmpty, None, self._really_close), ] self.add_transitions(spec) def write(self, data): '''Put data into write queue.''' was_empty = len(self._wbuf) == 0 self._wbuf.add(data) if was_empty and len(self._wbuf) > 0: self._start_writing(None, None) self.mainloop.queue_event(self, _WriteBufferNotEmpty()) def close(self): '''Tell state machine to terminate.''' self.mainloop.queue_event(self, _Close()) def _report_error(self, event_source, event): logging.error(str(event)) def _fill(self, event_source, event): try: data = event.sock.read(self._max_buffer) except (IOError, OSError), e: logging.debug('%s: _fill(): Exception %s from sock.read()', self, e) return [SocketError(event.sock, e)] if data: self.mainloop.queue_event(self, SocketBufferNewData(data)) else: event_source.stop_reading() self.mainloop.queue_event(self, SocketBufferEof())
def toDotString(self, attributes=False, fill=None): cr = r'\n' sb = StringBuffer() has_attribute = False highlight = 'yellow' sb.append(self.nid).append(' [label="').append(self.name) if attributes: if isinstance(attributes, list): for key in self.attributes: if key in attributes: has_attribute = True sb.append(cr).append(key).append(' = ').append( self.attributes[key]) else: for key in self.attributes: #has_attribute = True sb.append(cr).append(key).append(' = ').append( self.attributes[key]) sb.append('"') if fill: sb.append(', color=').append(fill).append(',style=filled') elif has_attribute: sb.append(', color=').append(highlight).append(',style=filled') sb.append('];') return str(sb)
def toDotString(self, nodes=None, attributes=False, highlights=None, fill=None): """produces the dot for either the entire graph, or just restricted to the nodes passed in. """ highighted_nids = set() if highlights is None else self.toNidSet( highlights) nids = set( self.nid_to_node.keys()) if nodes is None else self.toNidSet(nodes) sb = StringBuffer() sb.append('digraph ').append(self.gname).append(' {\n') #sb.append('\tnode [shape=box];\n') for name in self.name_to_node: node = self.name_to_node[name] node_id = node.nid if node_id not in nids: continue if fill and (node_id in highighted_nids): sb.append('\t').append(node.toDotString(attributes, fill)).append('\n') else: sb.append('\t').append( node.toDotString(attributes)).append('\n') for edge in self.edges: src_id = edge[0] tgt_id = edge[1] if src_id not in nids: continue if tgt_id not in nids: continue sb.append('\t').append(src_id).append(' -> ').append( tgt_id).append(';\n') sb.append('}\n') return str(sb)