structstd.base64.Base64Encoder[src]

Fields

alphabet_chars: [64]u8
pad_char: ?u8

Functions

Functioninit[src]

pub fn init(alphabet_chars: [64]u8, pad_char: ?u8) Base64Encoder

A bunch of assertions, then simply pass the data right through.

Parameters

alphabet_chars: [64]u8
pad_char: ?u8

Source Code

Source code
pub fn init(alphabet_chars: [64]u8, pad_char: ?u8) Base64Encoder {
    assert(alphabet_chars.len == 64);
    var char_in_alphabet = [_]bool{false} ** 256;
    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,
    };
}

FunctioncalcSize[src]

pub fn calcSize(encoder: *const Base64Encoder, source_len: usize) usize

Compute the encoded length

Parameters

encoder: *const Base64Encoder
source_len: usize

Source Code

Source code
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);
    }
}

FunctionencodeWriter[src]

pub fn encodeWriter(encoder: *const Base64Encoder, dest: anytype, source: []const u8) !void

Parameters

encoder: *const Base64Encoder
source: []const u8

Source Code

Source code
pub fn encodeWriter(encoder: *const Base64Encoder, dest: anytype, 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);
    }
}

FunctionencodeFromReaderToWriter[src]

pub fn encodeFromReaderToWriter(encoder: *const Base64Encoder, destWriter: anytype, sourceReader: anytype) !void

Parameters

encoder: *const Base64Encoder

Source Code

Source code
pub fn encodeFromReaderToWriter(encoder: *const Base64Encoder, destWriter: anytype, sourceReader: anytype) !void {
    while (true) {
        var tempSource: [3]u8 = undefined;
        const bytesRead = try sourceReader.read(&tempSource);
        if (bytesRead == 0) {
            break;
        }

        var temp: [5]u8 = undefined;
        const s = encoder.encode(&temp, tempSource[0..bytesRead]);
        try destWriter.writeAll(s);
    }
}

Functionencode[src]

pub fn encode(encoder: *const Base64Encoder, dest: []u8, source: []const u8) []const u8

dest.len must at least be what you get from ::calcSize.

Parameters

encoder: *const Base64Encoder
dest: []u8
source: []const u8

Source Code

Source code
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];
}

Source Code

Source code
pub const Base64Encoder = struct {
    alphabet_chars: [64]u8,
    pad_char: ?u8,

    /// A bunch of assertions, then simply pass the data right through.
    pub fn init(alphabet_chars: [64]u8, pad_char: ?u8) Base64Encoder {
        assert(alphabet_chars.len == 64);
        var char_in_alphabet = [_]bool{false} ** 256;
        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,
        };
    }

    /// Compute the encoded length
    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);
        }
    }

    // dest must be compatible with std.io.Writer's writeAll interface
    pub fn encodeWriter(encoder: *const Base64Encoder, dest: anytype, 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);
        }
    }

    // destWriter must be compatible with std.io.Writer's writeAll interface
    // sourceReader must be compatible with std.io.Reader's read interface
    pub fn encodeFromReaderToWriter(encoder: *const Base64Encoder, destWriter: anytype, sourceReader: anytype) !void {
        while (true) {
            var tempSource: [3]u8 = undefined;
            const bytesRead = try sourceReader.read(&tempSource);
            if (bytesRead == 0) {
                break;
            }

            var temp: [5]u8 = undefined;
            const s = encoder.encode(&temp, tempSource[0..bytesRead]);
            try destWriter.writeAll(s);
        }
    }

    /// dest.len must at least be what you get from ::calcSize.
    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];
    }
}