input.go (993B)
1 package tdo 2 3 import ( 4 "bytes" 5 "encoding/ascii85" 6 "errors" 7 "fmt" 8 "io" 9 "os" 10 ) 11 12 // Read piped input from stdin and ascii85 decode. 13 func DecodePipedInput() ([]byte, error) { 14 stat, err := os.Stdin.Stat() 15 if err != nil { 16 return nil, err 17 } 18 if (stat.Mode() & os.ModeCharDevice) != 0 { 19 return nil, errors.New("no piped input") 20 } 21 in, err := io.ReadAll(os.Stdin) 22 if err != nil { 23 return nil, err 24 } 25 return decode(in) 26 } 27 28 // decode is a convenience wrapper around encoding/ascii85, adding 29 // support for Adobe version, which the TDO layer inputs use, and 30 // enables easy decoding from layer inputs without extra parsing. 31 // 32 // https://en.wikipedia.org/wiki/Ascii85#Adobe_version 33 func decode(bs []byte) ([]byte, error) { 34 _, bs, _ = bytes.Cut(bs, []byte("<~")) 35 bs, _, _ = bytes.Cut(bs, []byte("~>")) 36 37 res := make([]byte, 4*len(bs)) 38 ndst, _, err := ascii85.Decode(res, bs, true) 39 if err != nil { 40 return nil, fmt.Errorf("failed to decode buffer: %v", err) 41 } 42 return res[:ndst], nil 43 }