1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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;
}
|