removed yaz-date.h
[yaz-moved-to-github.git] / retrieval / d1_expat.c
1 /*
2  * Copyright (c) 2002, Index Data.
3  * See the file LICENSE for details.
4  *
5  * $Id: d1_expat.c,v 1.1 2002-05-13 14:13:37 adam Exp $
6  */
7
8 #if HAVE_EXPAT_H
9
10 #include <assert.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13
14 #include <yaz/xmalloc.h>
15 #include <yaz/log.h>
16 #include <yaz/data1.h>
17
18 #include <expat.h>
19
20 struct user_info {
21     data1_node *d1_stack[256];
22     int level;
23     data1_handle dh;
24     NMEM nmem;
25 };
26
27 static void cb_start (void *user, const char *el, const char **attr)
28 {
29     struct user_info *ui = (struct user_info*) user;
30     if (ui->level)
31     {
32         ui->d1_stack[ui->level] = data1_mk_tag (ui->dh, ui->nmem, el, attr,
33                                                 ui->d1_stack[ui->level-1]);
34     }
35     else
36     {
37         ui->d1_stack[0] = data1_mk_root (ui->dh, ui->nmem, el);
38     }
39     ui->level++;
40 }
41
42 static void cb_end (void *user, const char *el)
43 {
44     struct user_info *ui = (struct user_info*) user;
45
46     ui->level--;
47 }
48
49 static void cb_chardata (void *user, const char *s, int len)
50 {
51     struct user_info *ui = (struct user_info*) user;
52     ui->d1_stack[ui->level] = data1_mk_text_n (ui->dh, ui->nmem, s, len,
53                                                ui->d1_stack[ui->level -1]);
54 }
55
56 #define XML_CHUNK 1024
57
58 data1_node *data1_read_xml (data1_handle dh,
59                             int (*rf)(void *, char *, size_t), void *fh,
60                             NMEM m)
61 {
62     XML_Parser parser;
63     struct user_info uinfo;
64     int done = 0;
65
66     uinfo.level = 0;
67     uinfo.dh = dh;
68     uinfo.d1_stack[0] = 0;
69     uinfo.nmem = m;
70
71     parser = XML_ParserCreate (0 /* encoding */);
72     
73     XML_SetElementHandler (parser, cb_start, cb_end);
74     XML_SetCharacterDataHandler (parser, cb_chardata);
75     XML_SetUserData (parser, &uinfo);
76
77     while (!done)
78     {
79         int r;
80         void *buf = XML_GetBuffer (parser, XML_CHUNK);
81         if (!buf)
82         {
83             /* error */
84             return 0;
85         }
86         r = (*rf)(fh, buf, XML_CHUNK);
87         if (r < 0)
88         {
89             /* error */
90             return 0;
91         }
92         else if (r == 0)
93             done = 1;
94         XML_ParseBuffer (parser, r, done);
95     }
96     XML_ParserFree (parser);
97     return uinfo.d1_stack[0];
98 }
99
100 #endif