From: Brendan Hansen Date: Mon, 31 Oct 2022 19:39:23 +0000 (-0500) Subject: added base64 to core library X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=f44aa66f8c232ff6aab495758b1411254b9c7a1c;p=onyx.git added base64 to core library --- diff --git a/core/container/array.onyx b/core/container/array.onyx index 3d5f3169..3bbd3b00 100644 --- a/core/container/array.onyx +++ b/core/container/array.onyx @@ -305,6 +305,8 @@ contains :: #match #locked { } } +empty :: (arr: [] $T) => arr.count == 0; + // Uses '+' to sum. sum :: (arr: [] $T, start: T = 0) -> T { sum := start; diff --git a/core/encoding/base64.onyx b/core/encoding/base64.onyx new file mode 100644 index 00000000..d4c9454b --- /dev/null +++ b/core/encoding/base64.onyx @@ -0,0 +1,89 @@ +package core.encoding.base64 + +encode :: (data: [] u8, allocator := context.allocator) -> [] u8 { + out := make([..] u8, allocator=allocator); + + for i: range.{0, data.count - 2, 3} { + c1 := data[i + 0]; + c2 := data[i + 1]; + c3 := data[i + 2]; + + out << encode_map[c1 >> 2]; + out << encode_map[((c1 & 0x3) << 4) | ((c2 & 0xf0) >> 4)]; + out << encode_map[((c2 & 0xf) << 2) | ((c3 & 0xc0) >> 6)]; + out << encode_map[c3 & 0x3f]; + } + + if data.count % 3 == 1 { + c := data[data.count - 1]; + out << encode_map[c >> 2]; + out << encode_map[(c & 0x3) << 4]; + out << #char "="; + out << #char "="; + + } elseif data.count % 3 == 2 { + c1 := data[data.count - 2]; + c2 := data[data.count - 1]; + out << encode_map[c1 >> 2]; + out << encode_map[((c1 & 0x3) << 4) | ((c2 & 0xf0) >> 4)]; + out << encode_map[(c2 & 0xf) << 2]; + out << #char "="; + } + + return out; +} + +decode :: (data: [] u8, allocator := context.allocator) -> [] u8 { + if data.count % 4 != 0 do return null_str; + + out := make([..] u8, allocator=allocator); + + for i: range.{0, data.count, 4} { + c1 := data[i + 0]; + c2 := data[i + 1]; + c3 := data[i + 2]; + c4 := data[i + 3]; + + v1 := decode_map[c1 - #char "+"]; + v2 := decode_map[c2 - #char "+"]; + v3 := decode_map[c3 - #char "+"]; + v4 := decode_map[c4 - #char "+"]; + + o1 := (v1 << 2) | ((v2 & 0x30) >> 4); + o2 := ((v2 & 0xf) << 4) | ((v3 & 0x3c) >> 2); + o3 := ((v3 & 0x3) << 6) | (v4 & 0x3f); + + out << o1; + if c3 != #char "=" do out << o2; + if c4 != #char "=" do out << o3; + } + + return out; +} + + +#local +encode_map := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +// Use as: +// decode_map[ch - #char "+"]; +#local +decode_map := u8.[ + 62, // + + 0, 0, 0, // , - . Invalid + 63, // / + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // 0-9 + 0, 0, 0, 0, 0, 0, 0, // : ; < = > ? @ Invalid + + // A-Z + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, + + 0, 0, 0, 0, 0, 0, // [ \ ] ^ _ ` + + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 49, 50, 51, +]; + diff --git a/core/std.onyx b/core/std.onyx index c13c94f7..76e445ca 100644 --- a/core/std.onyx +++ b/core/std.onyx @@ -41,8 +41,6 @@ package core #load "./misc/any_utils" -#load "./encoding/csv" - #local runtime :: package runtime #if runtime.runtime == .Wasi || runtime.runtime == .Onyx { #load "./os/file" @@ -75,6 +73,9 @@ package core #if runtime.runtime != .Custom { #load "./runtime/info/helper" #load "./stdio" + + #load "./encoding/base64" + #load "./encoding/csv" } #if runtime.Multi_Threading_Enabled { diff --git a/core/time/date.onyx b/core/time/date.onyx index 72c9cdfe..0323e827 100644 --- a/core/time/date.onyx +++ b/core/time/date.onyx @@ -14,6 +14,10 @@ Date :: struct { #inject Date { month_durations := u32.[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + make :: (year, month, day: i32) -> Date { + return .{ year, month - 1, day - 1 }; + } + add_months :: (d: Date, days: i32) -> Date { nd := d; @@ -51,13 +55,13 @@ Date :: struct { } before :: (d1, d2: Date) -> bool { - if d1.year != d2.year do return d1.year < d2.year; + if d1.year != d2.year do return d1.year < d2.year; if d1.month != d2.month do return d1.month < d2.month; return d1.day < d2.day; } after :: (d1, d2: Date) -> bool { - if d1.year != d2.year do return d1.year > d2.year; + if d1.year != d2.year do return d1.year > d2.year; if d1.month != d2.month do return d1.month > d2.month; return d1.day > d2.day; } diff --git a/tests/stdlib/base64 b/tests/stdlib/base64 new file mode 100644 index 00000000..f5577a39 --- /dev/null +++ b/tests/stdlib/base64 @@ -0,0 +1,11 @@ +Many hands make light work. +light w +light wo +light wor + + +TWFueSBoYW5kcyBtYWtlIGxpZ2h0IHdvcmsu +bGlnaHQgdw== +bGlnaHQgd28= +bGlnaHQgd29y +bGlnaHQgd29yaw== diff --git a/tests/stdlib/base64.onyx b/tests/stdlib/base64.onyx new file mode 100644 index 00000000..db7645cb --- /dev/null +++ b/tests/stdlib/base64.onyx @@ -0,0 +1,32 @@ +use core.encoding + +decode_test :: () { + for .[ + "TWFueSBoYW5kcyBtYWtlIGxpZ2h0IHdvcmsu", + "bGlnaHQgdw==", + "bGlnaHQgd28=", + "bGlnaHQgd29y", + ] { + core.println(base64.decode(it)); + } +} + +encode_test :: () { + for .[ + "Many hands make light work.", + "light w", + "light wo", + "light wor", + "light work", + ] { + encoded := base64.encode(it); + core.println(encoded); + } +} + +main :: () { + decode_test(); + core.println("\n"); + encode_test(); +} +