// Written in the D programming language.

/**
 * Support for Base64 encoding and decoding.
 *
 * This module provides two default implementations of Base64 encoding,
 * $(LREF Base64) with a standard encoding alphabet, and a variant
 * $(LREF Base64URL) that has a modified encoding alphabet designed to be
 * safe for embedding in URLs and filenames.
 *
 * Both variants are implemented as instantiations of the template
 * $(LREF Base64Impl). Most users will not need to use this template
 * directly; however, it can be used to create customized Base64 encodings,
 * such as one that omits padding characters, or one that is safe to embed
 * inside a regular expression.
 *
 * Example:
 * -----
 * ubyte[] data = [0x14, 0xfb, 0x9c, 0x03, 0xd9, 0x7e];
 *
 * const(char)[] encoded = Base64.encode(data);
 * assert(encoded == "FPucA9l+");
 *
 * ubyte[] decoded = Base64.decode("FPucA9l+");
 * assert(decoded == [0x14, 0xfb, 0x9c, 0x03, 0xd9, 0x7e]);
 * -----
 *
 * The range API is supported for both encoding and decoding:
 *
 * Example:
 * -----
 * // Create MIME Base64 with CRLF, per line 76.
 * File f = File("./text.txt", "r");
 * scope(exit) f.close();
 *
 * Appender!string mime64 = appender!string;
 *
 * foreach (encoded; Base64.encoder(f.byChunk(57)))
 * {
 *     mime64.put(encoded);
 *     mime64.put("\r\n");
 * }
 *
 * writeln(mime64.data);
 * -----
 *
 * References:
 * $(LINK2 https://tools.ietf.org/html/rfc4648, RFC 4648 - The Base16, Base32, and Base64
 * Data Encodings)
 *
 * Copyright: Masahiro Nakagawa 2010-.
 * License:   $(HTTP boost.org/LICENSE_1_0.txt, Boost License 1.0).
 * Authors:   Masahiro Nakagawa, Daniel Murphy (Single value Encoder and Decoder)
 * Source:    $(PHOBOSSRC std/_base64.d)
 * Macros:
 *      LREF2=<a href="#$1">$(D $2)</a>
 */
module std.base64;

import std.exception;  // enforce
import std.range.primitives;      // isInputRange, isOutputRange, isForwardRange, ElementType, hasLength
import std.traits;     // isArray

// Make sure module header code examples work correctly.
@safe unittest
{
    ubyte[] data = [0x14, 0xfb, 0x9c, 0x03, 0xd9, 0x7e];

    const(char)[] encoded = Base64.encode(data);
    assert(encoded == "FPucA9l+");

    ubyte[] decoded = Base64.decode("FPucA9l+");
    assert(decoded == [0x14, 0xfb, 0x9c, 0x03, 0xd9, 0x7e]);
}

/**
 * Implementation of standard _Base64 encoding.
 *
 * See $(LREF Base64Impl) for a description of available methods.
 */
alias Base64 = Base64Impl!('+', '/');

///
@safe unittest
{
    ubyte[] data = [0x83, 0xd7, 0x30, 0x7a, 0x01, 0x3f];
    assert(Base64.encode(data) == "g9cwegE/");
    assert(Base64.decode("g9cwegE/") == data);
}


/**
 * Variation of Base64 encoding that is safe for use in URLs and filenames.
 *
 * See $(LREF Base64Impl) for a description of available methods.
 */
alias Base64URL = Base64Impl!('-', '_');

///
@safe unittest
{
    ubyte[] data = [0x83, 0xd7, 0x30, 0x7a, 0x01, 0x3f];
    assert(Base64URL.encode(data) == "g9cwegE_");
    assert(Base64URL.decode("g9cwegE_") == data);
}

/**
 * Unpadded variation of Base64 encoding that is safe for use in URLs and
 * filenames, as used in RFCs 4648 and 7515 (JWS/JWT/JWE).
 *
 * See $(LREF Base64Impl) for a description of available methods.
 */
alias Base64URLNoPadding = Base64Impl!('-', '_', Base64.NoPadding);

///
@safe unittest
{
    ubyte[] data = [0x83, 0xd7, 0x30, 0x7b, 0xef];
    assert(Base64URLNoPadding.encode(data) == "g9cwe-8");
    assert(Base64URLNoPadding.decode("g9cwe-8") == data);
}

/**
 * Template for implementing Base64 encoding and decoding.
 *
 * For most purposes, direct usage of this template is not necessary; instead,
 * this module provides default implementations: $(LREF Base64), implementing
 * basic Base64 encoding, and $(LREF Base64URL) and $(LREF Base64URLNoPadding),
 * that implement the Base64 variant for use in URLs and filenames, with
 * and without padding, respectively.
 *
 * Customized Base64 encoding schemes can be implemented by instantiating this
 * template with the appropriate arguments. For example:
 *
 * -----
 * // Non-standard Base64 format for embedding in regular expressions.
 * alias Base64Re = Base64Impl!('!', '=', Base64.NoPadding);
 * -----
 *
 * NOTE:
 * Encoded strings will not have any padding if the $(D Padding) parameter is
 * set to $(D NoPadding).
 */
