The D Programming Language

Encoding / Decoding Base64 format.

Implemented according to RFC 4648 - The Base16.

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]);


Support Range interface using Encoder / Decoder.
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);
License
Boost License 1.0.
Authors
Masahiro Nakagawa, Daniel Murphy (Single value Encoder and Decoder)
Source:
std/base64.d

alias  Base64 = Base64Impl!('+', '/');

The  Base64


alias  Base64URL = Base64Impl!('-', '_');

The "URL and Filename safe" Base64


template  Base64Impl(char Map62th, char Map63th, char Padding = '=')

Core implementation for Base64 format.

Example:
alias Base64Impl!('+', '/')                   Base64;    // The Base64 format(Already defined).

alias Base64Impl!('!', '=', Base64.NoPadding) Base64Re;  // non-standard Base64 format for Regular expression

NOTE:
encoded-string doesn't have padding character if set Padding parameter to NoPadding.

size_t  encodeLength(in size_t sourceLength);

Calculates the minimum length for encoding.

Parameters
size_t sourceLength the length of source array.
Returns
the calculated length using sourceLength.

char[]  encode(R1, R2)(in R1 source, R2 buffer) if (isArray!R1 && is(ElementType!R1 : ubyte) && is(R2 == char[]));
char[]  encode(R1, R2)(R1 source, R2 buffer) if (!isArray!R1 && isInputRange!R1 && is(ElementType!R1 : ubyte) && hasLength!R1 && is(R2 == char[]));

Encodes source into buffer.

Parameters
R1 source an InputRange to  encode.
R2 buffer a buffer to store encoded result.
Returns
the encoded string that slices buffer.

size_t  encode(R1, R2)(in R1 source, R2 range) if (isArray!R1 && is(ElementType!R1 : ubyte) && !is(R2 == char[]));
size_t  encode(R1, R2)(R1 source, R2 range) if (!isArray!R1 && isInputRange!R1 && is(ElementType!R1 : ubyte) && hasLength!R1 && !is(R2 == char[]) && isOutputRange!(R2, char));

Encodes source into range.

Parameters
R1 source an InputRange to  encode.
R2 range an OutputRange to put encoded result.
Returns
the number of calling put.

char[]  encode(Range)(Range source) if (isArray!Range && is(ElementType!Range : ubyte));
char[]  encode(Range)(Range source) if (!isArray!Range && isInputRange!Range && is(ElementType!Range : ubyte) && hasLength!Range);

Encodes source to new buffer.

Shortcut to  encode(source, buffer) function.


struct  Encoder(Range) if (isInputRange!Range && (is(ElementType!Range : const(ubyte)[]) || is(ElementType!Range : const(char)[])));

Range that encodes chunk data at a time.


bool  empty();

Range primitive operation that checks iteration state.

Returns
true if there are no more elements to be iterated.

char[]  front();

Range primitive operation that returns the currently iterated element.

Returns
the encoded string.

void  popFront();

Range primitive operation that advances the range to its next element.

Throws
an Exception when you try to call  popFront on empty range.

typeof(this)  save();

Captures a Range state.

Returns
a copy of this.

struct  Encoder(Range) if (isInputRange!Range && is(ElementType!Range : ubyte));

Range that encodes single character at a time.


const bool  empty();

Range primitive operation that checks iteration state.

Returns
true if there are no more elements to be iterated.

ubyte  front();

Range primitive operation that returns the currently iterated element.

Returns
the encoded character.

void  popFront();

Range primitive operation that advances the range to its next element.

Throws
an Exception when you try to call  popFront on empty range.

typeof(this)  save();

Captures a Range state.

Returns
a copy of this.

Encoder!Range  encoder(Range)(Range range) if (isInputRange!Range);

Iterates through an InputRange at a time by using Encoder.

Default Encoder encodes chunk data.

Example:
File f = File("text.txt", "r");
scope(exit) f.close();

uint line = 0;
foreach (encoded; Base64.encoder(f.byLine()))
{
    writeln(++line, ". ", encoded);
}


