Compare commits

...

2 Commits

Author SHA1 Message Date
0a7c8d3e4e start writing code for decompressing chunk data.
I still haven't much of an idea where I'll take this, but it's a start.

I know it is needed for block filtering and such, I still need to find a
way how I'll actually implement it.
2025-09-05 21:25:00 +02:00
c6c9cc147e rework error.h, to decrease impact on binary size.
We were statically creating a new string per log message, so re-using
the same message would cause duplicate byte sizes.
Now, all prefixes / suffixes are only defined once, the file name is
defined once per file, the line number should be defined once per unique
line.
This just saves some memory in the final binary, allowing things to be
optimised a little better.
2025-09-05 15:17:53 +02:00
3 changed files with 98 additions and 11 deletions

View File

@@ -2,6 +2,7 @@
* Licensed under the MIT Licence. See LICENSE for details */ * Licensed under the MIT Licence. See LICENSE for details */
#include "mcx.h" #include "mcx.h"
#include <archive.h>
#include <assert.h> #include <assert.h>
#include <endian.h> #include <endian.h>
#include <stdint.h> #include <stdint.h>
@@ -9,12 +10,46 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include "../error.h"
#include "../util/intdef.h" #include "../util/intdef.h"
#define SECTOR 0x1000 // sector size #define SECTOR 0x1000 // sector size
#define TABLE 0x800 // table (total) element count #define TABLE 0x800 // table (total) element count
#define CHUNKS 0x400 // amount of chunks in a file #define CHUNKS 0x400 // amount of chunks in a file
enum mcx_compression {
MCX_COMPRESSION_GZIP = 0x01,
MCX_COMPRESSION_ZLIB = 0x02,
MCX_COMPRESSION_NONE = 0x03,
MCX_COMPRESSION_LZ4 = 0x04,
MCX_COMPRESSION_CUSTOM = 0x7F,
};
/* first 4 bytes is an i32 indicating remaining bytes, the following byte defines the compression scheme */
static void mcx_loadchunk(const u8 *restrict buf, const i32 *restrict table, int idx) {
const u8 *chunk = buf + (be32toh(table[idx]) >> 8) * SECTOR;
i32 len;
memcpy(&len, chunk, 4);
len = be32toh(len);
chunk += 4;
if (*chunk != MCX_COMPRESSION_CUSTOM) {
struct archive *archive = archive_read_new();
archive_read_support_format_raw(archive);
switch (*chunk) {
case MCX_COMPRESSION_GZIP: archive_read_support_filter_gzip(archive); break;
case MCX_COMPRESSION_ZLIB: archive_read_support_filter_zlib(archive); break; // BUG: this does not exist, but will have to do for now
case MCX_COMPRESSION_LZ4: archive_read_support_filter_lz4(archive); break;
case MCX_COMPRESSION_CUSTOM: // TODO: implement using filtering any format
default: fatal("compression type of '%ihh' is unsupported!", *chunk);
}
// TODO: implement decompression, somehow.
// https://github.com/libarchive/libarchive/wiki/Examples#user-content-A_Universal_Decompressor
}
}
/* Moves chunks `src_s` to `src_e` (inclusive) from `src`, back onto `dst`. */ /* Moves chunks `src_s` to `src_e` (inclusive) from `src`, back onto `dst`. */
static void mvchunks(u8 *dst, u8 *src, u32 *restrict table, int src_s, int src_e) { static void mvchunks(u8 *dst, u8 *src, u32 *restrict table, int src_s, int src_e) {
assert(src > dst); assert(src > dst);

51
src/error.c Normal file
View File

@@ -0,0 +1,51 @@
#include "error.h"
#include <stdarg.h>
#include <stdio.h>
#include "util/intdef.h"
static void error_log(FILE *restrict stream, const char *restrict pfx, uint ln, const char *restrict file, const char *restrict fmt, va_list ap) {
fprintf(stream, "(%s:%lu) [%s] '", file, ln, pfx);
vfprintf(stream, fmt, ap);
fprintf(stream, "'\n");
}
void error_dbg(uint ln, const char *restrict file, const char *restrict fmt, ...) {
va_list ap;
va_start(ap, fmt);
error_log(stdout, "\033[95mDBG\033[0m", ln, file, fmt, ap);
va_end(ap);
}
void error_inf(uint ln, const char *restrict file, const char *restrict fmt, ...) {
va_list ap;
va_start(ap, fmt);
error_log(stdout, "\033[93mINF\033[0m", ln, file, fmt, ap);
va_end(ap);
}
void error_war(uint ln, const char *restrict file, const char *restrict fmt, ...) {
va_list ap;
va_start(ap, fmt);
error_log(stdout, "\033[91mWAR\033[0m", ln, file, fmt, ap);
va_end(ap);
}
void error_err(uint ln, const char *restrict file, const char *restrict fmt, ...) {
va_list ap;
va_start(ap, fmt);
error_log(stdout, "\033[mFAT\033[0m", ln, file, fmt, ap);
va_end(ap);
}
void error_fat(uint ln, const char *restrict file, const char *restrict fmt, ...) {
va_list ap;
va_start(ap, fmt);
error_log(stdout, "\033[mFAT\033[0m", ln, file, fmt, ap);
va_end(ap);
exit(EXIT_FAILURE);
}

View File

@@ -2,20 +2,21 @@
* Licensed under the MIT Licence. See LICENSE for details */ * Licensed under the MIT Licence. See LICENSE for details */
#pragma once #pragma once
#if __INCLUDE_LEVEL__ > 0
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include "util/atrb.h"
#include "util/intdef.h"
#include "util/macro.h" #include "util/macro.h"
#endif
#define debug(s, ...) printf("\033[95m" __FILE__ ":" MACRO_STR2(__LINE__) ": [DBG]: " s "\033[0m\n", ##__VA_ARGS__) void error_dbg(uint ln, const char *restrict file, const char *restrict fmt, ...);
#define info(s, ...) printf(__FILE__ ":" MACRO_STR2(__LINE__) ": [INF]: " s "\n", ##__VA_ARGS__) void error_inf(uint ln, const char *restrict file, const char *restrict fmt, ...);
#define warn(s, ...) fprintf(stderr, "\033[93m" __FILE__ ":" MACRO_STR2(__LINE__) ": [WAR]: " s "\033[0m\n", ##__VA_ARGS__) void error_war(uint ln, const char *restrict file, const char *restrict fmt, ...);
#define error(s, ...) fprintf(stderr, "\033[91m" __FILE__ ":" MACRO_STR2(__LINE__) ": [ERR]: " s "\033[0m\n", ##__VA_ARGS__) void error_err(uint ln, const char *restrict file, const char *restrict fmt, ...);
void error_fat(uint ln, const char *restrict file, const char *restrict fmt, ...) NORET;
#define fatal(s, ...) \ #define debug(s, ...) error_dbg(__LINE__, __FILE__, s, ##__VA_ARGS__)
do { \ #define info(s, ...) error_inf(__LINE__, __FILE__, s, ##__VA_ARGS__)
fprintf(stderr, "\033[101m" __FILE__ ":" MACRO_STR2(__LINE__) ": [FAT]: " s "\033[0m\n", ##__VA_ARGS__); \ #define warn(s, ...) error_war(__LINE__, __FILE__, s, ##__VA_ARGS__)
exit(EXIT_FAILURE); \ #define error(s, ...) error_err(__LINE__, __FILE__, s, ##__VA_ARGS__)
} while (0) #define fatal(s, ...) error_fat(__LINE__, __FILE__, s, ##__VA_ARGS__)