Esempio n. 1
0
def messarg_is_None(messarg):
    """Indicates whether or not a message argument looks like the value None.

    Returns true if the message argument is one of the
    following:

       *''* (the string)
       *'None'* (the string)
       *'[]'* (the list, not the string... this corresponds to the EmacsLisp
       *nil* value)
    
    **INPUTS**
    
    STR *messarg* -- The message argument to be converted.
    
    
    **OUTPUTS**
    
    BOOL *answer* -- True iif the message argument can be interpreted as the value None
    """

    if messarg == 'None' or messarg == '' or messarg == []:
        #
        # Note: MessEncoder_LenPrefArgs encodes None value as string 'None',
        # while MessEncoderWDDX encodes it as the empty string, and
        # EmacsLisp's nil value gets encoded as an empty list.
        # 
        if tracing('messarg_is_None'):
            trace('messarg_is_None', 'messarg=%s, returning 1' % messarg)       
        return 1
    else:
        if tracing('messarg_is_None'):
            trace('messarg_is_None', 'messarg=%s, returning 0' % messarg)
        return 0
Esempio n. 2
0
def messarg_is_None(messarg):
    """Indicates whether or not a message argument looks like the value None.

    Returns true if the message argument is one of the
    following:

       *''* (the string)
       *'None'* (the string)
       *'[]'* (the list, not the string... this corresponds to the EmacsLisp
       *nil* value)
    
    **INPUTS**
    
    STR *messarg* -- The message argument to be converted.
    
    
    **OUTPUTS**
    
    BOOL *answer* -- True iif the message argument can be interpreted as the value None
    """

    if messarg == 'None' or messarg == '' or messarg == []:
        #
        # Note: MessEncoder_LenPrefArgs encodes None value as string 'None',
        # while MessEncoderWDDX encodes it as the empty string, and
        # EmacsLisp's nil value gets encoded as an empty list.
        # 
        if tracing('messarg_is_None'):
            trace('messarg_is_None', 'messarg=%s, returning 1' % messarg)       
        return 1
    else:
        if tracing('messarg_is_None'):
            trace('messarg_is_None', 'messarg=%s, returning 0' % messarg)
        return 0
Esempio n. 3
0
    def send_mess(self, mess_name, mess_argvals=None):
        
        """Sends a message to the external editor.

        **INPUTS**

        STR *mess_name* -- Identifier indicating what kind of message this is.
        
        {STR: STR} *mess_argvals* -- Dictionary of arguments and
        values for the message to be sent to the editor.
                
        **OUTPUTS**

        *none* response -- 
        """

        trace_id = 'send_mess.%s' % mess_name
        if tracing(trace_id):
            trace(trace_id, 'self=%s, mess_name=\'%s\'' % (self, mess_name))
        if mess_argvals == None:
            tmp_args = {}
        else:
            tmp_args = copy.copy(mess_argvals)
        if tracing(trace_id):
            trace(trace_id, 'mess_argvals=\'%s\'' % tmp_args)        
        unpkd_mess = self.encoder.encode(mess_name, tmp_args)
        pkd_mess = self.packager.pack_mess(unpkd_mess)        
        self.packager.send_packed_mess(pkd_mess, self.transporter)
Esempio n. 4
0
    def send_mess(self, mess_name, mess_argvals=None):
        
        """Sends a message to the external editor.

        **INPUTS**

        STR *mess_name* -- Identifier indicating what kind of message this is.
        
        {STR: STR} *mess_argvals* -- Dictionary of arguments and
        values for the message to be sent to the editor.
                
        **OUTPUTS**

        *none* response -- 
        """

        trace_id = 'send_mess.%s' % mess_name
        if tracing(trace_id):
##            trace(trace_id, 'self=%s, mess_name=\'%s\'' % (self, mess_name))
            trace(trace_id, '--mess_name=\'%s\'' % mess_name)
        if mess_argvals == None:
            tmp_args = {}
        else:
            tmp_args = copy.copy(mess_argvals)
        if tracing(trace_id):
            trace(trace_id, 'mess_argvals=\'%s\'' % tmp_args)        
        unpkd_mess = self.encoder.encode(mess_name, tmp_args)
        pkd_mess = self.packager.pack_mess(unpkd_mess)        
        self.packager.send_packed_mess(pkd_mess, self.transporter)
    def _push_change(self, change):
        """ private method for pushing a new ReverseBufferChange object onto
        the change_history stack

        **INPUTS**

        *ReverseBufferChange change* -- the object representing the reverse
        diff (would undo the change the editor reported)

        **OUTPUTS**

        *none*
        """
        if tracing('SourceBuffWithDiffs._push_change'):
            debug.trace('SourceBuffWithDiffs._push_change',
                'change to buff %s: old text "%s", replaced range = %s' \
                % (self.name(), change.old_text, repr(change.range)))
        dropped = self.change_history.push(change)
        if dropped:
            if tracing('SourceBuffWithDiffs._push_change'):
                debug.trace('SourceBuffWithDiffs._push_change',
                    'dropped old text "%s", replaced range = %s' \
                    % (dropped.old_text, repr(dropped.range)))
