extension.py 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. class Extension(object):
  2. name = ''
  3. rsv1 = False
  4. rsv2 = False
  5. rsv3 = False
  6. opcodes = []
  7. defaults = {}
  8. request = {}
  9. def __init__(self, defaults={}, request={}):
  10. for param in defaults.keys() + request.keys():
  11. if param not in self.defaults:
  12. raise KeyError('unrecognized parameter "%s"' % param)
  13. # Copy dict first to avoid duplicate references to the same object
  14. self.defaults = dict(self.__class__.defaults)
  15. self.defaults.update(defaults)
  16. self.request = dict(self.__class__.request)
  17. self.request.update(request)
  18. self.init()
  19. def __str__(self):
  20. return '<Extension "%s" defaults=%s request=%s>' \
  21. % (self.name, self.defaults, self.request)
  22. def init(self):
  23. return NotImplemented
  24. def create_hook(self, **kwargs):
  25. params = {}
  26. params.update(self.defaults)
  27. params.update(kwargs)
  28. hook = self.Hook(**params)
  29. hook.init(self)
  30. return hook
  31. class Hook:
  32. def __init__(self, **kwargs):
  33. for param, value in kwargs.iteritems():
  34. setattr(self, param, value)
  35. def init(self, extension):
  36. return NotImplemented
  37. def send(self, frame):
  38. return frame
  39. def recv(self, frame):
  40. return frame
  41. def extension_conflicts(ext, existing):
  42. rsv1_reserved = False
  43. rsv2_reserved = False
  44. rsv3_reserved = False
  45. reserved_opcodes = []
  46. for e in existing:
  47. rsv1_reserved |= e.rsv1
  48. rsv2_reserved |= e.rsv2
  49. rsv3_reserved |= e.rsv3
  50. reserved_opcodes.extend(e.opcodes)
  51. return ext.rsv1 and rsv1_reserved \
  52. or ext.rsv2 and rsv2_reserved \
  53. or ext.rsv3 and rsv3_reserved \
  54. or len(set(ext.opcodes) & set(reserved_opcodes))