2 * Copyright (c) 1995-1998, Index Data.
3 * See the file LICENSE for details.
4 * Sebastian Hammer, Adam Dickmeiss
6 * $Log: d1_expout.c,v $
7 * Revision 1.10 1998-03-31 15:13:20 adam
8 * Development towards compiled ASN.1.
10 * Revision 1.9 1998/03/05 08:07:58 adam
11 * Make data1 to EXPLAIN ignore local tags in root.
13 * Revision 1.8 1998/02/11 11:53:35 adam
14 * Changed code so that it compiles as C++.
16 * Revision 1.7 1997/12/09 16:18:16 adam
17 * Work on EXPLAIN schema. First implementation of sub-schema facility
20 * Revision 1.6 1997/11/24 11:33:56 adam
21 * Using function odr_nullval() instead of global ODR_NULLVAL when
24 * Revision 1.5 1997/11/19 10:30:06 adam
27 * Revision 1.4 1997/11/18 09:51:08 adam
28 * Removed element num_children from data1_node. Minor changes in
31 * Revision 1.3 1997/09/17 12:10:36 adam
34 * Revision 1.2 1995/12/14 16:28:30 quinn
37 * Revision 1.1 1995/12/14 11:09:51 quinn
60 static int is_numeric_tag (ExpHandle *eh, data1_node *c)
62 if (!c || c->which != DATA1N_tag)
64 if (!c->u.tag.element)
66 logf(LOG_WARN, "Tag %s is local", c->u.tag.tag);
69 if (c->u.tag.element->tag->which != DATA1T_numeric)
71 logf(LOG_WARN, "Tag %s is not numeric", c->u.tag.tag);
74 if (eh->select && !c->u.tag.node_selected)
76 return c->u.tag.element->tag->value.numeric;
79 static int is_data_tag (ExpHandle *eh, data1_node *c)
81 if (!c || c->which != DATA1N_data)
83 if (eh->select && !c->u.tag.node_selected)
88 static int *f_integer(ExpHandle *eh, data1_node *c)
94 if (!is_data_tag (eh, c) || c->u.data.len > 63)
96 r = (int *)odr_malloc(eh->o, sizeof(*r));
97 sprintf(intbuf, "%.*s", 63, c->u.data.data);
102 static char *f_string(ExpHandle *eh, data1_node *c)
107 if (!is_data_tag (eh, c))
109 r = (char *)odr_malloc(eh->o, c->u.data.len+1);
110 memcpy(r, c->u.data.data, c->u.data.len);
111 r[c->u.data.len] = '\0';
115 static bool_t *f_bool(ExpHandle *eh, data1_node *c)
121 if (!is_data_tag (eh, c) || c->u.data.len > 63)
123 tf = (int *)odr_malloc (eh->o, sizeof(*tf));
124 sprintf(intbuf, "%.*s", c->u.data.len, c->u.data.data);
129 static Odr_oid *f_oid(ExpHandle *eh, data1_node *c, oid_class oclass)
133 oid_value value_for_this;
136 if (!is_data_tag (eh, c) || c->u.data.len > 63)
138 sprintf(oidstr, "%.*s", c->u.data.len, c->u.data.data);
139 value_for_this = oid_getvalbyname(oidstr);
140 if (value_for_this == VAL_NONE)
141 return NULL; /* fix */
146 ident.oclass = oclass;
147 ident.proto = PROTO_Z3950;
148 ident.value = value_for_this;
150 oid_ent_to_oid (&ident, oid_this);
152 return odr_oiddup (eh->o, oid_this);
155 static Z_IntUnit *f_intunit(ExpHandle *eh, data1_node *c)
161 static Z_HumanString *f_humstring(ExpHandle *eh, data1_node *c)
164 Z_HumanStringUnit *u;
167 if (!is_data_tag (eh, c))
169 r = (Z_HumanString *)odr_malloc(eh->o, sizeof(*r));
171 r->strings = (Z_HumanStringUnit **)odr_malloc(eh->o, sizeof(Z_HumanStringUnit*));
172 r->strings[0] = u = (Z_HumanStringUnit *)odr_malloc(eh->o, sizeof(*u));
174 u->text = (char *)odr_malloc(eh->o, c->u.data.len+1);
175 memcpy(u->text, c->u.data.data, c->u.data.len);
176 u->text[c->u.data.len] = '\0';
180 static Z_CommonInfo *f_commonInfo(ExpHandle *eh, data1_node *n)
182 Z_CommonInfo *res = (Z_CommonInfo *)odr_malloc(eh->o, sizeof(*res));
186 res->dateChanged = 0;
188 res->humanStringLanguage = 0;
191 for (c = n->child; c; c = c->next)
193 switch (is_numeric_tag (eh, c))
195 case 601: res->dateAdded = f_string(eh, c); break;
196 case 602: res->dateChanged = f_string(eh, c); break;
197 case 603: res->expiry = f_string(eh, c); break;
198 case 604: res->humanStringLanguage = f_string(eh, c); break;
204 Z_QueryTypeDetails *f_queryTypeDetails (ExpHandle *eh, data1_node *n)
210 Odr_oid **f_oid_seq (ExpHandle *eh, data1_node *n, int *num, oid_class oclass)
217 for (c = n->child ; c; c = c->next)
219 if (is_numeric_tag (eh, c) != 1000)
225 res = (int **)odr_malloc (eh->o, sizeof(*res) * (*num));
226 for (c = n->child, i = 0 ; c; c = c->next)
228 if (is_numeric_tag (eh, c) != 1000)
230 res[i++] = f_oid (eh, c, oclass);
235 char **f_string_seq (ExpHandle *eh, data1_node *n, int *num)
242 for (c = n->child ; c; c = c->next)
244 if (!is_numeric_tag (eh, c) != 1001)
250 res = (char **)odr_malloc (eh->o, sizeof(*res) * (*num));
251 for (c = n->child, i = 0 ; c; c = c->next)
253 if (!is_numeric_tag (eh, c) != 1001)
255 res[i++] = f_string (eh, c);
260 char **f_humstring_seq (ExpHandle *eh, data1_node *n, int *num)
267 Z_RpnCapabilities *f_rpnCapabilities (ExpHandle *eh, data1_node *c)
269 Z_RpnCapabilities *res = (Z_RpnCapabilities *)odr_malloc (eh->o, sizeof(*res));
271 res->num_operators = 0;
272 res->operators = NULL;
273 res->resultSetAsOperandSupported = eh->false_value;
274 res->restrictionOperandSupported = eh->false_value;
275 res->proximity = NULL;
276 /* fix */ /* 550 - 560 */
280 Z_QueryTypeDetails **f_queryTypesSupported (ExpHandle *eh, data1_node *c,
284 Z_QueryTypeDetails **res;
288 for (n = c->child; n; n = n->next)
290 if (is_numeric_tag(eh, n) != 519)
292 /* fix */ /* 518 and 520 */
297 res = (Z_QueryTypeDetails **)odr_malloc (eh->o, *num * sizeof(*res));
299 for (n = c->child; n; n = n->next)
301 if (is_numeric_tag(eh, n) == 519)
303 res[i] = (Z_QueryTypeDetails *)odr_malloc (eh->o, sizeof(**res));
304 res[i]->which = Z_QueryTypeDetails_rpn;
305 res[i]->u.rpn = f_rpnCapabilities (eh, n);
310 /* fix */ /* 518 and 520 */
315 static Z_AccessInfo *f_accessInfo(ExpHandle *eh, data1_node *n)
317 Z_AccessInfo *res = (Z_AccessInfo *)odr_malloc(eh->o, sizeof(*res));
320 res->num_queryTypesSupported = 0;
321 res->queryTypesSupported = 0;
322 res->num_diagnosticsSets = 0;
323 res->diagnosticsSets = 0;
324 res->num_attributeSetIds = 0;
325 res->attributeSetIds = 0;
326 res->num_schemas = 0;
328 res->num_recordSyntaxes = 0;
329 res->recordSyntaxes = 0;
330 res->num_resourceChallenges = 0;
331 res->resourceChallenges = 0;
332 res->restrictedAccess = 0;
334 res->num_variantSets = 0;
335 res->variantSets = 0;
336 res->num_elementSetNames = 0;
337 res->elementSetNames = 0;
338 res->num_unitSystems = 0;
339 res->unitSystems = 0;
341 for (c = n->child; c; c = c->next)
343 switch (is_numeric_tag (eh, c))
346 res->queryTypesSupported =
347 f_queryTypesSupported (eh, c, &res->num_queryTypesSupported);
350 res->diagnosticsSets =
351 f_oid_seq(eh, c, &res->num_diagnosticsSets, CLASS_DIAGSET);
354 res->attributeSetIds =
355 f_oid_seq(eh, c, &res->num_attributeSetIds, CLASS_ATTSET);
359 f_oid_seq(eh, c, &res->num_schemas, CLASS_SCHEMA);
362 res->recordSyntaxes =
363 f_oid_seq (eh, c, &res->num_recordSyntaxes, CLASS_RECSYN);
366 res->resourceChallenges =
367 f_oid_seq (eh, c, &res->num_resourceChallenges, CLASS_RESFORM);
369 case 513: res->restrictedAccess = NULL; break; /* fix */
370 case 514: res->costInfo = NULL; break; /* fix */
373 f_oid_seq (eh, c, &res->num_variantSets, CLASS_VARSET);
376 res->elementSetNames =
377 f_string_seq (eh, c, &res->num_elementSetNames);
380 res->unitSystems = f_string_seq (eh, c, &res->num_unitSystems);
387 static int *f_recordCount(ExpHandle *eh, data1_node *c, int *which)
389 int *r= (int *)odr_malloc(eh->o, sizeof(*r));
394 if (!is_numeric_tag (eh, c))
397 if (c->u.tag.element->tag->value.numeric == 210)
398 *wp = Z_DatabaseInfo_actualNumber;
399 else if (c->u.tag.element->tag->value.numeric == 211)
400 *wp = Z_DatabaseInfo_approxNumber;
404 if (c->u.tag.element->tag->value.numeric == 210)
405 *wp = Z_Exp_RecordCount_actualNumber;
406 else if (c->u.tag.element->tag->value.numeric == 211)
407 *wp = Z_Exp_RecordCount_approxNumber;
411 if (!c->child || c->child->which != DATA1N_data)
413 sprintf(intbuf, "%.*s", 63, c->child->u.data.data);
418 static Z_ContactInfo *f_contactInfo(ExpHandle *eh, data1_node *n)
424 static Z_DatabaseList *f_databaseList(ExpHandle *eh, data1_node *n)
430 for (c = n->child; c; c = c->next)
432 if (!is_numeric_tag (eh, c) != 102)
439 res = (Z_DatabaseList *)odr_malloc (eh->o, sizeof(*res));
441 res->num_databases = i;
442 res->databases = (char **)odr_malloc (eh->o, sizeof(*res->databases) * i);
444 for (c = n->child; c; c = c->next)
446 if (!is_numeric_tag (eh, c) != 102)
448 res->databases[i++] = f_string (eh, c);
453 static Z_TargetInfo *f_targetInfo(ExpHandle *eh, data1_node *n)
455 Z_TargetInfo *res = (Z_TargetInfo *)odr_malloc(eh->o, sizeof(*res));
462 res->namedResultSets = 0;
463 res->multipleDbSearch = 0;
464 res->maxResultSets = 0;
465 res->maxResultSize = 0;
467 res->timeoutInterval = 0;
468 res->welcomeMessage = 0;
469 res->contactInfo = 0;
470 res->description = 0;
471 res->num_nicknames = 0;
474 res->paymentAddr = 0;
476 res->num_dbCombinations = 0;
477 res->dbCombinations = 0;
478 res->num_addresses = 0;
480 res->commonAccessInfo = 0;
482 for (c = n->child; c; c = c->next)
486 if (!is_numeric_tag (eh, c))
488 switch (c->u.tag.element->tag->value.numeric)
490 case 600: res->commonInfo = f_commonInfo(eh, c); break;
491 case 102: res->name = f_string(eh, c); break;
492 case 103: res->recentNews = f_humstring(eh, c); break;
493 case 104: res->icon = NULL; break; /* fix */
494 case 105: res->namedResultSets = f_bool(eh, c); break;
495 case 106: res->multipleDbSearch = f_bool(eh, c); break;
496 case 107: res->maxResultSets = f_integer(eh, c); break;
497 case 108: res->maxResultSize = f_integer(eh, c); break;
498 case 109: res->maxTerms = f_integer(eh, c); break;
499 case 110: res->timeoutInterval = f_intunit(eh, c); break;
500 case 111: res->welcomeMessage = f_humstring(eh, c); break;
501 case 112: res->contactInfo = f_contactInfo(eh, c); break;
502 case 113: res->description = f_humstring(eh, c); break;
504 res->num_nicknames = 0;
505 for (n = c->child; n; n = n->next)
507 if (is_numeric_tag(eh, n) != 102)
509 (res->num_nicknames)++;
511 if (res->num_nicknames)
513 (char **)odr_malloc (eh->o, res->num_nicknames
514 * sizeof(*res->nicknames));
515 for (n = c->child; n; n = n->next)
517 if (is_numeric_tag(eh, n) != 102)
519 res->nicknames[i++] = f_string (eh, n);
522 case 115: res->usageRest = f_humstring(eh, c); break;
523 case 116: res->paymentAddr = f_humstring(eh, c); break;
524 case 117: res->hours = f_humstring(eh, c); break;
526 res->num_dbCombinations = 0;
527 for (n = c->child; n; n = n->next)
529 if (!is_numeric_tag(eh, n) != 605)
531 (res->num_dbCombinations)++;
533 if (res->num_dbCombinations)
534 res->dbCombinations =
535 (Z_DatabaseList **)odr_malloc (eh->o, res->num_dbCombinations
536 * sizeof(*res->dbCombinations));
537 for (n = c->child; n; n = n->next)
539 if (!is_numeric_tag(eh, n) != 605)
541 res->dbCombinations[i++] = f_databaseList (eh, n);
544 case 119: res->addresses = 0; break; /* fix */
545 case 500: res->commonAccessInfo = f_accessInfo(eh, c); break;
548 if (!res->namedResultSets)
549 res->namedResultSets = eh->false_value;
550 if (!res->multipleDbSearch)
551 res->multipleDbSearch = eh->false_value;
555 static Z_DatabaseInfo *f_databaseInfo(ExpHandle *eh, data1_node *n)
557 Z_DatabaseInfo *res = (Z_DatabaseInfo *)odr_malloc(eh->o, sizeof(*res));
562 res->explainDatabase = 0;
563 res->num_nicknames = 0;
568 res->titleString = 0;
569 res->num_keywords = 0;
571 res->description = 0;
572 res->associatedDbs = 0;
574 res->disclaimers = 0;
577 res->u.actualNumber = 0;
579 res->recordCount = 0;
581 res->defaultOrder = 0;
582 res->avRecordSize = 0;
583 res->maxRecordSize = 0;
587 res->updateInterval = 0;
589 res->proprietary = 0;
590 res->copyrightText = 0;
591 res->copyrightNotice = 0;
592 res->producerContactInfo = 0;
593 res->supplierContactInfo = 0;
594 res->submissionContactInfo = 0;
597 for (c = n->child; c; c = c->next)
601 switch (is_numeric_tag (eh, c))
603 case 600: res->commonInfo = f_commonInfo(eh, c); break;
604 case 102: res->name = f_string(eh, c); break;
605 case 226: res->explainDatabase = odr_nullval(); break;
607 res->num_nicknames = 0;
608 for (n = c->child; n; n = n->next)
610 if (!is_numeric_tag(eh, n) ||
611 n->u.tag.element->tag->value.numeric != 102)
613 (res->num_nicknames)++;
615 if (res->num_nicknames)
617 (char **)odr_malloc (eh->o, res->num_nicknames
618 * sizeof(*res->nicknames));
619 for (n = c->child; n; n = n->next)
621 if (!is_numeric_tag(eh, n) ||
622 n->u.tag.element->tag->value.numeric != 102)
624 res->nicknames[i++] = f_string (eh, n);
627 case 104: res->icon = 0; break; /* fix */
628 case 201: res->userFee = f_bool(eh, c); break;
629 case 202: res->available = f_bool(eh, c); break;
630 case 203: res->titleString = f_humstring(eh, c); break;
632 res->num_keywords = 0;
633 for (n = c->child; n; n = n->next)
635 if (!is_numeric_tag(eh, n) != 1000)
637 (res->num_keywords)++;
639 if (res->num_keywords)
641 (Z_HumanString **)odr_malloc (eh->o, res->num_keywords
642 * sizeof(*res->keywords));
643 for (n = c->child; n; n = n->next)
645 if (!is_numeric_tag(eh, n) != 1000)
647 res->keywords[i++] = f_humstring (eh, n);
650 case 113: res->description = f_humstring(eh, c); break;
652 res->associatedDbs = f_databaseList (eh, c);
655 res->subDbs = f_databaseList (eh, c);
657 case 207: res->disclaimers = f_humstring(eh, c); break;
658 case 103: res->news = f_humstring(eh, c); break;
660 case 209: res->u.actualNumber =
661 f_recordCount(eh, c, &res->which); break;
663 case 209: res->recordCount =
664 f_recordCount(eh, c, &res->recordCount_which); break;
666 case 212: res->defaultOrder = f_humstring(eh, c); break;
667 case 213: res->avRecordSize = f_integer(eh, c); break;
668 case 214: res->maxRecordSize = f_integer(eh, c); break;
669 case 215: res->hours = f_humstring(eh, c); break;
670 case 216: res->bestTime = f_humstring(eh, c); break;
671 case 217: res->lastUpdate = f_string(eh, c); break;
672 case 218: res->updateInterval = f_intunit(eh, c); break;
673 case 219: res->coverage = f_humstring(eh, c); break;
674 case 220: res->proprietary = f_bool(eh, c); break;
675 case 221: res->copyrightText = f_humstring(eh, c); break;
676 case 222: res->copyrightNotice = f_humstring(eh, c); break;
677 case 223: res->producerContactInfo = f_contactInfo(eh, c); break;
678 case 224: res->supplierContactInfo = f_contactInfo(eh, c); break;
679 case 225: res->submissionContactInfo = f_contactInfo(eh, c); break;
680 case 500: res->accessInfo = f_accessInfo(eh, c); break;
684 res->userFee = eh->false_value;
686 res->available = eh->true_value;
690 Z_ExplainRecord *data1_nodetoexplain (data1_handle dh, data1_node *n,
694 Z_ExplainRecord *res = (Z_ExplainRecord *)odr_malloc(o, sizeof(*res));
699 eh.false_value = (int *)odr_malloc(eh.o, sizeof(eh.false_value));
701 eh.true_value = (int *)odr_malloc(eh.o, sizeof(eh.true_value));
704 assert(n->which == DATA1N_root);
705 if (strcmp(n->u.root.type, "explain"))
707 logf(LOG_WARN, "Attempt to convert a non-Explain record");
710 for (n = n->child; n; n = n->next)
712 switch (is_numeric_tag (&eh, n))
715 res->which = Z_Explain_targetInfo;
716 if (!(res->u.targetInfo = f_targetInfo(&eh, n)))
720 res->which = Z_Explain_databaseInfo;
721 if (!(res->u.databaseInfo = f_databaseInfo(&eh, n)))
726 logf(LOG_WARN, "No category in Explain record");