aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2017-08-07 23:15:31 +0200
committerDimitri Sokolyuk <demon@dim13.org>2017-08-07 23:15:31 +0200
commit6882f0b341ab5038f707bd44de9684ce676ee72c (patch)
treee30d6fdd29e6f596d53f118c3e6b49d6f059e58c
parentb32268bad4b65dc4263370a2199be73e4bca4626 (diff)
b64 as ReadWriter
-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 {