+ """
+ OP_ID = "OP_ABSTRACT"
+ __slots__ = []
+
+ def __getstate__(self):
+ """Specialized getstate for opcodes.
+
+ This method adds to the state dictionary the OP_ID of the class,
+ so that on unload we can identify the correct class for
+ instantiating the opcode.
+
+ @rtype: C{dict}
+ @return: the state as a dictionary
+
+ """
+ data = BaseOpCode.__getstate__(self)
+ data["OP_ID"] = self.OP_ID
+ return data
+
+ @classmethod
+ def LoadOpCode(cls, data):
+ """Generic load opcode method.
+
+ The method identifies the correct opcode class from the dict-form
+ by looking for a OP_ID key, if this is not found, or its value is
+ not available in this module as a child of this class, we fail.
+
+ @type data: C{dict}
+ @param data: the serialized opcode
+
+ """
+ if not isinstance(data, dict):
+ raise ValueError("Invalid data to LoadOpCode (%s)" % type(data))
+ if "OP_ID" not in data:
+ raise ValueError("Invalid data to LoadOpcode, missing OP_ID")
+ op_id = data["OP_ID"]
+ op_class = None
+ for item in globals().values():
+ if (isinstance(item, type) and
+ issubclass(item, cls) and
+ hasattr(item, "OP_ID") and
+ getattr(item, "OP_ID") == op_id):
+ op_class = item
+ break
+ if op_class is None:
+ raise ValueError("Invalid data to LoadOpCode: OP_ID %s unsupported" %
+ op_id)
+ op = op_class()
+ new_data = data.copy()
+ del new_data["OP_ID"]
+ op.__setstate__(new_data)
+ return op
+
+ def Summary(self):
+ """Generates a summary description of this opcode.
+
+ """
+ # all OP_ID start with OP_, we remove that
+ txt = self.OP_ID[3:]
+ field_name = getattr(self, "OP_DSC_FIELD", None)
+ if field_name:
+ field_value = getattr(self, field_name, None)
+ txt = "%s(%s)" % (txt, field_value)
+ return txt
+
+
+# cluster opcodes