template Base64Impl(char Map62th, char Map63th, char Padding = '=')
{
    enum NoPadding = '\0';  /// represents no-padding encoding


    // Verify Base64 characters
    static assert(Map62th < 'A' || Map62th > 'Z', "Character '" ~ Map62th ~ "' cannot be used twice");
    static assert(Map63th < 'A' || Map63th > 'Z', "Character '" ~ Map63th ~ "' cannot be used twice");
    static assert(Padding < 'A' || Padding > 'Z', "Character '" ~ Padding ~ "' cannot be used twice");
    static assert(Map62th < 'a' || Map62th > 'z', "Character '" ~ Map62th ~ "' cannot be used twice");
    static assert(Map63th < 'a' || Map63th > 'z', "Character '" ~ Map63th ~ "' cannot be used twice");
    static assert(Padding < 'a' || Padding > 'z', "Character '" ~ Padding ~ "' cannot be used twice");
    static assert(Map62th < '0' || Map62th > '9', "Character '" ~ Map62th ~ "' cannot be used twice");
    static assert(Map63th < '0' || Map63th > '9', "Character '" ~ Map63th ~ "' cannot be used twice");
    static assert(Padding < '0' || Padding > '9', "Character '" ~ Padding ~ "' cannot be used twice");
    static assert(Map62th != Map63th, "Character '" ~ Map63th ~ "' cannot be used twice");
    static assert(Map62th != Padding, "Character '" ~ Padding ~ "' cannot be used twice");
    static assert(Map63th != Padding, "Character '" ~ Padding ~ "' cannot be used twice");
    static assert(Map62th != NoPadding, "'\\0' is not a valid Base64character");
    static assert(Map63th != NoPadding, "'\\0' is not a valid Base64character");


    /* Encode functions */


    private immutable EncodeMap = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" ~ Map62th ~ Map63th;


    /**
     * Calculates the length needed to store the encoded string corresponding
     * to an input of the given length.
     *
     * Params:
     *  sourceLength = Length of the source array.
     *
     * Returns:
     *  The length of a Base64 encoding of an array of the given length.
     */
    @safe
    pure nothrow size_t encodeLength(in size_t sourceLength)
    {
        static if (Padding == NoPadding)
            return (sourceLength / 3) * 4 + (sourceLength % 3 == 0 ? 0 : sourceLength % 3 == 1 ? 2 : 3);
        else
            return (sourceLength / 3 + (sourceLength % 3 ? 1 : 0)) * 4;
    }

    ///
    @safe unittest
    {
        ubyte[] data = [0x1a, 0x2b, 0x3c, 0x4d, 0x5d, 0x6e];

        // Allocate a buffer large enough to hold the encoded string.
        auto buf = new char[Base64.encodeLength(data.length)];

        Base64.encode(data, buf);
        assert(buf == "Gis8TV1u");
    }


    // ubyte[] to char[]


    /**
     * Encode $(D_PARAM source) into a $(D char[]) buffer using Base64
     * encoding.
     *
     * Params:
     *  source = The $(LINK2 std_range_primitives.html#isInputRange, input
     *           range) to _encode.
     *  buffer = The $(D char[]) buffer to store the encoded result.
     *
     * Returns:
     *  The slice of $(D_PARAM buffer) that contains the encoded string.
     */
    @trusted
    pure char[] encode(R1, R2)(in R1 source, R2 buffer) if (isArray!R1 && is(ElementType!R1 : ubyte) &&
                                                            is(R2 == char[]))
    in
    {
        assert(buffer.length >= encodeLength(source.length), "Insufficient buffer for encoding");
    }
    out(result)
    {
        assert(result.length == encodeLength(source.length), "The length of result is different from Base64");
    }
    body
    {
        immutable srcLen = source.length;
        if (srcLen == 0)
            return [];

        immutable blocks = srcLen / 3;
        immutable remain = srcLen % 3;
        auto      bufptr = buffer.ptr;
        auto      srcptr = source.ptr;

        foreach (Unused; 0 .. blocks)
        {
            immutable val = srcptr[0] << 16 | srcptr[1] << 8 | srcptr[2];
            *bufptr++ = EncodeMap[val >> 18       ];
            *bufptr++ = EncodeMap[val >> 12 & 0x3f];
            *bufptr++ = EncodeMap[val >>  6 & 0x3f];
            *bufptr++ = EncodeMap[val       & 0x3f];
            srcptr += 3;
        }

        if (remain)
        {
            immutable val = srcptr[0] << 16 | (remain == 2 ? srcptr[1] << 8 : 0);
            *bufptr++ = EncodeMap[val >> 18       ];
            *bufptr++ = EncodeMap[val >> 12 & 0x3f];

            final switch (remain)
            {
            case 2:
                *bufptr++ = EncodeMap[val >> 6 & 0x3f];
                static if (Padding != NoPadding)
                    *bufptr++ = Padding;
                break;
            case 1:
                static if (Padding != NoPadding)
                {
                    *bufptr++ = Padding;
                    *bufptr++ = Padding;
                }
                break;
            }
        }

        // encode method can't assume buffer length. So, slice needed.
        return buffer[0 .. bufptr - buffer.ptr];
    }

    ///
    @safe unittest
    {
        ubyte[] data = [0x83, 0xd7, 0x30, 0x7a, 0x01, 0x3f];
        char[32] buffer;    // much bigger than necessary

        // Just to be sure...
        auto encodedLength = Base64.encodeLength(data.length);
        assert(buffer.length >= encodedLength);

        // encode() returns a slice to the provided buffer.
        auto encoded = Base64.encode(data, buffer[]);
        assert(encoded is buffer[0 .. encodedLength]);
        assert(encoded == "g9cwegE/");
    }


    // InputRange to char[]


    /**
     * ditto
     */
    char[] encode(R1, R2)(R1 source, R2 buffer) if (!isArray!R1 && isInputRange!R1 &&
                                                    is(ElementType!R1 : ubyte) && hasLength!R1 &&
                                                    is(R2 == char[]))
    in
    {
        assert(buffer.length >= encodeLength(source.length), "Insufficient buffer for encoding");
    }
    out(result)
    {
        // @@@BUG@@@ D's DbC can't caputre an argument of function and store the result of precondition.
        //assert(result.length == encodeLength(source.length), "The length of result is different from Base64");
    }
    body
    {
        immutable srcLen = source.length;
        if (srcLen == 0)
            return [];

        immutable blocks = srcLen / 3;
        immutable remain = srcLen % 3;
        auto      bufptr = buffer.ptr;

        foreach (Unused; 0 .. blocks)
        {
            immutable v1 = source.front; source.popFront();
            immutable v2 = source.front; source.popFront();
            immutable v3 = source.front; source.popFront();
            immutable val = v1 << 16 | v2 << 8 | v3;
            *bufptr++ = EncodeMap[val >> 18       ];
            *bufptr++ = EncodeMap[val >> 12 & 0x3f];
            *bufptr++ = EncodeMap[val >>  6 & 0x3f];
            *bufptr++ = EncodeMap[val       & 0x3f];
        }

        if (remain)
        {
            size_t val = source.front << 16;
            if (remain == 2)
            {
                source.popFront();
                val |= source.front << 8;
            }

            *bufptr++ = EncodeMap[val >> 18       ];
            *bufptr++ = EncodeMap[val >> 12 & 0x3f];

            final switch (remain)
            {
            case 2:
                *bufptr++ = EncodeMap[val >> 6 & 0x3f];
                static if (Padding != NoPadding)
                    *bufptr++ = Padding;
                break;
            case 1:
                static if (Padding != NoPadding)
                {
                    *bufptr++ = Padding;
                    *bufptr++ = Padding;
                }
                break;
            }
        }

        // @@@BUG@@@ Workaround for DbC problem. See comment on 'out'.
        version (unittest)
            assert(
                bufptr - buffer.ptr == encodeLength(srcLen),
                "The length of result is different from Base64"
            );

        // encode method can't assume buffer length. So, slice needed.
        return buffer[0 .. bufptr - buffer.ptr];
    }


    // ubyte[] to OutputRange


    /**
     * Encodes $(D_PARAM source) into an
     * $(LINK2 std_range_primitives.html#isOutputRange, output range) using
     * Base64 encoding.
     *
     * Params:
     *  source = The $(LINK2 std_range_primitives.html#isInputRange, input
     *           range) to _encode.
     *  range  = The $(LINK2 std_range_primitives.html#isOutputRange, output
     *           range) to store the encoded result.
     *
     * Returns:
     *  The number of times the output range's $(D put) method was invoked.
     */
    size_t encode(R1, R2)(in R1 source, auto ref R2 range)
        if (isArray!R1 && is(ElementType!R1 : ubyte) &&
            !is(R2 == char[]) && isOutputRange!(R2, char))
    out(result)
    {
        assert(result == encodeLength(source.length), "The number of put is different from the length of Base64");
    }
    body
    {
        immutable srcLen = source.length;
        if (srcLen == 0)
            return 0;

        immutable blocks = srcLen / 3;
        immutable remain = srcLen % 3;
        auto      srcptr = source.ptr;
        size_t    pcount;

        foreach (Unused; 0 .. blocks)
        {
            immutable val = srcptr[0] << 16 | srcptr[1] << 8 | srcptr[2];
            put(range, EncodeMap[val >> 18       ]);
            put(range, EncodeMap[val >> 12 & 0x3f]);
            put(range, EncodeMap[val >>  6 & 0x3f]);
            put(range, EncodeMap[val       & 0x3f]);
            srcptr += 3;
            pcount += 4;
        }

        if (remain)
        {
            immutable val = srcptr[0] << 16 | (remain == 2 ? srcptr[1] << 8 : 0);
            put(range, EncodeMap[val >> 18       ]);
            put(range, EncodeMap[val >> 12 & 0x3f]);
            pcount += 2;

            final switch (remain)
            {
            case 2:
                put(range, EncodeMap[val >> 6 & 0x3f]);
                pcount++;

                static if (Padding != NoPadding)
                {
                    put(range, Padding);
                    pcount++;
                }
                break;
            case 1:
                static if (Padding != NoPadding)
                {
                    put(range, Padding);
                    put(range, Padding);
                    pcount += 2;
                }
                break;
            }
        }

        return pcount;
    }

    ///
    @system unittest
    {
        // @system because encode for OutputRange is @system
        struct OutputRange
        {
            char[] result;
            void put(const(char) ch) @safe { result ~= ch; }
        }

        ubyte[] data = [0x1a, 0x2b, 0x3c, 0x4d, 0x5d, 0x6e];

        // This overload of encode() returns the number of calls to the output
        // range's put method.
        OutputRange output;
        assert(Base64.encode(data, output) == 8);
        assert(output.result == "Gis8TV1u");
    }


    // InputRange to OutputRange


    /**
     * ditto
     */
    size_t encode(R1, R2)(R1 source, auto ref R2 range)
        if (!isArray!R1 && isInputRange!R1 && is(ElementType!R1 : ubyte) &&
            hasLength!R1 && !is(R2 == char[]) && isOutputRange!(R2, char))
    out(result)
    {
        // @@@BUG@@@ Workaround for DbC problem.
        //assert(result == encodeLength(source.length), "The number of put is different from the length of Base64");
    }
    body
    {
        immutable srcLen = source.length;
        if (srcLen == 0)
            return 0;

        immutable blocks = srcLen / 3;
        immutable remain = srcLen % 3;
        size_t    pcount;

        foreach (Unused; 0 .. blocks)
        {
            immutable v1 = source.front; source.popFront();
            immutable v2 = source.front; source.popFront();
            immutable v3 = source.front; source.popFront();
            immutable val = v1 << 16 | v2 << 8 | v3;
            put(range, EncodeMap[val >> 18       ]);
            put(range, EncodeMap[val >> 12 & 0x3f]);
            put(range, EncodeMap[val >>  6 & 0x3f]);
            put(range, EncodeMap[val       & 0x3f]);
            pcount += 4;
        }

        if (remain)
        {
            size_t val = source.front << 16;
            if (remain == 2)
            {
                source.popFront();
                val |= source.front << 8;
            }

            put(range, EncodeMap[val >> 18       ]);
            put(range, EncodeMap[val >> 12 & 0x3f]);
            pcount += 2;

            final switch (remain)
            {
            case 2:
                put(range, EncodeMap[val >> 6 & 0x3f]);
                pcount++;

                static if (Padding != NoPadding)
                {
                    put(range, Padding);
                    pcount++;
                }
                break;
            case 1:
                static if (Padding != NoPadding)
                {
                    put(range, Padding);
                    put(range, Padding);
                    pcount += 2;
                }
                break;
            }
        }

        // @@@BUG@@@ Workaround for DbC problem.
        version (unittest)
            assert(
                pcount == encodeLength(srcLen),
                "The number of put is different from the length of Base64"
            );

        return pcount;
    }


    /**
     * Encodes $(D_PARAM source) to newly-allocated buffer.
     *
     * This convenience method alleviates the need to manually manage output
     * buffers.
     *
     * Params:
     *  source = The $(LINK2 std_range_primitives.html#isInputRange, input
     *           range) to _encode.
     *
     * Returns:
     *  A newly-allocated $(D char[]) buffer containing the encoded string.
     */
    @safe
    pure char[] encode(Range)(Range source) if (isArray!Range && is(ElementType!Range : ubyte))
    {
        return encode(source, new char[encodeLength(source.length)]);
    }

    ///
    @safe unittest
    {
        ubyte[] data = [0x1a, 0x2b, 0x3c, 0x4d, 0x5d, 0x6e];
        assert(Base64.encode(data) == "Gis8TV1u");
    }


    /**
     * ditto
     */
    char[] encode(Range)(Range source) if (!isArray!Range && isInputRange!Range &&
                                           is(ElementType!Range : ubyte) && hasLength!Range)
    {
        return encode(source, new char[encodeLength(source.length)]);
    }


    /**
     * An $(LINK2 std_range_primitives.html#isInputRange, input range) that
     * iterates over the respective Base64 encodings of a range of data items.
     *
     * This range will be a $(LINK2 std_range_primitives.html#isForwardRange,
     * forward range) if the underlying data source is at least a forward
     * range.
     *
     * Note: This struct is not intended to be created in user code directly;
     * use the $(LREF encoder) function instead.
     */
    struct Encoder(Range) if (isInputRange!Range && (is(ElementType!Range : const(ubyte)[]) ||
                                                     is(ElementType!Range : const(char)[])))
    {
      private:
        Range  range_;
        char[] buffer_, encoded_;


      public:
        this(Range range)
        {
            range_ = range;
            doEncoding();
        }


        /**
         * Returns:
         *  true if there is no more encoded data left.
         */
        @property @trusted
        bool empty()
        {
            return range_.empty;
        }


        /**
         * Returns: The current chunk of encoded data.
         */
        @property @safe
        nothrow char[] front()
        {
            return encoded_;
        }


        /**
         * Advance the range to the next chunk of encoded data.
         *
         * Throws:
         *  $(D Base64Exception) If invoked when
         *  $(LREF2 .Base64Impl.Encoder.empty, empty) returns $(D true).
         */
        void popFront()
        {
            enforce(!empty, new Base64Exception("Cannot call popFront on Encoder with no data remaining"));

            range_.popFront();

            /*
             * This check is very ugly. I think this is a Range's flaw.
             * I very strongly want the Range guideline for unified implementation.
             *
             * In this case, Encoder becomes a beautiful implementation if 'front' performs Base64 encoding.
             */
            if (!empty)
                doEncoding();
        }


        static if (isForwardRange!Range)
        {
            /**
             * Save the current iteration state of the range.
             *
             * This method is only available if the underlying range is a
             * $(LINK2 std_range_primitives.html#isForwardRange, forward
             * range).
             *
             * Returns:
             *  A copy of $(D this).
             */
            @property
            typeof(this) save()
            {
                typeof(return) encoder;

                encoder.range_   = range_.save;
                encoder.buffer_  = buffer_.dup;
                encoder.encoded_ = encoder.buffer_[0 .. encoded_.length];

                return encoder;
            }
        }


      private:
        void doEncoding()
        {
            auto data = cast(const(ubyte)[])range_.front;
            auto size = encodeLength(data.length);
            if (size > buffer_.length)
                buffer_.length = size;

            encoded_ = encode(data, buffer_);
        }
    }


    /**
     * An $(LINK2 std_range_primitives.html#isInputRange, input range) that
     * iterates over the encoded bytes of the given source data.
     *
     * It will be a $(LINK2 std_range_primitives.html#isForwardRange, forward
     * range) if the underlying data source is at least a forward range.
     *
     * Note: This struct is not intended to be created in user code directly;
     * use the $(LREF encoder) function instead.
     */
    struct Encoder(Range) if (isInputRange!Range && is(ElementType!Range : ubyte))
    {
      private:
        Range range_;
        ubyte first;
        int   pos, padding;


      public:
        this(Range range)
        {
            range_ = range;
            static if (isForwardRange!Range)
                range_ = range_.save;

            if (range_.empty)
                pos = -1;
            else
                popFront();
        }


        /**
         * Returns:
         *  true if there are no more encoded characters to be iterated.
         */
        @property @safe
        nothrow bool empty() const
        {
            static if (Padding == NoPadding)
                return pos < 0;
            else
                return pos < 0 && !padding;
        }


        /**
         * Returns: The current encoded character.
         */
        @property @safe
        nothrow ubyte front()
        {
            return first;
        }


        /**
         * Advance to the next encoded character.
         *
         * Throws:
         *  $(D Base64Exception) If invoked when $(LREF2 .Base64Impl.Encoder.empty.2,
         *  empty) returns $(D true).
         */
        void popFront()
        {
            enforce(!empty, new Base64Exception("Cannot call popFront on Encoder with no data remaining"));

            static if (Padding != NoPadding)
                if (padding)
                {
                    first = Padding;
                    pos   = -1;
                    padding--;
                    return;
                }

            if (range_.empty)
            {
                pos = -1;
                return;
            }

            final switch (pos)
            {
            case 0:
                first = EncodeMap[range_.front >> 2];
                break;
            case 1:
                immutable t = (range_.front & 0b11) << 4;
                range_.popFront();

                if (range_.empty)
                {
                    first   = EncodeMap[t];
                    padding = 3;
                }
                else
                {
                    first = EncodeMap[t | (range_.front >> 4)];
                }
                break;
            case 2:
                immutable t = (range_.front & 0b1111) << 2;
                range_.popFront();

                if (range_.empty)
                {
                    first   = EncodeMap[t];
                    padding = 2;
                }
                else
                {
                    first = EncodeMap[t | (range_.front >> 6)];
                }
                break;
            case 3:
                first = EncodeMap[range_.front & 0b111111];
                range_.popFront();
                break;
            }

            ++pos %= 4;
        }


        static if (isForwardRange!Range)
        {
            /**
             * Save the current iteration state of the range.
             *
             * This method is only available if the underlying range is a
             * $(LINK2 std_range_primitives.html#isForwardRange, forward
             * range).
             *
             * Returns:
             *  A copy of $(D this).
             */
            @property
            typeof(this) save()
            {
                auto encoder = this;
                encoder.range_ = encoder.range_.save;
                return encoder;
            }
        }
    }


    /**
     * Construct an $(D Encoder) that iterates over the Base64 encoding of the
     * given $(LINK2 std_range_primitives.html#isInputRange, input range).
     *
     * Params:
     *  range = An $(LINK2 std_range_primitives.html#isInputRange, input
     *      range) over the data to be encoded.
     *
     * Returns:
     *  If $(D_PARAM range) is a range of bytes, an $(D Encoder) that iterates
     *  over the bytes of the corresponding Base64 encoding.
     *
     *  If $(D_PARAM range) is a range of ranges of bytes, an $(D Encoder) that
     *  iterates over the Base64 encoded strings of each element of the range.
     *
     *  In both cases, the returned $(D Encoder) will be a
     *  $(LINK2 std_range_primitives.html#isForwardRange, forward range) if the
     *  given $(D range) is at least a forward range, otherwise it will be only
     *  an input range.
     *
     * Example:
     * This example encodes the input one line at a time.
     * -----
     * File f = File("text.txt", "r");
     * scope(exit) f.close();
     *
     * uint line = 0;
     * foreach (encoded; Base64.encoder(f.byLine()))
     * {
     *     writeln(++line, ". ", encoded);
     * }
     * -----
     *
     * Example:
     * This example encodes the input data one byte at a time.
     * -----
     * ubyte[] data = cast(ubyte[]) "0123456789";
     *
     * // The ElementType of data is not aggregation type
     * foreach (encoded; Base64.encoder(data))
     * {
     *     writeln(encoded);
     * }
     * -----
     */
    Encoder!(Range) encoder(Range)(Range range) if (isInputRange!Range)
    {
        return typeof(return)(range);
    }


    /* Decode functions */


    private immutable int[char.max + 1] DecodeMap = [
        'A':0b000000, 'B':0b000001, 'C':0b000010, 'D':0b000011, 'E':0b000100,
        'F':0b000101, 'G':0b000110, 'H':0b000111, 'I':0b001000, 'J':0b001001,
        'K':0b001010, 'L':0b001011, 'M':0b001100, 'N':0b001101, 'O':0b001110,
        'P':0b001111, 'Q':0b010000, 'R':0b010001, 'S':0b010010, 'T':0b010011,
        'U':0b010100, 'V':0b010101, 'W':0b010110, 'X':0b010111, 'Y':0b011000,
        'Z':0b011001, 'a':0b011010, 'b':0b011011, 'c':0b011100, 'd':0b011101,
        'e':0b011110, 'f':0b011111, 'g':0b100000, 'h':0b100001, 'i':0b100010,
        'j':0b100011, 'k':0b100100, 'l':0b100101, 'm':0b100110, 'n':0b100111,
        'o':0b101000, 'p':0b101001, 'q':0b101010, 'r':0b101011, 's':0b101100,
        't':0b101101, 'u':0b101110, 'v':0b101111, 'w':0b110000, 'x':0b110001,
        'y':0b110010, 'z':0b110011, '0':0b110100, '1':0b110101, '2':0b110110,
        '3':0b110111, '4':0b111000, '5':0b111001, '6':0b111010, '7':0b111011,
        '8':0b111100, '9':0b111101, Map62th:0b111110, Map63th:0b111111, Padding:-1
    ];


    /**
     * Given a Base64 encoded string, calculates the length of the decoded
     * string.
     *
     * Params:
     *  sourceLength = The length of the Base64 encoding.
     *
     * Returns:
     *  The length of the decoded string corresponding to a Base64 encoding of
     *  length $(D_PARAM sourceLength).
     */
    @safe
    pure nothrow size_t decodeLength(in size_t sourceLength)
    {
        static if (Padding == NoPadding)
            return (sourceLength / 4) * 3 + (sourceLength % 4 < 2 ? 0 : sourceLength % 4 == 2 ? 1 : 2);
        else
            return (sourceLength / 4) * 3;
    }

    ///
    @safe unittest
    {
        auto encoded = "Gis8TV1u";

        // Allocate a sufficiently large buffer to hold to decoded result.
        auto buffer = new ubyte[Base64.decodeLength(encoded.length)];

        Base64.decode(encoded, buffer);
        assert(buffer == [0x1a, 0x2b, 0x3c, 0x4d, 0x5d, 0x6e]);
    }


    // Used in decode contracts. Calculates the actual size the decoded
    // result should have, taking into account trailing padding.
    @safe
    pure nothrow private size_t realDecodeLength(R)(R source)
    {
        auto expect = decodeLength(source.length);
        static if (Padding != NoPadding)
        {
            if (source.length % 4 == 0)
            {
                expect -= source.length == 0       ? 0 :
                          source[$ - 2] == Padding ? 2 :
                          source[$ - 1] == Padding ? 1 : 0;
            }
        }
        return expect;
    }


    // char[] to ubyte[]


    /**
     * Decodes $(D_PARAM source) into the given buffer.
     *
     * Params:
     *  source = The $(LINK2 std_range_primitives.html#isInputRange, input
     *      range) to _decode.
     *  buffer = The buffer to store decoded result.
     *
     * Returns:
     *  The slice of $(D_PARAM buffer) containing the decoded result.
     *
     * Throws:
     *  $(D Base64Exception) if $(D_PARAM source) contains characters outside the
     *  base alphabet of the current Base64 encoding scheme.
     */
    @trusted
    pure ubyte[] decode(R1, R2)(in R1 source, R2 buffer) if (isArray!R1 && is(ElementType!R1 : dchar) &&
                                                             is(R2 == ubyte[]) && isOutputRange!(R2, ubyte))
    in
    {
        assert(buffer.length >= realDecodeLength(source), "Insufficient buffer for decoding");
    }
    out(result)
    {
        immutable expect = realDecodeLength(source);
        assert(result.length == expect, "The length of result is different from the expected length");
    }
    body
    {
        immutable srcLen = source.length;
        if (srcLen == 0)
            return [];
        static if (Padding != NoPadding)
            enforce(srcLen % 4 == 0, new Base64Exception("Invalid length of encoded data"));

        immutable blocks = srcLen / 4;
        auto      srcptr = source.ptr;
        auto      bufptr = buffer.ptr;

        foreach (Unused; 0 .. blocks)
        {
            immutable v1 = decodeChar(*srcptr++);
            immutable v2 = decodeChar(*srcptr++);

            *bufptr++ = cast(ubyte)(v1 << 2 | v2 >> 4);

            immutable v3 = decodeChar(*srcptr++);
            if (v3 == -1)
                break;

            *bufptr++ = cast(ubyte)((v2 << 4 | v3 >> 2) & 0xff);

            immutable v4 = decodeChar(*srcptr++);
            if (v4 == -1)
                break;

            *bufptr++ = cast(ubyte)((v3 << 6 | v4) & 0xff);
        }

        static if (Padding == NoPadding)
        {
            immutable remain = srcLen % 4;

            if (remain)
            {
                immutable v1 = decodeChar(*srcptr++);
                immutable v2 = decodeChar(*srcptr++);

                *bufptr++ = cast(ubyte)(v1 << 2 | v2 >> 4);

                if (remain == 3)
                    *bufptr++ = cast(ubyte)((v2 << 4 | decodeChar(*srcptr++) >> 2) & 0xff);
            }
        }

        return buffer[0 .. bufptr - buffer.ptr];
    }

    ///
    @safe unittest
    {
        auto encoded = "Gis8TV1u";
        ubyte[32] buffer;   // much bigger than necessary

        // Just to be sure...
        auto decodedLength = Base64.decodeLength(encoded.length);
        assert(buffer.length >= decodedLength);

        // decode() returns a slice of the given buffer.
        auto decoded = Base64.decode(encoded, buffer[]);
        assert(decoded is buffer[0 .. decodedLength]);
        assert(decoded == [0x1a, 0x2b, 0x3c, 0x4d, 0x5d, 0x6e]);
    }

    // InputRange to ubyte[]


    /**
     * ditto
     */
    ubyte[] decode(R1, R2)(R1 source, R2 buffer) if (!isArray!R1 && isInputRange!R1 &&
                                                     is(ElementType!R1 : dchar) && hasLength!R1 &&
                                                     is(R2 == ubyte[]) && isOutputRange!(R2, ubyte))
    in
    {
        assert(buffer.length >= decodeLength(source.length), "Insufficient buffer for decoding");
    }
    out(result)
    {
        // @@@BUG@@@ Workaround for DbC problem.
        //immutable expect = decodeLength(source.length) - 2;
        //assert(result.length >= expect, "The length of result is smaller than expected length");
    }
    body
    {
        immutable srcLen = source.length;
        if (srcLen == 0)
            return [];
        static if (Padding != NoPadding)
            enforce(srcLen % 4 == 0, new Base64Exception("Invalid length of encoded data"));

        immutable blocks = srcLen / 4;
        auto      bufptr = buffer.ptr;

        foreach (Unused; 0 .. blocks)
        {
            immutable v1 = decodeChar(source.front); source.popFront();
            immutable v2 = decodeChar(source.front); source.popFront();

            *bufptr++ = cast(ubyte)(v1 << 2 | v2 >> 4);

            immutable v3 = decodeChar(source.front);
            if (v3 == -1)
                break;

            *bufptr++ = cast(ubyte)((v2 << 4 | v3 >> 2) & 0xff);
            source.popFront();

            immutable v4 = decodeChar(source.front);
            if (v4 == -1)
                break;

            *bufptr++ = cast(ubyte)((v3 << 6 | v4) & 0xff);
            source.popFront();
        }

        static if (Padding == NoPadding)
        {
            immutable remain = srcLen % 4;

            if (remain)
            {
                immutable v1 = decodeChar(source.front); source.popFront();
                immutable v2 = decodeChar(source.front);

                *bufptr++ = cast(ubyte)(v1 << 2 | v2 >> 4);

                if (remain == 3)
                {
                    source.popFront();
                    *bufptr++ = cast(ubyte)((v2 << 4 | decodeChar(source.front) >> 2) & 0xff);
                }
            }
        }

        // @@@BUG@@@ Workaround for DbC problem.
        version (unittest)
            assert(
                (bufptr - buffer.ptr) >= (decodeLength(srcLen) - 2),
                "The length of result is smaller than expected length"
            );

        return buffer[0 .. bufptr - buffer.ptr];
    }


    // char[] to OutputRange


    /**
     * Decodes $(D_PARAM source) into a given
     * $(LINK2 std_range_primitives.html#isOutputRange, output range).
     *
     * Params:
     *  source = The $(LINK2 std_range_primitives.html#isInputRange, input
     *           range) to _decode.
     *  range  = The $(LINK2 std_range_primitives.html#isOutputRange, output
     *           range) to store the decoded result.
     *
     * Returns:
     *  The number of times the output range's $(D put) method was invoked.
     *
     * Throws:
     *  $(D Base64Exception) if $(D_PARAM source) contains characters outside the
     *  base alphabet of the current Base64 encoding scheme.
     */
    size_t decode(R1, R2)(in R1 source, auto ref R2 range)
        if (isArray!R1 && is(ElementType!R1 : dchar) &&
            !is(R2 == ubyte[]) && isOutputRange!(R2, ubyte))
    out(result)
    {
        immutable expect = realDecodeLength(source);
        assert(result == expect, "The result of decode is different from the expected");
    }
    body
    {
        immutable srcLen = source.length;
        if (srcLen == 0)
            return 0;
        static if (Padding != NoPadding)
            enforce(srcLen % 4 == 0, new Base64Exception("Invalid length of encoded data"));

        immutable blocks = srcLen / 4;
        auto      srcptr = source.ptr;
        size_t    pcount;

        foreach (Unused; 0 .. blocks)
        {
            immutable v1 = decodeChar(*srcptr++);
            immutable v2 = decodeChar(*srcptr++);

            put(range, cast(ubyte)(v1 << 2 | v2 >> 4));
            pcount++;

            immutable v3 = decodeChar(*srcptr++);
            if (v3 == -1)
                break;

            put(range, cast(ubyte)((v2 << 4 | v3 >> 2) & 0xff));
            pcount++;

            immutable v4 = decodeChar(*srcptr++);
            if (v4 == -1)
                break;

            put(range, cast(ubyte)((v3 << 6 | v4) & 0xff));
            pcount++;
        }

        static if (Padding == NoPadding)
        {
            immutable remain = srcLen % 4;

            if (remain)
            {
                immutable v1 = decodeChar(*srcptr++);
                immutable v2 = decodeChar(*srcptr++);

                put(range, cast(ubyte)(v1 << 2 | v2 >> 4));
                pcount++;

                if (remain == 3)
                {
                    put(range, cast(ubyte)((v2 << 4 | decodeChar(*srcptr++) >> 2) & 0xff));
                    pcount++;
                }
            }
        }

        return pcount;
    }

    ///
    @system unittest
    {
        struct OutputRange
        {
            ubyte[] result;
            void put(ubyte b) { result ~= b; }
        }
        OutputRange output;

        // This overload of decode() returns the number of calls to put().
        assert(Base64.decode("Gis8TV1u", output) == 6);
        assert(output.result == [0x1a, 0x2b, 0x3c, 0x4d, 0x5d, 0x6e]);
    }


    // InputRange to OutputRange


    /**
     * ditto
     */
    size_t decode(R1, R2)(R1 source, auto ref R2 range)
        if (!isArray!R1 && isInputRange!R1 && is(ElementType!R1 : dchar) &&
            hasLength!R1 && !is(R2 == ubyte[]) && isOutputRange!(R2, ubyte))
    out(result)
    {
        // @@@BUG@@@ Workaround for DbC problem.
        //immutable expect = decodeLength(source.length) - 2;
        //assert(result >= expect, "The length of result is smaller than expected length");
    }
    body
    {
        immutable srcLen = source.length;
        if (srcLen == 0)
            return 0;
        static if (Padding != NoPadding)
            enforce(srcLen % 4 == 0, new Base64Exception("Invalid length of encoded data"));

        immutable blocks = srcLen / 4;
        size_t    pcount;

        foreach (Unused; 0 .. blocks)
        {
            immutable v1 = decodeChar(source.front); source.popFront();
            immutable v2 = decodeChar(source.front); source.popFront();

            put(range, cast(ubyte)(v1 << 2 | v2 >> 4));
            pcount++;

            immutable v3 = decodeChar(source.front);
            if (v3 == -1)
                break;

            put(range, cast(ubyte)((v2 << 4 | v3 >> 2) & 0xff));
            source.popFront();
            pcount++;

            immutable v4 = decodeChar(source.front);
            if (v4 == -1)
                break;

            put(range, cast(ubyte)((v3 << 6 | v4) & 0xff));
            source.popFront();
            pcount++;
        }

        static if (Padding == NoPadding)
        {
            immutable remain = srcLen % 4;

            if (remain)
            {
                immutable v1 = decodeChar(source.front); source.popFront();
                immutable v2 = decodeChar(source.front);

                put(range, cast(ubyte)(v1 << 2 | v2 >> 4));
                pcount++;

                if (remain == 3)
                {
                    source.popFront();
                    put(range, cast(ubyte)((v2 << 4 | decodeChar(source.front) >> 2) & 0xff));
                    pcount++;
                }
            }
        }

        // @@@BUG@@@ Workaround for DbC problem.
        version (unittest)
            assert(
                pcount >= (decodeLength(srcLen) - 2),
                "The length of result is smaller than expected length"
            );

        return pcount;
    }


    /**
     * Decodes $(D_PARAM source) into newly-allocated buffer.
     *
     * This convenience method alleviates the need to manually manage decoding
     * buffers.
     *
     * Params:
     *  source = The $(LINK2 std_range_primitives.html#isInputRange, input
     *           range) to _decode.
     *
     * Returns:
     *  A newly-allocated $(D ubyte[]) buffer containing the decoded string.
     */
    @safe
    pure ubyte[] decode(Range)(Range source) if (isArray!Range && is(ElementType!Range : dchar))
    {
        return decode(source, new ubyte[decodeLength(source.length)]);
    }

    ///
    @safe unittest
    {
        auto data = "Gis8TV1u";
        assert(Base64.decode(data) == [0x1a, 0x2b, 0x3c, 0x4d, 0x5d, 0x6e]);
    }


    /**
     * ditto
     */
    ubyte[] decode(Range)(Range source) if (!isArray!Range && isInputRange!Range &&
                                            is(ElementType!Range : dchar) && hasLength!Range)
    {
        return decode(source, new ubyte[decodeLength(source.length)]);
    }


    /**
     * An $(LINK2 std_range_primitives.html#isInputRange, input range) that
     * iterates over the decoded data of a range of Base64 encodings.
     *
     * This range will be a $(LINK2 std_range_primitives.html#isForwardRange,
     * forward range) if the underlying data source is at least a forward
     * range.
     *
     * Note: This struct is not intended to be created in user code directly;
     * use the $(LREF decoder) function instead.
     */
    struct Decoder(Range) if (isInputRange!Range && (is(ElementType!Range : const(char)[]) ||
                                                     is(ElementType!Range : const(ubyte)[])))
    {
      private:
        Range   range_;
        ubyte[] buffer_, decoded_;


      public:
        this(Range range)
        {
            range_ = range;
            doDecoding();
        }


        /**
         * Returns:
         *  true if there are no more elements to be iterated.
         */
        @property @trusted
        bool empty()
        {
            return range_.empty;
        }


        /**
         * Returns: The decoding of the current element in the input.
         */
        @property @safe
        nothrow ubyte[] front()
        {
            return decoded_;
        }


        /**
         * Advance to the next element in the input to be decoded.
         *
         * Throws:
         *  $(D Base64Exception) if invoked when $(LREF2 .Base64Impl.Decoder.empty,
         *  empty) returns $(D true).
         */
        void popFront()
        {
            enforce(!empty, new Base64Exception("Cannot call popFront on Decoder with no data remaining."));

            range_.popFront();

            /*
             * I mentioned Encoder's popFront.
             */
            if (!empty)
                doDecoding();
        }


        static if (isForwardRange!Range)
        {
            /**
             * Saves the current iteration state.
             *
             * This method is only available if the underlying range is a
             * $(LINK2 std_range_primitives.html#isForwardRange, forward
             * range).
             *
             * Returns: A copy of $(D this).
             */
            @property
            typeof(this) save()
            {
                typeof(return) decoder;

                decoder.range_   = range_.save;
                decoder.buffer_  = buffer_.dup;
                decoder.decoded_ = decoder.buffer_[0 .. decoded_.length];

                return decoder;
            }
        }


      private:
        void doDecoding()
        {
            auto data = cast(const(char)[])range_.front;

            static if (Padding == NoPadding)
            {
                while (data.length % 4 == 1)
                {
                    range_.popFront();
                    data ~= cast(const(char)[])range_.front;
                }
            }
            else
            {
                while (data.length % 4 != 0)
                {
                    range_.popFront();
                    data ~= cast(const(char)[])range_.front;
                }
            }

            auto size = decodeLength(data.length);
            if (size > buffer_.length)
                buffer_.length = size;

            decoded_ = decode(data, buffer_);
        }
    }


    /**
     * An $(LINK2 std_range_primitives.html#isInputRange, input range) that
     * iterates over the bytes of data decoded from a Base64 encoded string.
     *
     * This range will be a $(LINK2 std_range_primitives.html#isForwardRange,
     * forward range) if the underlying data source is at least a forward
     * range.
     *
     * Note: This struct is not intended to be created in user code directly;
     * use the $(LREF decoder) function instead.
     */
    struct Decoder(Range) if (isInputRange!Range && is(ElementType!Range : char))
    {
      private:
        Range range_;
        ubyte first;
        int   pos;


      public:
        this(Range range)
        {
            range_ = range;
            static if (isForwardRange!Range)
                range_ = range_.save;

            static if (Padding != NoPadding && hasLength!Range)
                enforce(range_.length % 4 == 0, new Base64Exception("Invalid length of encoded data"));

            if (range_.empty)
                pos = -1;
            else
                popFront();
        }


        /**
         * Returns:
         *  true if there are no more elements to be iterated.
         */
        @property @safe
        nothrow bool empty() const
        {
            return pos < 0;
        }


        /**
         * Returns: The current decoded byte.
         */
        @property @safe
        nothrow ubyte front()
        {
            return first;
        }


        /**
         * Advance to the next decoded byte.
         *
         * Throws:
         *  $(D Base64Exception) if invoked when $(LREF2 .Base64Impl.Decoder.empty,
         *  empty) returns $(D true).
         */
        void popFront()
        {
            enforce(!empty, new Base64Exception("Cannot call popFront on Decoder with no data remaining"));

            static if (Padding == NoPadding)
            {
                bool endCondition()
                {
                    return range_.empty;
                }
            }
            else
            {
                bool endCondition()
                {
                    enforce(!range_.empty, new Base64Exception("Missing padding"));
                    return range_.front == Padding;
                }
            }

            if (range_.empty || range_.front == Padding)
            {
                pos = -1;
                return;
            }

            final switch (pos)
            {
            case 0:
                enforce(!endCondition(), new Base64Exception("Premature end of data found"));

                immutable t = DecodeMap[range_.front] << 2;
                range_.popFront();

                enforce(!endCondition(), new Base64Exception("Premature end of data found"));
                first = cast(ubyte)(t | (DecodeMap[range_.front] >> 4));
                break;
            case 1:
                immutable t = (DecodeMap[range_.front] & 0b1111) << 4;
                range_.popFront();

                if (endCondition())
                {
                    pos = -1;
                    return;
                }
                else
                {
                    first = cast(ubyte)(t | (DecodeMap[range_.front] >> 2));
                }
                break;
            case 2:
                immutable t = (DecodeMap[range_.front] & 0b11) << 6;
                range_.popFront();

                if (endCondition())
                {
                    pos = -1;
                    return;
                }
                else
                {
                    first = cast(ubyte)(t | DecodeMap[range_.front]);
                }

                range_.popFront();
                break;
            }

            ++pos %= 3;
        }


        static if (isForwardRange!Range)
        {
            /**
             * Saves the current iteration state.
             *
             * This method is only available if the underlying range is a
             * $(LINK2 std_range_primitives.html#isForwardRange, forward
             * range).
             *
             * Returns: A copy of $(D this).
             */
            @property
            typeof(this) save()
            {
                auto decoder = this;
                decoder.range_ = decoder.range_.save;
                return decoder;
            }
        }
    }


    /**
     * Construct a $(D Decoder) that iterates over the decoding of the given
     * Base64 encoded data.
     *
     * Params:
     *  range = An $(LINK2 std_range_primitives.html#isInputRange, input
     *      range) over the data to be decoded.
     *
     * Returns:
     *  If $(D_PARAM range) is a range of characters, a $(D Decoder) that
     *  iterates over the bytes of the corresponding Base64 decoding.
     *
     *  If $(D_PARAM range) is a range of ranges of characters, a $(D Decoder)
     *  that iterates over the decoded strings corresponding to each element of
     *  the range. In this case, the length of each subrange must be a multiple
     *  of 4; the returned _decoder does not keep track of Base64 decoding
     *  state across subrange boundaries.
     *
     *  In both cases, the returned $(D Decoder) will be a
     *  $(LINK2 std_range_primitives.html#isForwardRange, forward range) if the
     *  given $(D range) is at least a forward range, otherwise it will be only
     *  an input range.
     *
     * If the input data contains characters not found in the base alphabet of
     * the current Base64 encoding scheme, the returned range may throw a
     * $(D Base64Exception).
     *
     * Example:
     * This example shows decoding over a range of input data lines.
     * -----
     * foreach (decoded; Base64.decoder(stdin.byLine()))
     * {
     *     writeln(decoded);
     * }
     * -----
     *
     * Example:
     * This example shows decoding one byte at a time.
     * -----
     * auto encoded = Base64.encoder(cast(ubyte[])"0123456789");
     * foreach (n; map!q{a - '0'}(Base64.decoder(encoded)))
     * {
     *     writeln(n);
     * }
     * -----
     */
    Decoder!(Range) decoder(Range)(Range range) if (isInputRange!Range)
    {
        return typeof(return)(range);
    }


  private:
    @safe
    pure int decodeChar()(char chr)
    {
        immutable val = DecodeMap[chr];

        // enforce can't be a pure function, so I use trivial check.
        if (val == 0 && chr != 'A')
            throw new Base64Exception("Invalid character: " ~ chr);

        return val;
    }


    @safe
    pure int decodeChar()(dchar chr)
    {
        // See above comment.
        if (chr > 0x7f)
            throw new Base64Exception("Base64-encoded character must be a single byte");

        return decodeChar(cast(char) chr);
    }
}

