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