Source code for canlib.kvamemolibxml.configuration

from collections import namedtuple

from .enums import ValidationError, ValidationWarning
from .wrapper import (kvaBufferToXml, kvaXmlToBuffer, kvaXmlValidate,
                      xmlGetValidationError, xmlGetValidationWarning)


[docs]def load_lif(lif_bytes): """Create a `Configuration` from a param.lif `bytes` Args: lif_bytes (`bytes`): Binary configuration in param.lif format """ return Configuration(lif=lif_bytes)
[docs]def load_lif_file(filepath): """Like `load_lif` but takes a path to a file containing the lif configuration""" with open(filepath, 'rb') as f: lif_bytes = f.read() return load_lif(lif_bytes)
[docs]def load_xml(xml_string): """Create a `Configuration` from an xml `string` Args: xml_string (`str`): XML configuration """ return Configuration(xml=xml_string)
[docs]def load_xml_file(filepath): """Like `load_lif` but takes a path to a file containing the XML configuration""" with open(filepath) as f: xml_string = f.read() return load_xml(xml_string)
ValidationResult = namedtuple('ValidationResult', "errors, warnings") """Validation errors and warnings. Args: errors (list(`int`)): Valdiation errors. warnings ([`str`]): Validation warnings. """ ValidationMessage = namedtuple('ValidationMessage', "code text") """Validation code and message. Args: code (`int`): Valdiation status code. text (`str`): Validation message. """
[docs]class ValidationErrorMessage(ValidationMessage): """An error found during validation""" __slots__ = () def __str__(self): return f"Error: {self.text} ({self.code!s})"
[docs]class ValidationWarningMessage(ValidationMessage): """A warning found during validation""" __slots__ = () def __str__(self): return f"Warning: {self.text} ({self.code!s})"
[docs]class Configuration: """Configuration data for Kvaser devices It is usually preferred to create objects of this class with one of the functions: * `load_xml` * `load_xml_file` * `load_lif` * `load_lif_file` The XML and param.lif representation of this configuration can be accessed with the `xml` and `lif` attributes, respectively. Two `Configuration` objects can be tested for equality:: config1 == config2 This will test whether the objects are equivalent: whether they have the same param.lif representation. Finally, the configuration can be validated with `Configuration.validate`:: errors, warnings = configuration.validate() for error in errors: print(error) for warning in warnings: print(warning) if errors: raise ValueError("Invalid configuration") .. versionadded: 1.6 """ def __init__(self, xml=None, lif=None): if xml is None and lif is None: raise TypeError("Either xml or lif required") self._xml = xml self._lif = lif def __eq__(self, other): # Two xml strings might be formatted differently while still # equivalent, so we need to compare the binary lif return self.lif == other.lif @property def xml(self): """`str`: The XML representation of this configuration""" if self._xml is None: self._xml = kvaBufferToXml(self._lif) return self._xml @property def lif(self): """`bytes`: The param.lif representation of this configuration""" if self._lif is None: self._lif = kvaXmlToBuffer(self._xml) return self._lif
[docs] def validate(self): """Validate this configuration Validates the XML representation of this configuration, and returns a tuple ``(errors, warnings)`` where ``errors`` is a `list` of `~canlib.kvamemolibxml.ValidationError` and ``warnings`` is a `list` `~canlib.kvamemolibxml.ValidationWarning`. """ kvaXmlValidate(self.xml) errors = list(self._errors()) warnings = list(self._warnings()) return ValidationResult(errors, warnings)
def _warnings(self): while True: code, text = xmlGetValidationWarning() if code != 0: yield ValidationWarningMessage(ValidationWarning(code), text.rstrip()) else: return def _errors(self): while True: code, text = xmlGetValidationError() if code != 0: yield ValidationErrorMessage(ValidationError(code), text.rstrip()) else: return