tdo

Dicing the onion
git clone git@abtrout.com:tdo.git
Log | Files | Refs | README

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 }