Skip to content

Commit 8917f7c

Browse files
authored
Merge pull request #2 from qubesome/hard-fork
Performance improvements and introduction of VendorID + ProductID
2 parents 88aac1b + 2380a31 commit 8917f7c

File tree

7 files changed

+377
-124
lines changed

7 files changed

+377
-124
lines changed

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
# libudev
22
Golang native implementation Udev library
33

4-
[![Go Report Card](https://goreportcard.com/badge/github.com/qubesome/libudev)](https://goreportcard.com/report/github.com/qubesome/libudev)
54
[![GoDoc](https://godoc.org/github.com/qubesome/libudev?status.svg)](https://godoc.org/github.com/qubesome/libudev)
6-
[![GitHub release](https://img.shields.io/github/release/qubesome/libudev.svg)](https://github.com/qubesome/libudev/releases)
75
[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/qubesome/libudev/badge)](https://scorecard.dev/viewer/?uri=github.com/qubesome/libudev)
86

97
Installation

matcher/matcher.go

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
/*
2-
Package matcher implements a service for filtering devices.
3-
4-
Matcher allows you to add multiple filter rules by using the method `AddRule`
5-
and effectively filter the list of devices in a single pass.
6-
7-
By default, Matcher uses the `AND` comparison strategy, but you can set the filtering strategy to` OR`.
8-
*/
1+
// Package matcher implements a mechanism for filtering devices.
2+
//
3+
// Matcher allows you to add multiple filter rules by using the method `AddRule`
4+
// and effectively filter the list of devices in a single pass.
5+
//
6+
// By default, Matcher uses the `AND` comparison strategy, but you can set the filtering strategy to` OR`.
97
package matcher
108

119
import (
@@ -50,7 +48,17 @@ func (m *Matcher) AddRule(rule Rule) {
5048
m.rules = append(m.rules, rule)
5149
}
5250

53-
func (m *Matcher) Match(devices []*types.Device) []*types.Device {
51+
func (m *Matcher) Match(devices ...*types.Device) bool {
52+
for _, v := range devices {
53+
if m.matchDevice(v) {
54+
return true
55+
}
56+
}
57+
58+
return false
59+
}
60+
61+
func (m *Matcher) Matches(devices []*types.Device) []*types.Device {
5462
var ret []*types.Device
5563
for _, v := range devices {
5664
if !m.matchDevice(v) {

matcher/matcher_test.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,19 +44,19 @@ func TestMatchDefault(t *testing.T) {
4444
m := NewMatcher()
4545
m.AddRule(NewRuleDevpath("devpaht-1"))
4646
m.AddRule(NewRuleDevpath("devpaht-2"))
47-
if len(m.Match(devices)) != 0 {
47+
if len(m.Matches(devices)) != 0 {
4848
t.Fatal("Devices was found incorrectly")
4949
}
5050

5151
m2 := NewMatcher()
5252
m2.AddRule(NewRuleDevpath("devpaht-.+"))
5353
m2.AddRule(NewRuleDevpath("devpaht-[0-9]+"))
54-
if len(m2.Match(devices)) != 2 {
54+
if len(m2.Matches(devices)) != 2 {
5555
t.Fatal("Not found two devices")
5656
}
5757

5858
m3 := NewMatcher()
59-
if len(m3.Match(devices)) != 0 {
59+
if len(m3.Matches(devices)) != 0 {
6060
t.Fatal("Empty rules Matcher finded not 0 devices")
6161
}
6262
}
@@ -68,34 +68,34 @@ func TestMatchAnd(t *testing.T) {
6868
m.SetStrategy(StrategyAnd)
6969
m.AddRule(NewRuleDevpath("devpaht-1"))
7070
m.AddRule(NewRuleDevpath("devpaht-2"))
71-
if len(m.Match(devices)) != 0 {
71+
if len(m.Matches(devices)) != 0 {
7272
t.Fatal("Devices was found incorrectly")
7373
}
7474

7575
m2 := NewMatcher()
7676
m2.SetStrategy(StrategyAnd)
7777
m2.AddRule(NewRuleDevpath("devpaht-.+"))
7878
m2.AddRule(NewRuleDevpath("devpaht-[0-9]+"))
79-
if len(m2.Match(devices)) != 2 {
79+
if len(m2.Matches(devices)) != 2 {
8080
t.Fatal("Not found two devices")
8181
}
8282

8383
m2.AddRule(NewRuleEnv("ENV-1", "[a-z]+"))
8484
m2.AddRule(NewRuleEnv("ENV-2", "[0-9]+"))
8585
m2.AddRule(NewRuleAttr("ATTR-1", "[a-z]+"))
8686
m2.AddRule(NewRuleAttr("ATTR-2", "[0-9]+"))
87-
if len(m2.Match(devices)) != 2 {
87+
if len(m2.Matches(devices)) != 2 {
8888
t.Fatal("Not found two devices")
8989
}
9090

9191
m2.AddRule(NewRuleAttr("ATTR-2", "123"))
92-
if len(m.Match(devices)) != 0 {
92+
if len(m.Matches(devices)) != 0 {
9393
t.Fatal("Devices was found incorrectly")
9494
}
9595

9696
m3 := NewMatcher()
9797
m3.SetStrategy(StrategyAnd)
98-
if len(m3.Match(devices)) != 0 {
98+
if len(m3.Matches(devices)) != 0 {
9999
t.Fatal("Empty rules Matcher finded not 0 devices")
100100
}
101101
}
@@ -107,12 +107,12 @@ func TestMatchOr(t *testing.T) {
107107
m.SetStrategy(StrategyOr)
108108
m.AddRule(NewRuleDevpath("devpaht-1"))
109109
m.AddRule(NewRuleDevpath("devpaht-3"))
110-
if len(m.Match(devices)) != 1 {
110+
if len(m.Matches(devices)) != 1 {
111111
t.Fatal("Not found one device")
112112
}
113113

114114
m.AddRule(NewRuleDevpath("devpaht-2"))
115-
if len(m.Match(devices)) != 2 {
115+
if len(m.Matches(devices)) != 2 {
116116
t.Fatal("Not found two devices")
117117
}
118118

@@ -123,13 +123,13 @@ func TestMatchOr(t *testing.T) {
123123
m2.AddRule(NewRuleEnv("ENV-2", "NOT_FOUND"))
124124
m2.AddRule(NewRuleAttr("ATTR-1", "ghi456jkl"))
125125
m2.AddRule(NewRuleAttr("ATTR-2", "NOT_FOUND"))
126-
if len(m2.Match(devices)) != 2 {
126+
if len(m2.Matches(devices)) != 2 {
127127
t.Fatal("Not found two devices")
128128
}
129129

130130
m3 := NewMatcher()
131131
m3.SetStrategy(StrategyOr)
132-
if len(m3.Match(devices)) != 0 {
132+
if len(m3.Matches(devices)) != 0 {
133133
t.Fatal("Empty rules Matcher finded not 0 devices")
134134
}
135135
}

options.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package libudev
2+
3+
import (
4+
"os"
5+
"regexp"
6+
7+
"github.com/qubesome/libudev/matcher"
8+
)
9+
10+
type Option func(*scanner)
11+
12+
type options struct {
13+
matcher *matcher.Matcher
14+
15+
pathFilterPattern *regexp.Regexp
16+
17+
devicesRoot *os.Root
18+
udevDataRoot *os.Root
19+
}
20+
21+
// WithPathFilterPattern sets a pattern to filter out device paths that
22+
// are irrelevant to the query. This speeds up the scanning process, as
23+
// the scanner won't deal with files (and devices) that do not match the
24+
// regex.
25+
//
26+
// For example, when querying USB devices, this could be used:
27+
// libudev.WithPathFilterPattern(regexp.MustCompile("(?i)^.*pci0000:00.*usb.*"))
28+
func WithPathFilterPattern(p *regexp.Regexp) Option {
29+
return func(o *scanner) {
30+
o.opts.pathFilterPattern = p
31+
}
32+
}
33+
34+
// WithMatcher sets a matcher to the scanner, so that only devices matching
35+
// the rules are returned.
36+
func WithMatcher(m *matcher.Matcher) Option {
37+
return func(o *scanner) {
38+
o.opts.matcher = m
39+
}
40+
}
41+
42+
// WithDevicesRoot provides a way to set a different os.Root to be used
43+
// as the Devices dir. When not provided, defaults to an os.Root pointing
44+
// to /sys/devices.
45+
func WithDevicesRoot(r *os.Root) Option {
46+
return func(o *scanner) {
47+
o.opts.devicesRoot = r
48+
}
49+
}
50+
51+
// WithUDevDataRoot provides a way to set a different os.Root to be used
52+
// as the udev data dir. When not provided, defaults to an os.Root pointing
53+
// to /run/udev/data.
54+
func WithUDevDataRoot(r *os.Root) Option {
55+
return func(o *scanner) {
56+
o.opts.udevDataRoot = r
57+
}
58+
}

0 commit comments

Comments
 (0)