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.8 1998-02-11 11:53:35 adam
8 * Changed code so that it compiles as C++.
10 * Revision 1.7 1997/12/09 16:18:16 adam
11 * Work on EXPLAIN schema. First implementation of sub-schema facility
14 * Revision 1.6 1997/11/24 11:33:56 adam
15 * Using function odr_nullval() instead of global ODR_NULLVAL when
18 * Revision 1.5 1997/11/19 10:30:06 adam
21 * Revision 1.4 1997/11/18 09:51:08 adam
22 * Removed element num_children from data1_node. Minor changes in
25 * Revision 1.3 1997/09/17 12:10:36 adam
28 * Revision 1.2 1995/12/14 16:28:30 quinn
31 * Revision 1.1 1995/12/14 11:09:51 quinn
54 static int is_numeric_tag (ExpHandle *eh, data1_node *c)
56 if (!c || c->which != DATA1N_tag)
58 if (!c->u.tag.element)
60 logf(LOG_WARN, "Tag %s is local", c->u.tag.tag);
63 if (c->u.tag.element->tag->which != DATA1T_numeric)
65 logf(LOG_WARN, "Tag %s is not numeric", c->u.tag.tag);
68 if (eh->select && !c->u.tag.node_selected)
70 return c->u.tag.element->tag->value.numeric;
73 static int is_data_tag (ExpHandle *eh, data1_node *c)
75 if (!c || c->which != DATA1N_data)
77 if (eh->select && !c->u.tag.node_selected)
82 static int *f_integer(ExpHandle *eh, data1_node *c)
88 if (!is_data_tag (eh, c) || c->u.data.len > 63)
90 r = (int *)odr_malloc(eh->o, sizeof(*r));
91 sprintf(intbuf, "%.*s", 63, c->u.data.data);
96 static char *f_string(ExpHandle *eh, data1_node *c)
101 if (!is_data_tag (eh, c))
103 r = (char *)odr_malloc(eh->o, c->u.data.len+1);
104 memcpy(r, c->u.data.data, c->u.data.len);
105 r[c->u.data.len] = '\0';
109 static bool_t *f_bool(ExpHandle *eh, data1_node *c)
115 if (!is_data_tag (eh, c) || c->u.data.len > 63)
117 tf = (int *)odr_malloc (eh->o, sizeof(*tf));
118 sprintf(intbuf, "%.*s", c->u.data.len, c->u.data.data);
123 static Odr_oid *f_oid(ExpHandle *eh, data1_node *c, oid_class oclass)
127 oid_value value_for_this;
130 if (!is_data_tag (eh, c) || c->u.data.len > 63)
132 sprintf(oidstr, "%.*s", c->u.data.len, c->u.data.data);
133 value_for_this = oid_getvalbyname(oidstr);
134 if (value_for_this == VAL_NONE)
135 return NULL; /* fix */
140 ident.oclass = oclass;
141 ident.proto = PROTO_Z3950;
142 ident.value = value_for_this;
144 oid_ent_to_oid (&ident, oid_this);
146 return odr_oiddup (eh->o, oid_this);
149 static Z_IntUnit *f_intunit(ExpHandle *eh, data1_node *c)
155 static Z_HumanString *f_humstring(ExpHandle *eh, data1_node *c)
158 Z_HumanStringUnit *u;
161 if (!is_data_tag (eh, c))
163 r = (Z_HumanString *)odr_malloc(eh->o, sizeof(*r));
165 r->strings = (Z_HumanStringUnit **)odr_malloc(eh->o, sizeof(Z_HumanStringUnit*));
166 r->strings[0] = u = (Z_HumanStringUnit *)odr_malloc(eh->o, sizeof(*u));
168 u->text = (char *)odr_malloc(eh->o, c->u.data.len+1);
169 memcpy(u->text, c->u.data.data, c->u.data.len);
170 u->text[c->u.data.len] = '\0';
174 static Z_CommonInfo *f_commonInfo(ExpHandle *eh, data1_node *n)
176 Z_CommonInfo *res = (Z_CommonInfo *)odr_malloc(eh->o, sizeof(*res));
180 res->dateChanged = 0;
182 res->humanStringLanguage = 0;
185 for (c = n->child; c; c = c->next)
187 switch (is_numeric_tag (eh, c))
189 case 601: res->dateAdded = f_string(eh, c); break;
190 case 602: res->dateChanged = f_string(eh, c); break;
191 case 603: res->expiry = f_string(eh, c); break;
192 case 604: res->humanStringLanguage = f_string(eh, c); break;
198 Z_QueryTypeDetails *f_queryTypeDetails (ExpHandle *eh, data1_node *n)
204 Odr_oid **f_oid_seq (ExpHandle *eh, data1_node *n, int *num, oid_class oclass)
211 for (c = n->child ; c; c = c->next)
213 if (is_numeric_tag (eh, c) != 1000)
219 res = (int **)odr_malloc (eh->o, sizeof(*res) * (*num));
220 for (c = n->child, i = 0 ; c; c = c->next)
222 if (is_numeric_tag (eh, c) != 1000)
224 res[i++] = f_oid (eh, c, oclass);
229 char **f_string_seq (ExpHandle *eh, data1_node *n, int *num)
236 for (c = n->child ; c; c = c->next)
238 if (!is_numeric_tag (eh, c) != 1001)
244 res = (char **)odr_malloc (eh->o, sizeof(*res) * (*num));
245 for (c = n->child, i = 0 ; c; c = c->next)
247 if (!is_numeric_tag (eh, c) != 1001)
249 res[i++] = f_string (eh, c);
254 char **f_humstring_seq (ExpHandle *eh, data1_node *n, int *num)
261 Z_RpnCapabilities *f_rpnCapabilities (ExpHandle *eh, data1_node *c)
263 Z_RpnCapabilities *res = (Z_RpnCapabilities *)odr_malloc (eh->o, sizeof(*res));
265 res->num_operators = 0;
266 res->operators = NULL;
267 res->resultSetAsOperandSupported = eh->false_value;
268 res->restrictionOperandSupported = eh->false_value;
269 res->proximity = NULL;
270 /* fix */ /* 550 - 560 */
274 Z_QueryTypeDetails **f_queryTypesSupported (ExpHandle *eh, data1_node *c,
278 Z_QueryTypeDetails **res;
282 for (n = c->child; n; n = n->next)
284 if (is_numeric_tag(eh, n) != 519)
286 /* fix */ /* 518 and 520 */
291 res = (Z_QueryTypeDetails **)odr_malloc (eh->o, *num * sizeof(*res));
293 for (n = c->child; n; n = n->next)
295 if (is_numeric_tag(eh, n) == 519)
297 res[i] = (Z_QueryTypeDetails *)odr_malloc (eh->o, sizeof(**res));
298 res[i]->which = Z_QueryTypeDetails_rpn;
299 res[i]->u.rpn = f_rpnCapabilities (eh, n);
304 /* fix */ /* 518 and 520 */
309 static Z_AccessInfo *f_accessInfo(ExpHandle *eh, data1_node *n)
311 Z_AccessInfo *res = (Z_AccessInfo *)odr_malloc(eh->o, sizeof(*res));
314 res->num_queryTypesSupported = 0;
315 res->queryTypesSupported = 0;
316 res->num_diagnosticsSets = 0;
317 res->diagnosticsSets = 0;
318 res->num_attributeSetIds = 0;
319 res->attributeSetIds = 0;
320 res->num_schemas = 0;
322 res->num_recordSyntaxes = 0;
323 res->recordSyntaxes = 0;
324 res->num_resourceChallenges = 0;
325 res->resourceChallenges = 0;
326 res->restrictedAccess = 0;
328 res->num_variantSets = 0;
329 res->variantSets = 0;
330 res->num_elementSetNames = 0;
331 res->elementSetNames = 0;
332 res->num_unitSystems = 0;
333 res->unitSystems = 0;
335 for (c = n->child; c; c = c->next)
337 switch (is_numeric_tag (eh, c))
340 res->queryTypesSupported =
341 f_queryTypesSupported (eh, c, &res->num_queryTypesSupported);
344 res->diagnosticsSets =
345 f_oid_seq(eh, c, &res->num_diagnosticsSets, CLASS_DIAGSET);
348 res->attributeSetIds =
349 f_oid_seq(eh, c, &res->num_attributeSetIds, CLASS_ATTSET);
353 f_oid_seq(eh, c, &res->num_schemas, CLASS_SCHEMA);
356 res->recordSyntaxes =
357 f_oid_seq (eh, c, &res->num_recordSyntaxes, CLASS_RECSYN);
360 res->resourceChallenges =
361 f_oid_seq (eh, c, &res->num_resourceChallenges, CLASS_RESFORM);
363 case 513: res->restrictedAccess = NULL; break; /* fix */
364 case 514: res->costInfo = NULL; break; /* fix */
367 f_oid_seq (eh, c, &res->num_variantSets, CLASS_VARSET);
370 res->elementSetNames =
371 f_string_seq (eh, c, &res->num_elementSetNames);
374 res->unitSystems = f_string_seq (eh, c, &res->num_unitSystems);
381 static int *f_recordCount(ExpHandle *eh, data1_node *c, int *which)
383 int *r= (int *)odr_malloc(eh->o, sizeof(*r));
388 if (!is_numeric_tag (eh, c))
390 if (c->u.tag.element->tag->value.numeric == 210)
391 *wp = Z_Exp_RecordCount_actualNumber;
392 else if (c->u.tag.element->tag->value.numeric == 211)
393 *wp = Z_Exp_RecordCount_approxNumber;
396 if (!c->child || c->child->which != DATA1N_data)
398 sprintf(intbuf, "%.*s", 63, c->child->u.data.data);
403 static Z_ContactInfo *f_contactInfo(ExpHandle *eh, data1_node *n)
409 static Z_DatabaseList *f_databaseList(ExpHandle *eh, data1_node *n)
415 for (c = n->child; c; c = c->next)
417 if (!is_numeric_tag (eh, c) != 102)
424 res = (Z_DatabaseList *)odr_malloc (eh->o, sizeof(*res));
426 res->num_databases = i;
427 res->databases = (char **)odr_malloc (eh->o, sizeof(*res->databases) * i);
429 for (c = n->child; c; c = c->next)
431 if (!is_numeric_tag (eh, c) != 102)
433 res->databases[i++] = f_string (eh, c);
438 static Z_TargetInfo *f_targetInfo(ExpHandle *eh, data1_node *n)
440 Z_TargetInfo *res = (Z_TargetInfo *)odr_malloc(eh->o, sizeof(*res));
447 res->namedResultSets = 0;
448 res->multipleDbSearch = 0;
449 res->maxResultSets = 0;
450 res->maxResultSize = 0;
452 res->timeoutInterval = 0;
453 res->welcomeMessage = 0;
454 res->contactInfo = 0;
455 res->description = 0;
456 res->num_nicknames = 0;
459 res->paymentAddr = 0;
461 res->num_dbCombinations = 0;
462 res->dbCombinations = 0;
463 res->num_addresses = 0;
465 res->commonAccessInfo = 0;
467 for (c = n->child; c; c = c->next)
471 if (!is_numeric_tag (eh, c))
473 switch (c->u.tag.element->tag->value.numeric)
475 case 600: res->commonInfo = f_commonInfo(eh, c); break;
476 case 102: res->name = f_string(eh, c); break;
477 case 103: res->recentNews = f_humstring(eh, c); break;
478 case 104: res->icon = NULL; break; /* fix */
479 case 105: res->namedResultSets = f_bool(eh, c); break;
480 case 106: res->multipleDbSearch = f_bool(eh, c); break;
481 case 107: res->maxResultSets = f_integer(eh, c); break;
482 case 108: res->maxResultSize = f_integer(eh, c); break;
483 case 109: res->maxTerms = f_integer(eh, c); break;
484 case 110: res->timeoutInterval = f_intunit(eh, c); break;
485 case 111: res->welcomeMessage = f_humstring(eh, c); break;
486 case 112: res->contactInfo = f_contactInfo(eh, c); break;
487 case 113: res->description = f_humstring(eh, c); break;
489 res->num_nicknames = 0;
490 for (n = c->child; n; n = n->next)
492 if (is_numeric_tag(eh, n) != 102)
494 (res->num_nicknames)++;
496 if (res->num_nicknames)
498 (char **)odr_malloc (eh->o, res->num_nicknames
499 * sizeof(*res->nicknames));
500 for (n = c->child; n; n = n->next)
502 if (is_numeric_tag(eh, n) != 102)
504 res->nicknames[i++] = f_string (eh, n);
507 case 115: res->usageRest = f_humstring(eh, c); break;
508 case 116: res->paymentAddr = f_humstring(eh, c); break;
509 case 117: res->hours = f_humstring(eh, c); break;
511 res->num_dbCombinations = 0;
512 for (n = c->child; n; n = n->next)
514 if (!is_numeric_tag(eh, n) != 605)
516 (res->num_dbCombinations)++;
518 if (res->num_dbCombinations)
519 res->dbCombinations =
520 (Z_DatabaseList **)odr_malloc (eh->o, res->num_dbCombinations
521 * sizeof(*res->dbCombinations));
522 for (n = c->child; n; n = n->next)
524 if (!is_numeric_tag(eh, n) != 605)
526 res->dbCombinations[i++] = f_databaseList (eh, n);
529 case 119: res->addresses = 0; break; /* fix */
530 case 500: res->commonAccessInfo = f_accessInfo(eh, c); break;
533 if (!res->namedResultSets)
534 res->namedResultSets = eh->false_value;
535 if (!res->multipleDbSearch)
536 res->multipleDbSearch = eh->false_value;
540 static Z_DatabaseInfo *f_databaseInfo(ExpHandle *eh, data1_node *n)
542 Z_DatabaseInfo *res = (Z_DatabaseInfo *)odr_malloc(eh->o, sizeof(*res));
547 res->explainDatabase = 0;
548 res->num_nicknames = 0;
553 res->titleString = 0;
554 res->num_keywords = 0;
556 res->description = 0;
557 res->associatedDbs = 0;
559 res->disclaimers = 0;
561 res->recordCount = 0;
562 res->defaultOrder = 0;
563 res->avRecordSize = 0;
564 res->maxRecordSize = 0;
568 res->updateInterval = 0;
570 res->proprietary = 0;
571 res->copyrightText = 0;
572 res->copyrightNotice = 0;
573 res->producerContactInfo = 0;
574 res->supplierContactInfo = 0;
575 res->submissionContactInfo = 0;
578 for (c = n->child; c; c = c->next)
582 switch (is_numeric_tag (eh, c))
584 case 600: res->commonInfo = f_commonInfo(eh, c); break;
585 case 102: res->name = f_string(eh, c); break;
586 case 226: res->explainDatabase = odr_nullval(); break;
588 res->num_nicknames = 0;
589 for (n = c->child; n; n = n->next)
591 if (!is_numeric_tag(eh, n) ||
592 n->u.tag.element->tag->value.numeric != 102)
594 (res->num_nicknames)++;
596 if (res->num_nicknames)
598 (char **)odr_malloc (eh->o, res->num_nicknames
599 * sizeof(*res->nicknames));
600 for (n = c->child; n; n = n->next)
602 if (!is_numeric_tag(eh, n) ||
603 n->u.tag.element->tag->value.numeric != 102)
605 res->nicknames[i++] = f_string (eh, n);
608 case 104: res->icon = 0; break; /* fix */
609 case 201: res->userFee = f_bool(eh, c); break;
610 case 202: res->available = f_bool(eh, c); break;
611 case 203: res->titleString = f_humstring(eh, c); break;
613 res->num_keywords = 0;
614 for (n = c->child; n; n = n->next)
616 if (!is_numeric_tag(eh, n) != 1000)
618 (res->num_keywords)++;
620 if (res->num_keywords)
622 (Z_HumanString **)odr_malloc (eh->o, res->num_keywords
623 * sizeof(*res->keywords));
624 for (n = c->child; n; n = n->next)
626 if (!is_numeric_tag(eh, n) != 1000)
628 res->keywords[i++] = f_humstring (eh, n);
631 case 113: res->description = f_humstring(eh, c); break;
633 res->associatedDbs = f_databaseList (eh, c);
636 res->subDbs = f_databaseList (eh, c);
638 case 207: res->disclaimers = f_humstring(eh, c); break;
639 case 103: res->news = f_humstring(eh, c); break;
640 case 209: res->recordCount =
641 f_recordCount(eh, c, &res->recordCount_which); break;
642 case 212: res->defaultOrder = f_humstring(eh, c); break;
643 case 213: res->avRecordSize = f_integer(eh, c); break;
644 case 214: res->maxRecordSize = f_integer(eh, c); break;
645 case 215: res->hours = f_humstring(eh, c); break;
646 case 216: res->bestTime = f_humstring(eh, c); break;
647 case 217: res->lastUpdate = f_string(eh, c); break;
648 case 218: res->updateInterval = f_intunit(eh, c); break;
649 case 219: res->coverage = f_humstring(eh, c); break;
650 case 220: res->proprietary = f_bool(eh, c); break;
651 case 221: res->copyrightText = f_humstring(eh, c); break;
652 case 222: res->copyrightNotice = f_humstring(eh, c); break;
653 case 223: res->producerContactInfo = f_contactInfo(eh, c); break;
654 case 224: res->supplierContactInfo = f_contactInfo(eh, c); break;
655 case 225: res->submissionContactInfo = f_contactInfo(eh, c); break;
656 case 500: res->accessInfo = f_accessInfo(eh, c); break;
660 res->userFee = eh->false_value;
662 res->available = eh->true_value;
666 Z_ExplainRecord *data1_nodetoexplain (data1_handle dh, data1_node *n,
670 Z_ExplainRecord *res = (Z_ExplainRecord *)odr_malloc(o, sizeof(*res));
675 eh.false_value = (int *)odr_malloc(eh.o, sizeof(eh.false_value));
677 eh.true_value = (int *)odr_malloc(eh.o, sizeof(eh.true_value));
680 assert(n->which == DATA1N_root);
681 if (strcmp(n->u.root.type, "explain"))
683 logf(LOG_WARN, "Attempt to convert a non-Explain record");
689 logf(LOG_WARN, "Explain record should have one exactly one child");
692 switch (is_numeric_tag (&eh, n))
695 res->which = Z_Explain_targetInfo;
696 if (!(res->u.targetInfo = f_targetInfo(&eh, n)))
700 res->which = Z_Explain_databaseInfo;
701 if (!(res->u.databaseInfo = f_databaseInfo(&eh, n)))
705 logf(LOG_WARN, "Unknown explain category");