Recreate base64 project
This commit is contained in:
140
base64/base64.c
Normal file
140
base64/base64.c
Normal file
@@ -0,0 +1,140 @@
|
||||
// vim:fileencoding=utf-8:foldmethod=marker
|
||||
|
||||
#include "base64.h"
|
||||
#include "../wapp/wapp.h"
|
||||
#include <math.h>
|
||||
|
||||
internal Str8RO alphabet = wapp_str8_lit_ro("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/");
|
||||
|
||||
internal c8 char_at(u8 index);
|
||||
internal u8 char_index(c8 c);
|
||||
internal u64 calc_encode_length(Str8RO *input);
|
||||
internal u64 calc_decode_length(Str8RO *input);
|
||||
|
||||
Str8 *encode(Allocator *allocator, Str8RO *input) {
|
||||
if (input->size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u64 n_out = calc_encode_length(input);
|
||||
Str8 *out = wapp_str8_alloc_and_fill_buf(allocator, n_out);
|
||||
if (!out) return NULL;
|
||||
|
||||
u8 buf[3] = {0};
|
||||
u8 count = 0;
|
||||
u64 iout = 0;
|
||||
|
||||
|
||||
for (u64 i = 0; i < input->size; ++i) {
|
||||
buf[count] = wapp_str8_get(input, i);
|
||||
count += 1;
|
||||
if (count == 3) {
|
||||
wapp_str8_set(out, iout, char_at(buf[0] >> 2));
|
||||
wapp_str8_set(out, iout + 1, char_at(((buf[0] & 0x03) << 4) + (buf[1] >> 4)));
|
||||
wapp_str8_set(out, iout + 2, char_at(((buf[1] & 0x0f) << 2) + (buf[2] >> 6)));
|
||||
wapp_str8_set(out, iout + 3, char_at(buf[2] & 0x3f));
|
||||
|
||||
iout += 4;
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 1) {
|
||||
wapp_str8_set(out, iout, char_at(buf[0] >> 2));
|
||||
wapp_str8_set(out, iout + 1, char_at((buf[0] & 0x03) << 4));
|
||||
wapp_str8_set(out, iout + 2, '=');
|
||||
wapp_str8_set(out, iout + 3, '=');
|
||||
}
|
||||
|
||||
if (count == 2) {
|
||||
wapp_str8_set(out, iout, char_at(buf[0] >> 2));
|
||||
wapp_str8_set(out, iout + 1, char_at(((buf[0] & 0x03) << 4) + (buf[1] >> 4)));
|
||||
wapp_str8_set(out, iout + 2, char_at((buf[1] & 0x0f) << 2));
|
||||
wapp_str8_set(out, iout + 3, '=');
|
||||
|
||||
iout += 4;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
Str8 *decode(Allocator *allocator, Str8RO *input) {
|
||||
if (input->size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u64 n_out = calc_decode_length(input);
|
||||
Str8 *out = wapp_str8_alloc_and_fill_buf(allocator, n_out);
|
||||
if (!out) return NULL;
|
||||
|
||||
u8 buf[4] = {0};
|
||||
u8 count = 0;
|
||||
u64 iout = 0;
|
||||
|
||||
for (u64 i = 0; i < input->size; ++i) {
|
||||
buf[count] = char_index(wapp_str8_get(input, i));
|
||||
count += 1;
|
||||
if (count == 4) {
|
||||
wapp_str8_set(out, iout, (buf[0] << 2) + (buf[1] >> 4));
|
||||
if (buf[2] != 64) {
|
||||
wapp_str8_set(out, iout + 1, (buf[1] << 4) + (buf[2] >> 2));
|
||||
}
|
||||
if (buf[3] != 64) {
|
||||
wapp_str8_set(out, iout + 2, (buf[2] << 6) + buf[3]);
|
||||
}
|
||||
|
||||
iout += 3;
|
||||
count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
internal c8 char_at(u8 index) {
|
||||
return wapp_str8_get(&alphabet, index);
|
||||
}
|
||||
|
||||
internal u8 char_index(c8 c) {
|
||||
if (c == '=') {
|
||||
return 64;
|
||||
}
|
||||
|
||||
u8 index = 0;
|
||||
for (u8 i = 0; i < 63; ++i) {
|
||||
if (char_at(i) == c) {
|
||||
break;
|
||||
}
|
||||
index += 1;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
internal u64 calc_encode_length(Str8RO *input) {
|
||||
if (input->size < 3) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
u64 n_groups = (u64)(ceilf((f32)input->size / 3.0f));
|
||||
|
||||
return n_groups * 4;
|
||||
}
|
||||
|
||||
internal u64 calc_decode_length(Str8RO *input) {
|
||||
if (input->size < 4) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
u64 n_groups = (u64)(floorf((f32)input->size / 4.0f));
|
||||
|
||||
u64 groups = n_groups * 3;
|
||||
|
||||
for (u64 i = input->size; i > 0; --i) {
|
||||
if (wapp_str8_get(input, i) == '=') {
|
||||
groups -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return groups;
|
||||
}
|
||||
11
base64/base64.h
Normal file
11
base64/base64.h
Normal file
@@ -0,0 +1,11 @@
|
||||
// vim:fileencoding=utf-8:foldmethod=marker
|
||||
|
||||
#ifndef BASE64_H
|
||||
#define BASE64_H
|
||||
|
||||
#include "../wapp/wapp.h"
|
||||
|
||||
Str8 *encode(Allocator *allocator, Str8RO *input);
|
||||
Str8 *decode(Allocator *allocator, Str8RO *input);
|
||||
|
||||
#endif // !BASE64_H
|
||||
5
base64/build
Executable file
5
base64/build
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
script_dir="$(dirname $0)"
|
||||
|
||||
clang $script_dir/*.c $script_dir/../wapp/wapp.c -lm -o b64
|
||||
23
base64/main.c
Normal file
23
base64/main.c
Normal file
@@ -0,0 +1,23 @@
|
||||
// vim:fileencoding=utf-8:foldmethod=marker
|
||||
|
||||
#include "base64.h"
|
||||
#include "../wapp/wapp.h"
|
||||
#include <stdio.h>
|
||||
|
||||
int main(void) {
|
||||
Allocator allocator = wapp_mem_arena_allocator_init(MB(10));
|
||||
|
||||
Str8RO text = wapp_str8_lit_ro("Testing some more stuff");
|
||||
Str8RO etext = wapp_str8_lit_ro("VGVzdGluZyBzb21lIG1vcmUgc3R1ZmY=");
|
||||
|
||||
Str8 *encoded_text = encode(&allocator, &text);
|
||||
Str8 *decoded_text = decode(&allocator, &etext);
|
||||
wapp_runtime_assert(encoded_text != NULL && decoded_text != NULL, "Failed to allocate strings");
|
||||
|
||||
printf("Encoded text: " WAPP_STR8_SPEC "\n", wapp_str8_varg(*encoded_text));
|
||||
printf("Decoded text: " WAPP_STR8_SPEC "\n", wapp_str8_varg(*decoded_text));
|
||||
|
||||
wapp_mem_arena_allocator_destroy(&allocator);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user