a9eddf4d1586ba42785ca4689cd7fcffd332d4d4
[idzebra-moved-to-github.git] / data1 / d1_sutrs.c
1 /* $Id: d1_sutrs.c,v 1.7 2007-01-15 15:10:14 adam Exp $
2    Copyright (C) 1995-2007
3    Index Data ApS
4
5 This file is part of the Zebra server.
6
7 Zebra is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 Zebra is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20
21 */
22
23 /* converts data1 tree to SUTRS record */
24
25 #include <idzebra/data1.h>
26
27 #define NTOBUF_INDENT   2
28 #define NTOBUF_MARGIN 75
29
30 static int wordlen(char *b, int i)
31 {
32     int l = 0;
33
34     while (i && !d1_isspace(*b))
35         l++, b++, i--;
36     return l;
37 }
38
39 static int nodetobuf(data1_node *n, int select, WRBUF b, int indent, int col)
40 {
41     data1_node *c;
42     char line[1024];
43
44     for (c = n->child; c; c = c->next)
45     {
46         char *tag;
47
48         if (c->which == DATA1N_tag)
49         {
50             if (select && !c->u.tag.node_selected)
51                 continue;
52             if (c->u.tag.element && c->u.tag.element->tag)
53                 tag = c->u.tag.element->tag->names->name; /* first name */
54             else
55                 tag = c->u.tag.tag; /* local string tag */
56             if (data1_matchstr(tag, "wellknown")) /* skip wellknown */
57             {
58                 if (col)
59                     wrbuf_putc(b, '\n');
60                 sprintf(line, "%*s%s:", indent * NTOBUF_INDENT, "", tag);
61                 wrbuf_write(b, line, strlen(line));
62                 col = strlen(line);
63             }
64             if (nodetobuf(c, select, b, indent+1, col) < 0)
65                 return 0;
66         }
67         else if (c->which == DATA1N_data)
68         {
69             char *p = c->u.data.data;
70             int l = c->u.data.len;
71             int first = 0;
72
73             if ((c->u.data.what == DATA1I_text ||
74                 c->u.data.what == DATA1I_xmltext) && c->u.data.formatted_text)
75             {
76                 wrbuf_putc(b, '\n');
77                 wrbuf_write(b, c->u.data.data, c->u.data.len);
78                 sprintf(line, "%*s", indent * NTOBUF_INDENT, "");
79                 wrbuf_write(b, line, strlen(line));
80                 col = indent * NTOBUF_INDENT;
81             }
82             else if (c->u.data.what == DATA1I_text ||
83                      c->u.data.what == DATA1I_xmltext)
84             {
85                 while (l)
86                 {
87                     int wlen;
88
89                     while (l && d1_isspace(*p))
90                         p++, l--;
91                     if (!l)
92                         break;
93                     /* break if we'll cross margin and word is not too long */
94                     if (col + (wlen = wordlen(p, l)) > NTOBUF_MARGIN && wlen <
95                         NTOBUF_MARGIN - indent * NTOBUF_INDENT)
96                     {
97                         sprintf(line, "\n%*s", indent * NTOBUF_INDENT, "");
98                         wrbuf_write(b, line, strlen(line));
99                         col = indent * NTOBUF_INDENT;
100                         first = 1;
101                     }
102                     if (!first)
103                     {
104                         wrbuf_putc(b, ' ');
105                         col++;
106                     }
107                     while (l && !d1_isspace(*p))
108                     {
109                         if (col > NTOBUF_MARGIN)
110                         {
111                             wrbuf_putc(b, '=');
112                             wrbuf_putc(b, '\n');
113                             sprintf(line, "%*s", indent * NTOBUF_INDENT, "");
114                             wrbuf_write(b, line, strlen(line));
115                             col = indent * NTOBUF_INDENT;
116                         }
117                         wrbuf_putc(b, *p);
118                         p++;
119                         l--;
120                         col++;
121                     }
122                     first = 0;
123                 }
124             }
125             else if (c->u.data.what == DATA1I_num)
126             {
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 /*
136  * Return area containing SUTRS-formatted data. Ownership of this data
137  * remains in this module, and the buffer is reused on next call. This may
138  * need changing.
139  */
140
141 char *data1_nodetobuf (data1_handle dh, data1_node *n, int select, int *len)
142 {
143     WRBUF b = data1_get_wrbuf (dh);
144
145     wrbuf_rewind(b);
146     if (nodetobuf(n, select, b, 0, 0))
147         return 0;
148     wrbuf_putc(b, '\n');
149     *len = wrbuf_len(b);
150     return wrbuf_buf(b);
151 }
152 /*
153  * Local variables:
154  * c-basic-offset: 4
155  * indent-tabs-mode: nil
156  * End:
157  * vim: shiftwidth=4 tabstop=8 expandtab
158  */
159