2022-02-22 22:26:35 +00:00
|
|
|
package yqlib
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/base64"
|
|
|
|
"io"
|
2023-03-18 03:30:35 +00:00
|
|
|
"strings"
|
2022-02-22 22:26:35 +00:00
|
|
|
|
|
|
|
yaml "gopkg.in/yaml.v3"
|
|
|
|
)
|
|
|
|
|
2023-03-18 03:30:35 +00:00
|
|
|
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 {
|
2022-05-27 01:18:38 +00:00
|
|
|
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}
|
|
|
|
}
|
|
|
|
|
2022-10-28 03:16:46 +00:00
|
|
|
func (dec *base64Decoder) Init(reader io.Reader) error {
|
2023-03-18 03:30:35 +00:00
|
|
|
dec.reader = &base64Padder{Reader: reader}
|
2022-05-27 01:18:38 +00:00
|
|
|
dec.readAnything = false
|
2022-02-22 22:26:35 +00:00
|
|
|
dec.finished = false
|
2022-10-28 03:16:46 +00:00
|
|
|
return nil
|
2022-02-22 22:26:35 +00:00
|
|
|
}
|
|
|
|
|
2022-10-28 03:16:46 +00:00
|
|
|
func (dec *base64Decoder) Decode() (*CandidateNode, error) {
|
2022-02-22 22:26:35 +00:00
|
|
|
if dec.finished {
|
2022-10-28 03:16:46 +00:00
|
|
|
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 {
|
2022-10-28 03:16:46 +00:00
|
|
|
return nil, err
|
2022-02-22 22:26:35 +00:00
|
|
|
}
|
|
|
|
if buf.Len() == 0 {
|
|
|
|
dec.finished = true
|
2022-05-27 01:18:38 +00:00
|
|
|
|
|
|
|
// 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 {
|
2022-10-28 03:16:46 +00:00
|
|
|
return nil, io.EOF
|
2022-05-27 01:18:38 +00:00
|
|
|
}
|
2022-02-22 22:26:35 +00:00
|
|
|
}
|
2022-05-27 01:18:38 +00:00
|
|
|
dec.readAnything = true
|
2022-10-28 03:16:46 +00:00
|
|
|
return &CandidateNode{
|
|
|
|
Node: &yaml.Node{
|
|
|
|
Kind: yaml.ScalarNode,
|
|
|
|
Tag: "!!str",
|
|
|
|
Value: buf.String(),
|
|
|
|
},
|
|
|
|
}, nil
|
2022-02-22 22:26:35 +00:00
|
|
|
}
|