+ var rempad = if bytes_in_last_step > 0 then 3 - bytes_in_last_step else 0
+ for i in [0 .. rempad[ do result.add b'='
+
+ return result
+ end
+
+ # Decodes `self` from base64
+ #
+ # assert "c3RyaW5n".decode_base64.to_s == "string"
+ # assert "c3Rya\nW5n".decode_base64.to_s == "string"
+ # assert "c3RyaW5nCg==".decode_base64.to_s == "string\n"
+ # assert "c3RyaW5nCg".decode_base64.to_s == "string\n"
+ # assert "c3RyaW5neQo=".decode_base64.to_s == "stringy\n"
+ # assert "c3RyaW5neQo".decode_base64.to_s == "stringy\n"
+ #
+ private fun decode_base64(length: Int): Bytes do
+ if length == 0 then return new Bytes.empty
+
+ # Avoids constant unboxing
+ var pad = b'='
+
+ var result = new Bytes.with_capacity((length / 4 + 1) * 3)
+
+ var curr = 0
+ var cnt = 0
+ var endpos = -1
+ for i in [0 .. length[ do
+ var b = self[i]
+ if b == pad then
+ endpos = i
+ break
+ end
+ # Ignore whitespaces
+ if b <= 0x20u8 then continue
+ if not b.is_base64_char then continue
+ curr <<= 6
+ curr += b.to_base64_char.to_i
+ cnt += 1
+ if cnt == 4 then
+ result.add(((curr & 0xFF0000) >> 16).to_b)
+ result.add(((curr & 0xFF00) >> 8).to_b)
+ result.add((curr & 0xFF).to_b)
+ curr = 0
+ cnt = 0
+ end