forked from stampzilla/gozwave
-
Notifications
You must be signed in to change notification settings - Fork 0
/
serialrecordingtohex.go
141 lines (119 loc) · 2.64 KB
/
serialrecordingtohex.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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package main
import (
"encoding/gob"
"flag"
"fmt"
"io"
"log"
"os"
"sort"
"time"
"github.com/justinkiang/gozwave/serialrecorder"
)
var file string
var short bool
var read bool
var write bool
func main() {
flag.StringVar(&file, "file", "", "File to decode")
flag.BoolVar(&short, "short", false, "Exclude timestamp, direction and writes")
flag.BoolVar(&read, "read", true, "Include reads")
flag.BoolVar(&write, "write", true, "Include writes")
flag.Parse()
if file == "" {
log.Fatalln("No file specified. Use -file=")
return
}
// Open the logfile
file, err := os.Open(file)
if err != nil {
log.Fatalln(err)
}
// Read and decode all lines in the file
dec := gob.NewDecoder(file)
i := 0
var rows []serialrecorder.Row
for {
// Save the line number so we can print a better error message
i++
// Decode the row
var r serialrecorder.Row
err = dec.Decode(&r)
if err != nil {
if err == io.EOF {
break
}
log.Fatalf("decode row %d: %s\n", i, err.Error())
}
rows = append(rows, r)
}
// Create a list of combined rows
reads := logRowCombiner{}
writes := logRowCombiner{}
var combinedRows rowsByTimestamp
for _, v := range rows {
if v.Direction == serialrecorder.DirectionRead {
c := reads.combine(v)
if c != nil {
combinedRows = append(combinedRows, *c)
}
continue
}
c := writes.combine(v)
if c != nil {
combinedRows = append(combinedRows, *c)
}
}
// Sort the rows and print them out
sort.Sort(combinedRows)
for _, v := range combinedRows {
if v.Direction.IsRead() && !read {
continue
}
if v.Direction.IsWrite() && !write {
continue
}
if short {
fmt.Printf("%x\n", v.Data)
continue
}
fmt.Printf("%s: %s - %x\n", v.Timestamp, v.Direction, v.Data)
}
}
type row serialrecorder.Row
type rowsByTimestamp []row
func (c rowsByTimestamp) Len() int {
return len(c)
}
func (c rowsByTimestamp) Swap(i, j int) {
c[i], c[j] = c[j], c[i]
}
func (c rowsByTimestamp) Less(i, j int) bool {
return c[i].Timestamp.Before(c[j].Timestamp)
}
type logRowCombiner struct {
prev serialrecorder.Row
buf []byte
}
func (l *logRowCombiner) combine(r serialrecorder.Row) *row {
// If its the first row, set timestamp to same as first row
if (l.prev.Timestamp == time.Time{}) {
l.prev = r
}
// Calculate the duration from the last row
duration := r.Timestamp.Sub(l.prev.Timestamp)
// If duration is short, just add it to the buffer
if duration < time.Millisecond {
l.buf = append(l.buf, r.Data...)
l.prev = r
return nil
}
combinedRow := &row{
Timestamp: l.prev.Timestamp,
Direction: l.prev.Direction,
Data: l.buf,
}
l.buf = r.Data
l.prev = r
return combinedRow
}