Changed the way attribute sets are handled by the retriaval module.
[yaz-moved-to-github.git] / retrieval / d1_write.c
1 /*
2  * Copyright (c) 1995-1997, Index Data.
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: d1_write.c,v $
7  * Revision 1.4  1998-05-18 13:07:08  adam
8  * Changed the way attribute sets are handled by the retriaval module.
9  * Extended Explain conversion / schema.
10  * Modified server and client to work with ASN.1 compiled protocol handlers.
11  *
12  * Revision 1.3  1997/09/17 12:10:39  adam
13  * YAZ version 1.4.
14  *
15  * Revision 1.2  1995/12/13 17:14:27  quinn
16  * *** empty log message ***
17  *
18  * Revision 1.1  1995/12/13  15:38:43  quinn
19  * Added SGML-output filter.
20  *
21  *
22  */
23
24 #include <string.h>
25 #include <ctype.h>
26
27 #include <data1.h>
28 #include <wrbuf.h>
29
30 #define IDSGML_MARGIN 75
31
32 static int wordlen(char *b)
33 {
34     int l = 0;
35
36     while (*b && !isspace(*b))
37         l++, b++;
38     return l;
39 }
40
41 static int nodetoidsgml(data1_node *n, int select, WRBUF b, int col)
42 {
43     data1_node *c;
44     char line[1024];
45
46     for (c = n->child; c; c = c->next)
47     {
48         char *tag;
49
50         if (c->which == DATA1N_tag)
51         {
52             if (select && c->u.tag.node_selected)
53                 continue;
54             if (c->u.tag.element && c->u.tag.element->tag)
55                 tag = c->u.tag.element->tag->names->name; /* first name */
56             else
57                 tag = c->u.tag.tag; /* local string tag */
58             if (data1_matchstr(tag, "wellknown")) /* skip wellknown */
59             {
60                 sprintf(line, "<%s>\n", tag);
61                 wrbuf_write(b, line, strlen(line));
62                 col = 0;
63             }
64             if (nodetoidsgml(c, select, b, col) < 0)
65                 return -1;
66             wrbuf_write(b, "</>\n", 4);
67             col = 0;
68         }
69         else if (c->which == DATA1N_data)
70         {
71             char *p = c->u.data.data;
72             int l = c->u.data.len;
73             int first = 1;
74
75             switch (c->u.data.what)
76             {
77             case DATA1I_text:
78                 while (l)
79                 {
80                     int wlen;
81
82                     while (l && isspace(*p))
83                         p++, l--;
84                     if (!l)
85                         break;
86                     /* break if we'll cross margin and word is not too long */
87                     if (col + (wlen = wordlen(p)) > IDSGML_MARGIN && wlen <
88                         IDSGML_MARGIN)
89                     {
90                         sprintf(line, "\n");
91                         col = 0;
92                         wrbuf_write(b, line, strlen(line));
93                         first = 1;
94                     }
95                     if (!first)
96                     {
97                         wrbuf_putc(b, ' ');
98                         col++;
99                     }
100                     while (l && !isspace(*p))
101                     {
102 #if 0
103                         if (col > NTOBUF_MARGIN)
104                         {
105                             wrbuf_putc(b, '=');
106                             wrbuf_putc(b, '\n');
107                             sprintf(line, "%*s", indent * NTOBUF_INDENT, "");
108                             wrbuf_write(b, line, strlen(line));
109                             col = indent * NTOBUF_INDENT;
110                         }
111 #endif
112                         wrbuf_putc(b, *p);
113                         p++;
114                         l--;
115                         col++;
116                     }
117                     first = 0;
118                 }
119                 wrbuf_write(b, "\n", 1);
120                 col = 0;
121                 break;
122             case DATA1I_num:
123                 wrbuf_putc(b, ' ');
124                 wrbuf_write(b, c->u.data.data, c->u.data.len);
125                 break;
126             case DATA1I_oid:
127                 wrbuf_putc(b, ' ');
128                 wrbuf_write(b, c->u.data.data, c->u.data.len);
129             }
130         }
131     }
132     return 0;
133 }
134
135 char *data1_nodetoidsgml (data1_handle dh, data1_node *n, int select, int *len)
136 {
137     WRBUF b = data1_get_wrbuf (dh);
138     char line[1024];
139
140     wrbuf_rewind(b);
141     
142     sprintf(line, "<%s>\n", n->u.root.type);
143     wrbuf_write(b, line, strlen(line));
144     if (nodetoidsgml(n, select, b, 0))
145         return 0;
146     sprintf(line, "</%s>\n", n->u.root.type);
147     wrbuf_write(b, line, strlen(line));
148     *len = wrbuf_len(b);
149     return wrbuf_buf(b);
150 }