Happy new year.
[idzebra-moved-to-github.git] / index / stream.c
1 /* This file is part of the Zebra server.
2    Copyright (C) 1994-2011 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 #include <stdio.h>
21 #include <assert.h>
22
23 #include <fcntl.h>
24 #ifdef WIN32
25 #include <io.h>
26 #include <process.h>
27 #endif
28 #if HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
31
32 #include "index.h"
33
34 struct zebra_mem_control {
35     off_t offset_end;
36     off_t record_int_pos;
37     const char *record_int_buf;
38     int record_int_len;
39 };
40
41 struct zebra_ext_control {
42     off_t offset_end;
43     off_t record_offset;
44     int fd;
45 };
46
47 static off_t zebra_mem_seek(struct ZebraRecStream *s, off_t offset)
48 {
49     struct zebra_mem_control *fc = (struct zebra_mem_control *) s->fh;
50     return (off_t) (fc->record_int_pos = offset);
51 }
52
53 static off_t zebra_mem_tell(struct ZebraRecStream *s)
54 {
55     struct zebra_mem_control *fc = (struct zebra_mem_control *) s->fh;
56     return (off_t) fc->record_int_pos;
57 }
58
59 static int zebra_mem_read(struct ZebraRecStream *s, char *buf, size_t count)
60 {
61     struct zebra_mem_control *fc = (struct zebra_mem_control *) s->fh;
62     int l = fc->record_int_len - fc->record_int_pos;
63     if (l <= 0)
64         return 0;
65     l = (l < (int) count) ? l : (int) count;
66     memcpy (buf, fc->record_int_buf + fc->record_int_pos, l);
67     fc->record_int_pos += l;
68     return l;
69 }
70
71 static off_t zebra_mem_end(struct ZebraRecStream *s, off_t *offset)
72 {
73     struct zebra_mem_control *fc = (struct zebra_mem_control *) s->fh;
74     if (offset)
75         fc->offset_end = *offset;
76     return fc->offset_end;
77 }
78
79 static void zebra_mem_destroy(struct ZebraRecStream *s)
80 {
81     struct zebra_mem_control *fc = s->fh;
82     xfree(fc);
83 }
84
85 static int zebra_ext_read(struct ZebraRecStream *s, char *buf, size_t count)
86 {
87     struct zebra_ext_control *fc = (struct zebra_ext_control *) s->fh;
88     return read(fc->fd, buf, count);
89 }
90
91 static off_t zebra_ext_seek(struct ZebraRecStream *s, off_t offset)
92 {
93     struct zebra_ext_control *fc = (struct zebra_ext_control *) s->fh;
94     return lseek(fc->fd, offset + fc->record_offset, SEEK_SET);
95 }
96
97 static off_t zebra_ext_tell(struct ZebraRecStream *s)
98 {
99     struct zebra_ext_control *fc = (struct zebra_ext_control *) s->fh;
100     return lseek(fc->fd, 0, SEEK_CUR) - fc->record_offset;
101 }
102
103 static void zebra_ext_destroy(struct ZebraRecStream *s)
104 {
105     struct zebra_ext_control *fc = s->fh;
106     if (fc->fd != -1)
107         close(fc->fd);
108     xfree(fc);
109 }
110
111 static off_t zebra_ext_end(struct ZebraRecStream *s, off_t *offset)
112 {
113     struct zebra_ext_control *fc = (struct zebra_ext_control *) s->fh;
114     if (offset)
115         fc->offset_end = *offset;
116     return fc->offset_end;
117 }
118
119
120 void zebra_create_stream_mem(struct ZebraRecStream *stream,
121                              const char *buf, size_t sz)
122 {
123     struct zebra_mem_control *fc = xmalloc(sizeof(*fc));
124     fc->record_int_buf = buf;
125     fc->record_int_len = sz;
126     fc->record_int_pos = 0;
127     fc->offset_end = 0;
128
129     stream->fh = fc;
130     stream->readf = zebra_mem_read;
131     stream->seekf = zebra_mem_seek;
132     stream->tellf = zebra_mem_tell;
133     stream->endf = zebra_mem_end;
134     stream->destroy = zebra_mem_destroy;
135 }
136
137 void zebra_create_stream_fd(struct ZebraRecStream *stream,
138                             int fd, off_t start_offset)
139 {
140     struct zebra_ext_control *fc = xmalloc(sizeof(*fc));
141
142     fc->fd = fd;
143     fc->record_offset = start_offset;
144     fc->offset_end = 0;
145     
146     stream->fh = fc;
147     stream->readf = zebra_ext_read;
148     stream->seekf = zebra_ext_seek;
149     stream->tellf = zebra_ext_tell;
150     stream->endf = zebra_ext_end;
151     stream->destroy = zebra_ext_destroy;
152     zebra_ext_seek(stream, 0);
153 }
154
155 /*
156  * Local variables:
157  * c-basic-offset: 4
158  * c-file-style: "Stroustrup"
159  * indent-tabs-mode: nil
160  * End:
161  * vim: shiftwidth=4 tabstop=8 expandtab
162  */
163