Skip to content
This repository was archived by the owner on Dec 24, 2024. It is now read-only.

Commit 67f9b15

Browse files
committed
cmd/dif-split: first import
1 parent d46bab7 commit 67f9b15

File tree

2 files changed

+247
-0
lines changed

2 files changed

+247
-0
lines changed

cmd/dif-split/main.go

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
// Copyright 2021 The go-lpc Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// Command dif-split splits a DIF/EDA binary file into n DIF files,
6+
// one per DIF-ID.
7+
package main // import "github.com/go-lpc/mim/cmd/dif-split"
8+
9+
import (
10+
"errors"
11+
"flag"
12+
"fmt"
13+
"io"
14+
"log"
15+
"os"
16+
"path/filepath"
17+
"strings"
18+
19+
"github.com/go-lpc/mim/internal/eformat"
20+
)
21+
22+
var (
23+
msg = log.New(os.Stdout, "dif-split: ", 0)
24+
)
25+
26+
func main() {
27+
xmain(os.Args[1:])
28+
}
29+
30+
func xmain(args []string) {
31+
var (
32+
fset = flag.NewFlagSet("dif", flag.ExitOnError)
33+
34+
oname = fset.String("o", "out.raw", "path to output DIF file")
35+
eda = fset.Bool("eda", false, "enable EDA hack")
36+
)
37+
38+
fset.Usage = func() {
39+
fmt.Printf(`Usage: dif-split [OPTIONS] file.raw
40+
41+
ex:
42+
$> dif-split -o out.raw ./input.eda.raw
43+
44+
options:
45+
`)
46+
fset.PrintDefaults()
47+
}
48+
49+
err := fset.Parse(args)
50+
if err != nil {
51+
log.Fatalf("could not parse input arguments: %+v", err)
52+
}
53+
54+
if fset.NArg() != 1 {
55+
fset.Usage()
56+
msg.Fatalf("missing input DIF raw file")
57+
}
58+
59+
if *oname == "" {
60+
fset.Usage()
61+
msg.Fatalf("invalid output DIF raw file")
62+
}
63+
64+
for _, arg := range fset.Args() {
65+
err := process(*oname, *eda, arg)
66+
if err != nil {
67+
msg.Fatalf("could not split DIF file %q: %+v", arg, err)
68+
}
69+
}
70+
}
71+
72+
func process(oname string, isEDA bool, fname string) error {
73+
f, err := os.Open(fname)
74+
if err != nil {
75+
return fmt.Errorf("could not open EDA file: %w", err)
76+
}
77+
defer f.Close()
78+
79+
out := make(map[uint8]*eformat.Encoder)
80+
81+
dec := eformat.NewDecoder(0, f)
82+
dec.IsEDA = isEDA
83+
84+
loop:
85+
for {
86+
var d eformat.DIF
87+
err := dec.Decode(&d)
88+
if err != nil {
89+
if errors.Is(err, io.EOF) {
90+
break loop
91+
}
92+
return fmt.Errorf("could not decode DIF: %w", err)
93+
}
94+
95+
enc, ok := out[d.Header.ID]
96+
if !ok {
97+
oid := outFileFrom(oname, d.Header.ID)
98+
msg.Printf("creating output file %q...", oid)
99+
o, err := os.Create(oid)
100+
if err != nil {
101+
return fmt.Errorf("could not create output file: %w", err)
102+
}
103+
defer o.Close()
104+
105+
enc = eformat.NewEncoder(o)
106+
out[d.Header.ID] = enc
107+
}
108+
109+
err = enc.Encode(&d)
110+
if err != nil {
111+
return fmt.Errorf("could not encode DIF: %w", err)
112+
}
113+
}
114+
115+
return nil
116+
}
117+
118+
func outFileFrom(fname string, id uint8) string {
119+
var (
120+
ext = filepath.Ext(fname)
121+
oname = strings.Replace(fname, ext, fmt.Sprintf("-%03d%s", id, ext), 1)
122+
)
123+
return oname
124+
}

