Source code for dfvfs.analyzer.specification

# -*- coding: utf-8 -*-
"""The format specification classes."""


[docs] class Signature(object): """Signature of a format specification. The signature consists of a byte string pattern, an optional offset relative to the start of the data, and a value to indicate if the pattern is bound to the offset. Attributes: identifier (str): unique signature identifier for a specification store. offset (int): offset of the signature, where None indicates the signature has no offset. A positive offset or 0 is relative to the start of the data a negative offset is relative to the end of the data. pattern (bytes): pattern of the signature. """
[docs] def __init__(self, pattern, offset=None): """Initializes a signature. Args: pattern (bytes): pattern of the signature. Wildcards or regular pattern (regexp) are not supported. offset (Optional[int]): offset of the signature, where None indicates the signature has no offset. A positive offset or 0 is relative from the start of the data a negative offset is relative to the end of the data. """ super(Signature, self).__init__() self.identifier = None self.offset = offset self.pattern = pattern
[docs] def SetIdentifier(self, identifier): """Sets the identifier of the signature in the specification store. Args: identifier (str): unique signature identifier for a specification store. """ self.identifier = identifier
[docs] class FormatSpecification(object): """Format specification."""
[docs] def __init__(self, identifier): """Initializes a specification. Args: identifier (str): unique name for the format. """ super(FormatSpecification, self).__init__() self.identifier = identifier self.signatures = []
[docs] def AddNewSignature(self, pattern, offset=None): """Adds a signature. Args: pattern (bytes): pattern of the signature. Wildcards or regular pattern (regexp) are not supported. offset (Optional[int]): offset of the signature, where None indicates the signature has no offset. A positive offset or 0 is relative from the start of the data a negative offset is relative to the end of the data. """ self.signatures.append(Signature(pattern, offset=offset))
[docs] class FormatSpecificationStore(object): """Store for format specifications."""
[docs] def __init__(self): """Initializes a format specification store.""" super(FormatSpecificationStore, self).__init__() self._format_specifications = {} # Maps signature identifiers to format specifications. self._signature_map = {}
@property def specifications(self): """Retrieves the format specifications. Returns: generator[FormatSpecification]: format specifications. """ return iter(self._format_specifications.values())
[docs] def AddNewSpecification(self, identifier): """Adds a new format specification. Args: identifier (str): unique signature identifier for a specification store. Returns: FormatSpecification: format specification. Raises: KeyError: if the store already contains a specification with the same identifier. """ if identifier in self._format_specifications: raise KeyError( f'Format specification {identifier:s} is already defined in store.') self._format_specifications[identifier] = FormatSpecification(identifier) return self._format_specifications[identifier]
[docs] def AddSpecification(self, specification): """Adds a specification. Args: specification (FormatSpecification): format specification. Raises: KeyError: if the store already contains a specification with the same identifier. """ if specification.identifier in self._format_specifications: raise KeyError(( f'Format specification {specification.identifier:s} is already ' f'defined in store.')) self._format_specifications[specification.identifier] = specification for signature in specification.signatures: signature_index = len(self._signature_map) signature_identifier = f'{specification.identifier:s}:{signature_index:d}' if signature_identifier in self._signature_map: raise KeyError( f'Signature {signature_identifier:s} is already defined in map.') signature.SetIdentifier(signature_identifier) self._signature_map[signature_identifier] = specification
[docs] def GetSpecificationBySignature(self, signature_identifier): """Retrieves a specification mapped to a signature identifier. Args: signature_identifier (str): unique signature identifier for a specification store. Returns: FormatSpecification: A format specification or None if the signature identifier does not exist within the specification store. """ return self._signature_map.get(signature_identifier, None)