1
0
Fork 0
mirror of git://git.psyced.org/git/pypsyc synced 2024-08-15 03:20:04 +00:00
pypsyc/fippos-twisted/pypsyc/State.py
psyc://psyced.org/~lynX 0f02e9cd76 last state we had in cvs
2010-02-24 09:50:45 +01:00

156 lines
5.7 KiB
Python

# TODO: write tests
from pypsyc import MMPVARS
from copy import deepcopy
class SenderState:
def __init__(self):
self.laststate = {}
self.persistent_out = {}
def serializeList(self, varname, value):
t = []
old = self.persistent_out.get(varname)
# that is far to experimental
if True: # not old: # no previous list sent
self.persistent_out[varname] = value
t.append(':%s\t%s\n'%(varname, value[0].replace('\n', '\n\t')))
for item in value[1:]:
t.append(':\t%s\n'%(item.replace('\n', '\n\t')))
return '\n'.join(t)
if False:
augmented = filter(lambda x: x not in old, value)
if augmented:
packet += '+%s\t%s\n'%(varname, augmented[0].replace('\n',
'\n\t'))
for item in augmented[1:]:
packet += '+\t%s\n'%(item.replace('\n', '\n\t'))
diminished = filter(lambda x: x not in value, old)
if diminished:
packet += '-%s\t%s\n'%(varname, diminished[0].replace('\n',
'\n\t'))
for item in diminished[1:]:
packet += '-\t%s\n'%(item.replace('\n', '\n\t'))
self.persistent_out[varname] = value
def serialize(self, state):
"""
serializes a set of variables into a string
@type state: C{dict}
@param state: Dictionary of variables to be serialized
"""
L = []
# beware of the lambdas!
L.append(self.varencode(filter(lambda x: x[0] in MMPVARS and x[1],
state.items())))
if L != []:
L.append('\n')
L.append(self.varencode(filter(lambda x: x[0] not in MMPVARS and x[1],
state.items())))
self.laststate = state
bytes = '\n'.join(L)
return bytes
def varencode(self, v):
"""
encodes a set of variables, setting the state persistent according to
some strategy
@type v: C{dict}
@param v: Dictionary of variables to be serialized
"""
t = []
for (varname, value) in v:
if self.persistent_out.get(varname) == value:
pass
elif varname.startswith('_list') or type(value) == type([]):
t.append(self.serializeList(varname, value))
elif self.laststate.get(varname) == value and varname != '_context':
self.persistent_out[varname] = value
t.append('=%s\t%s\n'%(varname, value.replace('\n', '\n\t')))
else:
t.append(':%s\t%s\n'%(varname, value.replace('\n', '\n\t')))
return '\n'.join(t)
class ReceiverState:
glyph = ''
varname = ''
listFlag = False
value = ''
def __init__(self):
self.state = {}
self.persistent = {}
def reset(self):
self.state = {}
self.glyph = ''
self.varname = ''
self.listFlag= False
self.value = ''
def copy(self):
# do we actually need those deep copys? TODO
t = deepcopy(self.persistent)
t.update(deepcopy(self.state))
return t
def eat(self, line):
"""
this one is tricky... first it handles the previous line,
and then it prepares the current line.
This is needed to implement multiline-continuations in lists
@type line: C{str} or C{None}
@param line: line to be parsed, a None signals that variable
parsing for current packet is finished
"""
if line: line = line.decode('iso-8859-1') # we use unicode internally
if line and (line[0] == ' ' or line[0] == '\t'): # multiline support
self.value += '\n' + line[1:]
return
# glyph handling
if self.glyph == ':':
if self.listFlag:
if not type(self.state[self.varname]) == list:
self.state[self.varname] = [self.state[self.varname]]
self.state[self.varname].append(self.value)
else:
if self.varname.startswith('_list'):
self.value = [self.value]
self.state[self.varname] = self.value
elif self.glyph == '=':
if self.listFlag:
if not type(self.persistent[self.varname]) == list:
self.persistent[self.varname] = [self.self.persistent[self.varname]]
self.persistent[self.varname].append(self.value)
else:
self.persistent[self.varname] = self.value
elif self.glyph == '+':
self.persistent.get(self.varname, []).append(self.value)
elif self.glyph == '-':
raise NotImplementedError
elif self.glyph == '?':
raise NotImplementedError
if not line: # feeding done
return
# here we parse the current line
self.glyph = line[0]
if line[1] == '\t':
# lastvarname-optimization: varname remains the same
self.listFlag = True
self.value = line[2:]
else:
self.listFlag = False
if line.find('\t') == -1:
self.varname = line[1:]
self.value = ''
else:
self.varname, self.value = line[1:].split('\t', 1)
self.value = self.value
class State(SenderState, ReceiverState):
"""combination of sender and receiver state"""
def __init__(self):
SenderState.__init__(self)
ReceiverState.__init__(self)