forked from dotabuff/manta
/
reader_util.go
87 lines (77 loc) · 2.33 KB
/
reader_util.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
package manta
import (
"regexp"
"strings"
"github.com/fatih/color"
)
var (
colorBold = color.New(color.Bold).SprintFunc()
colorError = color.New(color.FgRed).SprintFunc()
colorValue = color.New(color.FgCyan).SprintFunc()
colorZero = color.New(color.Faint).SprintFunc()
printableRe = regexp.MustCompile(`^[a-zA-Z0-9\.\s]+$`)
)
func isPrintable(s string) bool {
return printableRe.MatchString(s)
}
// Something capable of dumping data in a given format.
type readerDumper struct {
name string
fmt string
zero interface{}
fn func(r *Reader) interface{}
}
// The list of name columns with dumpers that will be dumped.
var readerDumpers = []readerDumper{
{"binary", "%-1v", "0", func(r *Reader) interface{} { return r.readBits(1) }},
{"uint8", "%-3v", "0", func(r *Reader) interface{} { return r.readBits(8) }},
{"handle", "%-10v", "0", func(r *Reader) interface{} { return r.readBits(21) }},
{"var32", "%-11v", "0", func(r *Reader) interface{} { return r.readVarInt32() }},
{"varu32", "%-10v", "0", func(r *Reader) interface{} { return r.readVarUint32() }},
{"varu64", "%-20v", "0", func(r *Reader) interface{} { return r.readVarUint64() }},
{"uint64", "%-20v", "0", func(r *Reader) interface{} { return r.readLeUint64() }},
{"ubitvar", "%-10v", "0", func(r *Reader) interface{} { return r.readUBitVar() }},
{"byte", "%-4s", "[]", func(r *Reader) interface{} { return _sprintf("0x%02x", r.readByte()) }},
{"string", "%v", "-", func(r *Reader) interface{} {
if s := r.readString(); isPrintable(s) {
return s
}
return "-"
}},
}
// Dumps the rest of the buffer.
func (r *Reader) dumpRemaining() {
r.dumpBits(r.remBits())
}
// Dumps a given number of bits.
func (r *Reader) dumpBits(n int) {
o := r.pos
for i := r.pos; i < (o + n); i++ {
r.pos = i
x := r.pos
line := _sprintf("@ bit %05d (byte %03d + %d) ", r.pos, r.pos/8, r.pos%8)
for _, d := range readerDumpers {
val := func() (out string) {
var v interface{}
defer func() {
if err := recover(); err != nil {
v = "ERR"
}
r.pos = x
out = _sprintf(d.fmt, v)
}()
v = d.fn(r)
return
}()
colorFn := colorValue
if val == "ERR" {
colorFn = colorError
} else if strings.TrimSpace(val) == d.zero {
colorFn = colorZero
}
line += _sprintf(" | %s: %s", d.name, colorFn(val))
}
_debugfl(10, line)
}
r.pos = o
}