# level of the dropped change was:
            dropped_level = self.change_history.lowest()
            debug.trace('SourceBuffWithDiffs._push_change',
                'dropped level %d' % dropped_level)
# look through the cookie stack for cookies which referred to changes at or
# below the dropped level, and drop them, since they are no longer valid
            lowest_cookie = self.cookie_jar.lowest()
            jar_height = self.cookie_jar.height()
            debug.trace('SourceBuffWithDiffs._push_change',
                'cookie jar lowest, height = %d, %d' % (lowest_cookie,
                jar_height))
            debug.trace('SourceBuffWithDiffs._push_change',
                'looking through cookie jar...')
            found = 0
            for i in range(lowest_cookie, jar_height):
                cookie_data = self.cookie_jar.peek(i)
                level = cookie_data.level
                debug.trace('SourceBuffWithDiffs._push_change',
                    'at index %d, level = %d' % (i, level))
                if level > dropped_level:
                    debug.trace('SourceBuffWithDiffs._push_change',
                        'found level')
                    found = 1
                    break
            if found:
                debug.trace('SourceBuffWithDiffs._push_change',
                    'dropping cookies below index %d' % i)
                dropped_cookies = self.cookie_jar.drop_below(i)
                debug.trace('SourceBuffWithDiffs._push_change',
                    'dropped %d cookies' % dropped_cookies)
            else:
                debug.trace('SourceBuffWithDiffs._push_change',
                    'dropping cookies below height' % i)
                self.cookie_jar.drop_below(self.cookie_jar.height())
                debug.trace('SourceBuffWithDiffs._push_change',
                    'dropped %d cookies' % dropped_cookies)
    def insert_cbk(self, range, text):
        
        """External editor invokes that callback to notify VoiceCode
        of a deletion event.

        **INPUTS**
                
        (INT, INT) *range* -- Start and end position of text to be
        replaced by the insertion. If end of range is None, default to 
        the end of the buffer.

        STR *text* -- Text to be inserted

        **OUTPUTS**
        
        *none* -- 
        """
        if tracing('SourceBuffWithDiffs.insert_cbk'):
            debug.trace('SourceBuffWithDiffs.insert_cbk',
                'buff %s: replacing range %s with "%s"' \
                % (self.name(), repr(range), text))
        if self.undoing:
            debug.trace('SourceBuffWithDiffs.insert_cbk',
                'in process of undoing')
            self.during_undo(text = text, range = range)
        else:
            if self._not_cached('get_text'):
# if we don't have the buffer contents cached, we don't know what text 
# was replaced, so we can't create a reverse diff, and all our previous
# change_history is invalid
                debug.trace('SourceBuffWithDiffs.insert_cbk',
                    'not cached')
                if range[1] != range[0] and range[1] != range[0] + 1:
                    debug.trace('SourceBuffWithDiffs.insert_cbk',
                        'non-empty change')
                    self.clear_stacks()
            else:
# we need the old text, so we have to do all this processing before
# calling SourceBuffCached.insert_cbk
                range_non_nil = [range[0], range[1]]
                if range_non_nil[1] == None:
                   range_non_nil[1] = len(self._get_cache('get_text')) - 1
                replaced = self.cache['get_text'][range_non_nil[0]:range_non_nil[1]]
                if tracing('SourceBuffWithDiffs.insert_cbk'):
                    debug.trace('SourceBuffWithDiffs.insert_cbk',
                        'replaced text "%s"' % replaced)
# don't record non-changes
                if replaced != text:
# for the reverse diff, we need the range of the new text
# The start of the new text is the same as the start of the old text,
# but the end is offset from the start by one more than the length of
# the new text
                    start = range_non_nil[0]
