├── Makefile └── bin2go.go /Makefile: -------------------------------------------------------------------------------- 1 | include $(GOROOT)/src/Make.inc 2 | 3 | TARG=bin2go 4 | GOFILES=bin2go.go 5 | 6 | include $(GOROOT)/src/Make.cmd 7 | -------------------------------------------------------------------------------- /bin2go.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "flag" 6 | "fmt" 7 | "io" 8 | "io/ioutil" 9 | "os" 10 | ) 11 | 12 | var ( 13 | in = flag.String("in", "", "use this file instead of the stdin for input") 14 | out = flag.String("out", "", "use this file instead of the stdout for output") 15 | pkg = flag.String("pkg", "", "prepend package clause specifying this package") 16 | ) 17 | 18 | // Exit error codes 19 | const ( 20 | NO_ERROR = iota 21 | WRONG_ARGS 22 | INPUT_FAIL 23 | OUTPUT_FAIL 24 | ) 25 | 26 | func printUsage() { 27 | fmt.Printf("usage: %s [-in=] [-out=] [-pkg=] \n", os.Args[0]) 28 | flag.PrintDefaults() 29 | } 30 | 31 | func printUsageAndExit() { 32 | flag.Usage() 33 | os.Exit(WRONG_ARGS) 34 | } 35 | 36 | func readInput() []byte { 37 | var data []byte 38 | var err error 39 | 40 | if *in != "" { 41 | data, err = ioutil.ReadFile(*in) 42 | } else { 43 | data, err = ioutil.ReadAll(os.Stdin) 44 | } 45 | 46 | if err != nil { 47 | fmt.Fprintf(os.Stderr, "Failed to read input: %s\n", err) 48 | os.Exit(INPUT_FAIL) 49 | } 50 | return data 51 | } 52 | 53 | func checkOutputFailure(err error) { 54 | if err != nil { 55 | fmt.Fprintf(os.Stderr, "Failed to write output: %s\n", err) 56 | os.Exit(OUTPUT_FAIL) 57 | } 58 | } 59 | 60 | func writeData(data []byte, out io.Writer) { 61 | varname := flag.Arg(0) 62 | 63 | // write header 64 | _, err := fmt.Fprintf(out, "var %s = []byte{\n\t", varname) 65 | checkOutputFailure(err) 66 | 67 | lastbytei := len(data) - 1 68 | n := 8 69 | for i, b := range data { 70 | // write single byte 71 | _, err = fmt.Fprintf(out, "0x%.2x,", b) 72 | checkOutputFailure(err) 73 | 74 | n += 6 75 | 76 | // if this is not the last byte 77 | if i != lastbytei { 78 | // be readable, break line after 78 characters 79 | if n >= 78 { 80 | _, err = fmt.Fprint(out, "\n\t") 81 | checkOutputFailure(err) 82 | 83 | n = 8 84 | } else { 85 | // if we're not breaking the line, insert space 86 | // after ',' 87 | _, err = fmt.Fprint(out, " ") 88 | checkOutputFailure(err) 89 | } 90 | 91 | } 92 | } 93 | _, err = fmt.Fprint(out, "\n}\n") 94 | checkOutputFailure(err) 95 | } 96 | 97 | func writeOutput(data []byte) { 98 | var output *bufio.Writer 99 | 100 | // prepare "output" 101 | if *out != "" { 102 | file, err := os.Create(*out) 103 | checkOutputFailure(err) 104 | defer file.Close() 105 | 106 | output = bufio.NewWriter(file) 107 | } else { 108 | output = bufio.NewWriter(os.Stdout) 109 | } 110 | 111 | // write package clause if any 112 | if *pkg != "" { 113 | _, err := fmt.Fprintf(output, "package %s\n\n", *pkg) 114 | checkOutputFailure(err) 115 | } 116 | 117 | // write data 118 | writeData(data, output) 119 | 120 | // flush 121 | err := output.Flush() 122 | checkOutputFailure(err) 123 | } 124 | 125 | func main() { 126 | flag.Usage = printUsage 127 | flag.Parse() 128 | 129 | if flag.NArg() != 1 { 130 | printUsageAndExit() 131 | } 132 | 133 | data := readInput() 134 | writeOutput(data) 135 | } 136 | --------------------------------------------------------------------------------