From 6882f0b341ab5038f707bd44de9684ce676ee72c Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Mon, 7 Aug 2017 23:15:31 +0200 Subject: b64 as ReadWriter --- b64file/file.go | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/b64file/file.go b/b64file/file.go index 624dc2d..86c6636 100644 --- a/b64file/file.go +++ b/b64file/file.go @@ -15,7 +15,60 @@ import ( const untrusted = "untrusted comment: " // Original Error: "invalid comment in %s; must start with 'untrusted comment: '" -var ErrUntrusted = errors.New("comment must start with 'untrusted comment: '") +var ( + ErrUntrusted = errors.New("comment must start with 'untrusted comment: '") + ErrMissingHeader = errors.New("missing required header fields") +) + +type Header struct { + Comment string + Bytes []byte +} + +type Reader struct { + Header + r io.Reader +} + +type Writer struct { + Header + w io.Writer + wroteHeader bool +} + +func NewReader(r io.Reader) (*Reader, error) { + buf := bufio.NewReader(r) + + comment, err := buf.ReadString('\n') + if err != nil { + return nil, err + } + if !strings.HasPrefix(comment, untrusted) { + return nil, ErrUntrusted + } + comment = strings.TrimSpace(comment[len(untrusted):]) + + raw, err := buf.ReadString('\n') + if err != nil { + return nil, err + } + b, err := base64.StdEncoding.DecodeString(raw) + if err != nil { + return nil, err + } + + return &Reader{ + Header: Header{ + Comment: comment, + Bytes: b, + }, + r: buf, + }, nil +} + +func (r *Reader) Read(p []byte) (n int, err error) { + return r.r.Read(p) +} func Decode(r io.Reader, u encoding.BinaryUnmarshaler) (string, []byte, error) { buf := bufio.NewReader(r) @@ -49,6 +102,21 @@ func Decode(r io.Reader, u encoding.BinaryUnmarshaler) (string, []byte, error) { return comment, message, nil } +func NewWriter(w io.Writer) (*Writer, error) { + return &Writer{w: w}, nil +} + +func (w *Writer) Write(p []byte) (n int, err error) { + if !w.wroteHeader { + if w.Comment == "" || w.Bytes == nil { + return 0, ErrMissingHeader + } + fmt.Fprintf(w.w, "%s%s\n", untrusted, w.Comment) + fmt.Fprintf(w.w, "%s\n", base64.StdEncoding.EncodeToString(w.Bytes)) + } + return w.w.Write(p) +} + func Encode(w io.Writer, u encoding.BinaryMarshaler, comment string, msg []byte) error { raw, err := u.MarshalBinary() if err != nil { -- cgit v1.2.3