# we use the same convention for ranges as Python's slice
                    end = start + len(text)
                    reverse = ReverseBufferChange(replaced, (start, end))
                    self._push_change(reverse)

        SourceBuffCached.insert_cbk(self, range, text)
    def insert_cbk(self, range, text):
        """External editor invokes that callback to notify VoiceCode
        of an insertion event.

        **INPUTS**
        
        (INT, INT) *range* -- Start and end position of text to be
        replaced by the insertion. 

        STR *text* -- Text to be inserted

        **OUTPUTS**
        
        *none* -- 
        """
        if tracing('SourceBuffCached.insert_cbk.short'):
            trace('SourceBuffCached.insert_cbk.short', 
                'range=%s, len(text) = %d, text="%s..."' \
                % (range, len(text), text[0:60]))
        if tracing('SourceBuffCached.insert_cbk'):
            trace('SourceBuffCached.insert_cbk', 'range=%s, text=\'%s\'' % (range, text))

#        if range == None:
#            range = self.get_selection()
# bad: if this gets the selection from the application, it will be all
# screwed up because the application will already have made the change.
# Basically, callbacks should never use defaults for the range

        SourceBuff.SourceBuff.insert_cbk(self, range, text)
        if self._not_cached('get_text'):
# if we don't have the buffer contents cached, just get the entire
# current contents (which should already include the deletion), thereby
# caching it
#            self.get_text()
# 
# Oops - this causes major problems because there may already have been
# other changes to the buffer, whose change callbacks are still in the
# queue.  Therefore, the safe thing to do is to leave the buffer
# uncached until the next time we explicitly synchronize with the 
# application (which first flushes all updates from the listen_msgr)
            trace('SourceBuffCached.insert_cbk.short', 
                'no cache - ignoring callback')
            pass
        else:
            trace('SourceBuffCached.insert_cbk', 'updating cached value')
            old_text = self.get_text()
            self._put_cache('get_text', old_text[:range[0]] + text + \
                     old_text[range[1]:])

        self.uncache_data_after_buffer_change(what_changed = 'get_text')
Esempio n. 8
0
    def get_mess(self, expect=None):
        """Gets a message from the external editor.
        **NOTE:** In this version, get_mess won't block, but will return 
        None if no message is available.
        
        **INPUTS**
        
        [STR] *expect* -- If not *None*, then make sure the
        message's name is listed in *expect*. If not, send an
        error message.

        **OUTPUTS**
        
        (STR, {STR: STR}) name_argvals_mess -- The message retrieved
         from external editor in *(mess_name, {arg:val})* format, or
         None if no message is available."""

        trace('get_mess', 'self=%s, expecting %s' % (self, repr(expect)))        
        
        try:
            name_argvals_mess = self.receiver.get(block=0)
        except Queue.Empty:
            return None

        if expect != None and (not (name_argvals_mess[0] in expect)):
            self.wrong_message(name_argvals_mess, expect)

        if tracing('get_mess.%s' % name_argvals_mess[0]):
            trace('get_mess.%s' % name_argvals_mess[0], 
                  'got one of %s! It was: %s' \
                  % (repr(expect), repr(name_argvals_mess)))

        return name_argvals_mess
Esempio n. 9
0
    def decode(self, str_mess):
        """Decodes a message to {arg:val} format.
      
        **INPUTS**
        
        *STR* str_mess -- The message in raw string format
        
        **OUTPUTS**
        
        *(STR, {STR: STR}) name_argvals_mess* -- First element is the
        message name, second element is message arguments in
        *(name, {arg:val})* format.  """

        if tracing('messaging.MessEncoderWDDX.decode'):
            trace('messaging.MessEncoderWDDX.decode',
                  'decoding str_mess="%s"' % str_mess)
        
        mess_argvals = self.unmarshaller.loads(str_mess)

        #
        # Name of message is one of the entries in the unmarshalled dictionnary.
        # Remove it from there.
        #
        mess_name = mess_argvals['message_name']
        del mess_argvals['message_name']
        return (mess_name, mess_argvals)
Esempio n. 10
0
    def get_mess(self, expect=None):
        """Gets a message from the external editor.
        **NOTE:** In this version, get_mess won't block, but will return 
        None if no message is available.
        
        **INPUTS**
        
        [STR] *expect* -- If not *None*, then make sure the
        message's name is listed in *expect*. If not, send an
        error message.

        **OUTPUTS**
        
        (STR, {STR: STR}) name_argvals_mess -- The message retrieved
         from external editor in *(mess_name, {arg:val})* format, or
         None if no message is available."""

        trace('get_mess', 'expecting %s' % repr(expect))
        
        try:
            name_argvals_mess = self.receiver.get(block=0)
        except Queue.Empty:
            return None

        if expect != None and (not (name_argvals_mess[0] in expect)):
            self.wrong_message(name_argvals_mess, expect)

        if tracing('get_mess.%s' % name_argvals_mess[0]):
            trace('get_mess.%s' % name_argvals_mess[0], 
                  'got one of %s! It was: %s' \
                  % (repr(expect), repr(name_argvals_mess)))

        return name_argvals_mess
