// and returns the extended buffer.
// If the input is malformed, it returns the partially decoded src and an error.
func (enc *Encoding) AppendDecode(dst, src []byte) ([]byte, error) {
- n := enc.DecodedLen(len(src))
+ // Compute the output size without padding to avoid over allocating.
+ n := len(src)
+ for n > 0 && rune(src[n-1]) == enc.padChar {
+ n--
+ }
+ n = decodedLen(n, NoPadding)
+
dst = slices.Grow(dst, n)
n, err := enc.Decode(dst[len(dst):][:n], src)
return dst[:len(dst)+n], err
// DecodedLen returns the maximum length in bytes of the decoded data
// corresponding to n bytes of base32-encoded data.
func (enc *Encoding) DecodedLen(n int) int {
- if enc.padChar == NoPadding {
+ return decodedLen(n, enc.padChar)
+}
+
+func decodedLen(n int, padChar rune) int {
+ if padChar == NoPadding {
return n/8*5 + n%8*5/8
}
return n / 8 * 5
dst, err := StdEncoding.AppendDecode([]byte("lead"), []byte(p.encoded))
testEqual(t, "AppendDecode(%q) = error %v, want %v", p.encoded, err, error(nil))
testEqual(t, `AppendDecode("lead", %q) = %q, want %q`, p.encoded, string(dst), "lead"+p.decoded)
+
+ dst2, err := StdEncoding.AppendDecode(dst[:0:len(p.decoded)], []byte(p.encoded))
+ testEqual(t, "AppendDecode(%q) = error %v, want %v", p.encoded, err, error(nil))
+ testEqual(t, `AppendDecode("", %q) = %q, want %q`, p.encoded, string(dst2), p.decoded)
+ if len(dst) > 0 && len(dst2) > 0 && &dst[0] != &dst2[0] {
+ t.Errorf("unexpected capacity growth: got %d, want %d", cap(dst2), cap(dst))
+ }
}
}
// and returns the extended buffer.
// If the input is malformed, it returns the partially decoded src and an error.
func (enc *Encoding) AppendDecode(dst, src []byte) ([]byte, error) {
- n := enc.DecodedLen(len(src))
+ // Compute the output size without padding to avoid over allocating.
+ n := len(src)
+ for n > 0 && rune(src[n-1]) == enc.padChar {
+ n--
+ }
+ n = decodedLen(n, NoPadding)
+
dst = slices.Grow(dst, n)
n, err := enc.Decode(dst[len(dst):][:n], src)
return dst[:len(dst)+n], err
// DecodedLen returns the maximum length in bytes of the decoded data
// corresponding to n bytes of base64-encoded data.
func (enc *Encoding) DecodedLen(n int) int {
- if enc.padChar == NoPadding {
+ return decodedLen(n, enc.padChar)
+}
+
+func decodedLen(n int, padChar rune) int {
+ if padChar == NoPadding {
// Unpadded data may end with partial block of 2-3 characters.
return n/4*3 + n%4*6/8
}
dst, err := tt.enc.AppendDecode([]byte("lead"), []byte(encoded))
testEqual(t, "AppendDecode(%q) = error %v, want %v", p.encoded, err, error(nil))
testEqual(t, `AppendDecode("lead", %q) = %q, want %q`, p.encoded, string(dst), "lead"+p.decoded)
+
+ dst2, err := tt.enc.AppendDecode(dst[:0:len(p.decoded)], []byte(encoded))
+ testEqual(t, "AppendDecode(%q) = error %v, want %v", p.encoded, err, error(nil))
+ testEqual(t, `AppendDecode("", %q) = %q, want %q`, p.encoded, string(dst2), p.decoded)
+ if len(dst) > 0 && len(dst2) > 0 && &dst[0] != &dst2[0] {
+ t.Errorf("unexpected capacity growth: got %d, want %d", cap(dst2), cap(dst))
+ }
}
}
}