summaryrefslogtreecommitdiffstats
path: root/src/roof-read-file.c
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@suren.me>2020-09-03 03:00:30 +0200
committerSuren A. Chilingaryan <csa@suren.me>2020-09-03 03:00:30 +0200
commit5172421d248250b4ab3b69eb57fd83656e23a4da (patch)
treea499d9f1dd0b74b754816884a59927b3171656fc /src/roof-read-file.c
parent7b2e6168b049be9e7852b2d364d897592eff69fc (diff)
downloadufo-roof-temp-5172421d248250b4ab3b69eb57fd83656e23a4da.tar.gz
ufo-roof-temp-5172421d248250b4ab3b69eb57fd83656e23a4da.tar.bz2
ufo-roof-temp-5172421d248250b4ab3b69eb57fd83656e23a4da.tar.xz
ufo-roof-temp-5172421d248250b4ab3b69eb57fd83656e23a4da.zip
This is unfinished work implemeting out-of-UFO network serversHEADmaster
Diffstat (limited to 'src/roof-read-file.c')
-rw-r--r--src/roof-read-file.c98
1 files changed, 98 insertions, 0 deletions
diff --git a/src/roof-read-file.c b/src/roof-read-file.c
new file mode 100644
index 0000000..da8d51c
--- /dev/null
+++ b/src/roof-read-file.c
@@ -0,0 +1,98 @@
+#include <stdio.h>
+#include <errno.h>
+#include <assert.h>
+#include <stdint.h>
+
+#include "glib.h"
+
+#include "ufo-roof.h"
+#include "ufo-roof-read-file.h"
+
+typedef struct {
+ RoofReadInterface iface;
+
+ RoofConfig *cfg;
+
+ gchar *fname;
+ FILE *fd;
+ uint8_t *buf;
+} RoofReadFile;
+
+static void roof_read_file_free(RoofReadInterface *iface) {
+ RoofReadFile *reader = (RoofReadFile*)iface;
+
+ if (reader) {
+ if (reader->fname)
+ g_free(reader->fname);
+
+ if (reader->fd)
+ fclose(reader->fd);
+
+ if (reader->buf)
+ free(reader->buf);
+ free(reader);
+ }
+}
+
+static guint roof_read_file(RoofReadInterface *iface, uint8_t **buffers, GError **error) {
+ RoofReadFile *reader = (RoofReadFile*)iface;
+ RoofConfig *cfg = reader->cfg;
+
+ assert(iface);
+ assert(buffers);
+
+ size_t bytes = 0;
+ size_t packet_size = cfg->header_size + cfg->payload_size;
+ size_t expected = cfg->max_packets * packet_size;
+
+ while ((!feof(reader->fd))&&(!ferror(reader->fd))&&(bytes < expected)) {
+ size_t ret = fread(reader->buf + bytes, 1, expected - bytes, reader->fd);
+ bytes += ret;
+ }
+
+ guint packets = bytes / packet_size;
+
+ if (ferror(reader->fd)) {
+ roof_network_error_with_retval(error, 0, "read failed, error %i", ferror(reader->fd));
+ } else if ((feof(reader->fd))&&(bytes % packet_size)) {
+ roof_network_error_with_retval(error, packets, "extra data in the end of input");
+ }
+
+ *buffers = reader->buf;
+ return packets;
+}
+
+
+RoofReadInterface *roof_read_file_new(RoofConfig *cfg, const char *path, guint file_id, GError **error) {
+ RoofReadFile *reader = (RoofReadFile*)calloc(1, sizeof(RoofReadFile));
+ if (!reader) roof_new_error(error, "Can't allocate RoofReadFile");
+
+ // FIXME: Shall we jump if max_packet_size > header+payload (or will be extra data included in the data files)? Report error for now.
+ if ((cfg->header_size + cfg->payload_size) != cfg->max_packet_size)
+ roof_new_error(error, "packet_size (%u) should be equal to max_packet_size (%u) if RoofReadFile is used", cfg->header_size + cfg->payload_size, cfg->max_packet_size);
+
+ reader->cfg = cfg;
+ reader->iface.close = roof_read_file_free;
+ reader->iface.read =roof_read_file;
+
+ reader->fname = g_strdup_printf(path, file_id);
+ if (!reader->fname) {
+ free(reader);
+ roof_new_error(error, "Can't build file name");
+ }
+
+ reader->fd = fopen(reader->fname, "rb");
+ if (!reader->fd) {
+ g_free(reader->fname);
+ g_free(reader);
+ roof_new_error(error, "Can't open file %i at path %s", file_id, path);
+ }
+
+ reader->buf = (uint8_t*)malloc(cfg->max_packets * (cfg->header_size + cfg->payload_size));
+ if (!reader->buf) {
+ roof_read_file_free((RoofReadInterface*)reader);
+ roof_new_error(error, "Can't allocate file buffer");
+ }
+
+ return (RoofReadInterface*)reader;
+}