///
@safe unittest
{
    import std.string : representation;

    // pre-defined: alias Base64 = Base64Impl!('+', '/');
    ubyte[] emptyArr;
    assert(Base64.encode(emptyArr) == "");
    assert(Base64.encode("f".representation) == "Zg==");
    assert(Base64.encode("foo".representation) == "Zm9v");

    alias Base64Re = Base64Impl!('!', '=', Base64.NoPadding);
    assert(Base64Re.encode("f".representation) == "Zg");
    assert(Base64Re.encode("foo".representation) == "Zm9v");
}

/**
 * Exception thrown upon encountering Base64 encoding or decoding errors.
 */
class Base64Exception : Exception
{
    @safe pure nothrow
    this(string s, string fn = __FILE__, size_t ln = __LINE__)
    {
        super(s, fn, ln);
    }
}

///
@system unittest
{
    import std.exception : assertThrown;
    assertThrown!Base64Exception(Base64.decode("ab|c"));
}


@system unittest
{
    import std.algorithm.comparison : equal;
    import std.algorithm.sorting : sort;
    import std.conv;
    import std.file;
    import std.stdio;

    alias Base64Re = Base64Impl!('!', '=', Base64.NoPadding);

    // Test vectors from RFC 4648
    ubyte[][string] tv = [
         ""      :cast(ubyte[])"",
         "f"     :cast(ubyte[])"f",
         "fo"    :cast(ubyte[])"fo",
         "foo"   :cast(ubyte[])"foo",
         "foob"  :cast(ubyte[])"foob",
         "fooba" :cast(ubyte[])"fooba",
         "foobar":cast(ubyte[])"foobar"
    ];

    { // Base64
        // encode
        assert(Base64.encodeLength(tv[""].length)       == 0);
        assert(Base64.encodeLength(tv["f"].length)      == 4);
        assert(Base64.encodeLength(tv["fo"].length)     == 4);
        assert(Base64.encodeLength(tv["foo"].length)    == 4);
        assert(Base64.encodeLength(tv["foob"].length)   == 8);
        assert(Base64.encodeLength(tv["fooba"].length)  == 8);
        assert(Base64.encodeLength(tv["foobar"].length) == 8);

        assert(Base64.encode(tv[""])       == "");
        assert(Base64.encode(tv["f"])      == "Zg==");
        assert(Base64.encode(tv["fo"])     == "Zm8=");
        assert(Base64.encode(tv["foo"])    == "Zm9v");
        assert(Base64.encode(tv["foob"])   == "Zm9vYg==");
        assert(Base64.encode(tv["fooba"])  == "Zm9vYmE=");
        assert(Base64.encode(tv["foobar"]) == "Zm9vYmFy");

        // decode
        assert(Base64.decodeLength(Base64.encode(tv[""]).length)       == 0);
        assert(Base64.decodeLength(Base64.encode(tv["f"]).length)      == 3);
        assert(Base64.decodeLength(Base64.encode(tv["fo"]).length)     == 3);
        assert(Base64.decodeLength(Base64.encode(tv["foo"]).length)    == 3);
        assert(Base64.decodeLength(Base64.encode(tv["foob"]).length)   == 6);
        assert(Base64.decodeLength(Base64.encode(tv["fooba"]).length)  == 6);
        assert(Base64.decodeLength(Base64.encode(tv["foobar"]).length) == 6);

        assert(Base64.decode(Base64.encode(tv[""]))       == tv[""]);
        assert(Base64.decode(Base64.encode(tv["f"]))      == tv["f"]);
        assert(Base64.decode(Base64.encode(tv["fo"]))     == tv["fo"]);
        assert(Base64.decode(Base64.encode(tv["foo"]))    == tv["foo"]);
        assert(Base64.decode(Base64.encode(tv["foob"]))   == tv["foob"]);
        assert(Base64.decode(Base64.encode(tv["fooba"]))  == tv["fooba"]);
        assert(Base64.decode(Base64.encode(tv["foobar"])) == tv["foobar"]);

        assertThrown!Base64Exception(Base64.decode("ab|c"));

        // Test decoding incomplete strings. RFC does not specify the correct
        // behavior, but the code should never throw Errors on invalid input.

        // decodeLength is nothrow
        assert(Base64.decodeLength(1) == 0);
        assert(Base64.decodeLength(2) <= 1);
        assert(Base64.decodeLength(3) <= 2);

        // may throw Exceptions, may not throw Errors
        assertThrown!Base64Exception(Base64.decode("Zg"));
        assertThrown!Base64Exception(Base64.decode("Zg="));
        assertThrown!Base64Exception(Base64.decode("Zm8"));
        assertThrown!Base64Exception(Base64.decode("Zg==;"));
    }

    { // No padding
        // encode
        assert(Base64Re.encodeLength(tv[""].length)       == 0);
        assert(Base64Re.encodeLength(tv["f"].length)      == 2);
        assert(Base64Re.encodeLength(tv["fo"].length)     == 3);
        assert(Base64Re.encodeLength(tv["foo"].length)    == 4);
        assert(Base64Re.encodeLength(tv["foob"].length)   == 6);
        assert(Base64Re.encodeLength(tv["fooba"].length)  == 7);
        assert(Base64Re.encodeLength(tv["foobar"].length) == 8);

        assert(Base64Re.encode(tv[""])       == "");
        assert(Base64Re.encode(tv["f"])      == "Zg");
        assert(Base64Re.encode(tv["fo"])     == "Zm8");
        assert(Base64Re.encode(tv["foo"])    == "Zm9v");
        assert(Base64Re.encode(tv["foob"])   == "Zm9vYg");
        assert(Base64Re.encode(tv["fooba"])  == "Zm9vYmE");
        assert(Base64Re.encode(tv["foobar"]) == "Zm9vYmFy");

        // decode
        assert(Base64Re.decodeLength(Base64Re.encode(tv[""]).length)       == 0);
        assert(Base64Re.decodeLength(Base64Re.encode(tv["f"]).length)      == 1);
        assert(Base64Re.decodeLength(Base64Re.encode(tv["fo"]).length)     == 2);
        assert(Base64Re.decodeLength(Base64Re.encode(tv["foo"]).length)    == 3);
        assert(Base64Re.decodeLength(Base64Re.encode(tv["foob"]).length)   == 4);
        assert(Base64Re.decodeLength(Base64Re.encode(tv["fooba"]).length)  == 5);
        assert(Base64Re.decodeLength(Base64Re.encode(tv["foobar"]).length) == 6);

        assert(Base64Re.decode(Base64Re.encode(tv[""]))       == tv[""]);
        assert(Base64Re.decode(Base64Re.encode(tv["f"]))      == tv["f"]);
        assert(Base64Re.decode(Base64Re.encode(tv["fo"]))     == tv["fo"]);
        assert(Base64Re.decode(Base64Re.encode(tv["foo"]))    == tv["foo"]);
        assert(Base64Re.decode(Base64Re.encode(tv["foob"]))   == tv["foob"]);
        assert(Base64Re.decode(Base64Re.encode(tv["fooba"]))  == tv["fooba"]);
        assert(Base64Re.decode(Base64Re.encode(tv["foobar"])) == tv["foobar"]);

        // decodeLength is nothrow
        assert(Base64.decodeLength(1) == 0);
    }

    { // with OutputRange
        import std.array;

        auto a = Appender!(char[])([]);
        auto b = Appender!(ubyte[])([]);

        assert(Base64.encode(tv[""], a) == 0);
        assert(Base64.decode(a.data, b) == 0);
        assert(tv[""] == b.data); a.clear(); b.clear();

        assert(Base64.encode(tv["f"], a) == 4);
        assert(Base64.decode(a.data,  b) == 1);
        assert(tv["f"] == b.data); a.clear(); b.clear();

        assert(Base64.encode(tv["fo"], a) == 4);
        assert(Base64.decode(a.data,   b) == 2);
        assert(tv["fo"] == b.data); a.clear(); b.clear();

        assert(Base64.encode(tv["foo"], a) == 4);
        assert(Base64.decode(a.data,    b) == 3);
        assert(tv["foo"] == b.data); a.clear(); b.clear();

        assert(Base64.encode(tv["foob"], a) == 8);
        assert(Base64.decode(a.data,     b) == 4);
        assert(tv["foob"] == b.data); a.clear(); b.clear();

        assert(Base64.encode(tv["fooba"], a) == 8);
        assert(Base64.decode(a.data, b)      == 5);
        assert(tv["fooba"] == b.data); a.clear(); b.clear();

        assert(Base64.encode(tv["foobar"], a) == 8);
        assert(Base64.decode(a.data, b)       == 6);
        assert(tv["foobar"] == b.data); a.clear(); b.clear();
    }

    // @@@9543@@@ These tests were disabled because they actually relied on the input range having length.
    // The implementation (currently) doesn't support encoding/decoding from a length-less source.
    version (none)
    { // with InputRange
        // InputRange to ubyte[] or char[]
        auto encoded = Base64.encode(map!(to!(ubyte))(["20", "251", "156", "3", "217", "126"]));
        assert(encoded == "FPucA9l+");
        assert(Base64.decode(map!q{a}(encoded)) == [0x14, 0xfb, 0x9c, 0x03, 0xd9, 0x7e]);

        // InputRange to OutputRange
        auto a = Appender!(char[])([]);
        auto b = Appender!(ubyte[])([]);
        assert(Base64.encode(map!(to!(ubyte))(["20", "251", "156", "3", "217", "126"]), a) == 8);
        assert(a.data == "FPucA9l+");
        assert(Base64.decode(map!q{a}(a.data), b) == 6);
        assert(b.data == [0x14, 0xfb, 0x9c, 0x03, 0xd9, 0x7e]);
    }

    { // Encoder and Decoder
        {
            string encode_file = std.file.deleteme ~ "-testingEncoder";
            std.file.write(encode_file, "\nf\nfo\nfoo\nfoob\nfooba\nfoobar");

            auto witness = ["", "Zg==", "Zm8=", "Zm9v", "Zm9vYg==", "Zm9vYmE=", "Zm9vYmFy"];
            auto f = File(encode_file);
            scope(exit)
            {
                f.close();
                assert(!f.isOpen);
                std.file.remove(encode_file);
            }

            size_t i;
            foreach (encoded; Base64.encoder(f.byLine()))
                assert(encoded == witness[i++]);

            assert(i == witness.length);
        }

        {
            string decode_file = std.file.deleteme ~ "-testingDecoder";
            std.file.write(decode_file, "\nZg==\nZm8=\nZm9v\nZm9vYg==\nZm9vYmE=\nZm9vYmFy");

            auto witness = sort(tv.keys);
            auto f = File(decode_file);
            scope(exit)
            {
                f.close();
                assert(!f.isOpen);
                std.file.remove(decode_file);
            }

            size_t i;
            foreach (decoded; Base64.decoder(f.byLine()))
                assert(decoded == witness[i++]);

            assert(i == witness.length);
        }

        { // ForwardRange
            {
                auto encoder = Base64.encoder(sort(tv.values));
                auto witness = ["", "Zg==", "Zm8=", "Zm9v", "Zm9vYg==", "Zm9vYmE=", "Zm9vYmFy"];
                size_t i;

                assert(encoder.front == witness[i++]); encoder.popFront();
                assert(encoder.front == witness[i++]); encoder.popFront();
                assert(encoder.front == witness[i++]); encoder.popFront();

                foreach (encoded; encoder.save)
                    assert(encoded == witness[i++]);
            }

            {
                auto decoder = Base64.decoder(["", "Zg==", "Zm8=", "Zm9v", "Zm9vYg==", "Zm9vYmE=", "Zm9vYmFy"]);
                auto witness = sort(tv.values);
                size_t i;

                assert(decoder.front == witness[i++]); decoder.popFront();
                assert(decoder.front == witness[i++]); decoder.popFront();
                assert(decoder.front == witness[i++]); decoder.popFront();

                foreach (decoded; decoder.save)
                    assert(decoded == witness[i++]);
            }
        }
    }

    { // Encoder and Decoder for single character encoding and decoding
        alias Base64NoPadding = Base64Impl!('+', '/', Base64.NoPadding);

        auto tests = [
            ""       : ["", "", "", ""],
            "f"      : ["Zg==", "Zg==", "Zg", "Zg"],
            "fo"     : ["Zm8=", "Zm8=", "Zm8", "Zm8"],
            "foo"    : ["Zm9v", "Zm9v", "Zm9v", "Zm9v"],
            "foob"   : ["Zm9vYg==", "Zm9vYg==", "Zm9vYg", "Zm9vYg"],
            "fooba"  : ["Zm9vYmE=", "Zm9vYmE=", "Zm9vYmE", "Zm9vYmE"],
            "foobar" : ["Zm9vYmFy", "Zm9vYmFy", "Zm9vYmFy", "Zm9vYmFy"],
        ];

        foreach (u, e; tests)
        {
            assert(equal(Base64.encoder(cast(ubyte[]) u), e[0]));
            assert(equal(Base64.decoder(Base64.encoder(cast(ubyte[]) u)), u));

            assert(equal(Base64URL.encoder(cast(ubyte[]) u), e[1]));
            assert(equal(Base64URL.decoder(Base64URL.encoder(cast(ubyte[]) u)), u));

            assert(equal(Base64NoPadding.encoder(cast(ubyte[]) u), e[2]));
            assert(equal(Base64NoPadding.decoder(Base64NoPadding.encoder(cast(ubyte[]) u)), u));

            assert(equal(Base64Re.encoder(cast(ubyte[]) u), e[3]));
            assert(equal(Base64Re.decoder(Base64Re.encoder(cast(ubyte[]) u)), u));
        }
    }
}

