Files

51 lines
1.7 KiB
Go

package fileedit
import (
"encoding/base64"
"fmt"
"strconv"
)
// splitContent is the base64 of content cut into contentChunk-sized parts, the
// values of ContentEnv_0 … ContentEnv_<n-1>. Empty content is zero parts.
func splitContent(content []byte) []string {
enc := base64.StdEncoding.EncodeToString(content)
parts := make([]string, 0, (len(enc)+contentChunk-1)/contentChunk)
for len(enc) > 0 {
n := min(len(enc), contentChunk)
parts = append(parts, enc[:n])
enc = enc[n:]
}
return parts
}
// contentPartEnv names part i of the content.
func contentPartEnv(i int) string { return ContentEnv + "_" + strconv.Itoa(i) }
// ContentFromEnv reassembles a write's content from the environment the Job spec
// set (see ContentEnv). A part count that is missing, not a number or negative,
// or a part that is not set, is an error rather than a shorter file: writing a
// truncated config would be worse than not writing at all. Parts are looked up
// rather than read so an unset one cannot pass as empty; the lookups stop at the
// first one missing, so a count larger than the spec carries costs nothing.
func ContentFromEnv(lookup func(string) (string, bool)) ([]byte, error) {
raw, _ := lookup(ContentPartsEnv)
n, err := strconv.Atoi(raw)
if err != nil || n < 0 {
return nil, fmt.Errorf("%s=%q is not a part count", ContentPartsEnv, raw)
}
var enc []byte
for i := range n {
part, ok := lookup(contentPartEnv(i))
if !ok {
return nil, fmt.Errorf("%s is not set", contentPartEnv(i))
}
enc = append(enc, part...)
}
content, err := base64.StdEncoding.DecodeString(string(enc))
if err != nil {
return nil, fmt.Errorf("the content is not valid base64: %w", err)
}
return content, nil
}