aboutsummaryrefslogtreecommitdiff
path: root/b64file/file.go
diff options
context:
space:
mode:
Diffstat (limited to 'b64file/file.go')
-rw-r--r--b64file/file.go70
1 files changed, 69 insertions, 1 deletions
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 {