Happy new year.
[idzebra-moved-to-github.git] / index / mod_grs_sgml.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
21 #include <assert.h>
22 #include <yaz/log.h>
23
24 #include <idzebra/recgrs.h>
25
26 struct sgml_getc_info {
27     char *buf;
28     int buf_size;
29     int size;
30     int off;
31     struct ZebraRecStream *stream;
32     off_t moffset;
33     WRBUF wrbuf;
34 };
35
36 int sgml_getc (void *clientData)
37 {
38     struct sgml_getc_info *p = (struct sgml_getc_info *) clientData;
39     int res;
40     
41     if (p->off < p->size)
42         return p->buf[(p->off)++];
43     if (p->size < p->buf_size)
44         return 0;
45     p->moffset += p->off;
46     p->off = 0;
47     p->size = 0;
48     res = p->stream->readf(p->stream, p->buf, p->buf_size);
49     if (res > 0)
50     {
51         p->size += res;
52         return p->buf[(p->off)++];
53     }
54     return 0;
55 }
56
57 static data1_node *grs_read_sgml (struct grs_read_info *p)
58 {
59     struct sgml_getc_info *sgi = (struct sgml_getc_info *) p->clientData;
60     data1_node *node;
61     int res;
62     
63     sgi->moffset = p->stream->tellf(p->stream);
64     sgi->stream = p->stream;
65     sgi->off = 0;
66     sgi->size = 0;
67     res = sgi->stream->readf(sgi->stream, sgi->buf, sgi->buf_size);
68     if (res > 0)
69         sgi->size += res;
70     else
71         return 0;
72     node = data1_read_nodex(p->dh, p->mem, sgml_getc, sgi, sgi->wrbuf);
73     if (node && p->stream->endf)
74     {
75         off_t end_offset = sgi->moffset + sgi->off;
76         p->stream->endf(sgi->stream, &end_offset);
77     }
78     return node;
79 }
80
81 static void *grs_init_sgml(Res res, RecType recType)
82 {
83     struct sgml_getc_info *p = (struct sgml_getc_info *) xmalloc (sizeof(*p));
84     p->buf_size = 512;
85     p->buf = xmalloc (p->buf_size);
86     p->wrbuf = wrbuf_alloc();
87     return p;
88 }
89
90 static ZEBRA_RES grs_config_sgml(void *clientData, Res res, const char *args)
91 {
92     return ZEBRA_OK;
93 }
94
95 static void grs_destroy_sgml(void *clientData)
96 {
97     struct sgml_getc_info *p = (struct sgml_getc_info *) clientData;
98
99     wrbuf_destroy(p->wrbuf);
100     xfree(p->buf);
101     xfree(p);
102 }
103
104 static int grs_extract_sgml(void *clientData, struct recExtractCtrl *ctrl)
105 {
106     return zebra_grs_extract(clientData, ctrl, grs_read_sgml);
107 }
108
109 static int grs_retrieve_sgml(void *clientData, struct recRetrieveCtrl *ctrl)
110 {
111     return zebra_grs_retrieve(clientData, ctrl, grs_read_sgml);
112 }
113
114 static struct recType grs_type_sgml =
115 {
116     0,
117     "grs.sgml",
118     grs_init_sgml,
119     grs_config_sgml,
120     grs_destroy_sgml,
121     grs_extract_sgml,
122     grs_retrieve_sgml
123 };
124
125 RecType
126 #ifdef IDZEBRA_STATIC_GRS_SGML
127 idzebra_filter_grs_sgml
128 #else
129 idzebra_filter
130 #endif
131
132 [] = {
133     &grs_type_sgml,
134     0,
135 };
136 /*
137  * Local variables:
138  * c-basic-offset: 4
139  * c-file-style: "Stroustrup"
140  * indent-tabs-mode: nil
141  * End:
142  * vim: shiftwidth=4 tabstop=8 expandtab
143  */
144