yq/pkg/yqlib/decoder_base64.go

81 lines
1.6 KiB
Go
Raw Normal View History

2022-02-22 22:26:35 +00:00
package yqlib
import (
"bytes"
"encoding/base64"
"io"
"strings"
2022-02-22 22:26:35 +00:00
yaml "gopkg.in/yaml.v3"
)
type base64Padder struct {
count uint64
io.Reader
}
func (c *base64Padder) pad(buf []byte) (int, error) {
pad := strings.Repeat("=", int(4-c.count%4))
n, err := strings.NewReader(pad).Read(buf)
c.count += uint64(n)
return n, err
}
func (c *base64Padder) Read(buf []byte) (int, error) {
n, err := c.Reader.Read(buf)
c.count += uint64(n)
if err == io.EOF && c.count%4 != 0 {
return c.pad(buf)
}
return n, err
}
2022-02-22 22:26:35 +00:00
type base64Decoder struct {
reader io.Reader
finished bool
readAnything bool
encoding base64.Encoding
2022-02-22 22:26:35 +00:00
}
func NewBase64Decoder() Decoder {
return &base64Decoder{finished: false, encoding: *base64.StdEncoding}
}
func (dec *base64Decoder) Init(reader io.Reader) error {
dec.reader = &base64Padder{Reader: reader}
dec.readAnything = false
2022-02-22 22:26:35 +00:00
dec.finished = false
return nil
2022-02-22 22:26:35 +00:00
}
func (dec *base64Decoder) Decode() (*CandidateNode, error) {
2022-02-22 22:26:35 +00:00
if dec.finished {
return nil, io.EOF
2022-02-22 22:26:35 +00:00
}
base64Reader := base64.NewDecoder(&dec.encoding, dec.reader)
buf := new(bytes.Buffer)
if _, err := buf.ReadFrom(base64Reader); err != nil {
return nil, err
2022-02-22 22:26:35 +00:00
}
if buf.Len() == 0 {
dec.finished = true
// if we've read _only_ an empty string, lets return that
// otherwise if we've already read some bytes, and now we get
// an empty string, then we are done.
if dec.readAnything {
return nil, io.EOF
}
2022-02-22 22:26:35 +00:00
}
dec.readAnything = true
return &CandidateNode{
Node: &yaml.Node{
Kind: yaml.ScalarNode,
Tag: "!!str",
Value: buf.String(),
},
}, nil
2022-02-22 22:26:35 +00:00
}