-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathmtfstream.c
111 lines (101 loc) · 2.28 KB
/
mtfstream.c
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
99
100
101
102
103
104
105
106
107
108
109
110
111
#include "mtf.h"
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#ifdef DEBUG
#include <stdio.h>
#endif
#include "util.h"
int mtf_stream_start(struct mtf_stream *s)
{
s->laststream = 0;
s->stream = mtfdb_off(s);
#ifdef DEBUG
fprintf(stderr, "offset: %llu\n", (unsigned long long)s->stream);
fflush(stderr);
#endif
s->streamdid = 0;
if (!mtfscan_ready(s, s->stream + mtf_stream_sizeof)) return 0;
return 1;
}
int mtf_stream_read(struct mtf_stream *s, unsigned char *buf, int len)
{
int r, total;
total = 0;
while (len > 0) {
if (s->streamdid + len > mtf_stream_length(s)) {
len = (int)(mtf_stream_length(s) - s->streamdid);
}
if (len < 1) break;
do {
r = read(s->fd, buf, len);
} while (r == -1 && errno == EINTR);
if (r < 1) return -1;
len -= r;
buf += r;
s->abspos += r;
s->streamdid += r;
s->flbread += r;
total += r;
while (s->flbread > s->flbsize) {
s->flbread -= s->flbsize;
}
}
return total;
}
int mtf_stream_eof(struct mtf_stream *s)
{
return (mtf_stream_length(s) == s->streamdid) ? 1 :0;
}
int mtf_stream_eset(struct mtf_stream *s)
{
return s->laststream ? 1 : 0;
}
int mtf_stream_copy(struct mtf_stream *s, int outfd)
{
unsigned char stump[4096];
int islaststream;
int len;
#ifdef DEBUG
fprintf(stderr, "type of this stream: %x\n",
mtf_stream_type(s));
fprintf(stderr, "length of this stream: %llu\n",
(unsigned long long)mtf_stream_length(s));
#endif
islaststream = (mtf_stream_type(s) == mtfst_spad ? 1 : 0);
/* okay, skip this blob */
while (!mtf_stream_eof(s)) {
len = mtf_stream_read(s, stump, sizeof(stump));
if (len < 0) return 0;
if (outfd > -1) {
if (!bwrite(outfd, stump, len))
return 0;
}
}
if ((s->laststream |= islaststream)) {
/* okay, resync with regular data stream */
#ifdef DEBUG
fprintf(stderr, "SYNCING: %lu\n", s->flbread);
#endif
return 1;
}
/* load the next stream offset */
s->ready = 0;
s->header = s->buffer;
if ((s->flbread % 4) != 0) {
/* stream offsets are on a boundary */
s->stream = 4 - (s->flbread % 4);
} else {
s->stream = 0;
}
#ifdef DEBUG
fprintf(stderr, "FLBREAD: %lu\n", s->flbread);
#endif
s->streamdid = 0;
if (!mtfscan_ready(s, s->stream + mtf_stream_sizeof)) return 0;
return 1;
}
int mtf_stream_next(struct mtf_stream *s)
{
return mtf_stream_copy(s, -1);
}