Skip to content
This repository was archived by the owner on Feb 18, 2025. It is now read-only.

Commit 46f99c3

Browse files
committed
stdlib: add Base64 encoder
1 parent f0b06ef commit 46f99c3

File tree

6 files changed

+177
-1
lines changed

6 files changed

+177
-1
lines changed

core/stdlib/base64.core

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
use std.string.StringBuffer
2+
3+
let STANDARD: String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
4+
let STANDARD_URL_SAFE: String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
5+
let ORDERED: String = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
6+
7+
@pub
8+
fun encodeStandard(src: Array[UInt8]): String = encode(src, STANDARD)
9+
10+
@pub
11+
fun encodeUrlSafe(src: Array[UInt8]): String = encode(src, STANDARD_URL_SAFE)
12+
13+
@pub
14+
fun encodeOrdered(src: Array[UInt8]): String = encode(src, ORDERED)
15+
16+
fun encode(src: Array[UInt8], alphabet: String): String {
17+
let buffer = StringBuffer::new()
18+
var srcSize = src.size()
19+
let remainder = srcSize.remainder(3)
20+
srcSize = srcSize - remainder
21+
var i = 0
22+
while (i < srcSize) {
23+
let bits = src(i).toInt32().shiftLeft(16i32) | src(i+1).toInt32().shiftLeft(8i32) | src(i+2).toInt32()
24+
i = i + 3
25+
buffer.appendChar(alphabet.getByte(bits.shiftRight(18i32).asInt64() & 0b111111).toChar())
26+
buffer.appendChar(alphabet.getByte(bits.shiftRight(12i32).asInt64() & 0b111111).toChar())
27+
buffer.appendChar(alphabet.getByte(bits.shiftRight( 6i32).asInt64() & 0b111111).toChar())
28+
buffer.appendChar(alphabet.getByte(bits .asInt64() & 0b111111).toChar())
29+
}
30+
if remainder
31+
... == 2 {
32+
let bits = src(i).toInt32().shiftLeft(16i32) | src(i+1).toInt32().shiftLeft(8i32)
33+
buffer.appendChar(alphabet.getByte(bits.shiftRight(18i32).asInt64() & 0b111111).toChar())
34+
buffer.appendChar(alphabet.getByte(bits.shiftRight(12i32).asInt64() & 0b111111).toChar())
35+
buffer.appendChar(alphabet.getByte(bits.shiftRight( 6i32).asInt64() & 0b111111).toChar())
36+
}
37+
... == 1 {
38+
let bits = src(i).toInt32().shiftLeft(16i32)
39+
buffer.appendChar(alphabet.getByte(bits.shiftRight(18i32).asInt64() & 0b111111).toChar())
40+
buffer.appendChar(alphabet.getByte(bits.shiftRight(12i32).asInt64() & 0b111111).toChar())
41+
}
42+
buffer.toString()
43+
}

core/stdlib/stdlib.core

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
@pub use thread.{AtomicInt32, AtomicInt64, Condition, Mutex, Thread};
77

88
@pub mod annotations;
9+
@pub mod base64;
910
@pub mod collections;
1011
@pub mod primitives
1112
@pub mod rand

tests/base64/base64_ordered.core

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
fun main(): Unit {
2+
bytes0()
3+
bytes1()
4+
bytes2()
5+
bytes3()
6+
bytes13()
7+
bytes15()
8+
}
9+
10+
fun bytes0(): Unit {
11+
let bytes = Array[UInt8]::new()
12+
let string = std::base64::encodeOrdered(bytes)
13+
assert(string == "")
14+
}
15+
16+
fun bytes1(): Unit {
17+
let bytes = Array[UInt8]::new(0u8)
18+
let string = std::base64::encodeOrdered(bytes)
19+
assert(string == "--")
20+
}
21+
22+
fun bytes2(): Unit {
23+
let bytes = Array[UInt8]::new(0u8, 12u8)
24+
let string = std::base64::encodeOrdered(bytes)
25+
assert(string == "--k")
26+
}
27+
28+
fun bytes3(): Unit {
29+
let bytes = Array[UInt8]::new(0u8, 12u8, 23u8)
30+
let string = std::base64::encodeOrdered(bytes)
31+
assert(string == "--kM")
32+
}
33+
34+
fun bytes13(): Unit {
35+
let bytes = Array[UInt8]::new(255u8, 234u8, 23u8, 45u8, 238u8, 78u8, 89u8, 23u8, 45u8, 67u8, 78u8, 89u8, 91u8)
36+
let string = std::base64::encodeOrdered(bytes)
37+
assert(string == "zycMATtDLGRhFotOLk")
38+
}
39+
40+
fun bytes15(): Unit {
41+
let bytes = Array[UInt8]::new(0u8, 12u8, 23u8, 45u8, 67u8, 78u8, 89u8, 91u8, 12u8, 23u8, 45u8, 67u8, 78u8, 89u8, 91u8);
42+
let string = std::base64::encodeOrdered(bytes);
43+
assert(string == "--kMAJCDLKgB4mp2I__Q");
44+
}

