summary refs log tree commit diff
path: root/src/common/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/common.c')
-rw-r--r--src/common/common.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/common/common.c b/src/common/common.c
new file mode 100644
index 0000000..508140d
--- /dev/null
+++ b/src/common/common.c
@@ -0,0 +1,54 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../include.h"
+#include "common.h"
+
+int (*file_ext(char *file))(struct blob *, struct userdata *) {
+	size_t len = strlen(file);
+	#define ext(extension) memcmp(file + len - sizeof (extension) + 1, extension, sizeof (extension))
+	if ((ext(".mptm") && ext(".mod") && ext(".xm") && ext(".s3m") && ext(".it")) == 0) {
+		return module_openmpt;
+	} else if ((ext(".mid") && ext(".midi")) == 0) {
+		return module_fluidsynth;
+	}
+	#undef ext
+	return NULL;
+}
+
+struct blob load_file(char const *const name) {
+	const size_t START_SIZE = 1;
+	FILE *file = fopen(name, "rb");
+	if (file == NULL) {
+		return (struct blob) {.data = NULL};
+	}
+	void *data = malloc(START_SIZE);
+	size_t allocated = START_SIZE;
+	size_t used = 0;
+	while (1) {
+		size_t read = fread(data + used, 1, allocated - used, file);
+		if (read != allocated - used) {
+			used += read;
+			break;
+		}
+		used += read;
+		allocated *= 2;
+		void *const newdata = realloc(data, allocated);
+		if (newdata == NULL) {
+			goto realloc_error;
+		}
+		data = newdata;
+	}
+	void *const newdata = realloc(data, used);
+	if (newdata == NULL && used != 0) {
+		goto realloc_error;
+	}
+	fclose(file);
+	return (struct blob) {.data = newdata, .size = used};
+	
+	realloc_error:
+	free(data);
+	fclose(file);
+	return (struct blob) {.data = NULL};
+}