// Regression control for the output range ref bug in encode.
@system unittest
{
    struct InputRange
    {
        ubyte[] impl = [0x1a, 0x2b, 0x3c, 0x4d, 0x5d, 0x6e];
        @property bool empty() { return impl.length == 0; }
        @property ubyte front() { return impl[0]; }
        void popFront() { impl = impl[1 .. $]; }
        @property size_t length() { return impl.length; }
    }

    struct OutputRange
    {
        char[] result;
        void put(char b) { result ~= b; }
    }

    InputRange ir;
    OutputRange or;
    assert(Base64.encode(ir, or) == 8);
    assert(or.result == "Gis8TV1u");

    // Verify that any existing workaround that uses & still works.
    InputRange ir2;
    OutputRange or2;
    assert(Base64.encode(ir2, &or2) == 8);
    assert(or2.result == "Gis8TV1u");
}

// Regression control for the output range ref bug in decode.
@system unittest
{
    struct InputRange
    {
        const(char)[] impl = "Gis8TV1u";
        @property bool empty() { return impl.length == 0; }
        @property dchar front() { return impl[0]; }
        void popFront() { impl = impl[1 .. $]; }
        @property size_t length() { return impl.length; }
    }

    struct OutputRange
    {
        ubyte[] result;
        void put(ubyte b) { result ~= b; }
    }

    InputRange ir;
    OutputRange or;
    assert(Base64.decode(ir, or) == 6);
    assert(or.result == [0x1a, 0x2b, 0x3c, 0x4d, 0x5d, 0x6e]);

    // Verify that any existing workaround that uses & still works.
    InputRange ir2;
    OutputRange or2;
    assert(Base64.decode(ir2, &or2) == 6);
    assert(or2.result == [0x1a, 0x2b, 0x3c, 0x4d, 0x5d, 0x6e]);
}