Esempio n. 11
0
    def get_mess(self, expect=None):
        """Gets a message from the external editor.
        **NOTE:** get_mess may block if no message is available.
        
        **INPUTS**
        
        [STR] *expect* -- If not *None*, then make sure the
        message's name is listed in *expect*. If not, send an
        error message.

        **OUTPUTS**
        
        (STR, {STR: STR}) name_argvals_mess -- The message retrieved
         from external editor in *(mess_name, {arg:val})* format, or
         None if no message is available."""

        trace('get_mess', 'self=%s, expecting %s' % (self, repr(expect)))
        
        pkd_mess = self.packager.get_packed_mess(self.transporter)
        unpkd_mess = self.packager.unpack_mess(pkd_mess)
        name_argvals_mess = self.encoder.decode(unpkd_mess)

        if expect != None and (not (name_argvals_mess[0] in expect)):
            trace('get_mess', 'wrong_message %s, expecting %s' % \
                (repr(name_argvals_mess), repr(expect)))
            self.wrong_message(name_argvals_mess, expect)

        if tracing('get_mess.%s' % name_argvals_mess[0]):
            trace('get_mess.%s' % name_argvals_mess[0], 
                  'got one of %s! It was: %s' \
                  % (repr(expect), repr(name_argvals_mess)))
        
        return name_argvals_mess
Esempio n. 12
0
    def decode(self, str_mess):
        """Decodes a message to {arg:val} format.
      
        **INPUTS**
        
        *STR* str_mess -- The message in raw string format
        
        **OUTPUTS**
        
        *(STR, {STR: STR}) name_argvals_mess* -- First element is the
        message name, second element is message arguments in
        *(name, {arg:val})* format.  """

        if tracing('messaging.MessEncoderWDDX.decode'):
            trace('messaging.MessEncoderWDDX.decode',
                  'decoding str_mess="%s"' % str_mess)
        
        mess_argvals = self.unmarshaller.loads(str_mess)

        #
        # Name of message is one of the entries in the unmarshalled dictionnary.
        # Remove it from there.
        #
        mess_name = mess_argvals['message_name']
        del mess_argvals['message_name']
        return (mess_name, mess_argvals)
Esempio n. 13
0
    def get_mess(self, expect=None):
        """Gets a message from the external editor.
        **NOTE:** get_mess may block if no message is available.
        
        **INPUTS**
        
        [STR] *expect* -- If not *None*, then make sure the
        message's name is listed in *expect*. If not, send an
        error message.

        **OUTPUTS**
        
        (STR, {STR: STR}) name_argvals_mess -- The message retrieved
         from external editor in *(mess_name, {arg:val})* format, or
         None if no message is available."""
        # leave away self here (see send_mess.) QH
        trace('get_mess', '--expecting %s' % repr(expect))
        
        pkd_mess = self.packager.get_packed_mess(self.transporter)
        unpkd_mess = self.packager.unpack_mess(pkd_mess)
        name_argvals_mess = self.encoder.decode(unpkd_mess)

        if expect != None and (not (name_argvals_mess[0] in expect)):
            trace('get_mess', 'wrong_message %s, expecting %s' % \
                (repr(name_argvals_mess), repr(expect)))
            self.wrong_message(name_argvals_mess, expect)

        if tracing('get_mess.%s' % name_argvals_mess[0]):
            trace('get_mess.%s' % name_argvals_mess[0], 
                  'got one of %s! It was: %s' \
                  % (repr(expect), repr(name_argvals_mess)))
        
        return name_argvals_mess
Esempio n. 14
0
 def _get_cache_multiple(self, names):
     trace('SourceBuffCached._get_cache_multiple', 'names=%s' % repr(names))
     values = []
     for a_name in names:
         values.append(self._get_cache(a_name))
     if tracing('SourceBuffCached._get_cache_multiple'):
         trace('SourceBuffCached._get_cache_multiple', 'returning values=%s' % repr(values))
     return values
