1 /* This file is part of the Zebra server.
2 Copyright (C) 2004-2013 Index Data
3
4 Zebra is free software; you can redistribute it and/or modify it under
5 the terms of the GNU General Public License as published by the Free
6 Software Foundation; either version 2, or (at your option) any later
7 version.
8
9 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
18 */
19
20 #if HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 #include <stdio.h>
24 #include <assert.h>
25
26 #include <fcntl.h>
27 #ifdef WIN32
28 #include <io.h>
29 #include <process.h>
30 #endif
31 #if HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
34
35 #include "index.h"
36
37 struct zebra_mem_control {
38 off_t offset_end;
39 off_t record_int_pos;
40 const char *record_int_buf;
41 int record_int_len;
42 };
43
44 struct zebra_ext_control {
45 off_t offset_end;
46 off_t record_offset;
47 int fd;
48 };
49
zebra_mem_seek(struct ZebraRecStream * s,off_t offset)50 static off_t zebra_mem_seek(struct ZebraRecStream *s, off_t offset)
51 {
52 struct zebra_mem_control *fc = (struct zebra_mem_control *) s->fh;
53 return (off_t) (fc->record_int_pos = offset);
54 }
55
zebra_mem_tell(struct ZebraRecStream * s)56 static off_t zebra_mem_tell(struct ZebraRecStream *s)
57 {
58 struct zebra_mem_control *fc = (struct zebra_mem_control *) s->fh;
59 return (off_t) fc->record_int_pos;
60 }
61
zebra_mem_read(struct ZebraRecStream * s,char * buf,size_t count)62 static int zebra_mem_read(struct ZebraRecStream *s, char *buf, size_t count)
63 {
64 struct zebra_mem_control *fc = (struct zebra_mem_control *) s->fh;
65 int l = fc->record_int_len - fc->record_int_pos;
66 if (l <= 0)
67 return 0;
68 l = (l < (int) count) ? l : (int) count;
69 memcpy (buf, fc->record_int_buf + fc->record_int_pos, l);
70 fc->record_int_pos += l;
71 return l;
72 }
73
zebra_mem_end(struct ZebraRecStream * s,off_t * offset)74 static off_t zebra_mem_end(struct ZebraRecStream *s, off_t *offset)
75 {
76 struct zebra_mem_control *fc = (struct zebra_mem_control *) s->fh;
77 if (offset)
78 fc->offset_end = *offset;
79 return fc->offset_end;
80 }
81
zebra_mem_destroy(struct ZebraRecStream * s)82 static void zebra_mem_destroy(struct ZebraRecStream *s)
83 {
84 struct zebra_mem_control *fc = s->fh;
85 xfree(fc);
86 }
87
zebra_ext_read(struct ZebraRecStream * s,char * buf,size_t count)88 static int zebra_ext_read(struct ZebraRecStream *s, char *buf, size_t count)
89 {
90 struct zebra_ext_control *fc = (struct zebra_ext_control *) s->fh;
91 return read(fc->fd, buf, count);
92 }
93
zebra_ext_seek(struct ZebraRecStream * s,off_t offset)94 static off_t zebra_ext_seek(struct ZebraRecStream *s, off_t offset)
95 {
96 struct zebra_ext_control *fc = (struct zebra_ext_control *) s->fh;
97 return lseek(fc->fd, offset + fc->record_offset, SEEK_SET);
98 }
99
zebra_ext_tell(struct ZebraRecStream * s)100 static off_t zebra_ext_tell(struct ZebraRecStream *s)
101 {
102 struct zebra_ext_control *fc = (struct zebra_ext_control *) s->fh;
103 return lseek(fc->fd, 0, SEEK_CUR) - fc->record_offset;
104 }
105
zebra_ext_destroy(struct ZebraRecStream * s)106 static void zebra_ext_destroy(struct ZebraRecStream *s)
107 {
108 struct zebra_ext_control *fc = s->fh;
109 if (fc->fd != -1)
110 close(fc->fd);
111 xfree(fc);
112 }
113
zebra_ext_end(struct ZebraRecStream * s,off_t * offset)114 static off_t zebra_ext_end(struct ZebraRecStream *s, off_t *offset)
115 {
116 struct zebra_ext_control *fc = (struct zebra_ext_control *) s->fh;
117 if (offset)
118 fc->offset_end = *offset;
119 return fc->offset_end;
120 }
121
122
zebra_create_stream_mem(struct ZebraRecStream * stream,const char * buf,size_t sz)123 void zebra_create_stream_mem(struct ZebraRecStream *stream,
124 const char *buf, size_t sz)
125 {
126 struct zebra_mem_control *fc = xmalloc(sizeof(*fc));
127 fc->record_int_buf = buf;
128 fc->record_int_len = sz;
129 fc->record_int_pos = 0;
130 fc->offset_end = 0;
131
132 stream->fh = fc;
133 stream->readf = zebra_mem_read;
134 stream->seekf = zebra_mem_seek;
135 stream->tellf = zebra_mem_tell;
136 stream->endf = zebra_mem_end;
137 stream->destroy = zebra_mem_destroy;
138 }
139
zebra_create_stream_fd(struct ZebraRecStream * stream,int fd,off_t start_offset)140 void zebra_create_stream_fd(struct ZebraRecStream *stream,
141 int fd, off_t start_offset)
142 {
143 struct zebra_ext_control *fc = xmalloc(sizeof(*fc));
144
145 fc->fd = fd;
146 fc->record_offset = start_offset;
147 fc->offset_end = 0;
148
149 stream->fh = fc;
150 stream->readf = zebra_ext_read;
151 stream->seekf = zebra_ext_seek;
152 stream->tellf = zebra_ext_tell;
153 stream->endf = zebra_ext_end;
154 stream->destroy = zebra_ext_destroy;
155 zebra_ext_seek(stream, 0);
156 }
157
158 /*
159 * Local variables:
160 * c-basic-offset: 4
161 * c-file-style: "Stroustrup"
162 * indent-tabs-mode: nil
163 * End:
164 * vim: shiftwidth=4 tabstop=8 expandtab
165 */
166
167