tests/base64/base64_standard.core

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
fun main(): Unit {
2+
bytes0()
3+
bytes1()
4+
bytes2()
5+
bytes3()
6+
bytes13()
7+
bytes15()
8+
}
9+
10+
fun bytes0(): Unit {
11+
let bytes = Array[UInt8]::new()
12+
let string = std::base64::encodeStandard(bytes)
13+
assert(string == "")
14+
}
15+
16+
fun bytes1(): Unit {
17+
let bytes = Array[UInt8]::new(0u8)
18+
let string = std::base64::encodeStandard(bytes)
19+
assert(string == "AA")
20+
}
21+
22+
fun bytes2(): Unit {
23+
let bytes = Array[UInt8]::new(0u8, 12u8)
24+
let string = std::base64::encodeStandard(bytes)
25+
assert(string == "AAw")
26+
}
27+
28+
fun bytes3(): Unit {
29+
let bytes = Array[UInt8]::new(0u8, 12u8, 23u8);
30+
let string = std::base64::encodeStandard(bytes);
31+
assert(string == "AAwX");
32+
}
33+
34+
fun bytes13(): Unit {
35+
let bytes = Array[UInt8]::new(255u8, 234u8, 23u8, 45u8, 238u8, 78u8, 89u8, 23u8, 45u8, 67u8, 78u8, 89u8, 91u8);
36+
let string = std::base64::encodeStandard(bytes);
37+
assert(string == "/+oXLe5OWRctQ05ZWw");
38+
}
39+
40+
fun bytes15(): Unit {
41+
let bytes = Array[UInt8]::new(0u8, 12u8, 23u8, 45u8, 67u8, 78u8, 89u8, 91u8, 12u8, 23u8, 45u8, 67u8, 78u8, 89u8, 91u8);
42+
let string = std::base64::encodeStandard(bytes);
43+
assert(string == "AAwXLUNOWVsMFy1DTllb");
44+
}

tests/base64/base64_urlsafe.core

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
fun main(): Unit {
2+
bytes0();
3+
bytes1();
4+
bytes2();
5+
bytes3();
6+
bytes13();
7+
bytes15();
8+
}
9+
10+
fun bytes0(): Unit {
11+
let bytes = Array[UInt8]::new();
12+
let string = std::base64::encodeUrlSafe(bytes);
13+
assert(string == "");
14+
}
15+
16+
fun bytes1(): Unit {
17+
let bytes = Array[UInt8]::new(0u8)
18+
let string = std::base64::encodeUrlSafe(bytes)
19+
assert(string == "AA")
20+
}
21+
22+
fun bytes2(): Unit {
23+
let bytes = Array[UInt8]::new(0u8, 12u8)
24+
let string = std::base64::encodeUrlSafe(bytes)
25+
assert(string == "AAw")
26+
}
27+
28+
fun bytes3(): Unit {
29+
let bytes = Array[UInt8]::new(0u8, 12u8, 23u8)
30+
let string = std::base64::encodeUrlSafe(bytes)
31+
assert(string == "AAwX")
32+
}
33+
34+
fun bytes13(): Unit {
35+
let bytes = Array[UInt8]::new(255u8, 234u8, 23u8, 45u8, 238u8, 78u8, 89u8, 23u8, 45u8, 67u8, 78u8, 89u8, 91u8)
36+
let string = std::base64::encodeUrlSafe(bytes)
37+
assert(string == "_-oXLe5OWRctQ05ZWw")
38+
}
39+
40+
fun bytes15(): Unit {
41+
let bytes = Array[UInt8]::new(0u8, 12u8, 23u8, 45u8, 67u8, 78u8, 89u8, 91u8, 12u8, 23u8, 45u8, 67u8, 78u8, 89u8, 91u8)
42+
let string = std::base64::encodeUrlSafe(bytes)
43+
assert(string == "AAwXLUNOWVsMFy1DTllb")
44+
}

tests/fatal1.core

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//= error code 1
2-
//= stderr "fatal error: bla\n std::fatalError (stdlib/stdlib.core:16)\n main (tests/fatal1.core:5)\n"
2+
//= stderr "fatal error: bla\n std::fatalError (stdlib/stdlib.core:17)\n main (tests/fatal1.core:5)\n"
33

44
fun main(): Unit {
55
std::fatalError("bla");

0 commit comments

Comments
 (0)