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.11 1998-04-02 08:27:37 adam
8 * Minor change in definition of Z_TargetInfo. Furhter work on Explain
9 * schema - added AttributeDetails.
11 * Revision 1.10 1998/03/31 15:13:20 adam
12 * Development towards compiled ASN.1.
14 * Revision 1.9 1998/03/05 08:07:58 adam
15 * Make data1 to EXPLAIN ignore local tags in root.
17 * Revision 1.8 1998/02/11 11:53:35 adam
18 * Changed code so that it compiles as C++.
20 * Revision 1.7 1997/12/09 16:18:16 adam
21 * Work on EXPLAIN schema. First implementation of sub-schema facility
24 * Revision 1.6 1997/11/24 11:33:56 adam
25 * Using function odr_nullval() instead of global ODR_NULLVAL when
28 * Revision 1.5 1997/11/19 10:30:06 adam
31 * Revision 1.4 1997/11/18 09:51:08 adam
32 * Removed element num_children from data1_node. Minor changes in
35 * Revision 1.3 1997/09/17 12:10:36 adam
38 * Revision 1.2 1995/12/14 16:28:30 quinn
41 * Revision 1.1 1995/12/14 11:09:51 quinn
64 static int is_numeric_tag (ExpHandle *eh, data1_node *c)
66 if (!c || c->which != DATA1N_tag)
68 if (!c->u.tag.element)
70 logf(LOG_WARN, "Tag %s is local", c->u.tag.tag);
73 if (c->u.tag.element->tag->which != DATA1T_numeric)
75 logf(LOG_WARN, "Tag %s is not numeric", c->u.tag.tag);
78 if (eh->select && !c->u.tag.node_selected)
80 return c->u.tag.element->tag->value.numeric;
83 static int is_data_tag (ExpHandle *eh, data1_node *c)
85 if (!c || c->which != DATA1N_data)
87 if (eh->select && !c->u.tag.node_selected)
92 static int *f_integer(ExpHandle *eh, data1_node *c)
98 if (!is_data_tag (eh, c) || c->u.data.len > 63)
100 r = (int *)odr_malloc(eh->o, sizeof(*r));
101 sprintf(intbuf, "%.*s", 63, c->u.data.data);
106 static char *f_string(ExpHandle *eh, data1_node *c)
111 if (!is_data_tag (eh, c))
113 r = (char *)odr_malloc(eh->o, c->u.data.len+1);
114 memcpy(r, c->u.data.data, c->u.data.len);
115 r[c->u.data.len] = '\0';
119 static bool_t *f_bool(ExpHandle *eh, data1_node *c)
125 if (!is_data_tag (eh, c) || c->u.data.len > 63)
127 tf = (int *)odr_malloc (eh->o, sizeof(*tf));
128 sprintf(intbuf, "%.*s", c->u.data.len, c->u.data.data);
133 static Odr_oid *f_oid(ExpHandle *eh, data1_node *c, oid_class oclass)
137 oid_value value_for_this;
140 if (!is_data_tag (eh, c) || c->u.data.len > 63)
142 sprintf(oidstr, "%.*s", c->u.data.len, c->u.data.data);
143 value_for_this = oid_getvalbyname(oidstr);
144 if (value_for_this == VAL_NONE)
145 return NULL; /* fix */
150 ident.oclass = oclass;
151 ident.proto = PROTO_Z3950;
152 ident.value = value_for_this;
154 oid_ent_to_oid (&ident, oid_this);
156 return odr_oiddup (eh->o, oid_this);
159 static Z_IntUnit *f_intunit(ExpHandle *eh, data1_node *c)
165 static Z_HumanString *f_humstring(ExpHandle *eh, data1_node *c)
168 Z_HumanStringUnit *u;
171 if (!is_data_tag (eh, c))
173 r = (Z_HumanString *)odr_malloc(eh->o, sizeof(*r));
175 r->strings = (Z_HumanStringUnit **)odr_malloc(eh->o, sizeof(Z_HumanStringUnit*));
176 r->strings[0] = u = (Z_HumanStringUnit *)odr_malloc(eh->o, sizeof(*u));
178 u->text = (char *)odr_malloc(eh->o, c->u.data.len+1);
179 memcpy(u->text, c->u.data.data, c->u.data.len);
180 u->text[c->u.data.len] = '\0';
184 static Z_CommonInfo *f_commonInfo(ExpHandle *eh, data1_node *n)
186 Z_CommonInfo *res = (Z_CommonInfo *)odr_malloc(eh->o, sizeof(*res));
190 res->dateChanged = 0;
192 res->humanStringLanguage = 0;
195 for (c = n->child; c; c = c->next)
197 switch (is_numeric_tag (eh, c))
199 case 601: res->dateAdded = f_string(eh, c); break;
200 case 602: res->dateChanged = f_string(eh, c); break;
201 case 603: res->expiry = f_string(eh, c); break;
202 case 604: res->humanStringLanguage = f_string(eh, c); break;
208 Z_QueryTypeDetails *f_queryTypeDetails (ExpHandle *eh, data1_node *n)
214 Odr_oid **f_oid_seq (ExpHandle *eh, data1_node *n, int *num, oid_class oclass)
221 for (c = n->child ; c; c = c->next)
223 if (is_numeric_tag (eh, c) != 1000)
229 res = (int **)odr_malloc (eh->o, sizeof(*res) * (*num));
230 for (c = n->child, i = 0 ; c; c = c->next)
232 if (is_numeric_tag (eh, c) != 1000)
234 res[i++] = f_oid (eh, c, oclass);
239 char **f_string_seq (ExpHandle *eh, data1_node *n, int *num)
246 for (c = n->child ; c; c = c->next)
248 if (!is_numeric_tag (eh, c) != 1001)
254 res = (char **)odr_malloc (eh->o, sizeof(*res) * (*num));
255 for (c = n->child, i = 0 ; c; c = c->next)
257 if (!is_numeric_tag (eh, c) != 1001)
259 res[i++] = f_string (eh, c);
264 char **f_humstring_seq (ExpHandle *eh, data1_node *n, int *num)
271 Z_RpnCapabilities *f_rpnCapabilities (ExpHandle *eh, data1_node *c)
273 Z_RpnCapabilities *res = (Z_RpnCapabilities *)odr_malloc (eh->o, sizeof(*res));
275 res->num_operators = 0;
276 res->operators = NULL;
277 res->resultSetAsOperandSupported = eh->false_value;
278 res->restrictionOperandSupported = eh->false_value;
279 res->proximity = NULL;
280 /* fix */ /* 550 - 560 */
284 Z_QueryTypeDetails **f_queryTypesSupported (ExpHandle *eh, data1_node *c,
288 Z_QueryTypeDetails **res;
292 for (n = c->child; n; n = n->next)
294 if (is_numeric_tag(eh, n) != 519)
296 /* fix */ /* 518 and 520 */
301 res = (Z_QueryTypeDetails **)odr_malloc (eh->o, *num * sizeof(*res));
303 for (n = c->child; n; n = n->next)
305 if (is_numeric_tag(eh, n) == 519)
307 res[i] = (Z_QueryTypeDetails *)odr_malloc (eh->o, sizeof(**res));
308 res[i]->which = Z_QueryTypeDetails_rpn;
309 res[i]->u.rpn = f_rpnCapabilities (eh, n);
314 /* fix */ /* 518 and 520 */
319 static Z_AccessInfo *f_accessInfo(ExpHandle *eh, data1_node *n)
321 Z_AccessInfo *res = (Z_AccessInfo *)odr_malloc(eh->o, sizeof(*res));
324 res->num_queryTypesSupported = 0;
325 res->queryTypesSupported = 0;
326 res->num_diagnosticsSets = 0;
327 res->diagnosticsSets = 0;
328 res->num_attributeSetIds = 0;
329 res->attributeSetIds = 0;
330 res->num_schemas = 0;
332 res->num_recordSyntaxes = 0;
333 res->recordSyntaxes = 0;
334 res->num_resourceChallenges = 0;
335 res->resourceChallenges = 0;
336 res->restrictedAccess = 0;
338 res->num_variantSets = 0;
339 res->variantSets = 0;
340 res->num_elementSetNames = 0;
341 res->elementSetNames = 0;
342 res->num_unitSystems = 0;
343 res->unitSystems = 0;
345 for (c = n->child; c; c = c->next)
347 switch (is_numeric_tag (eh, c))
350 res->queryTypesSupported =
351 f_queryTypesSupported (eh, c, &res->num_queryTypesSupported);
354 res->diagnosticsSets =
355 f_oid_seq(eh, c, &res->num_diagnosticsSets, CLASS_DIAGSET);
358 res->attributeSetIds =
359 f_oid_seq(eh, c, &res->num_attributeSetIds, CLASS_ATTSET);
363 f_oid_seq(eh, c, &res->num_schemas, CLASS_SCHEMA);
366 res->recordSyntaxes =
367 f_oid_seq (eh, c, &res->num_recordSyntaxes, CLASS_RECSYN);
370 res->resourceChallenges =
371 f_oid_seq (eh, c, &res->num_resourceChallenges, CLASS_RESFORM);
373 case 513: res->restrictedAccess = NULL; break; /* fix */
374 case 514: res->costInfo = NULL; break; /* fix */
377 f_oid_seq (eh, c, &res->num_variantSets, CLASS_VARSET);
380 res->elementSetNames =
381 f_string_seq (eh, c, &res->num_elementSetNames);
384 res->unitSystems = f_string_seq (eh, c, &res->num_unitSystems);
391 static int *f_recordCount(ExpHandle *eh, data1_node *c, int *which)
393 int *r= (int *)odr_malloc(eh->o, sizeof(*r));
398 if (!is_numeric_tag (eh, c))
401 if (c->u.tag.element->tag->value.numeric == 210)
402 *wp = Z_DatabaseInfo_actualNumber;
403 else if (c->u.tag.element->tag->value.numeric == 211)
404 *wp = Z_DatabaseInfo_approxNumber;
408 if (c->u.tag.element->tag->value.numeric == 210)
409 *wp = Z_Exp_RecordCount_actualNumber;
410 else if (c->u.tag.element->tag->value.numeric == 211)
411 *wp = Z_Exp_RecordCount_approxNumber;
415 if (!c->child || c->child->which != DATA1N_data)
417 sprintf(intbuf, "%.*s", 63, c->child->u.data.data);
422 static Z_ContactInfo *f_contactInfo(ExpHandle *eh, data1_node *n)
428 static Z_DatabaseList *f_databaseList(ExpHandle *eh, data1_node *n)
434 for (c = n->child; c; c = c->next)
436 if (!is_numeric_tag (eh, c) != 102)
443 res = (Z_DatabaseList *)odr_malloc (eh->o, sizeof(*res));
445 res->num_databases = i;
446 res->databases = (char **)odr_malloc (eh->o, sizeof(*res->databases) * i);
448 for (c = n->child; c; c = c->next)
450 if (!is_numeric_tag (eh, c) != 102)
452 res->databases[i++] = f_string (eh, c);
457 static Z_TargetInfo *f_targetInfo(ExpHandle *eh, data1_node *n)
459 Z_TargetInfo *res = (Z_TargetInfo *)odr_malloc(eh->o, sizeof(*res));
466 res->namedResultSets = 0;
467 res->multipleDBsearch = 0;
468 res->maxResultSets = 0;
469 res->maxResultSize = 0;
471 res->timeoutInterval = 0;
472 res->welcomeMessage = 0;
473 res->contactInfo = 0;
474 res->description = 0;
475 res->num_nicknames = 0;
478 res->paymentAddr = 0;
480 res->num_dbCombinations = 0;
481 res->dbCombinations = 0;
482 res->num_addresses = 0;
484 res->commonAccessInfo = 0;
486 for (c = n->child; c; c = c->next)
490 if (!is_numeric_tag (eh, c))
492 switch (c->u.tag.element->tag->value.numeric)
494 case 600: res->commonInfo = f_commonInfo(eh, c); break;
495 case 102: res->name = f_string(eh, c); break;
496 case 103: res->recentNews = f_humstring(eh, c); break;
497 case 104: res->icon = NULL; break; /* fix */
498 case 105: res->namedResultSets = f_bool(eh, c); break;
499 case 106: res->multipleDBsearch = f_bool(eh, c); break;
500 case 107: res->maxResultSets = f_integer(eh, c); break;
501 case 108: res->maxResultSize = f_integer(eh, c); break;
502 case 109: res->maxTerms = f_integer(eh, c); break;
503 case 110: res->timeoutInterval = f_intunit(eh, c); break;
504 case 111: res->welcomeMessage = f_humstring(eh, c); break;
505 case 112: res->contactInfo = f_contactInfo(eh, c); break;
506 case 113: res->description = f_humstring(eh, c); break;
508 res->num_nicknames = 0;
509 for (n = c->child; n; n = n->next)
511 if (is_numeric_tag(eh, n) != 102)
513 (res->num_nicknames)++;
515 if (res->num_nicknames)
517 (char **)odr_malloc (eh->o, res->num_nicknames
518 * sizeof(*res->nicknames));
519 for (n = c->child; n; n = n->next)
521 if (is_numeric_tag(eh, n) != 102)
523 res->nicknames[i++] = f_string (eh, n);
526 case 115: res->usageRest = f_humstring(eh, c); break;
527 case 116: res->paymentAddr = f_humstring(eh, c); break;
528 case 117: res->hours = f_humstring(eh, c); break;
530 res->num_dbCombinations = 0;
531 for (n = c->child; n; n = n->next)
533 if (!is_numeric_tag(eh, n) != 605)
535 (res->num_dbCombinations)++;
537 if (res->num_dbCombinations)
538 res->dbCombinations =
539 (Z_DatabaseList **)odr_malloc (eh->o, res->num_dbCombinations
540 * sizeof(*res->dbCombinations));
541 for (n = c->child; n; n = n->next)
543 if (!is_numeric_tag(eh, n) != 605)
545 res->dbCombinations[i++] = f_databaseList (eh, n);
548 case 119: res->addresses = 0; break; /* fix */
549 case 500: res->commonAccessInfo = f_accessInfo(eh, c); break;
552 if (!res->namedResultSets)
553 res->namedResultSets = eh->false_value;
554 if (!res->multipleDBsearch)
555 res->multipleDBsearch = eh->false_value;
559 static Z_DatabaseInfo *f_databaseInfo(ExpHandle *eh, data1_node *n)
561 Z_DatabaseInfo *res = (Z_DatabaseInfo *)odr_malloc(eh->o, sizeof(*res));
566 res->explainDatabase = 0;
567 res->num_nicknames = 0;
572 res->titleString = 0;
573 res->num_keywords = 0;
575 res->description = 0;
576 res->associatedDbs = 0;
578 res->disclaimers = 0;
581 res->u.actualNumber = 0;
583 res->recordCount = 0;
585 res->defaultOrder = 0;
586 res->avRecordSize = 0;
587 res->maxRecordSize = 0;
591 res->updateInterval = 0;
593 res->proprietary = 0;
594 res->copyrightText = 0;
595 res->copyrightNotice = 0;
596 res->producerContactInfo = 0;
597 res->supplierContactInfo = 0;
598 res->submissionContactInfo = 0;
601 for (c = n->child; c; c = c->next)
605 switch (is_numeric_tag (eh, c))
607 case 600: res->commonInfo = f_commonInfo(eh, c); break;
608 case 102: res->name = f_string(eh, c); break;
609 case 226: res->explainDatabase = odr_nullval(); break;
611 res->num_nicknames = 0;
612 for (n = c->child; n; n = n->next)
614 if (!is_numeric_tag(eh, n) ||
615 n->u.tag.element->tag->value.numeric != 102)
617 (res->num_nicknames)++;
619 if (res->num_nicknames)
621 (char **)odr_malloc (eh->o, res->num_nicknames
622 * sizeof(*res->nicknames));
623 for (n = c->child; n; n = n->next)
625 if (!is_numeric_tag(eh, n) ||
626 n->u.tag.element->tag->value.numeric != 102)
628 res->nicknames[i++] = f_string (eh, n);
631 case 104: res->icon = 0; break; /* fix */
632 case 201: res->userFee = f_bool(eh, c); break;
633 case 202: res->available = f_bool(eh, c); break;
634 case 203: res->titleString = f_humstring(eh, c); break;
636 res->num_keywords = 0;
637 for (n = c->child; n; n = n->next)
639 if (!is_numeric_tag(eh, n) != 1000)
641 (res->num_keywords)++;
643 if (res->num_keywords)
645 (Z_HumanString **)odr_malloc (eh->o, res->num_keywords
646 * sizeof(*res->keywords));
647 for (n = c->child; n; n = n->next)
649 if (!is_numeric_tag(eh, n) != 1000)
651 res->keywords[i++] = f_humstring (eh, n);
654 case 113: res->description = f_humstring(eh, c); break;
656 res->associatedDbs = f_databaseList (eh, c);
659 res->subDbs = f_databaseList (eh, c);
661 case 207: res->disclaimers = f_humstring(eh, c); break;
662 case 103: res->news = f_humstring(eh, c); break;
664 case 209: res->u.actualNumber =
665 f_recordCount(eh, c, &res->which); break;
667 case 209: res->recordCount =
668 f_recordCount(eh, c, &res->recordCount_which); break;
670 case 212: res->defaultOrder = f_humstring(eh, c); break;
671 case 213: res->avRecordSize = f_integer(eh, c); break;
672 case 214: res->maxRecordSize = f_integer(eh, c); break;
673 case 215: res->hours = f_humstring(eh, c); break;
674 case 216: res->bestTime = f_humstring(eh, c); break;
675 case 217: res->lastUpdate = f_string(eh, c); break;
676 case 218: res->updateInterval = f_intunit(eh, c); break;
677 case 219: res->coverage = f_humstring(eh, c); break;
678 case 220: res->proprietary = f_bool(eh, c); break;
679 case 221: res->copyrightText = f_humstring(eh, c); break;
680 case 222: res->copyrightNotice = f_humstring(eh, c); break;
681 case 223: res->producerContactInfo = f_contactInfo(eh, c); break;
682 case 224: res->supplierContactInfo = f_contactInfo(eh, c); break;
683 case 225: res->submissionContactInfo = f_contactInfo(eh, c); break;
684 case 500: res->accessInfo = f_accessInfo(eh, c); break;
688 res->userFee = eh->false_value;
690 res->available = eh->true_value;
694 Z_ExplainRecord *data1_nodetoexplain (data1_handle dh, data1_node *n,
698 Z_ExplainRecord *res = (Z_ExplainRecord *)odr_malloc(o, sizeof(*res));
703 eh.false_value = (int *)odr_malloc(eh.o, sizeof(eh.false_value));
705 eh.true_value = (int *)odr_malloc(eh.o, sizeof(eh.true_value));
708 assert(n->which == DATA1N_root);
709 if (strcmp(n->u.root.type, "explain"))
711 logf(LOG_WARN, "Attempt to convert a non-Explain record");
714 for (n = n->child; n; n = n->next)
716 switch (is_numeric_tag (&eh, n))
719 res->which = Z_Explain_targetInfo;
720 if (!(res->u.targetInfo = f_targetInfo(&eh, n)))
724 res->which = Z_Explain_databaseInfo;
725 if (!(res->u.databaseInfo = f_databaseInfo(&eh, n)))
730 logf(LOG_WARN, "No category in Explain record");