class AwlStructInstance(object): "Data structure instance" def __init__(self, struct): # Store a reference to the data structure self.struct = struct # Allocate self.dataBytes from awlsim.core.datatypes import ByteArray self.dataBytes = ByteArray(self.struct.getSize()) # Initialize the data structure for field in self.struct.fields: if not field.initBytes: continue try: self.dataBytes.store(field.offset, field.bitSize, field.initBytes) except AwlSimError as e: raise AwlSimError("Data structure field '%s' " "initialization is out of range." %\ str(field)) def getFieldData(self, field, baseOffset=None): if baseOffset is None: return self.dataBytes.fetch(field.offset, field.bitSize) return self.dataBytes.fetch(baseOffset + field.offset, field.bitSize) def setFieldData(self, field, value, baseOffset=None): if baseOffset is None: self.dataBytes.store(field.offset, field.bitSize, value) else: self.dataBytes.store(baseOffset + field.offset, field.bitSize, value) def getFieldDataByName(self, name): return self.getFieldData(self.struct.getField(name)) def setFieldDataByName(self, name, value): self.setFieldData(self.struct.getField(name), value)
def __init__(self, struct): # Store a reference to the data structure self.struct = struct # Allocate self.dataBytes from awlsim.core.datatypes import ByteArray self.dataBytes = ByteArray(self.struct.getSize()) # Initialize the data structure for field in self.struct.fields: if not field.initBytes: continue try: self.dataBytes.store(field.offset, field.bitSize, field.initBytes) except AwlSimError as e: raise AwlSimError("Data structure field '%s' " "initialization is out of range." %\ str(field))
def addField(self, cpu, name, dataType, initBytes=None): if dataType.type == dataType.TYPE_UDT_X: # Add an UDT. try: udt = cpu.udts[dataType.index] except KeyError: assert(0) # Should never happen assert(not initBytes) # Assign the struct to the UDT data type, if # not already done so. assert(dataType.struct is None or dataType.struct is udt.struct) dataType.setStruct(udt.struct) # Merge the UDT struct with this struct. return self.merge(udt.struct, name, dataType) if dataType.width < 0: raise AwlSimError("Width of data structure field '%s : %s' " "is undefined. This probably means that its data " "type is unsupported." %\ (name, str(dataType))) if dataType.type == dataType.TYPE_STRUCT or\ dataType.type == dataType.TYPE_STRING: # Add a STRUCT (or STRING, which is represented as struct). # The struct is represented by the data types struct. # Merge the data type struct into this struct. assert(dataType.struct) baseField = self.merge(dataType.struct, name, dataType) baseField.override = AwlStructField(baseField.name, baseField.offset, "VOID") baseField.initBytes = initBytes if dataType.type == dataType.TYPE_ARRAY: # Add an ARRAY. # First add a field with the array's name. # It has the data type 'ARRAY' and is informational only. offset = AwlOffset(self.getUnalignedSize()) baseField = AwlStructField(name, offset, dataType, override = AwlStructField(name, offset, "VOID")) self.__registerField(baseField) # Add fields for each ARRAY entry. initOffset = AwlOffset() childIdent = AwlDataIdent(name, [ d[0] for d in dataType.arrayDimensions ], doValidateName = False) childType = dataType.arrayElementType if not childType.allowedInArray: raise AwlSimError("Data type '%s' not allowed in ARRAY" %\ str(childType)) for i in range(dataType.arrayGetNrElements()): try: if not initBytes: raise ValueError fieldInitData = ByteArray(intDivRoundUp(childType.width, 8)) fieldInitData.store(AwlOffset(), childType.width, initBytes.fetch(initOffset, childType.width)) except (AwlSimError, ValueError) as e: fieldInitData = None self.addField(cpu, str(childIdent), childType, fieldInitData) initOffset += AwlOffset.fromBitOffset(childType.width) childIdent.advanceToNextArrayElement(dataType.arrayDimensions) if childType.width > 8 and\ intDivRoundUp(childType.width, 8) % 2 != 0: # Align each element to 2-byte-boundary, if word or bigger. self.addField(cpu, None, AwlDataType.makeByName("BYTE")) # Add a zero-length array-end guard field, # to enforce alignment of following fields. self.addDummyField() if dataType.type not in {dataType.TYPE_ARRAY, dataType.TYPE_STRUCT, dataType.TYPE_STRING}: # Add a single data type. if dataType.width == 1 and self.fields and\ self.fields[-1].bitSize == 1 and\ self.fields[-1].offset.bitOffset < 7: # Consecutive bitfields are merged into one byte offset = AwlOffset(self.fields[-1].offset.byteOffset, self.fields[-1].offset.bitOffset + 1) else: offset = AwlOffset(self.getUnalignedSize()) baseField = AwlStructField(name, offset, dataType, initBytes) self.__registerField(baseField) return baseField