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

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 

20 

21from d7a.alp.operands.length import Length 

22from d7a.alp.operands.offset import Offset 

23from d7a.support.schema import Validatable, Types 

24 

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 

32 

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 

40 

41class ArithQueryParams(Validatable): 

42 SCHEMA = [{ 

43 "signed_data_type": Types.BOOLEAN(), 

44 "comp_type": Types.OBJECT(ArithComparisonType), 

45 }] 

46 

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__() 

51 

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) 

57 

58 def __iter__(self): 

59 byte = self.signed_data_type << 3 

60 byte += self.comp_type.value 

61 yield byte 

62 

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 }] 

73 

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__() 

82 

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 

91 

92 

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)