class Message(object):
def __init__(self, id, version=10, flags=0, operation=0x01):
self.id = id
self.version = version
self.flags = flags
self.operation = operation
def encode(self):
# ...
def decode(self, message):
# ...
class Message(object):
metadata = {
"id": {"type": "uvarlong"},
"version": {"type": "byte"},
"flags": {"type": "uvarint", "since_version": 11},
"operation": {"type": "byte"}
}
def __init__(self, id, version=12, flags=0, operation=0x01):
self.id = id
self.version = version
self.flags = flags
self.operation = operation
import messenger as m
class Message(m.Message):
id = m.Uvarlong()
version = m.Byte(default=12)
flags = m.Uvarint(default=0, since_version=11)
operation = m.Byte(default=0x01)
class DataType(object):
def __init__(self, **kwargs):
for key, value in kwargs.iteritems():
setattr(self, key, value)
@property
def type(self):
return type(self).__name__.lower()
class Byte(DataType):
pass
class Uvarint(DataType):
pass
class Uvarlong(DataType):
pass
class Message(object):
def __init__(self, **kwargs):
# Filter out all defined fields that are private and that are not an
# instance of class DataType
m_fields = filter(
lambda f: not f.startswith('__') and
isinstance(getattr(self, f), DataType), dir(self))
for f_name in m_fields:
f_cls = getattr(self.__class__, f_name)
# If someone used key-word arguments in the initializer,
# let's pass them as the default values
if f_name in kwargs:
setattr(self, f_name, kwargs[f_name])
# If there is a default available, use that
elif hasattr(f_cls, 'default'):
setattr(self, f_name, f_cls.default)
# If all that fails, just initialize to None
else:
setattr(self, f_name, None)
@property
def cls(self):
return self.__class__
class CreatedCounter(object):
_count = 0
@staticmethod
def count():
count = CreatedCounter._count
CreatedCounter._count += 1
return count
class DataType(object):
def __init__(self, **kwargs):
self._created = CreatedCounter.count()
# ...
Python doesn't remember order of definiton, easy to fix:
class Message(object):
def __init__(self, **kwargs):
m_fields = filter(
lambda f: not f.startswith('__') and
isinstance(getattr(self, f), DataType), dir(self))
self.fields = \
sorted(m_fields, key=lambda fn: getattr(self, fn)._created)
for f_name in self.fields:
# ...
class Composite(DataType):
pass
class List(DataType):
pass
class Bytes(DataType):
def __init__(self, size, **kwargs):
super(Bytes, self).__init__(**kwargs)
self.args.append(size)
class Varbytes(DataType):
pass
class Ushort(DataType):
pass
class RequestHeader(m.Message):
magic = m.Byte(default=0xA0)
id = m.Uvarlong()
version = m.Byte(default=25)
op = m.Byte()
cname = m.String(optional=True)
flags = m.Uvarint(default=0)
ci = m.Byte(default=ClientIntelligence.BASIC)
t_id = m.Uvarint(default=0)
class Request(m.Message):
header = m.Composite(default=RequestHeader)
def __init__(self, **kwargs):
super(Request, self).__init__(**kwargs)
self.header.op = self.OP_CODE
class GetRequest(Request):
OP_CODE = 0x03
key = m.Varbytes()
@@ -229,6 +221,29 @@
OP_CODE = 0x14
+class StatsRequest(Request):
+ OP_CODE = 0x15
+
+
+class Stat(m.Message):
+ name = m.String()
+ value = m.String()
+
+
+class StatsResponse(Response):
+ OP_CODE = 0x16
+ n = m.Uvarint()
+ stats = m.List(of=Stat, size=lambda s: s.n)
+
+
class ErrorResponse(Response):
OP_CODE = 0x50
error_message = m.String()
@VaclavDedik