-
Notifications
You must be signed in to change notification settings - Fork 32
/
Copy pathnition.go
126 lines (103 loc) · 3.36 KB
/
nition.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
126
package recog
//go:generate go run gen/vfsdata/main.go
import (
"fmt"
"io/ioutil"
"net/http"
"strings"
log "github.com./sirupsen/logrus"
)
// FingerprintSet is a collection of loaded Recog fingerprint databases
type FingerprintSet struct {
Databases map[string]*FingerprintDB
Logger *log.Logger
}
// NewFingerprintSet returns an allocated FingerprintSet structure
func NewFingerprintSet() *FingerprintSet {
fs := &FingerprintSet{}
fs.Databases = make(map[string]*FingerprintDB)
return fs
}
// MatchFirst matches data to a given fingerprint database
func (fs *FingerprintSet) MatchFirst(name string, data string) *FingerprintMatch {
nomatch := &FingerprintMatch{Matched: false}
fdb, ok := fs.Databases[name]
if !ok {
nomatch.Errors = append(nomatch.Errors, fmt.Errorf("database %s is missing", name))
return nomatch
}
return fdb.MatchFirst(data)
}
// MatchAll matches data to a given fingerprint database
func (fs *FingerprintSet) MatchAll(name string, data string) []*FingerprintMatch {
nomatch := &FingerprintMatch{Matched: false}
fdb, ok := fs.Databases[name]
if !ok {
nomatch.Errors = append(nomatch.Errors, fmt.Errorf("database %s is missing", name))
return []*FingerprintMatch{nomatch}
}
return fdb.MatchAll(data)
}
// LoadFingerprints parses the embedded Recog XML databases, returning a FingerprintSet
func (fs *FingerprintSet) LoadFingerprints() error {
return fs.LoadFingerprintsFromFS(RecogXML)
}
// LoadFingerprintsDir parses Recog XML files from a local directory, returning a FingerprintSet
func (fs *FingerprintSet) LoadFingerprintsDir(dname string) error {
return fs.LoadFingerprintsFromFS(http.Dir(dname))
}
// LoadFingerprintsFromFS parses an embedded Recog XML database, returning a FingerprintSet
func (fs *FingerprintSet) LoadFingerprintsFromFS(efs http.FileSystem) error {
rootfs, err := efs.Open("/")
if err != nil {
return fmt.Errorf("failed to open root: %s", err.Error())
}
defer rootfs.Close()
files, err := rootfs.Readdir(65535)
if err != nil {
return fmt.Errorf("failed to read root: %s", err.Error())
}
for _, f := range files {
if !strings.Contains(f.Name(), ".xml") {
continue
}
fd, err := efs.Open(f.Name())
if err != nil {
return fmt.Errorf("failed to open %s: %s", f.Name(), err.Error())
}
xmlData, err := ioutil.ReadAll(fd)
if err != nil {
fd.Close()
return fmt.Errorf("failed to read %s: %s", f.Name(), err.Error())
}
fd.Close()
fdb, err := LoadFingerprintDB(f.Name(), xmlData)
if err != nil {
return fmt.Errorf("failed to load %s: %s", f.Name(), err.Error())
}
fdb.Logger = fs.Logger
// Create an alias for the file name
fs.Databases[f.Name()] = &fdb
// Create an alias for the "matches" attribute
fs.Databases[fdb.Matches] = &fdb
}
return nil
}
// LoadFingerprints parses embedded Recog XML databases, returning a FingerprintSet
func LoadFingerprints() (*FingerprintSet, error) {
res := NewFingerprintSet()
return res, res.LoadFingerprints()
}
// LoadFingerprintsDir parses Recog XML files from a local directory, returning a FingerprintSet
func LoadFingerprintsDir(dname string) (*FingerprintSet, error) {
res := NewFingerprintSet()
return res, res.LoadFingerprintsDir(dname)
}
// MustLoadFingerprints loads the built-in fingerprints, panicing otherwise
func MustLoadFingerprints() *FingerprintSet {
fset, err := LoadFingerprints()
if err != nil {
panic(err)
}
return fset
}