Coverage for d7a/alp/operands/query.py: 100%
62 statements
« prev ^ index » next coverage.py v7.5.0, created at 2024-05-24 08:03 +0200
« prev ^ index » next coverage.py v7.5.0, created at 2024-05-24 08:03 +0200
1#
2# Copyright (c) 2015-2021 University of Antwerp, Aloxy NV.
3#
4# This file is part of pyd7a.
5# See https://github.com/Sub-IoT/pyd7a for further info.
6#
7# Licensed under the Apache License, Version 2.0 (the "License");
8# you may not use this file except in compliance with the License.
9# You may obtain a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS,
15# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16# See the License for the specific language governing permissions and
17# limitations under the License.
18#
19from enum import Enum
21from d7a.alp.operands.length import Length
22from d7a.alp.operands.offset import Offset
23from d7a.support.schema import Validatable, Types
25class QueryType(Enum):
26 NON_VOID_CHECK = 0
27 ARITH_COMP_WITH_ZERO = 1
28 ARITH_COMP_WITH_VALUE = 2
29 ARITH_COMP_BETWEEN_FILES = 3
30 RANGE_COMP = 4
31 STRING_TOKEN = 7
33class ArithComparisonType(Enum):
34 INEQUALITY = 0
35 EQUALITY = 1
36 LESS_THAN = 2
37 LESS_THAN_OR_EQUAL_TO = 3
38 GREATER_THAN = 4
39 GREATER_THAN_OR_EQUAL_TO = 5
41class ArithQueryParams(Validatable):
42 SCHEMA = [{
43 "signed_data_type": Types.BOOLEAN(),
44 "comp_type": Types.OBJECT(ArithComparisonType),
45 }]
47 def __init__(self, signed_data_type, comp_type):
48 self.signed_data_type = signed_data_type
49 self.comp_type = comp_type
50 super(ArithQueryParams, self).__init__()
52 @staticmethod
53 def parse(s):
54 signed_data_type = s.read("bool")
55 comp_type = ArithComparisonType(s.read("uint:3"))
56 return ArithQueryParams(signed_data_type, comp_type)
58 def __iter__(self):
59 byte = self.signed_data_type << 3
60 byte += self.comp_type.value
61 yield byte
63# TODO refactor to support other query types
64class QueryOperand(Validatable):
65 SCHEMA = [{
66 "type": Types.ENUM(type=QueryType),
67 "mask_present": Types.BOOLEAN(),
68 "params": Types.OBJECT(ArithQueryParams), # TODO other query types
69 "compare_length": Types.OBJECT(Length),
70 "compare_value": Types.BYTES(),
71 "file_a_offset": Types.OBJECT(Offset)
72 }]
74 def __init__(self, type, mask_present, params, compare_length, compare_value, file_a_offset):
75 self.type = type
76 self.mask_present = mask_present
77 self.params = params
78 self.compare_length = compare_length
79 self.compare_value = compare_value
80 self.file_a_offset = file_a_offset
81 super(QueryOperand, self).__init__()
83 def __iter__(self):
84 byte = self.type.value << 5
85 byte += self.mask_present << 4
86 byte += bytearray(self.params)[0]
87 yield byte
88 for byte in self.compare_length: yield byte
89 for byte in self.compare_value: yield byte
90 for byte in self.file_a_offset: yield byte
93 @staticmethod
94 def parse(s):
95 type = QueryType(s.read("uint:3"))
96 assert(type == QueryType.ARITH_COMP_WITH_VALUE) # TODO implement other types
97 mask_present = s.read("bool")
98 assert(mask_present is False) # TODO implement this
99 params = ArithQueryParams.parse(s)
100 compare_length = Length.parse(s)
101 compare_value = list(s.read("bytes:" + str(compare_length.value)))
102 file_a_offset = Offset.parse(s)
103 return QueryOperand(type=type, mask_present=mask_present, params=params, compare_length=compare_length,
104 compare_value=compare_value, file_a_offset=file_a_offset)