DoxigAlpha

decode

Invalid characters that are not ignored result in error.InvalidCharacter. Invalid padding results in error.InvalidPadding. Decoding more data than can fit in dest results in error.NoSpaceLeft. See also ::calcSizeUpperBound. Returns the number of bytes written to dest.

Function parameters

Parameters

#
decoder_with_ignore:*const Base64DecoderWithIgnore
dest:[]u8
source:[]const u8

Base64 codecs

Types

#
Codecs
Base64 codecs

Error sets in this namespace

Error Sets

#

The Base64 alphabet defined in

Values

#
standard_alphabet_chars
The Base64 alphabet defined in
standard
Standard Base64 codecs, with padding, as defined in
standard_no_pad
Standard Base64 codecs, without padding, as defined in
url_safe_alphabet_chars
The URL-safe Base64 alphabet defined in
url_safe
URL-safe Base64 codecs, with padding, as defined in
url_safe_no_pad
URL-safe Base64 codecs, without padding, as defined in

Source

Implementation

#
pub fn decode(decoder_with_ignore: *const Base64DecoderWithIgnore, dest: []u8, source: []const u8) Error!usize {
    const decoder = &decoder_with_ignore.decoder;
    var acc: u12 = 0;
    var acc_len: u4 = 0;
    var dest_idx: usize = 0;
    var leftover_idx: ?usize = null;
    for (source, 0..) |c, src_idx| {
        if (decoder_with_ignore.char_is_ignored[c]) continue;
        const d = decoder.char_to_index[c];
        if (d == Base64Decoder.invalid_char) {
            if (decoder.pad_char == null or c != decoder.pad_char.?) return error.InvalidCharacter;
            leftover_idx = src_idx;
            break;
        }
        acc = (acc << 6) + d;
        acc_len += 6;
        if (acc_len >= 8) {
            if (dest_idx == dest.len) return error.NoSpaceLeft;
            acc_len -= 8;
            dest[dest_idx] = @as(u8, @truncate(acc >> acc_len));
            dest_idx += 1;
        }
    }
    if (acc_len > 4 or (acc & (@as(u12, 1) << acc_len) - 1) != 0) {
        return error.InvalidPadding;
    }
    const padding_len = acc_len / 2;
    if (leftover_idx == null) {
        if (decoder.pad_char != null and padding_len != 0) return error.InvalidPadding;
        return dest_idx;
    }
    const leftover = source[leftover_idx.?..];
    if (decoder.pad_char) |pad_char| {
        var padding_chars: usize = 0;
        for (leftover) |c| {
            if (decoder_with_ignore.char_is_ignored[c]) continue;
            if (c != pad_char) {
                return if (c == Base64Decoder.invalid_char) error.InvalidCharacter else error.InvalidPadding;
            }
            padding_chars += 1;
        }
        if (padding_chars != padding_len) return error.InvalidPadding;
    }
    return dest_idx;
}