1# Synthetic children provider example for class MaskedData
2# to use me:
3# command script import ./example.py --allow-reload
4# type synthetic add MaskedData --python-class example.MaskedData_SyntheticChildrenProvider
5class MaskedData_SyntheticChildrenProvider:
6	def __init__(self, valobj, dict):
7		self.valobj = valobj # remember the SBValue since you will not have another chance to get it :-)
8
9	def num_children(self):
10		# you could perform calculations involving the SBValue and/or its children to determine this value
11		# here, we have an hardcoded value - but since you have stored the SBValue you could use it to
12		# help figure out the correct thing to return here. if you return a number N, you should be prepared to
13		# answer questions about N children
14		return 4
15
16	def has_children(self):
17		# we simply say True here because we know we have 4 children
18		# in general, you want to make this calculation as simple as possible
19		# and return True if in doubt (you can always return num_children == 0 later)
20		return True
21
22	def get_child_index(self,name):
23		# given a name, return its index
24		# you can return None if you don't know the answer for a given name
25		if name == "value":
26			return 0
27		# here, we are using a reserved C++ keyword as a child name - we could not do that in the source code
28		# but we are free to use the names we like best in the synthetic children provider class
29		# we are also not respecting the order of declaration in the C++ class itself - as long as
30		# we are consistent, we can do that freely
31		if name == "operator":
32			return 1
33		if name == "mask":
34			return 2
35		# this member does not exist in the original class - we will compute its value and show it to the user
36		# when returning synthetic children, there is no need to only stick to what already exists in memory
37		if name == "apply()":
38			return 3
39		return None # no clue, just say none
40
41	def get_child_at_index(self,index):
42		# precautionary measures
43		if index < 0:
44			return None
45		if index > self.num_children():
46			return None
47		if self.valobj.IsValid() == False:
48			return None
49		if index == 0:
50			return self.valobj.GetChildMemberWithName("value")
51		if index == 1:
52			# fetch the value of the operator
53			op_chosen = self.valobj.GetChildMemberWithName("oper").GetValueAsUnsigned()
54			# if it is a known value, return a descriptive string for it
55			# we are not doing this in the most efficient possible way, but the code is very readable
56			# and easy to maintain - if you change the values on the C++ side, the same changes must be made here
57			if op_chosen == 0:
58				return self.valobj.CreateValueFromExpression("operator",'(const char*)"none"')
59			elif op_chosen == 1:
60				return self.valobj.CreateValueFromExpression("operator",'(const char*)"AND"')
61			elif op_chosen == 2:
62				return self.valobj.CreateValueFromExpression("operator",'(const char*)"OR"')
63			elif op_chosen == 3:
64				return self.valobj.CreateValueFromExpression("operator",'(const char*)"XOR"')
65			elif op_chosen == 4:
66				return self.valobj.CreateValueFromExpression("operator",'(const char*)"NAND"')
67			elif op_chosen == 5:
68				return self.valobj.CreateValueFromExpression("operator",'(const char*)"NOR"')
69			else:
70				return self.valobj.CreateValueFromExpression("operator",'(const char*)"unknown"') # something else
71		if index == 2:
72			return self.valobj.GetChildMemberWithName("mask")
73		if index == 3:
74			# for this, we must fetch all the other elements
75			# in an efficient implementation, we would be caching this data for efficiency
76			value = self.valobj.GetChildMemberWithName("value").GetValueAsUnsigned()
77			operator = self.valobj.GetChildMemberWithName("oper").GetValueAsUnsigned()
78			mask = self.valobj.GetChildMemberWithName("mask").GetValueAsUnsigned()
79			# compute the masked value according to the operator
80			if operator == 1:
81				value = value & mask
82			elif operator == 2:
83				value = value | mask
84			elif operator == 3:
85				value = value ^ mask
86			elif operator == 4:
87				value = ~(value & mask)
88			elif operator == 5:
89				value = ~(value | mask)
90			else:
91				pass
92			value &= 0xFFFFFFFF # make sure Python does not extend our values to 64-bits
93			# return it - again, not the most efficient possible way. we should actually be pushing the computed value
94			# into an SBData, and using the SBData to create an SBValue - this has the advantage of readability
95			return self.valobj.CreateValueFromExpression("apply()",'(uint32_t)(' + str(value) + ')')
96
97	def update(self):
98		# we do not do anything special in update - but this would be the right place to lookup
99		# the data we use in get_child_at_index and cache it
100		pass
101