Exemple #1
0
    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)
Exemple #2
0
 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
Exemple #3
0
    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)
Exemple #4
0
    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)
Exemple #5
0
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)
Exemple #6
0
 def writeString(self, string):
   buf = StringBuffer()
   for c in string:
     buf.writeUInt8(ord(c), -1)
   buf.writeUInt8(0, -1)
   self.append(buf)
Exemple #7
0
 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)
Exemple #8
0
    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)
Exemple #9
0
    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)
Exemple #10
0
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())
Exemple #11
0
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())
Exemple #12
0
    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)
Exemple #13
0
    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)