-
Notifications
You must be signed in to change notification settings - Fork 3
/
parse.go
125 lines (103 loc) · 2.82 KB
/
parse.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package pciids
import (
"bufio"
"strings"
log "github.com/sirupsen/logrus"
)
var (
currentDevice PCIID
currentVendorID string
vendors map[string]string
)
// Parse returns a list of all PCI IDs in a slice after parsing the PCI ID file.
func parse(rawIDs string) []PCIID {
var devices []PCIID
if vendors == nil {
vendors = parseVendors(rawIDs)
}
log.Debug("parsing PCI IDs")
scanner := bufio.NewScanner(strings.NewReader(rawIDs))
for scanner.Scan() {
line := scanner.Text()
if !valid(line) {
continue
}
switch {
case strings.HasPrefix(line, "\t\t"):
devices = append(devices, parseSubDevice(line))
case strings.HasPrefix(line, "\t"):
currentDevice = parseDevice(line)
devices = append(devices, currentDevice)
default:
splits := strings.Split(line, " ")
currentVendorID = strings.TrimSpace(splits[0])
}
}
return devices
}
// parseSubDevice parses a line starting with two tabs and returns the PCI ID.
func parseSubDevice(line string) PCIID {
splits := strings.Split(strings.TrimPrefix(line, "\t\t"), " ")
subVendorID := strings.TrimSpace(splits[0])
return PCIID{
DeviceID: currentDevice.DeviceID,
DeviceName: currentDevice.DeviceName,
VendorID: currentDevice.VendorID,
VendorName: currentDevice.VendorName,
SubDeviceID: splits[1],
SubDeviceName: strings.Join(splits[3:], " "),
SubVendorID: subVendorID,
SubVendorName: vendors[subVendorID],
}
}
// parseDevice parses the line starting with a tab and returns the PCI ID.
func parseDevice(line string) PCIID {
splits := strings.Split(strings.TrimPrefix(line, "\t"), " ")
return PCIID{
DeviceID: strings.TrimSpace(splits[0]),
DeviceName: strings.TrimSpace(strings.Join(splits[1:], " ")),
VendorID: currentVendorID,
VendorName: vendors[currentVendorID],
}
}
// parseVendors parses all Vendors from the PCI ID file.
func parseVendors(rawIDs string) map[string]string {
vendors := make(map[string]string)
log.Debug("parsing vendor IDs")
scanner := bufio.NewScanner(strings.NewReader(rawIDs))
for scanner.Scan() {
line := scanner.Text()
if !validVendor(line) {
continue
}
splits := strings.Split(line, " ")
vendors[strings.TrimSpace(splits[0])] = strings.Join(splits[1:], " ")
}
return vendors
}
// valid returns boolean if the line is a valid PCI ID content.
func valid(line string) bool {
switch {
case len(line) == 0:
return false
case strings.HasPrefix(line, "#"):
return false
case strings.HasPrefix(line, "C"):
return false
}
return true
}
// validVendor returns boolean if the line is a valid PCI ID vendor line.
func validVendor(line string) bool {
switch {
case len(line) == 0:
return false
case strings.HasPrefix(line, "\t"):
return false
case strings.HasPrefix(line, "#"):
return false
case strings.HasPrefix(line, "C"):
return false
}
return true
}