-
Notifications
You must be signed in to change notification settings - Fork 2
/
main.go
130 lines (116 loc) · 2.83 KB
/
main.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
package main
import (
"encoding/base64"
"flag"
"fmt"
"io"
"io/ioutil"
"os"
"gitlab.com/drosseau/degob"
)
var (
outFile = flag.String("ofile", "", "Output file (defaults to stdout)")
inFile = flag.String("ifile", "", "Input file (defaults to stdin)")
truncateOut = flag.Bool("trunc", false, "Truncate output file")
base64d = flag.Bool("b64", false, "base64 input")
base64urld = flag.Bool("b64url", false, "base64url input")
noComments = flag.Bool("nc", false, "don't print additional comments")
noTypes = flag.Bool("nt", false, "don't print type information")
json = flag.Bool("json", false, "show value as json")
pkgName = flag.String("pkg", "", "include a package definition in the output with the given name")
)
func errorf(s string, v ...interface{}) {
_, _ = fmt.Fprintf(os.Stderr, s, v...)
os.Exit(1)
}
func getWriter() io.WriteCloser {
if *outFile != "" {
opts := os.O_WRONLY | os.O_CREATE
if *truncateOut {
opts |= os.O_TRUNC
} else {
opts |= os.O_APPEND
}
f, err := os.OpenFile(*outFile, opts, 0644)
if err != nil {
errorf("failed to open `%s` for writing: %v\n", *outFile, err)
}
return f
}
return os.Stdout
}
func getReader() io.ReadCloser {
if *inFile != "" {
f, err := os.Open(*outFile)
if err != nil {
errorf("failed to open `%s` for reading: %v\n", *inFile, err)
}
return f
}
return ioutil.NopCloser(os.Stdin)
}
type writer struct {
w io.Writer
err error
}
func (w writer) Write(b []byte) (int, error) {
if w.err != nil {
errorf("error writing output: %v\n", w.err)
}
var n int
n, w.err = w.w.Write(b)
return n, w.err
}
func (w writer) writeComment(s string, v ...interface{}) {
if *noComments {
return
}
w.writeStr(s, v...)
}
func (w writer) writeStr(s string, v ...interface{}) {
if w.err != nil {
errorf("error writing output: %v\n")
}
_, w.err = fmt.Fprintf(w.w, s, v...)
}
func main() {
flag.Parse()
out := getWriter()
defer out.Close()
in := getReader()
defer in.Close()
if *base64d {
in = ioutil.NopCloser(base64.NewDecoder(base64.StdEncoding, in))
} else if *base64urld {
in = ioutil.NopCloser(base64.NewDecoder(base64.URLEncoding, in))
}
w := writer{w: out}
dec := degob.NewDecoder(in)
gobs, err := dec.Decode()
if err != nil {
errorf("failed to decode gob: %s\n", err)
}
if *pkgName != "" {
w.writeStr("package %s\n\n", *pkgName)
}
for i, g := range gobs {
w.writeComment("// Decoded gob %d\n\n", i+1)
if !*noTypes && g.Types != nil {
w.writeComment("//Types\n")
err = g.WriteTypes(w)
if err != nil {
errorf("error writing types: %v\n", err)
}
}
w.writeComment("// Value: ")
if *json {
err = g.WriteValue(w, degob.JSON)
} else {
err = g.WriteValue(w, degob.SingleLine)
}
if err != nil {
errorf("error writing values: %v\n", err)
}
w.writeComment("\n// End gob %d\n\n", i+1)
}
}