SF.net SVN: fclient:[689] trunk/fclient/src/fclient/lib/fcp2/lib/pmstruct. py
Status: Pre-Alpha
Brought to you by:
jurner
|
From: <jU...@us...> - 2008-07-20 10:34:07
|
Revision: 689
http://fclient.svn.sourceforge.net/fclient/?rev=689&view=rev
Author: jUrner
Date: 2008-07-20 10:34:07 +0000 (Sun, 20 Jul 2008)
Log Message:
-----------
support for persistent params handling
Added Paths:
-----------
trunk/fclient/src/fclient/lib/fcp2/lib/pmstruct.py
Added: trunk/fclient/src/fclient/lib/fcp2/lib/pmstruct.py
===================================================================
--- trunk/fclient/src/fclient/lib/fcp2/lib/pmstruct.py (rev 0)
+++ trunk/fclient/src/fclient/lib/fcp2/lib/pmstruct.py 2008-07-20 10:34:07 UTC (rev 689)
@@ -0,0 +1,215 @@
+"""poor mans struct
+
+simple structure with (safe) serializing support
+
+
+@requires: python >= 2.5 (L is never removed from str(nL) )
+"""
+
+import base64
+#*******************************************************************
+#
+#*******************************************************************
+class PMStructError(Exception): pass
+
+SEP = '|'
+HEADER = 'PMS'
+
+class BOOL(object):
+ _typecode_ = 'B'
+ @classmethod
+ def default(clss):
+ return False
+ @classmethod
+ def from_data(clss, data):
+ if data:
+ typecode, data = data[ :1], data [ 1: ]
+ if typecode == clss._typecode_:
+ try:
+ return data == '1'
+ except: pass
+ raise PMStructError('invalid bool')
+ @classmethod
+ def to_data(clss, value):
+ return clss._typecode_ + ('1' if value else '0')
+ @classmethod
+ def is_type(self, value):
+ return type(value) is bool
+
+
+class FLOAT(object):
+ _typecode_ = 'F'
+ @classmethod
+ def default(clss):
+ return 0.0
+ @classmethod
+ def from_data(clss, data):
+ if data:
+ typecode, data = data[ :1], data [ 1: ]
+ if typecode == clss._typecode_:
+ try:
+ return float(data)
+ except: pass
+ raise PMStructError('invalid int')
+ @classmethod
+ def to_data(clss, value):
+ return clss._typecode_ + str(value)
+ @classmethod
+ def is_type(self, value):
+ return type(value) is float
+
+
+class INT(object):
+ _typecode_ = 'I'
+ @classmethod
+ def default(clss):
+ return 0
+ @classmethod
+ def from_data(clss, data):
+ if data:
+ typecode, data = data[ :1], data [ 1: ]
+ if typecode == clss._typecode_:
+ try:
+ return int(data)
+ except: pass
+ raise PMStructError('invalid int')
+ @classmethod
+ def to_data(clss, value):
+ return clss._typecode_ + str(value)
+ @classmethod
+ def is_type(self, value):
+ return type(value) in (int, long)
+
+
+class STRING(object):
+ _typecode_ = 'S'
+ @classmethod
+ def default(clss):
+ return ''
+ @classmethod
+ def from_data(clss, data):
+ if data:
+ typecode, data = data[ :1], data [ 1: ]
+ if typecode == clss._typecode_:
+ try:
+ return base64.b64decode(data)
+ except: pass
+ raise PMStructError('invalid string')
+ @classmethod
+ def to_data(clss, value):
+ return clss._typecode_ + base64.b64encode(value)
+ @classmethod
+ def is_type(self, value):
+ return type(value) in (str, unicode)
+
+
+class PMStruct(object):
+ _fields_ = ()
+
+ def __init__(self, **kws):
+ self._fielddict_ = dict(self._fields_)
+ self.values = {}
+ for name, fieldtype in self._fields_:
+ value = kws.get(name, None)
+ if value is None:
+ value = fieldtype.default()
+ else:
+ if not fieldtype.is_type(value):
+ raise TypeError('invalid type for field: %r' % name)
+ del kws[name]
+ self.values[name] = value
+ if kws:
+ raise ValueError('no such field: %r' % kws.keys()[0])
+
+
+ def __getitem__(self, name):
+ return self.values[name]
+
+ def __setitem__(self, name, value):
+ fieldtype = self._fielddict_ [name]
+ if not fieldtype.is_type(value):
+ raise TypeError('invalid type for field: %r' % name)
+ self.values[name] = value
+
+
+ def __str__(self):
+ return self.__repr__()
+
+ def __repr__(self):
+ return '<PMS' + repr(self.values) + '>'
+
+ @classmethod
+ def load(clss, data):
+ data = data.split(SEP, 1)
+ if len(data) != 2:
+ raise PMStructError('invalid data')
+ header, data = data
+ if header != HEADER:
+ raise PMStructError('invalid data header')
+ #data = base64.b64decode(data)
+ data = data.split(SEP)
+ if len(data) != len(clss._fields_):
+ raise PMStructError('too few or too many fields')
+ kws = {}
+ for i, (name, fieldtype) in enumerate(clss._fields_):
+ kws[name] = fieldtype.from_data(data[i])
+ return clss(**kws)
+
+ def dump(self):
+ p = []
+ for name, fieldtype in self._fields_:
+ value = fieldtype.to_data(self.values[name])
+ p.append(value)
+ data = SEP.join(p)
+ #data = base64.b64encode(data)
+ return HEADER + SEP + data
+
+
+
+def foo():
+ class PersistentParamsGet(PMStruct):
+ _fields_ = (
+ ('Version', INT),
+ ('InitTime', FLOAT),
+ ('PersistentUserData', STRING),
+ ('HandleFilenameCollision', BOOL),
+ ('FilenameCollisionHandled', BOOL),
+ ('HandlePermanentRedirect', BOOL),
+ ('PermanentRedirectHandled', BOOL),
+ )
+
+
+ p = PersistentParamsGet()
+ print p.dump()
+ print p
+
+#foo()
+#print {1: 1, 2: 2}
+#print repr({1: 1, 2: 2})
+
+def test():
+
+ class MyStruct(PMStruct):
+ _fields_ = (
+ ('Foo', INT),
+ ('Bar', BOOL),
+ ('Baz', STRING),
+ ('Muu', FLOAT)
+ )
+
+
+
+ p = MyStruct(Foo=100000000000L, Bar=True, Baz=u'abcdefg', Muu=1.2345678)
+ x = p.dump()
+ print x
+ print p.load(x)
+ print p['Foo']
+ print p['Bar']
+ print p['Baz']
+ print p['Muu']
+
+ p['Muu'] = 123
+
+
+
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|