def __init__(self, lr_type: int, ld: File.LogicalData): self.lr_type: int = lr_type # [RP66V1 Section 3.3 Indirectly Formatted Logical Record] self.object_name: RepCode.ObjectName = RepCode.OBNAME(ld) # [RP66V1 Section 5.6.1 Frames] self.frame_number = RepCode.UVARI(ld) self.preamble_length = ld.index self.remain = ld.remain # Frame numbers start from 1 but there are many observed cases of IFLRs that have a 0 frame number and zero # remaining data. Here we only warn if the frame number is zero and the remaining data is non-zero. # We warn rather than raising in the spirit of optimism. if self.frame_number == 0 and self.remain != 0: logger.warning( f'Frame number needs to be >= 1, not {self.frame_number} [RP66V1 Section 5.6.1 Frames] (there is data remaining)' )
def __init__(self, ld: LogicalData, template: Template): component_descriptor = ComponentDescriptor(ld.read()) if not component_descriptor.is_object: raise ExceptionEFLRObject( f'Component Descriptor does not represent a object but a {component_descriptor.type}.' ) self.name: RepCode.ObjectName = RepCode.OBNAME(ld) self.attrs: typing.List[typing.Union[AttributeBase, None]] = [] self.attr_label_map: typing.Dict[bytes, int] = {} index: int = 0 while True: component_descriptor = ComponentDescriptor(ld.read()) if not component_descriptor.is_attribute_group: raise ExceptionEFLRObject( f'Component Descriptor does not represent a attribute but a {component_descriptor.type}.' ) if template[index].component_descriptor.is_invariant_attribute: self.attrs.append(template[index]) elif template[index].component_descriptor.is_absent_attribute: self.attrs.append(None) else: # TODO: Check the attribute label is the same as the template. Reference [RP66V1 Section 4.5] self.attrs.append( Attribute(component_descriptor, ld, template[index])) if ld.remain == 0 or ComponentDescriptor(ld.peek()).is_object: break # next_component_descriptor = ComponentDescriptor(ld.peek()) # if next_component_descriptor.is_object: # break index += 1 while len(self.attrs) < len(template): self.attrs.append(template[len(self.attrs)]) if len(template) != len(self.attrs): raise ExceptionEFLRObject( f'Template specifies {len(template)} attributes but Logical Data has {len(self.attrs)}' ) # Now populate self.attr_label_map for a, attr in enumerate(self.attrs): if attr is None: label = template.attrs[a].label else: label = attr.label # TODO: Assert that the attribute label is the same as the template. Reference [RP66V1 Section 4.5] if label in self.attr_label_map: raise ExceptionEFLRObjectDuplicateLabel( f'Duplicate Attribute label {label}') self.attr_label_map[label] = a
def test_OBNAME(ld, expected): result = RepCode.OBNAME(ld) assert result == expected assert ld.remain == 0