In addition, You can use Encoder that returns encoded single character. This Encoder performs Range-based and lazy encoding.
Example:
ubyte[] data = cast(ubyte[]) "0123456789";

// The ElementType of data is not aggregation type

foreach (encoded; Base64.encoder(data))
{
    writeln(encoded);
}
Parameters
Range range an InputRange to iterate.
Returns
a Encoder object instantiated and initialized according to the arguments.

size_t  decodeLength(in size_t sourceLength);

Calculates the minimum length for decoding.

Parameters
size_t sourceLength the length of source array.
Returns
calculated length using sourceLength.

ubyte[]  decode(R1, R2)(in R1 source, R2 buffer) if (isArray!R1 && is(ElementType!R1 : dchar) && is(R2 == ubyte[]) && isOutputRange!(R2, ubyte));
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));

Decodes source into buffer.

Parameters
R1 source an InputRange to  decode.
R2 buffer a buffer to store decoded result.
Returns
the decoded string that slices buffer.
Throws
an Exception if source has character outside base-alphabet.

size_t  decode(R1, R2)(in R1 source, R2 range) if (isArray!R1 && is(ElementType!R1 : dchar) && !is(R2 == ubyte[]) && isOutputRange!(R2, ubyte));
size_t  decode(R1, R2)(R1 source, R2 range) if (!isArray!R1 && isInputRange!R1 && is(ElementType!R1 : dchar) && hasLength!R1 && !is(R2 == ubyte[]) && isOutputRange!(R2, ubyte));

Decodes source into range.

Parameters
R1 source an InputRange to  decode.
R2 range an OutputRange to put decoded result
Returns
the number of calling put.
Throws
an Exception if source has character outside base-alphabet.

ubyte[]  decode(Range)(Range source) if (isArray!Range && is(ElementType!Range : dchar));
ubyte[]  decode(Range)(Range source) if (!isArray!Range && isInputRange!Range && is(ElementType!Range : dchar) && hasLength!Range);

Decodes source into new buffer.

Shortcut to  decode(source, buffer) function.


struct  Decoder(Range) if (isInputRange!Range && (is(ElementType!Range : const(char)[]) || is(ElementType!Range : const(ubyte)[])));

Range that decodes chunk data at a time.


bool  empty();

Range primitive operation that checks iteration state.

Returns
true if there are no more elements to be iterated.

ubyte[]  front();

Range primitive operation that returns the currently iterated element.

Returns
the decoded result.

void  popFront();

Range primitive operation that advances the range to its next element.

Throws
an Exception when you try to call  popFront on empty range.

typeof(this)  save();

Captures a Range state.

Returns
a copy of this.

struct  Decoder(Range) if (isInputRange!Range && is(ElementType!Range : char));

Range that decodes single character at a time.


const bool  empty();

Range primitive operation that checks iteration state.

Returns
true if there are no more elements to be iterated.

ubyte  front();

Range primitive operation that returns the currently iterated element.

Returns
the decoded result.

void  popFront();

Range primitive operation that advances the range to its next element.

Throws
an Exception when you try to call  popFront on empty range.

typeof(this)  save();

Captures a Range state.

Returns
a copy of this.

Decoder!Range  decoder(Range)(Range range) if (isInputRange!Range);

Iterates through an InputRange at a time by using Decoder.

Default Decoder decodes chunk data.

Example:
foreach (decoded; Base64.decoder(stdin.byLine()))
{
    writeln(decoded);
}


In addition, You can use Decoder that returns decoded single character. This Decoder performs Range-based and lazy decoding.
Example:
auto encoded = Base64.encoder(cast(ubyte[])"0123456789");
foreach (n; map!q{a - '0'}(Base64.decoder(encoded)))
{
    writeln(n);
}
NOTE:
If you use ByChunk, chunk-size should be the multiple of 4. Decoder can't judge a encode-boundary.
Parameters
Range range an InputRange to iterate.
Returns
a Decoder object instantiated and initialized according to the arguments.

class  Base64Exception: object.Exception;

Exception thrown on Base64 errors.