forked from sselph/scraper
-
Notifications
You must be signed in to change notification settings - Fork 0
/
rom.go
80 lines (72 loc) · 1.63 KB
/
rom.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
// Package rom has helper functions for extracting rom data. Currently it is only used to hash them.
package rom
import (
"crypto/sha1"
"encoding/hex"
"fmt"
"io"
"os"
"path"
"strings"
)
type Decoder func(io.ReadCloser, int64) (io.ReadCloser, error)
var formats = make(map[string]Decoder)
// RegisterFormat registers a format with the rom package.
func RegisterFormat(ext string, decode Decoder) {
formats[ext] = decode
}
// Decode takes a path and returns a reader for the inner rom data.
func Decode(p string) (io.ReadCloser, error) {
ext := strings.ToLower(path.Ext(p))
if ext == ".zip" {
r, err := decodeZip(p)
return r, err
}
decode, ok := formats[ext]
if !ok {
return nil, fmt.Errorf("no registered decoder for extention %s", ext)
}
r, err := os.Open(p)
if err != nil {
return nil, err
}
fi, err := r.Stat()
if err != nil {
return nil, err
}
ret, err := decode(r, fi.Size())
return ret, err
}
// SHA1 takes a pathand returns the SHA1 hash of the inner rom.
func SHA1(p string) (string, error) {
r, err := Decode(p)
if err != nil {
return "", err
}
defer r.Close()
buf := make([]byte, 4*1024*1024)
h := sha1.New()
for {
n, err := r.Read(buf)
if err != nil && err != io.EOF {
return "", err
}
if n == 0 {
break
}
h.Write(buf[:n])
}
return hex.EncodeToString(h.Sum(nil)), nil
}
// KnownExt returns True if the extention is registered.
func KnownExt(e string) bool {
if strings.ToLower(e) == ".zip" {
return true
}
_, ok := formats[strings.ToLower(e)]
return ok
}
// Noop does nothong but return the passed in file.
func Noop(f io.ReadCloser, s int64) (io.ReadCloser, error) {
return f, nil
}