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
|
#include <stdio.h>
#include <errno.h>
#include <stdint.h>
#include "glib.h"
#include "ufo-roof.h"
#include "ufo-roof-read-file.h"
typedef struct {
UfoRoofReadInterface iface;
UfoRoofConfig *cfg;
gchar *fname;
FILE *fd;
} UfoRoofReadFile;
static void ufo_roof_read_file_free(UfoRoofReadInterface *iface) {
UfoRoofReadFile *reader = (UfoRoofReadFile*)iface;
if (reader) {
if (reader->fname)
g_free(reader->fname);
if (reader->fd >= 0)
fclose(reader->fd);
free(reader);
}
}
static guint ufo_roof_read_file(UfoRoofReadInterface *iface, void *buffers, GError **error) {
UfoRoofReadFile *reader = (UfoRoofReadFile*)iface;
UfoRoofConfig *cfg = reader->cfg;
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(buffers + 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");
}
return packets;
}
UfoRoofReadInterface *ufo_roof_read_file_new(UfoRoofConfig *cfg, guint id, GError **error) {
UfoRoofReadFile *reader = (UfoRoofReadFile*)calloc(1, sizeof(UfoRoofReadFile));
if (!reader) roof_new_error(error, "Can't allocate UfoRoofReadFile");
// 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 UfoRoofReadFile is used", cfg->header_size + cfg->payload_size, cfg->max_packet_size);
reader->cfg = cfg;
reader->iface.close = ufo_roof_read_file_free;
reader->iface.read =ufo_roof_read_file;
reader->fname = g_strdup_printf(cfg->path, id + cfg->first_file_number);
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 %s", reader->fname);
}
return (UfoRoofReadInterface*)reader;
}
|