class Control(Validatable): SCHEMA = [{ "is_dialog_start": Types.BOOLEAN(), "is_dialog_end": Types.BOOLEAN(), "is_ack_return_template_requested": Types.BOOLEAN(), "is_ack_not_void": Types.BOOLEAN(), "is_ack_recorded": Types.BOOLEAN(), "has_ack_template": Types.BOOLEAN() }] def __init__(self, is_dialog_start, is_dialog_end, is_ack_return_template_requested, is_ack_not_void, is_ack_recorded): self.is_dialog_start = is_dialog_start self.is_dialog_end = is_dialog_end self.is_ack_return_template_requested = is_ack_return_template_requested self.is_ack_not_void = is_ack_not_void self.is_ack_recorded = is_ack_recorded super(Control, self).__init__() def __iter__(self): byte = 0 if self.is_dialog_start: byte |= 1 << 7 if self.is_dialog_end: byte |= 1 << 6 if self.is_ack_return_template_requested: byte |= 1 << 3 if self.is_ack_not_void: byte |= 1 << 2 if self.is_ack_recorded: byte |= 1 << 1 yield byte
class QueryOperand(Validatable): SCHEMA = [{ "type": Types.ENUM(type=QueryType), "mask_present": Types.BOOLEAN(), "params": Types.OBJECT(ArithQueryParams), # TODO other query types "compare_length": Types.OBJECT(Length), "compare_value": Types.BYTES(), "file_a_offset": Types.OBJECT(Offset) }] def __init__(self, type, mask_present, params, compare_length, compare_value, file_a_offset): self.type = type self.mask_present = mask_present self.params = params self.compare_length = compare_length self.compare_value = compare_value self.file_a_offset = file_a_offset super(QueryOperand, self).__init__() def __iter__(self): byte = self.type.value << 5 byte += self.mask_present << 4 byte += bytearray(self.params)[0] yield byte for byte in self.compare_length: yield byte for byte in self.compare_value: yield byte for byte in self.file_a_offset: yield byte @staticmethod def parse(s): type = QueryType(s.read("uint:3")) assert (type == QueryType.ARITH_COMP_WITH_VALUE ) # TODO implement other types mask_present = s.read("bool") assert (mask_present is False) # TODO implement this params = ArithQueryParams.parse(s) compare_length = Length.parse(s) compare_value = map(ord, s.read("bytes:" + str(compare_length.value))) file_a_offset = Offset.parse(s) return QueryOperand(type=type, mask_present=mask_present, params=params, compare_length=compare_length, compare_value=compare_value, file_a_offset=file_a_offset)
class ArithQueryParams(Validatable): SCHEMA = [{ "signed_data_type": Types.BOOLEAN(), "comp_type": Types.OBJECT(ArithComparisonType), }] def __init__(self, signed_data_type, comp_type): self.signed_data_type = signed_data_type self.comp_type = comp_type super(ArithQueryParams, self).__init__() @staticmethod def parse(s): signed_data_type = s.read("bool") comp_type = ArithComparisonType(s.read("uint:3")) return ArithQueryParams(signed_data_type, comp_type) def __iter__(self): byte = self.signed_data_type << 3 byte += self.comp_type.value yield byte