+HEXADECIMAL = "[0-9a-zA-Z]"
+
+
+class PciAddress(object):
+
+ PCI_PATTERN_STR = HEXADECIMAL.join([
+ "(",
+ "{4}):(", # domain (4 bytes)
+ "{2}):(", # bus (2 bytes)
+ "{2}).(", # function (2 bytes)
+ ")", # slot (1 byte)
+ ])
+
+ PCI_PATTERN = re.compile(PCI_PATTERN_STR)
+
+ @classmethod
+ def parse_address(cls, text, multi_line=False):
+ if multi_line:
+ text = text.replace(os.linesep, '')
+ match = cls.PCI_PATTERN.search(text)
+ return cls(match.group(0))
+
+ def __init__(self, address):
+ super(PciAddress, self).__init__()
+ match = self.PCI_PATTERN.match(address)
+ if not match:
+ raise ValueError('Invalid PCI address: {}'.format(address))
+ self.address = address
+ self.match = match
+
+ def __repr__(self):
+ return self.address
+
+ @property
+ def domain(self):
+ return self.match.group(1)
+
+ @property
+ def bus(self):
+ return self.match.group(2)
+
+ @property
+ def slot(self):
+ return self.match.group(3)
+
+ @property
+ def function(self):
+ return self.match.group(4)
+
+ def values(self):
+ return [self.match.group(n) for n in range(1, 5)]
+
+