Zig 0.17.0-dev (Split by item)
This is an example of documentation generated by
ZigDoc , an alternative to Zig's built-in
Auto Doc feature. See also
examples in other modes/formats . The project being documented here (as the example) is the Zig library itself.
Zig › std/ › base64.zig › Base64DecoderWithIgnore
Base64DecoderWithIgnore
base64.Base64DecoderWithIgnore
pub const Base64DecoderWithIgnore = struct
File
Code
pub const Base64DecoderWithIgnore = struct {
decoder : Base64Decoder ,
char_is_ignored : [256 ]bool ,
pub fn init (alphabet_chars : [64 ]u8 , pad_char : ?u8 , ignore_chars : []const u8 ) Base64DecoderWithIgnore {
var result = Base64DecoderWithIgnore {
.decoder = Base64Decoder .init (alphabet_chars , pad_char ),
.char_is_ignored = @splat (false ),
};
for (ignore_chars ) |c | {
assert (result .decoder .char_to_index [c ] == Base64Decoder .invalid_char );
assert (!result .char_is_ignored [c ]);
assert (result .decoder .pad_char != c );
result .char_is_ignored [c ] = true ;
}
return result ;
}
pub fn calcSizeUpperBound (decoder_with_ignore : *const Base64DecoderWithIgnore , source_len : usize ) usize {
var result = source_len / 4 * 3 ;
if (decoder_with_ignore .decoder .pad_char == null ) {
const leftover = source_len % 4 ;
result += leftover * 3 / 4 ;
}
return result ;
}
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 ;
}
}