Esempio n. 15
0
    def delete_cbk(self, range):
        """External editor invokes that callback to notify VoiceCode
        of a deletion event.

        **INPUTS**
        
        (INT, INT) *range* -- Start and end pos of range to be deleted
        

        **OUTPUTS**
        
        *none* -- 
        """
        debug.trace('SourceBuffWithDiffs.delete_cbk',
            'buff %s: deleting range = %s' % (self.name(), repr(range)))
        if self.undoing:
            debug.trace('SourceBuffWithDiffs.delete_cbk',
                'in process of undoing')
            self.during_undo(text = "", range = range)
        else:
            if self.cache['get_text'] == None:
# if we don't have the buffer contents cached, we don't know what text 
# was deleted, so we can't create a reverse diff, and all our previous
# change_history is invalid
                debug.trace('SourceBuffWithDiffs.delete_cbk',
                    'not cached')
                if range[1] != range[0] and range[1] != range[0] + 1:
                    debug.trace('SourceBuffWithDiffs.delete_cbk',
                        'non-empty change')
                    self.clear_stacks()
            else:
# we need the old text, so we have to do all this processing before
# calling SourceBuffCached.delete_cbk
                deleted = self.cache['get_text'][range[0]:range[1]]
# don't record deletions of nothing
                if tracing('SourceBuffWithDiffs.delete_cbk'):
                    debug.trace('SourceBuffWithDiffs.delete_cbk',
                        'deleted text "%s"' % deleted)
                if deleted:
# for the reverse diff, we need the range of the new text
# The start of the new text is the same as the start of the old text,
# but the end is offset from the start by one more than the length of
# the new text
                    start = range[0]
                    end = range[0]
# for deletions, the range of the new text is empty (technically, we 
                    reverse = ReverseBufferChange(deleted, (start, end))
                    self._push_change(reverse)

        SourceBuffCached.delete_cbk(self, range)
Esempio n. 16
0
    def contents_cbk(self, text):
        """External editor invokes that callback to inform VoiceCode
        of the complete contents of the buffer.
        
        **INPUTS**
        
        STR *text* -- Up-to-date contents of the buffer

        **OUTPUTS**
        
        *none* -- 
        """
        if tracing('SourceBuffCached.contents_cbk.short'):
            trace('SourceBuffCached.contents_cbk.short', 
                'len(text) = %d, text="%s..."' \
                % (len(text), text[0:60]))
        if tracing('SourceBuffCached.contents_cbk'):
            trace('SourceBuffCached.contents_cbk', 'range=%s, text=\'%s\'' % (range, text))


        SourceBuff.SourceBuff.contents_cbk(self, text)
        if self._not_cached('get_text'):
# if contents are not cached, cache them
            self._put_cache('get_text', text)
            self.uncache_data_after_buffer_change(what_changed = 'get_text')
            if tracing('SourceBuffCached.contents_cbk'):
                trace('SourceBuffCached.contents_cbk', 
                    ('** upon exit, self._get_cache("cur_pos")=%s,' +
                     ' self._get_cache("get_text")=%s') % \
                    (self._get_cache("cur_pos"), 
                    repr(self._get_cache("get_text"))))
        else:
# otherwise, treat this as an insert_cbk
            start, end, change = \
                find_difference.find_difference(self.cache['get_text'], text)
            self.insert_cbk(range = (start, end), text = change)
Esempio n. 17
0
 def _get_cache_element_multiple(self, elt_names, get_from_app_method):
     """Gets the value of one or more elements that could be in cache.
     
     **INPUTS**
     
     [STR] *elt_names* -- list of names of the elements in the cache.
     
     METHOD *get_from_app_method* -- the method to invoke in order to get the value of the 
     elements directly from the client application instead of from the cache. We assume that
     the method returns the elements in the same order as they are listed in *elt_names*.
     
     **OUTPUTS**
     
     [ANY] *values* -- values of each of the elements.
     """ 
     trace('SourceBuffCached._get_cache_element_multiple', 'elt_names=%s, get_from_app_method=%s, self.use_cache=%s' % 
                                                           (repr(elt_names), get_from_app_method, self.use_cache))
     if not self.use_cache:
        debug.trace('SourceBuffCached._get_cache_element_multiple', 'not using cache')        
        values = apply(get_from_app_method)
        if len(elt_names) == 1:
            # if only one element, assume that get_from_app_method returns a single
            # value for that element, as opposed to a list of values for earch
            # element
            values = [values]           
     else:  
        debug.trace('SourceBuffCached._get_cache_element_multiple', 'looking up in cache')                   
        if self._not_cached_multiple(elt_names):
           debug.trace('SourceBuffCached._get_cache_element_multiple', 'cache is dirty... retrieving from app')                   
           values_from_app = apply(get_from_app_method)
           if len(elt_names) == 1:
              # if only one element, assume that get_from_app_method returns a single
              # value for that element, as opposed to a list of values for earch
              # element
              values_from_app = [values_from_app]
           self._put_cache_multiple(elt_names, values_from_app)
        else:
           debug.trace('SourceBuffCached._get_cache_element_multiple', 'cache element was up to date')
        values = self._get_cache_multiple(elt_names)
        
     if tracing('SourceBuffCached._get_cache_element_multiple'):
         debug.trace('SourceBuffCached._get_cache_element_multiple', 'returning values=%s' % repr(values))
     return values
