*** empty log message ***
[yaz-moved-to-github.git] / retrieval / d1_expout.c
1 /*
2  * Copyright (c) 1995, Index Data.
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: d1_expout.c,v $
7  * Revision 1.2  1995-12-14 16:28:30  quinn
8  * More explain stuff.
9  *
10  * Revision 1.1  1995/12/14  11:09:51  quinn
11  * Work on Explain
12  *
13  *
14  */
15
16 #include <assert.h>
17 #include <string.h>
18 #include <stdlib.h>
19
20 #include <log.h>
21 #include <proto.h>
22 #include <data1.h>
23
24 static int *f_integer(data1_node *c, ODR o)
25 {
26     int *r;
27     char intbuf[64];
28
29     if (!c->child || c->child->which != DATA1N_data ||
30         c->child->u.data.len > 63)
31         return 0;
32     r = odr_malloc(o, sizeof(*r));
33     sprintf(intbuf, "%.*s", 63, c->child->u.data.data);
34     *r = atoi(intbuf);
35     return r;
36 }
37
38 static char *f_string(data1_node *c, ODR o)
39 {
40     char *r;
41
42     if (!c->child || c->child->which != DATA1N_data)
43         return 0;
44     r = odr_malloc(o, c->child->u.data.len+1);
45     memcpy(r, c->child->u.data.data, c->child->u.data.len);
46     r[c->child->u.data.len] = '\0';
47     return r;
48 }
49
50 static bool_t *f_bool(data1_node *c, ODR o)
51 {
52     return 0;
53 }
54
55 static Z_IntUnit *f_intunit(data1_node *c, ODR o)
56 {
57     return 0;
58 }
59
60 static Z_HumanString *f_humstring(data1_node *c, ODR o)
61 {
62     Z_HumanString *r;
63     Z_HumanStringUnit *u;
64
65     if (!c->child || c->child->which != DATA1N_data)
66         return 0;
67     r = odr_malloc(o, sizeof(*r));
68     r->num_strings = 1;
69     r->strings = odr_malloc(o, sizeof(Z_HumanStringUnit*));
70     r->strings[0] = u = odr_malloc(o, sizeof(*u));
71     u->language = 0;
72     u->text = odr_malloc(o, c->child->u.data.len+1);
73     memcpy(u->text, c->child->u.data.data, c->child->u.data.len);
74     u->text[c->child->u.data.len] = '\0';
75     return r;
76 }
77
78 static Z_CommonInfo *f_commonInfo(data1_node *n, int select, ODR o)
79 {
80     Z_CommonInfo *res = odr_malloc(o, sizeof(*res));
81     data1_node *c;
82
83     res->dateAdded = 0;
84     res->dateChanged = 0;
85     res->expiry = 0;
86     res->humanStringLanguage = 0;
87     res->otherInfo = 0;
88
89     for (c = n->child; c; c = c->next)
90     {
91         if (c->which != DATA1N_tag || !c->u.tag.element)
92         {
93             logf(LOG_WARN, "Malformed explain record");
94             return 0;
95         }
96         if (select && !c->u.tag.node_selected)
97             continue;
98         switch (c->u.tag.element->tag->value.numeric)
99         {
100             case 601: res->dateAdded = f_string(c, o); break;
101             case 602: res->dateChanged = f_string(c, o); break;
102             case 603: res->expiry = f_string(c, o); break;
103             case 604: res->humanStringLanguage = f_string(c, o); break;
104             /* otherInfo? */
105             default:
106                 logf(LOG_WARN, "Bad child in commonInfo");
107                 return 0;
108         }
109     }
110     return res;
111 }
112
113 static Z_AccessInfo *f_accessInfo(data1_node *n, int select, ODR o)
114 {
115     Z_AccessInfo *res = odr_malloc(o, sizeof(*res));
116     data1_node *c;
117
118     res->num_queryTypesSupported = 0;
119     res->queryTypesSupported = 0;
120     res->num_diagnosticsSets = 0;
121     res->diagnosticsSets = 0;
122     res->num_attributeSetIds = 0;
123     res->attributeSetIds = 0;
124     res->num_schemas = 0;
125     res->schemas = 0;
126     res->num_recordSyntaxes = 0;
127     res->recordSyntaxes = 0;
128     res->num_resourceChallenges = 0;
129     res->resourceChallenges = 0;
130     res->restrictedAccess = 0;
131     res->costInfo = 0;
132     res->num_variantSets = 0;
133     res->variantSets = 0;
134     res->num_elementSetNames = 0;
135     res->elementSetNames = 0;
136     res->num_unitSystems = 0;
137     res->unitSystems = 0;
138
139     for (c = n->child; c; c = c->next)
140     {
141         if (c->which != DATA1N_tag || !c->u.tag.element)
142         {
143             logf(LOG_WARN, "Malformed explain record");
144             return 0;
145         }
146         if (select && !c->u.tag.node_selected)
147             continue;
148         /* switch-statement here */
149     }
150     return res;
151 }
152
153 static int *f_recordCount(data1_node *c, ODR o, void *which)
154 {
155     int *r= odr_malloc(o, sizeof(*r));
156     int *wp = which;
157     char intbuf[64];
158
159     if (!c->child || c->child->which != DATA1N_tag || !c->child->u.tag.element)
160         return 0;
161     if (c->u.tag.element->tag->value.numeric == 210)
162         *wp = Z_Exp_RecordCount_actualNumber;
163     else if (c->u.tag.element->tag->value.numeric == 211)
164         *wp = Z_Exp_RecordCount_approxNumber;
165     else
166         return 0;
167     c = c->child;
168     if (!c->child || c->child->which != DATA1N_data)
169         return 0;
170     sprintf(intbuf, "%.*s", 63, c->child->u.data.data);
171     *r = atoi(intbuf);
172     return r;
173 }
174
175 static Z_ContactInfo *f_contactInfo(data1_node *n, ODR o)
176 {
177     return 0;
178 }
179
180 static Z_TargetInfo *f_targetInfo(data1_node *n, int select, ODR o)
181 {
182     Z_TargetInfo *res = odr_malloc(o, sizeof(*res));
183     data1_node *c;
184     static bool_t fl = 0;
185
186     res->commonInfo = 0;
187     res->name = 0;
188     res->recentNews = 0;
189     res->icon = 0;
190     res->namedResultSets = &fl;
191     res->multipleDbSearch = &fl;
192     res->maxResultSets = 0;
193     res->maxResultSize = 0;
194     res->maxTerms = 0;
195     res->timeoutInterval = 0;
196     res->welcomeMessage = 0;
197     res->contactInfo = 0;
198     res->description = 0;
199     res->num_nicknames = 0;
200     res->nicknames = 0;
201     res->usageRest = 0;
202     res->paymentAddr = 0;
203     res->hours = 0;
204     res->num_dbCombinations = 0;
205     res->dbCombinations = 0;
206     res->num_addresses = 0;
207     res->addresses = 0;
208     res->commonAccessInfo = 0;
209
210     for (c = n->child; c; c = c->next)
211     {
212         if (c->which != DATA1N_tag || !c->u.tag.element)
213         {
214             logf(LOG_WARN, "Malformed explain record");
215             return 0;
216         }
217         if (select && !c->u.tag.node_selected)
218             continue;
219         switch (c->u.tag.element->tag->value.numeric)
220         {
221             case 600: res->commonInfo = f_commonInfo(c, select, o);break;
222             case 102: res->name = f_string(c, o); break;
223             case 103: res->recentNews = f_humstring(c, o); break;
224             case 104: break; /* icon */
225             case 105: res->namedResultSets = f_bool(c, o); break;
226             case 106: res->multipleDbSearch = f_bool(c, o); break;
227             case 107: res->maxResultSets = f_integer(c, o); break;
228             case 108: res->maxResultSize = f_integer(c, o); break;
229             case 109: res->maxTerms = f_integer(c, o); break;
230             case 110: res->timeoutInterval = f_intunit(c, o); break;
231             case 111: res->welcomeMessage = f_humstring(c, o); break;
232             case 112: res->contactInfo = f_contactInfo(c, o); break;
233             case 113: res->description = f_humstring(c, o); break;
234             case 114: break; /* nicknames */
235             case 115: res->usageRest = f_humstring(c, o); break;
236             case 116: res->paymentAddr = f_humstring(c, o); break;
237             case 117: res->hours = f_humstring(c, o); break;
238             case 118: break; /* dbcombinations */
239             case 119: break; /* addresses */
240             case 500: res->commonAccessInfo = f_accessInfo(c, select, o); break;
241             default:
242                 logf(LOG_WARN, "Unknown target-info element");
243         }
244     }
245     return res;
246 }
247
248 static Z_DatabaseInfo *f_databaseInfo(data1_node *n, int select, ODR o)
249 {
250     Z_DatabaseInfo *res = odr_malloc(o, sizeof(*res));
251     data1_node *c;
252     static bool_t fl = 0, tr = 1;
253
254     res->commonInfo = 0;
255     res->name = 0;
256     res->explainDatabase = 0;
257     res->num_nicknames = 0;
258     res->nicknames = 0;
259     res->icon = 0;
260     res->userFee = &fl;
261     res->available = &tr;
262     res->titleString = 0;
263     res->num_keywords = 0;
264     res->keywords = 0;
265     res->description = 0;
266     res->associatedDbs = 0;
267     res->subDbs = 0;
268     res->disclaimers = 0;
269     res->news = 0;
270     res->recordCount = 0;
271     res->defaultOrder = 0;
272     res->avRecordSize = 0;
273     res->maxRecordSize = 0;
274     res->hours = 0;
275     res->bestTime = 0;
276     res->lastUpdate = 0;
277     res->updateInterval = 0;
278     res->coverage = 0;
279     res->proprietary = 0;
280     res->copyrightText = 0;
281     res->copyrightNotice = 0;
282     res->producerContactInfo = 0;
283     res->supplierContactInfo = 0;
284     res->submissionContactInfo = 0;
285     res->accessInfo = 0;
286
287     for (c = n->child; c; c = c->next)
288     {
289         if (c->which != DATA1N_tag || !c->u.tag.element)
290         {
291             logf(LOG_WARN, "Malformed explain record");
292             return 0;
293         }
294         if (select && !c->u.tag.node_selected)
295             continue;
296         switch (c->u.tag.element->tag->value.numeric)
297         {
298             case 600: res->commonInfo = f_commonInfo(c, select, o); break;
299             case 102: res->name = f_string(c, o); break;
300             case 226: res->explainDatabase = ODR_NULLVAL; break;
301             case 114:
302                 res->num_nicknames = 0; res->nicknames = 0; break; /* fix */
303             case 104: res->icon = 0; break;      /* fix */
304             case 201: res->userFee = f_bool(c, o); break;
305             case 202: res->available = f_bool(c, o); break;
306             case 203: res->titleString = f_humstring(c, o); break;
307             case 227: res->num_keywords = 0; res->keywords = 0; break; /* fix */
308             case 113: res->description = f_humstring(c, o); break;
309             case 205: res->associatedDbs = 0; break; /* fix */
310             case 206: res->subDbs = 0; break; /* fix */
311             case 207: res->disclaimers = f_humstring(c, o); break;
312             case 103: res->news = f_humstring(c, o); break;
313             case 209: res->recordCount =
314                 f_recordCount(c, o, &res->recordCount_which); break;
315             case 212: res->defaultOrder = f_humstring(c, o); break;
316             case 213: res->avRecordSize = f_integer(c, o); break;
317             case 214: res->maxRecordSize = f_integer(c, o); break;
318             case 215: res->hours = f_humstring(c, o); break;
319             case 216: res->bestTime = f_humstring(c, o); break;
320             case 217: res->lastUpdate = f_string(c, o); break;
321             case 218: res->updateInterval = f_intunit(c, o); break;
322             case 219: res->coverage = f_humstring(c, o); break;
323             case 220: res->proprietary = f_bool(c, o); break;
324             case 221: res->copyrightText = f_humstring(c, o); break;
325             case 222: res->copyrightNotice = f_humstring(c, o); break;
326             case 223: res->producerContactInfo = f_contactInfo(c, o); break;
327             case 224: res->supplierContactInfo = f_contactInfo(c, o); break;
328             case 225: res->submissionContactInfo = f_contactInfo(c, o); break;
329             case 500: res->accessInfo = f_accessInfo(c, select, o); break;
330             default:
331                 logf(LOG_WARN, "Unknown element in databaseInfo");
332         }
333     }
334     return res;
335 }
336
337 Z_ExplainRecord *data1_nodetoexplain(data1_node *n, int select, ODR o)
338 {
339     Z_ExplainRecord *res = odr_malloc(o, sizeof(*res));
340
341     assert(n->which == DATA1N_root);
342     if (strcmp(n->u.root.type, "explain"))
343     {
344         logf(LOG_WARN, "Attempt to convert a non-Explain record");
345         return 0;
346     }
347     if (n->num_children != 1 || n->child->which != DATA1N_tag ||
348         !n->u.tag.element)
349     {
350         logf(LOG_WARN, "Explain record should have one exactly one child");
351         return 0;
352     }
353     switch (n->child->u.tag.element->tag->value.numeric)
354     {
355         case 0: res->which = Z_Explain_targetInfo;
356             if (!(res->u.targetInfo = f_targetInfo(n->child, select, o)))
357                 return 0;
358             break;
359         case 1: res->which = Z_Explain_databaseInfo;
360             if (!(res->u.databaseInfo = f_databaseInfo(n->child, select, o)))
361                 return 0;
362             break;
363         default:
364             logf(LOG_WARN, "Unknown explain category");
365             return 0;
366     }
367     return res;
368 }