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 › Base64Encoder
Base64Encoder
base64.Base64Encoder
pub const Base64Encoder = struct
File
Code
pub const Base64Encoder = struct {
alphabet_chars : [64 ]u8 ,
pad_char : ?u8 ,
pub fn init (alphabet_chars : [64 ]u8 , pad_char : ?u8 ) Base64Encoder {
assert (alphabet_chars .len == 64 );
var char_in_alphabet : [256 ]bool = @splat (false );
for (alphabet_chars ) |c | {
assert (!char_in_alphabet [c ]);
assert (pad_char == null or c != pad_char .?);
char_in_alphabet [c ] = true ;
}
return Base64Encoder {
.alphabet_chars = alphabet_chars ,
.pad_char = pad_char ,
};
}
pub fn calcSize (encoder : *const Base64Encoder , source_len : usize ) usize {
if (encoder .pad_char != null ) {
return @divTrunc (source_len + 2 , 3 ) * 4 ;
} else {
const leftover = source_len % 3 ;
return @divTrunc (source_len , 3 ) * 4 + @divTrunc (leftover * 4 + 2 , 3 );
}
}
pub fn encodeWriter (encoder : *const Base64Encoder , dest : *std .Io .Writer , source : []const u8 ) !void {
var chunker = window (u8 , source , 3 , 3 );
while (chunker .next ()) |chunk | {
var temp : [5 ]u8 = undefined ;
const s = encoder .encode (&temp , chunk );
try dest .writeAll (s );
}
}
pub fn encode (encoder : *const Base64Encoder , dest : []u8 , source : []const u8 ) []const u8 {
const out_len = encoder .calcSize (source .len );
assert (dest .len >= out_len );
var idx : usize = 0 ;
var out_idx : usize = 0 ;
while (idx + 15 < source .len ) : (idx += 12 ) {
const bits = std .mem .readInt (u128 , source [idx ..][0 ..16 ], .big );
inline for (0 ..16 ) |i | {
dest [out_idx + i ] = encoder .alphabet_chars [@truncate ((bits >> (122 - i * 6 )) & 0x3f )];
}
out_idx += 16 ;
}
while (idx + 3 < source .len ) : (idx += 3 ) {
const bits = std .mem .readInt (u32 , source [idx ..][0 ..4 ], .big );
dest [out_idx ] = encoder .alphabet_chars [(bits >> 26 ) & 0x3f ];
dest [out_idx + 1 ] = encoder .alphabet_chars [(bits >> 20 ) & 0x3f ];
dest [out_idx + 2 ] = encoder .alphabet_chars [(bits >> 14 ) & 0x3f ];
dest [out_idx + 3 ] = encoder .alphabet_chars [(bits >> 8 ) & 0x3f ];
out_idx += 4 ;
}
if (idx + 2 < source .len ) {
dest [out_idx ] = encoder .alphabet_chars [source [idx ] >> 2 ];
dest [out_idx + 1 ] = encoder .alphabet_chars [((source [idx ] & 0x3 ) << 4 ) | (source [idx + 1 ] >> 4 )];
dest [out_idx + 2 ] = encoder .alphabet_chars [(source [idx + 1 ] & 0xf ) << 2 | (source [idx + 2 ] >> 6 )];
dest [out_idx + 3 ] = encoder .alphabet_chars [source [idx + 2 ] & 0x3f ];
out_idx += 4 ;
} else if (idx + 1 < source .len ) {
dest [out_idx ] = encoder .alphabet_chars [source [idx ] >> 2 ];
dest [out_idx + 1 ] = encoder .alphabet_chars [((source [idx ] & 0x3 ) << 4 ) | (source [idx + 1 ] >> 4 )];
dest [out_idx + 2 ] = encoder .alphabet_chars [(source [idx + 1 ] & 0xf ) << 2 ];
out_idx += 3 ;
} else if (idx < source .len ) {
dest [out_idx ] = encoder .alphabet_chars [source [idx ] >> 2 ];
dest [out_idx + 1 ] = encoder .alphabet_chars [(source [idx ] & 0x3 ) << 4 ];
out_idx += 2 ;
}
if (encoder .pad_char ) |pad_char | {
for (dest [out_idx ..out_len ]) |*pad | {
pad .* = pad_char ;
}
}
return dest [0 ..out_len ];
}
}