2 * Copyright (c) 1995-1997, Index Data.
3 * See the file LICENSE for details.
4 * Sebastian Hammer, Adam Dickmeiss
6 * $Log: d1_expout.c,v $
7 * Revision 1.9 1998-03-05 08:07:58 adam
8 * Make data1 to EXPLAIN ignore local tags in root.
10 * Revision 1.8 1998/02/11 11:53:35 adam
11 * Changed code so that it compiles as C++.
13 * Revision 1.7 1997/12/09 16:18:16 adam
14 * Work on EXPLAIN schema. First implementation of sub-schema facility
17 * Revision 1.6 1997/11/24 11:33:56 adam
18 * Using function odr_nullval() instead of global ODR_NULLVAL when
21 * Revision 1.5 1997/11/19 10:30:06 adam
24 * Revision 1.4 1997/11/18 09:51:08 adam
25 * Removed element num_children from data1_node. Minor changes in
28 * Revision 1.3 1997/09/17 12:10:36 adam
31 * Revision 1.2 1995/12/14 16:28:30 quinn
34 * Revision 1.1 1995/12/14 11:09:51 quinn
57 static int is_numeric_tag (ExpHandle *eh, data1_node *c)
59 if (!c || c->which != DATA1N_tag)
61 if (!c->u.tag.element)
63 logf(LOG_WARN, "Tag %s is local", c->u.tag.tag);
66 if (c->u.tag.element->tag->which != DATA1T_numeric)
68 logf(LOG_WARN, "Tag %s is not numeric", c->u.tag.tag);
71 if (eh->select && !c->u.tag.node_selected)
73 return c->u.tag.element->tag->value.numeric;
76 static int is_data_tag (ExpHandle *eh, data1_node *c)
78 if (!c || c->which != DATA1N_data)
80 if (eh->select && !c->u.tag.node_selected)
85 static int *f_integer(ExpHandle *eh, data1_node *c)
91 if (!is_data_tag (eh, c) || c->u.data.len > 63)
93 r = (int *)odr_malloc(eh->o, sizeof(*r));
94 sprintf(intbuf, "%.*s", 63, c->u.data.data);
99 static char *f_string(ExpHandle *eh, data1_node *c)
104 if (!is_data_tag (eh, c))
106 r = (char *)odr_malloc(eh->o, c->u.data.len+1);
107 memcpy(r, c->u.data.data, c->u.data.len);
108 r[c->u.data.len] = '\0';
112 static bool_t *f_bool(ExpHandle *eh, data1_node *c)
118 if (!is_data_tag (eh, c) || c->u.data.len > 63)
120 tf = (int *)odr_malloc (eh->o, sizeof(*tf));
121 sprintf(intbuf, "%.*s", c->u.data.len, c->u.data.data);
126 static Odr_oid *f_oid(ExpHandle *eh, data1_node *c, oid_class oclass)
130 oid_value value_for_this;
133 if (!is_data_tag (eh, c) || c->u.data.len > 63)
135 sprintf(oidstr, "%.*s", c->u.data.len, c->u.data.data);
136 value_for_this = oid_getvalbyname(oidstr);
137 if (value_for_this == VAL_NONE)
138 return NULL; /* fix */
143 ident.oclass = oclass;
144 ident.proto = PROTO_Z3950;
145 ident.value = value_for_this;
147 oid_ent_to_oid (&ident, oid_this);
149 return odr_oiddup (eh->o, oid_this);
152 static Z_IntUnit *f_intunit(ExpHandle *eh, data1_node *c)
158 static Z_HumanString *f_humstring(ExpHandle *eh, data1_node *c)
161 Z_HumanStringUnit *u;
164 if (!is_data_tag (eh, c))
166 r = (Z_HumanString *)odr_malloc(eh->o, sizeof(*r));
168 r->strings = (Z_HumanStringUnit **)odr_malloc(eh->o, sizeof(Z_HumanStringUnit*));
169 r->strings[0] = u = (Z_HumanStringUnit *)odr_malloc(eh->o, sizeof(*u));
171 u->text = (char *)odr_malloc(eh->o, c->u.data.len+1);
172 memcpy(u->text, c->u.data.data, c->u.data.len);
173 u->text[c->u.data.len] = '\0';
177 static Z_CommonInfo *f_commonInfo(ExpHandle *eh, data1_node *n)
179 Z_CommonInfo *res = (Z_CommonInfo *)odr_malloc(eh->o, sizeof(*res));
183 res->dateChanged = 0;
185 res->humanStringLanguage = 0;
188 for (c = n->child; c; c = c->next)
190 switch (is_numeric_tag (eh, c))
192 case 601: res->dateAdded = f_string(eh, c); break;
193 case 602: res->dateChanged = f_string(eh, c); break;
194 case 603: res->expiry = f_string(eh, c); break;
195 case 604: res->humanStringLanguage = f_string(eh, c); break;
201 Z_QueryTypeDetails *f_queryTypeDetails (ExpHandle *eh, data1_node *n)
207 Odr_oid **f_oid_seq (ExpHandle *eh, data1_node *n, int *num, oid_class oclass)
214 for (c = n->child ; c; c = c->next)
216 if (is_numeric_tag (eh, c) != 1000)
222 res = (int **)odr_malloc (eh->o, sizeof(*res) * (*num));
223 for (c = n->child, i = 0 ; c; c = c->next)
225 if (is_numeric_tag (eh, c) != 1000)
227 res[i++] = f_oid (eh, c, oclass);
232 char **f_string_seq (ExpHandle *eh, data1_node *n, int *num)
239 for (c = n->child ; c; c = c->next)
241 if (!is_numeric_tag (eh, c) != 1001)
247 res = (char **)odr_malloc (eh->o, sizeof(*res) * (*num));
248 for (c = n->child, i = 0 ; c; c = c->next)
250 if (!is_numeric_tag (eh, c) != 1001)
252 res[i++] = f_string (eh, c);
257 char **f_humstring_seq (ExpHandle *eh, data1_node *n, int *num)
264 Z_RpnCapabilities *f_rpnCapabilities (ExpHandle *eh, data1_node *c)
266 Z_RpnCapabilities *res = (Z_RpnCapabilities *)odr_malloc (eh->o, sizeof(*res));
268 res->num_operators = 0;
269 res->operators = NULL;
270 res->resultSetAsOperandSupported = eh->false_value;
271 res->restrictionOperandSupported = eh->false_value;
272 res->proximity = NULL;
273 /* fix */ /* 550 - 560 */
277 Z_QueryTypeDetails **f_queryTypesSupported (ExpHandle *eh, data1_node *c,
281 Z_QueryTypeDetails **res;
285 for (n = c->child; n; n = n->next)
287 if (is_numeric_tag(eh, n) != 519)
289 /* fix */ /* 518 and 520 */
294 res = (Z_QueryTypeDetails **)odr_malloc (eh->o, *num * sizeof(*res));
296 for (n = c->child; n; n = n->next)
298 if (is_numeric_tag(eh, n) == 519)
300 res[i] = (Z_QueryTypeDetails *)odr_malloc (eh->o, sizeof(**res));
301 res[i]->which = Z_QueryTypeDetails_rpn;
302 res[i]->u.rpn = f_rpnCapabilities (eh, n);
307 /* fix */ /* 518 and 520 */
312 static Z_AccessInfo *f_accessInfo(ExpHandle *eh, data1_node *n)
314 Z_AccessInfo *res = (Z_AccessInfo *)odr_malloc(eh->o, sizeof(*res));
317 res->num_queryTypesSupported = 0;
318 res->queryTypesSupported = 0;
319 res->num_diagnosticsSets = 0;
320 res->diagnosticsSets = 0;
321 res->num_attributeSetIds = 0;
322 res->attributeSetIds = 0;
323 res->num_schemas = 0;
325 res->num_recordSyntaxes = 0;
326 res->recordSyntaxes = 0;
327 res->num_resourceChallenges = 0;
328 res->resourceChallenges = 0;
329 res->restrictedAccess = 0;
331 res->num_variantSets = 0;
332 res->variantSets = 0;
333 res->num_elementSetNames = 0;
334 res->elementSetNames = 0;
335 res->num_unitSystems = 0;
336 res->unitSystems = 0;
338 for (c = n->child; c; c = c->next)
340 switch (is_numeric_tag (eh, c))
343 res->queryTypesSupported =
344 f_queryTypesSupported (eh, c, &res->num_queryTypesSupported);
347 res->diagnosticsSets =
348 f_oid_seq(eh, c, &res->num_diagnosticsSets, CLASS_DIAGSET);
351 res->attributeSetIds =
352 f_oid_seq(eh, c, &res->num_attributeSetIds, CLASS_ATTSET);
356 f_oid_seq(eh, c, &res->num_schemas, CLASS_SCHEMA);
359 res->recordSyntaxes =
360 f_oid_seq (eh, c, &res->num_recordSyntaxes, CLASS_RECSYN);
363 res->resourceChallenges =
364 f_oid_seq (eh, c, &res->num_resourceChallenges, CLASS_RESFORM);
366 case 513: res->restrictedAccess = NULL; break; /* fix */
367 case 514: res->costInfo = NULL; break; /* fix */
370 f_oid_seq (eh, c, &res->num_variantSets, CLASS_VARSET);
373 res->elementSetNames =
374 f_string_seq (eh, c, &res->num_elementSetNames);
377 res->unitSystems = f_string_seq (eh, c, &res->num_unitSystems);
384 static int *f_recordCount(ExpHandle *eh, data1_node *c, int *which)
386 int *r= (int *)odr_malloc(eh->o, sizeof(*r));
391 if (!is_numeric_tag (eh, c))
393 if (c->u.tag.element->tag->value.numeric == 210)
394 *wp = Z_Exp_RecordCount_actualNumber;
395 else if (c->u.tag.element->tag->value.numeric == 211)
396 *wp = Z_Exp_RecordCount_approxNumber;
399 if (!c->child || c->child->which != DATA1N_data)
401 sprintf(intbuf, "%.*s", 63, c->child->u.data.data);
406 static Z_ContactInfo *f_contactInfo(ExpHandle *eh, data1_node *n)
412 static Z_DatabaseList *f_databaseList(ExpHandle *eh, data1_node *n)
418 for (c = n->child; c; c = c->next)
420 if (!is_numeric_tag (eh, c) != 102)
427 res = (Z_DatabaseList *)odr_malloc (eh->o, sizeof(*res));
429 res->num_databases = i;
430 res->databases = (char **)odr_malloc (eh->o, sizeof(*res->databases) * i);
432 for (c = n->child; c; c = c->next)
434 if (!is_numeric_tag (eh, c) != 102)
436 res->databases[i++] = f_string (eh, c);
441 static Z_TargetInfo *f_targetInfo(ExpHandle *eh, data1_node *n)
443 Z_TargetInfo *res = (Z_TargetInfo *)odr_malloc(eh->o, sizeof(*res));
450 res->namedResultSets = 0;
451 res->multipleDbSearch = 0;
452 res->maxResultSets = 0;
453 res->maxResultSize = 0;
455 res->timeoutInterval = 0;
456 res->welcomeMessage = 0;
457 res->contactInfo = 0;
458 res->description = 0;
459 res->num_nicknames = 0;
462 res->paymentAddr = 0;
464 res->num_dbCombinations = 0;
465 res->dbCombinations = 0;
466 res->num_addresses = 0;
468 res->commonAccessInfo = 0;
470 for (c = n->child; c; c = c->next)
474 if (!is_numeric_tag (eh, c))
476 switch (c->u.tag.element->tag->value.numeric)
478 case 600: res->commonInfo = f_commonInfo(eh, c); break;
479 case 102: res->name = f_string(eh, c); break;
480 case 103: res->recentNews = f_humstring(eh, c); break;
481 case 104: res->icon = NULL; break; /* fix */
482 case 105: res->namedResultSets = f_bool(eh, c); break;
483 case 106: res->multipleDbSearch = f_bool(eh, c); break;
484 case 107: res->maxResultSets = f_integer(eh, c); break;
485 case 108: res->maxResultSize = f_integer(eh, c); break;
486 case 109: res->maxTerms = f_integer(eh, c); break;
487 case 110: res->timeoutInterval = f_intunit(eh, c); break;
488 case 111: res->welcomeMessage = f_humstring(eh, c); break;
489 case 112: res->contactInfo = f_contactInfo(eh, c); break;
490 case 113: res->description = f_humstring(eh, c); break;
492 res->num_nicknames = 0;
493 for (n = c->child; n; n = n->next)
495 if (is_numeric_tag(eh, n) != 102)
497 (res->num_nicknames)++;
499 if (res->num_nicknames)
501 (char **)odr_malloc (eh->o, res->num_nicknames
502 * sizeof(*res->nicknames));
503 for (n = c->child; n; n = n->next)
505 if (is_numeric_tag(eh, n) != 102)
507 res->nicknames[i++] = f_string (eh, n);
510 case 115: res->usageRest = f_humstring(eh, c); break;
511 case 116: res->paymentAddr = f_humstring(eh, c); break;
512 case 117: res->hours = f_humstring(eh, c); break;
514 res->num_dbCombinations = 0;
515 for (n = c->child; n; n = n->next)
517 if (!is_numeric_tag(eh, n) != 605)
519 (res->num_dbCombinations)++;
521 if (res->num_dbCombinations)
522 res->dbCombinations =
523 (Z_DatabaseList **)odr_malloc (eh->o, res->num_dbCombinations
524 * sizeof(*res->dbCombinations));
525 for (n = c->child; n; n = n->next)
527 if (!is_numeric_tag(eh, n) != 605)
529 res->dbCombinations[i++] = f_databaseList (eh, n);
532 case 119: res->addresses = 0; break; /* fix */
533 case 500: res->commonAccessInfo = f_accessInfo(eh, c); break;
536 if (!res->namedResultSets)
537 res->namedResultSets = eh->false_value;
538 if (!res->multipleDbSearch)
539 res->multipleDbSearch = eh->false_value;
543 static Z_DatabaseInfo *f_databaseInfo(ExpHandle *eh, data1_node *n)
545 Z_DatabaseInfo *res = (Z_DatabaseInfo *)odr_malloc(eh->o, sizeof(*res));
550 res->explainDatabase = 0;
551 res->num_nicknames = 0;
556 res->titleString = 0;
557 res->num_keywords = 0;
559 res->description = 0;
560 res->associatedDbs = 0;
562 res->disclaimers = 0;
564 res->recordCount = 0;
565 res->defaultOrder = 0;
566 res->avRecordSize = 0;
567 res->maxRecordSize = 0;
571 res->updateInterval = 0;
573 res->proprietary = 0;
574 res->copyrightText = 0;
575 res->copyrightNotice = 0;
576 res->producerContactInfo = 0;
577 res->supplierContactInfo = 0;
578 res->submissionContactInfo = 0;
581 for (c = n->child; c; c = c->next)
585 switch (is_numeric_tag (eh, c))
587 case 600: res->commonInfo = f_commonInfo(eh, c); break;
588 case 102: res->name = f_string(eh, c); break;
589 case 226: res->explainDatabase = odr_nullval(); break;
591 res->num_nicknames = 0;
592 for (n = c->child; n; n = n->next)
594 if (!is_numeric_tag(eh, n) ||
595 n->u.tag.element->tag->value.numeric != 102)
597 (res->num_nicknames)++;
599 if (res->num_nicknames)
601 (char **)odr_malloc (eh->o, res->num_nicknames
602 * sizeof(*res->nicknames));
603 for (n = c->child; n; n = n->next)
605 if (!is_numeric_tag(eh, n) ||
606 n->u.tag.element->tag->value.numeric != 102)
608 res->nicknames[i++] = f_string (eh, n);
611 case 104: res->icon = 0; break; /* fix */
612 case 201: res->userFee = f_bool(eh, c); break;
613 case 202: res->available = f_bool(eh, c); break;
614 case 203: res->titleString = f_humstring(eh, c); break;
616 res->num_keywords = 0;
617 for (n = c->child; n; n = n->next)
619 if (!is_numeric_tag(eh, n) != 1000)
621 (res->num_keywords)++;
623 if (res->num_keywords)
625 (Z_HumanString **)odr_malloc (eh->o, res->num_keywords
626 * sizeof(*res->keywords));
627 for (n = c->child; n; n = n->next)
629 if (!is_numeric_tag(eh, n) != 1000)
631 res->keywords[i++] = f_humstring (eh, n);
634 case 113: res->description = f_humstring(eh, c); break;
636 res->associatedDbs = f_databaseList (eh, c);
639 res->subDbs = f_databaseList (eh, c);
641 case 207: res->disclaimers = f_humstring(eh, c); break;
642 case 103: res->news = f_humstring(eh, c); break;
643 case 209: res->recordCount =
644 f_recordCount(eh, c, &res->recordCount_which); break;
645 case 212: res->defaultOrder = f_humstring(eh, c); break;
646 case 213: res->avRecordSize = f_integer(eh, c); break;
647 case 214: res->maxRecordSize = f_integer(eh, c); break;
648 case 215: res->hours = f_humstring(eh, c); break;
649 case 216: res->bestTime = f_humstring(eh, c); break;
650 case 217: res->lastUpdate = f_string(eh, c); break;
651 case 218: res->updateInterval = f_intunit(eh, c); break;
652 case 219: res->coverage = f_humstring(eh, c); break;
653 case 220: res->proprietary = f_bool(eh, c); break;
654 case 221: res->copyrightText = f_humstring(eh, c); break;
655 case 222: res->copyrightNotice = f_humstring(eh, c); break;
656 case 223: res->producerContactInfo = f_contactInfo(eh, c); break;
657 case 224: res->supplierContactInfo = f_contactInfo(eh, c); break;
658 case 225: res->submissionContactInfo = f_contactInfo(eh, c); break;
659 case 500: res->accessInfo = f_accessInfo(eh, c); break;
663 res->userFee = eh->false_value;
665 res->available = eh->true_value;
669 Z_ExplainRecord *data1_nodetoexplain (data1_handle dh, data1_node *n,
673 Z_ExplainRecord *res = (Z_ExplainRecord *)odr_malloc(o, sizeof(*res));
678 eh.false_value = (int *)odr_malloc(eh.o, sizeof(eh.false_value));
680 eh.true_value = (int *)odr_malloc(eh.o, sizeof(eh.true_value));
683 assert(n->which == DATA1N_root);
684 if (strcmp(n->u.root.type, "explain"))
686 logf(LOG_WARN, "Attempt to convert a non-Explain record");
689 for (n = n->child; n; n = n->next)
691 switch (is_numeric_tag (&eh, n))
694 res->which = Z_Explain_targetInfo;
695 if (!(res->u.targetInfo = f_targetInfo(&eh, n)))
699 res->which = Z_Explain_databaseInfo;
700 if (!(res->u.databaseInfo = f_databaseInfo(&eh, n)))
705 logf(LOG_WARN, "No category in Explain record");