Esempio n. 18
0
    def app_change_buffer(self, buff_name):
        """Changes the external application's active buffer. 

        **INPUTS**
        
        STR *buff_name* -- Name of the buffer to switch to.
       
        **OUTPUTS**
        
        *BOOL* -- true if buff_name exists and the application
        successfully switches to it
        """
        self.talk_msgr.send_mess('change_buff', {'buff_name': buff_name})
        response = self.talk_msgr.get_mess(expect=['change_buff_resp'])
        value = messaging.messarg2int(response[1]['value'])
        if tracing('AppStateEmacs.app_change_buffer'):
            trace('AppStateEmacs.app_change_buffer', 
                'response was %d' % value)
        return value
Esempio n. 19
0
    def receive_string(self, num_bytes):
        """Receives a string on the Socket connection.
        
        **INPUTS**
        
        INT *num_bytes* -- Number of bytes to receive.
        

        **OUTPUTS**
        
        STR *a_string* -- The received string
        """

        a_string = ''
        while len(a_string) < num_bytes:
            if self.sleep:
                while not self.data_available():
                    self.sleeper.sleep(self.sleep)
                    if self.sleeper.was_woken():
                        raise WokenUp("receive_string woken up")
#                    time.sleep(self.sleep)
            try:
                chunk = self.sock.recv(num_bytes - len(a_string))
                if tracing('receive_string'):
                    trace('receive_string', 'read chunk=\'%s\'' % chunk);
            except socket.error:
                chunk = ''
            if chunk == '':
                sys.stderr.write('MessTransporter_Socket.receive_string:')
                sys.stderr.write(' no data received in %s' % \
                    threading.currentThread().getName())
                raise SocketError("socket connection broken (receiving)")
#                raise SocketError, "socket connection broken"
            a_string = a_string + chunk

#        if tracing('receive_string'):
#            trace('receive_string', "received string '%s'" % a_chunk)
        return a_string         
Esempio n. 20
0
    def receive_string(self, num_bytes):
        """Receives a string on the Socket connection.
        
        **INPUTS**
        
        INT *num_bytes* -- Number of bytes to receive.
        

        **OUTPUTS**
        
        STR *a_string* -- The received string
        """

        a_string = ''
        while len(a_string) < num_bytes:
            if self.sleep:
                while not self.data_available():
                    self.sleeper.sleep(self.sleep)
                    if self.sleeper.was_woken():
                        raise WokenUp("receive_string woken up")
#                    time.sleep(self.sleep)
            try:
                chunk = self.sock.recv(num_bytes - len(a_string))
                if tracing('receive_string'):
                    trace('receive_string', 'read chunk=\'%s\'' % chunk);
            except socket.error:
                chunk = ''
            if chunk == '':
                sys.stderr.write('MessTransporter_Socket.receive_string:')
                sys.stderr.write(' no data received in %s' % \
                    threading.currentThread().getName())
                raise SocketError("socket connection broken (receiving)")
#                raise SocketError, "socket connection broken"
            a_string = a_string + chunk

#        if tracing('receive_string'):
#            trace('receive_string', "received string '%s'" % a_chunk)
        return a_string         
Esempio n. 21
0
    def send_packed_mess(self, pkd_mess, transporter):
        """Send a packaged message as a sequence of fixed length chunks.
        
        **INPUTS**
        
        STR *pkd_mess* -- The packed message
        
        [MessTransporter] *transporter* -- Transport channel to be used
        

        **OUTPUTS**
        
        *none* --

        ..[MessTransporter] file:///./messaging.MessTransporter.html"""

        if tracing('send_packed_mess'):
            trace('send_packed_mess', 'pkd_mess="%s"' % pkd_mess)
        
        #
        # Nothing particular about how such messages need to be sent.
        #
        transporter.send_string(pkd_mess)
