62 lines
1.6 KiB
Go
62 lines
1.6 KiB
Go
package content
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/base64"
|
|
|
|
"github.com/mleku/transit/chk"
|
|
"github.com/mleku/transit/errorf"
|
|
"github.com/mleku/transit/text"
|
|
)
|
|
|
|
var BinaryPrefix = []byte("base64:")
|
|
|
|
// C is a content field for an event.T that can be binary or text, if set to binary, it encodes
|
|
// to base64 URL format (with padding). Binary coded values have the prefix "base64:" prefix.
|
|
// Setting binary should be done in accordance with the mimetype being a binary mimetype.
|
|
type C struct {
|
|
Val []byte
|
|
Binary bool
|
|
}
|
|
|
|
// New creates a new mime.Type based on input string or bytes of value.
|
|
func New[V []byte | string](c V, binary bool) (content *C) {
|
|
content = &C{Val: []byte(c), Binary: binary}
|
|
return
|
|
}
|
|
|
|
func (c *C) MarshalJSON() (b []byte, err error) {
|
|
if c.Binary {
|
|
b = make([]byte, base64.URLEncoding.EncodedLen(len(c.Val))+2+len(BinaryPrefix))
|
|
copy(b[1:], BinaryPrefix)
|
|
base64.URLEncoding.Encode(b[1+len(BinaryPrefix):len(b)-1], c.Val)
|
|
b[0] = '"'
|
|
b[len(b)-1] = '"'
|
|
} else {
|
|
b = append(append([]byte{'"'}, text.Escape(nil, c.Val)...), '"')
|
|
}
|
|
return
|
|
}
|
|
|
|
func (c *C) UnmarshalJSON(b []byte) (err error) {
|
|
b = b[1:]
|
|
if bytes.HasPrefix(b, BinaryPrefix) {
|
|
c.Binary = true
|
|
// remove quotes and binary prefix
|
|
b = b[len(BinaryPrefix) : len(b)-1]
|
|
var n int
|
|
// we use AppendDecode to avoid needing to trim pad bytes
|
|
if c.Val, err = base64.URLEncoding.AppendDecode(c.Val, b); chk.E(err) {
|
|
err = errorf.E("error: decoding failed at %d: %s", n, err.Error())
|
|
return
|
|
}
|
|
c.Binary = true
|
|
} else {
|
|
b = b[:len(b)-1]
|
|
c.Val = b
|
|
c.Val = text.Unescape(c.Val)
|
|
c.Binary = false
|
|
}
|
|
return
|
|
}
|