cmd/dif-split/main_test.go

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
// Copyright 2021 The go-lpc Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package main
6+
7+
import (
8+
"io/ioutil"
9+
"os"
10+
"path/filepath"
11+
"reflect"
12+
"testing"
13+
14+
"github.com/go-lpc/mim/internal/eformat"
15+
)
16+
17+
func TestSplit(t *testing.T) {
18+
tmpdir, err := ioutil.TempDir("", "dif-split-")
19+
if err != nil {
20+
t.Fatal(err)
21+
}
22+
defer os.RemoveAll(tmpdir)
23+
24+
oname := filepath.Join(tmpdir, "out.raw")
25+
26+
f, err := os.Create(filepath.Join(tmpdir, "dif.raw"))
27+
if err != nil {
28+
t.Fatal(err)
29+
}
30+
defer f.Close()
31+
32+
dif1 := eformat.DIF{
33+
Header: eformat.GlobalHeader{
34+
ID: 0x1,
35+
DTC: 10,
36+
ATC: 11,
37+
GTC: 12,
38+
AbsBCID: 0x0000112233445566,
39+
TimeDIFTC: 0x00112233,
40+
},
41+
Frames: []eformat.Frame{
42+
{
43+
Header: 11,
44+
BCID: 0x001a1b1c,
45+
Data: [16]uint8{0xa, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
46+
},
47+
{
48+
Header: 12,
49+
BCID: 0x002a2b2c,
50+
Data: [16]uint8{
51+
0xb, 21, 22, 23, 24, 25, 26, 27, 28, 29,
52+
210, 211, 212, 213, 214, 215,
53+
},
54+
},
55+
},
56+
}
57+
58+
dif2 := eformat.DIF{
59+
Header: eformat.GlobalHeader{
60+
ID: 0x2,
61+
DTC: 20,
62+
ATC: 21,
63+
GTC: 22,
64+
AbsBCID: 0x0000112233445566,
65+
TimeDIFTC: 0x00112233,
66+
},
67+
Frames: []eformat.Frame{
68+
{
69+
Header: 21,
70+
BCID: 0x001a1b1c,
71+
Data: [16]uint8{0xa, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
72+
},
73+
{
74+
Header: 22,
75+
BCID: 0x002a2b2c,
76+
Data: [16]uint8{
77+
0xb, 21, 22, 23, 24, 25, 26, 27, 28, 29,
78+
210, 211, 212, 213, 214, 215,
79+
},
80+
},
81+
},
82+
}
83+
84+
for _, dif := range []eformat.DIF{dif1, dif2} {
85+
err = eformat.NewEncoder(f).Encode(&dif)
86+
if err != nil {
87+
t.Fatal(err)
88+
}
89+
}
90+
91+
err = f.Close()
92+
if err != nil {
93+
t.Fatalf("could not close input file: %+v", err)
94+
}
95+
96+
xmain([]string{"-eda", "-o", oname, f.Name()})
97+
98+
for _, tc := range []struct {
99+
fname string
100+
want eformat.DIF
101+
}{
102+
{filepath.Join(tmpdir, "out-001.raw"), dif1},
103+
{filepath.Join(tmpdir, "out-002.raw"), dif2},
104+
} {
105+
f, err := os.Open(tc.fname)
106+
if err != nil {
107+
t.Fatalf("could not open split file: %+v", err)
108+
}
109+
defer f.Close()
110+
111+
var dif eformat.DIF
112+
dec := eformat.NewDecoder(0, f)
113+
err = dec.Decode(&dif)
114+
if err != nil {
115+
t.Fatalf("could not decode DIF from %q: %+v", tc.fname, err)
116+
}
117+
118+
if got, want := dif, tc.want; !reflect.DeepEqual(got, want) {
119+
t.Fatalf("invalid split")
120+
}
121+
}
122+
123+
}

0 commit comments

Comments
 (0)