Esempio n. 22
0
    def send_packed_mess(self, pkd_mess, transporter):
        """Send a packaged message as a sequence of fixed length chunks.
        
        **INPUTS**
        
        STR *pkd_mess* -- The packed message
        
        [MessTransporter] *transporter* -- Transport channel to be used
        

        **OUTPUTS**
        
        *none* --

        ..[MessTransporter] file:///./messaging.MessTransporter.html"""

        if tracing('send_packed_mess'):
            trace('send_packed_mess', 'pkd_mess="%s"' % pkd_mess)
        
        #
        # Nothing particular about how such messages need to be sent.
        #
        transporter.send_string(pkd_mess)
Esempio n. 23
0
 def _put_cache_multiple(self, names, values):
     if tracing('SourceBuffCached._put_cache_multiple'):
         trace('SourceBuffCached._put_cache_multiple', 'names=%s, values=%s' % (repr(names), repr(values)))
     for ii in range(len(names)):
         self._put_cache(names[ii], values[ii])
Esempio n. 24
0
class ListenAndQueueMsgsThread(threading.Thread, Object.Object):
    """class for a thread which listens for messages using a given 
    Messenger puts completed messages on a Queue.

    **INSTANCE ATTRIBUTES**

    [Messenger] *underlying* -- underlying messenger (usually
    [MessengerBasic]) used to receive and unpack them messages.

    Queue.Queue *completed_msgs* -- Queue on which to deposit the
    completed messages.

    SocketHasDataEvent *event* -- object used to notify the main thread
    that a socket has data

    Event *connection_ending* -- threading.Event object which will be set
    to true if the connection has been terminated and the thread should die


    (STR, {STR: STR}) conn_broken_msg -- message to put onto the Queue to 
    indicate that the connection was broken unexpectedly.  Note that
    because of thread timing issues, this can occur even if the
    mediator previously received an editor_disconnecting message, or
    even if the editor disconnected in response to a
    mediator_closing or terminating message.  However, in the former case, 
    AppStateMessaging should process the editor_disconnecting message
    first, and will therefore ignore any subsequent messages in the
    queue (including the conn_broken one).  In the latter case, the mediator 
    should already have left the message loop, so, again, the
    conn_broken message should not be processed.

    CLASS ATTRIBUTES**
    
    *none* --

    .. [Messenger] file:///./messenger.Messenger.html
    .. [MessengerBasic] file:///./messenger.MessengerBasic.html"""
    def __init__(self, underlying, completed_msgs, event, connection_ending,
                 conn_broken_msg, **args_super):
        self.deep_construct(ListenAndQueueMsgsThread, {
            'underlying': underlying,
            'completed_msgs': completed_msgs,
            'event': event,
            'connection_ending': connection_ending,
            'conn_broken_msg': conn_broken_msg
        },
                            args_super,
                            exclude_bases={'threading.Thread': 1})
        # provides debug messages
        #        threading.Thread.__init__(self, verbose = 1)
        threading.Thread.__init__(self)

    def message_queue(self):
        """returns a reference to the message queue in which the thread
        puts completed messages

        **INPUTS**

        *none*

        **OUTPUTS**

        *Queue.Queue* -- the message queue
        """
        debug.trace('ListenAndQueueMsgsThread.message_queue',
                    '** invoked, call stack is:')
        #        debug.trace_call_stack('ListenAndQueueMsgsThread.message_queue', '**')
        return self.completed_msgs

    def get_mess(self):
        """Gets a message from the external editor.
        
        **INPUTS**

        *none*
        
        **OUTPUTS**
        
        (STR, {STR: STR}) name_argvals_mess -- The message retrieved
         from external editor in *(mess_name, {arg:val})* format.
         from external editor in *(mess_name, {arg:val})* format, or
         None if no message is available."""

        debug.trace('ListenAndQueueMsgsThread.get_mess', 'invoked')
        return self.underlying.get_mess()

    def notify_main(self):
        """notify the main thread that there is a new message waiting in 
        the Queue, and return asynchronously.
        
        **INPUTS**

        **OUTPUTS**

        *none*
        """
        debug.trace('ListenAndQueueMsgsThread.notify_main',
                    'self.event=%s' % self.event)
        #        debug.trace_call_stack('ListenAndQueueMsgsThread.notify_main', '**')
        self.event.notify()

    def run(self):
        """Start listening for data.
        
        **INPUTS**
        
        *none* -- 
        
        **OUTPUTS**
        
        *none* -- 
        """
        debug.trace('ListenAndQueueMsgsThread.run',
                    'thread %s starting' % threading.currentThread().getName())
        while 1:
            try:
                debug.trace('ListenAndQueueMsgsThread.run',
                            '** getting a message')
                data = self.get_mess()
            except messaging.SocketError, err:
                if self.connection_ending.isSet():
                    #                    sys.stderr.write('SocketError, but connection_ending was set\n')
                    break
