Skip to content

Commit

Permalink
Updated base64 encoding api.
Browse files Browse the repository at this point in the history
  • Loading branch information
lerno committed Nov 23, 2024
1 parent a58d782 commit 6010183
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 7 deletions.
82 changes: 81 additions & 1 deletion lib/std/encoding/base64.c3
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,73 @@ import std::core::bitorder;
const STD_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const URL_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";

fn String! encode_buffer(char[] code, char[] buffer)
{
@check_coder(std_encoder);
return (String)buffer[:std_encoder.encode(code, buffer)!];
}

fn char[]! decode_buffer(char[] code, char[] buffer)
{
@check_coder(std_decoder);
return buffer[:std_decoder.decode(code, buffer)!];
}

fn String encode(char[] code, Allocator allocator)
{
@check_coder(std_encoder);
char[] data = allocator::alloc_array(allocator, char, std_encoder.encode_len(code.len));
std_encoder.encode(code, data)!!;
return (String)data;
}

fn char[]! decode(char[] code, Allocator allocator)
{
@check_coder(std_decoder);
char[] data = allocator::alloc_array(allocator, char, std_decoder.decode_len(code.len))!;
std_decoder.decode(code, data)!;
return data;
}

fn String encode_new(char[] code) @inline => encode(code, allocator::heap());
fn String encode_temp(char[] code) @inline => encode(code, allocator::temp());
fn char[]! decode_new(char[] code) @inline => decode(code, allocator::heap());
fn char[]! decode_temp(char[] code) @inline => decode(code, allocator::temp());

fn String urlencode(char[] code, Allocator allocator)
{
@check_coder(url_encoder);
char[] data = allocator::alloc_array(allocator, char, url_encoder.encode_len(code.len));
url_encoder.encode(code, data)!!;
return (String)data;
}

fn char[]! urldecode(char[] code, Allocator allocator)
{
@check_coder(url_decoder);
char[] data = allocator::alloc_array(allocator, char, url_decoder.decode_len(code.len))!;
url_decoder.decode(code, data)!;
return data;
}

fn String! urlencode_buffer(char[] code, char[] buffer)
{
@check_coder(url_encoder);
return (String)buffer[:std_encoder.encode(code, buffer)!];
}

fn char[]! urldecode_buffer(char[] code, char[] buffer)
{
@check_coder(url_decoder);
return buffer[:url_decoder.decode(code, buffer)!];
}

fn String! urlencode_new(char[] code) @inline => urlencode(code, allocator::heap());
fn String! urlencode_temp(char[] code) @inline => urlencode(code, allocator::temp());
fn char[]! urldecode_new(char[] code) @inline => decode(code, allocator::heap());
fn char[]! urldecode_temp(char[] code) @inline => decode(code, allocator::temp());


const MASK @private = 0b111111;

struct Base64Encoder
Expand All @@ -32,10 +99,11 @@ fault Base64Error
@require padding < 256
@return! Base64Error.DUPLICATE_IN_ALPHABET, Base64Error.PADDING_IN_ALPHABET
*>
fn void! Base64Encoder.init(&self, String alphabet, int padding = '=')
fn Base64Encoder*! Base64Encoder.init(&self, String alphabet, int padding = '=')
{
check_alphabet(alphabet, padding)!;
*self = { .padding = padding, .alphabet = alphabet };
return self;
}

<*
Expand Down Expand Up @@ -272,3 +340,15 @@ fn void! check_alphabet(String alphabet, int padding) @local
checked[c] = true;
}
}

tlocal Base64Encoder std_encoder @local;
tlocal Base64Encoder url_encoder @local;
tlocal Base64Decoder std_decoder @local;
tlocal Base64Decoder url_decoder @local;


macro @check_coder(#coder) @local
{
if (#coder.alphabet) return;
#coder.init(STD_ALPHABET, '=')!!;
}
16 changes: 10 additions & 6 deletions test/unit/stdlib/encoding/base64.c3
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,16 @@ fn void encode()
};
foreach (tc : tcases)
{
Base64Encoder b;
b.init(base64::STD_ALPHABET)!;
usz n = b.encode_len(tc.in.len);
char[64] buf;
b.encode(tc.in, buf[:n])!;
assert(buf[:n] == tc.out);
@pool()
{
Base64Encoder b;
b.init(base64::STD_ALPHABET)!;
usz n = b.encode_len(tc.in.len);
char[64] buf;
b.encode(tc.in, buf[:n])!;
assert(buf[:n] == tc.out);
assert(base64::encode_temp(tc.in) == tc.out);
};
}
}

Expand Down

0 comments on commit 6010183

Please sign in to comment.