Happy new year.
[idzebra-moved-to-github.git] / rset / rsisamb.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 #include <idzebra/util.h>
23 #include <rset.h>
24 #include <string.h>
25
26 static RSFD r_open(RSET ct, int flag);
27 static void r_close(RSFD rfd);
28 static void r_delete(RSET ct);
29 static int r_forward(RSFD rfd, void *buf, TERMID *term, const void *untilbuf);
30 static void r_pos(RSFD rfd, double *current, double *total);
31 static int r_read(RSFD rfd, void *buf, TERMID *term);
32 static int r_read_filter(RSFD rfd, void *buf, TERMID *term);
33 static int r_write(RSFD rfd, const void *buf);
34
35 static const struct rset_control control = 
36 {
37     "isamb",
38     r_delete,
39     rset_get_one_term,
40     r_open,
41     r_close,
42     r_forward, 
43     r_pos,
44     r_read,
45     r_write,
46 };
47
48 static const struct rset_control control_filter = 
49 {
50     "isamb",
51     r_delete,
52     rset_get_one_term,
53     r_open,
54     r_close,
55     r_forward, 
56     r_pos,
57     r_read_filter,
58     r_write,
59 };
60
61 struct rfd_private {
62     ISAMB_PP pt;
63     void *buf;
64 };
65
66 struct rset_private {
67     ISAMB   is;
68     ISAM_P pos;
69 };
70
71 static int log_level = 0;
72 static int log_level_initialized = 0;
73
74 RSET rsisamb_create(NMEM nmem, struct rset_key_control *kcontrol,
75                     int scope,
76                     ISAMB is, ISAM_P pos, TERMID term)
77 {
78     RSET rnew = rset_create_base(
79         kcontrol->filter_func ? &control_filter : &control,
80         nmem, kcontrol, scope, term, 0, 0);
81     struct rset_private *info;
82     assert(pos);
83     if (!log_level_initialized)
84     {
85         log_level = yaz_log_module_level("rsisamb");
86         log_level_initialized = 1;
87     }
88     info = (struct rset_private *) nmem_malloc(rnew->nmem, sizeof(*info));
89     info->is = is;
90     info->pos = pos;
91     rnew->priv = info;
92     yaz_log(log_level, "rsisamb_create");
93     return rnew;
94 }
95
96 static void r_delete(RSET ct)
97 {
98     yaz_log(log_level, "rsisamb_delete");
99 }
100
101 RSFD r_open(RSET ct, int flag)
102 {
103     struct rset_private *info = (struct rset_private *) ct->priv;
104     RSFD rfd;
105     struct rfd_private *ptinfo;
106
107     if (flag & RSETF_WRITE)
108     {
109         yaz_log(YLOG_FATAL, "ISAMB set type is read-only");
110         return NULL;
111     }
112     rfd = rfd_create_base(ct);
113     if (rfd->priv)
114         ptinfo = (struct rfd_private *) (rfd->priv);
115     else {
116         ptinfo = (struct rfd_private *) nmem_malloc(ct->nmem,sizeof(*ptinfo));
117         ptinfo->buf = nmem_malloc(ct->nmem,ct->keycontrol->key_size);
118         rfd->priv = ptinfo;
119     }
120     ptinfo->pt = isamb_pp_open(info->is, info->pos, ct->scope );
121     yaz_log(log_level, "rsisamb_open");
122     return rfd;
123 }
124
125 static void r_close(RSFD rfd)
126 {
127     struct rfd_private *ptinfo = (struct rfd_private *)(rfd->priv);
128     isamb_pp_close (ptinfo->pt);
129     yaz_log(log_level, "rsisamb_close");
130 }
131
132
133 static int r_forward(RSFD rfd, void *buf, TERMID *term, const void *untilbuf)
134 {
135     struct rfd_private *pinfo = (struct rfd_private *)(rfd->priv);
136     int rc;
137     rc = isamb_pp_forward(pinfo->pt, buf, untilbuf);
138     if (rc && term)
139         *term = rfd->rset->term;
140     yaz_log(log_level, "rsisamb_forward");
141     return rc; 
142 }
143
144 static void r_pos(RSFD rfd, double *current, double *total)
145 {
146     struct rfd_private *pinfo = (struct rfd_private *)(rfd->priv);
147     assert(rfd);
148     isamb_pp_pos(pinfo->pt, current, total);
149     yaz_log(log_level, "isamb.r_pos returning %0.1f/%0.1f",
150               *current, *total);
151 }
152
153 static int r_read(RSFD rfd, void *buf, TERMID *term)
154 {
155     struct rfd_private *pinfo = (struct rfd_private *)(rfd->priv);
156     int rc;
157     rc = isamb_pp_read(pinfo->pt, buf);
158     if (rc && term)
159         *term = rfd->rset->term;
160     yaz_log(log_level, "isamb.r_read ");
161     return rc;
162 }
163
164 static int r_read_filter(RSFD rfd, void *buf, TERMID *term)
165 {
166     struct rfd_private *pinfo = (struct rfd_private *)rfd->priv;
167     const struct rset_key_control *kctrl = rfd->rset->keycontrol;
168     int rc;
169     while((rc = isamb_pp_read(pinfo->pt, buf)))
170     {
171         int incl = (*kctrl->filter_func)(buf, kctrl->filter_data);
172         if (incl)
173             break;
174     }
175     if (rc && term)
176         *term = rfd->rset->term;
177     yaz_log(log_level, "isamb.r_read_filter");
178     return rc;
179 }
180
181 static int r_write(RSFD rfd, const void *buf)
182 {
183     yaz_log(YLOG_FATAL, "ISAMB set type is read-only");
184     return -1;
185 }
186 /*
187  * Local variables:
188  * c-basic-offset: 4
189  * c-file-style: "Stroustrup"
190  * indent-tabs-mode: nil
191  * End:
192  * vim: shiftwidth=4 tabstop=8 expandtab
193  */
194