# connection broken unexpectedly (unless we just didn't get the
# connection_ending event in time)
#                sys.stderr.write('unexpected SocketError\n')
                self.completed_msgs.put(self.conn_broken_msg)
                self.notify_main()
                break
            except messaging.WokenUp:
                break

            if debug.tracing('ListenAndQueueMsgsThread.run'):
                debug.trace('ListenAndQueueMsgsThread.run',
                            '** data=%s' % repr(data))
            if data:
                debug.trace(
                    'ListenAndQueueMsgsThread.run',
                    '** sending notification message that data was received.')
                self.completed_msgs.put(data)
                self.notify_main()


#            time.sleep(0.01)
#            time.sleep(1)
#           waits for timeout, or until connection_ending is set
            self.connection_ending.wait(0.01)
            #            self.connection_ending.wait(1.0)
            if self.connection_ending.isSet():
                #                sys.stderr.write('connection_ending detected\n')
                break
Esempio n. 25
0
    def restore_state(self, cookie):
        """restores the buffer to its state at the time when
        the cookie was returned by store_current_state.  Both the
        contents and the selection will be restored.  However, other
        data, such as the search history, may not.  The restore
        operation can fail, which will be indicated by a return value of
        0, so the caller should always check the return value.
        
        **INPUTS**

        *SourceBuffCookie cookie* -- see above.  Note that
        SourceBuffCookie is a dummy type, not an actual class.  The
        actual type will vary with SourceBuff subclass.

        **OUTPUTS**

        *BOOL* -- true if restore was successful

        """
        if not self.valid_cookie(cookie):
            return 0
        if not (self.accumulated is None):
            debug.trace('SourceBuffWithDiffs.restore_state',
                'already inside a restore_state call')
            return 0
        debug.trace('SourceBuffWithDiffs.restore_state',
            'key is %s' % cookie.cookie_key)
        index = self.cookie_jar.index(cookie.cookie_key)
        debug.trace('SourceBuffWithDiffs.restore_state',
            'at index %d in the cookie jar' % index)
        data = self.cookie_jar.peek(index)

        level = data.level
        debug.trace('SourceBuffWithDiffs.restore_state',
            'data.level = %d out of %d' % \
            (level, self.change_history.height()))
# later, we may put this stuff on a forward stack, but for now, just pop
# it
        while self.cookie_jar.height() > index:
            debug.trace('SourceBuffWithDiffs.restore_state',
                'cookie jar height = %d, popping' \
                    % self.cookie_jar.height())
            self.cookie_jar.pop()

        self.undoing = 1
        success = 0
        try:
            while self.change_history.height() > level:
                debug.trace('SourceBuffWithDiffs.restore_state',
                    'change history height = %d, popping' \
                    % self.change_history.height())
                change = self.change_history.pop()
                text = change.old_text
                start, end = change.range
                self.accumulated = []
                if tracing('SourceBuffWithDiffs.restore_state'):
                    debug.trace('SourceBuffWithDiffs.restore_state',
                        'popped text "%s", range = (%d, %d)' \
                        % (text, start, end))
                self.set_text(text, start = start, end = end)
# the callback should clear this if we got the expected change.
# if it didn't, then we're in trouble.  Since we don't have a forward
# stack yet, there's nothing we can do except return false to indicated
# failure
                if len(self.accumulated) != 1:
                    break
                accumulated_text = self.accumulated[0].text
                accumulated_range = self.accumulated[0].range
                if text != accumulated_text:
                    if tracing('SourceBuffWithDiffs.restore_state'):
                        debug.trace('SourceBuffWithDiffs.restore_state',
                           'text "%s" != expected "%s"' % (accumulated_text, text))
                    break
                if change.range != accumulated_range:
                    debug.trace('SourceBuffWithDiffs.restore_state',
                       'range %s != expected %s' \
                       % (repr(accumulated_range), repr(change.range)))
                    break
            success = 1
        finally:
            self.undoing = 0
            self.accumulated = None
            if success:
                self.set_selection(data.get_selection(), 
                    cursor_at = data.cursor_at())
                self.last_search = data.last_search()
            self.print_buff_if_necessary()
            return success