source: lib/ior-peek.c @ 15e9390

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 15e9390 was d4a1691, checked in by Shane Alcock <salcock@…>, 12 years ago
  • Seems to be like this offset should be initialised at some point - I think this might fix the random corrupt packet errors I was getting (haven't seen any since I made this change!)
  • Property mode set to 100644
File size: 3.0 KB
Line 
1#include "wandio.h"
2#include <sys/types.h>
3#include <sys/stat.h>
4#include <fcntl.h>
5#include <stdlib.h>
6#include <unistd.h>
7#include <string.h>
8
9struct peek_t {
10        io_t *child;
11        char *buffer;
12        int length;
13        int offset;
14};
15
16extern io_source_t peek_source;
17
18#define DATA(io) ((struct peek_t *)((io)->data))
19#define MIN(a,b) ((a) < (b) ? (a) : (b))
20
21io_t *peek_open(io_t *child)
22{
23        io_t *io;
24        if (!child)
25                return NULL;
26        io =  malloc(sizeof(io_t));
27        io->data = malloc(sizeof(struct peek_t));
28        io->source = &peek_source;
29
30        DATA(io)->child = child;
31        DATA(io)->buffer = NULL;
32        DATA(io)->length = 0;
33        DATA(io)->offset = 0;   
34
35        return io;
36}
37
38static off_t peek_read(io_t *io, void *buffer, off_t len)
39{
40        off_t ret = 0;
41
42        /* Is some of this data in the buffer? */
43        if (DATA(io)->buffer) {
44                ret = MIN(len,DATA(io)->length - DATA(io)->offset);
45
46                memcpy(buffer, 
47                        DATA(io)->buffer + DATA(io)->offset,
48                        ret);
49                buffer += ret;
50                DATA(io)->offset += ret;
51                len -= ret;
52        }
53        /* Copy the rest of the data from the child */
54        if (len>0) {
55                off_t bytes_read = 
56                        DATA(io)->child->source->read(
57                                DATA(io)->child, buffer, len);
58                /* Error? */
59                if (bytes_read < 1) {
60                        /* Return if we have managed to get some data ok */
61                        if (ret > 0)
62                                return ret;
63                        /* Return the error upstream */
64                        return bytes_read;
65                }
66                ret += bytes_read;
67        }
68
69        /* Have we read past the end of the buffer? */
70        if (DATA(io)->buffer && DATA(io)->offset >= DATA(io)->length) {
71                /* If so, free the memory it used */
72                free(DATA(io)->buffer);
73                DATA(io)->buffer = NULL;
74                DATA(io)->offset = 0;
75                DATA(io)->length = 0;
76        }
77
78        return ret;
79}
80
81/* Round reads for peeks into the buffer up to this size */
82#define PEEK_SIZE (1024*1024)
83
84static off_t peek_peek(io_t *io, void *buffer, off_t len)
85{
86        off_t ret = 0;
87
88        /* Is there enough data in the buffer to serve this request? */
89        if (DATA(io)->length - DATA(io)->offset < len) {
90                /* No, we need to extend the buffer. */
91                off_t read_amount = len - (DATA(io)->length - DATA(io)->offset);
92                /* Round the read_amount up to the nearest MB */
93                read_amount += PEEK_SIZE - ((DATA(io)->length + read_amount) % PEEK_SIZE);
94                DATA(io)->buffer = realloc(DATA(io)->buffer, DATA(io)->length + read_amount);
95                read_amount = wandio_read(DATA(io)->child, 
96                        DATA(io)->buffer + DATA(io)->length,
97                        read_amount);
98
99                /* Pass errors up */
100                if (read_amount <1) {
101                        return read_amount;
102                }
103
104                DATA(io)->length += read_amount;
105        }
106
107        /* Right, now return data from the buffer (that now should be large enough, but might
108         * not be if we hit EOF) */
109        ret = MIN(len, DATA(io)->length - DATA(io)->offset);
110        memcpy(buffer, DATA(io)->buffer + DATA(io)->offset, ret);
111        return ret;
112}
113
114static off_t peek_tell(io_t *io)
115{
116        return wandio_tell(DATA(io)->child);
117}
118
119static off_t peek_seek(io_t *io, off_t offset, int whence)
120{
121        return wandio_seek(DATA(io)->child,offset,whence);
122}
123
124static void peek_close(io_t *io)
125{
126        wandio_destroy(DATA(io)->child);
127        if (DATA(io)->buffer)
128                free(DATA(io)->buffer);
129        free(io->data);
130        free(io);
131}
132
133io_source_t peek_source = {
134        "peek",
135        peek_read,
136        peek_peek,
137        peek_tell,
138        peek_seek,
139        peek_close
140};
141
Note: See TracBrowser for help on using the repository browser.