* Sebastian Hammer, Adam Dickmeiss
*
* $Log: prt-exp.c,v $
- * Revision 1.6 1995-12-14 11:09:09 quinn
+ * Revision 1.7 1995-12-14 16:28:07 quinn
+ * More explain stuff.
+ *
+ * Revision 1.6 1995/12/14 11:09:09 quinn
* Fixed bug in tagging.
*
* Revision 1.5 1995/12/05 11:15:50 quinn
int z_HumanString(ODR o, Z_HumanString **p, int opt)
{
- if (o->direction == ODR_DECODE)
- *p = odr_malloc(o, sizeof(**p));
- else if (!*p)
- {
- o->t_class = -1;
- return opt && odr_ok(o);
- }
+ if (!odr_initmember(o, p, sizeof(**p)))
+ return opt && odr_ok(o);
if (odr_sequence_of(o, z_HumanStringUnit, &(*p)->strings,
&(*p)->num_strings))
return 1;
int z_IconObject(ODR o, Z_IconObject **p, int opt)
{
- if (o->direction == ODR_DECODE)
- *p = odr_malloc(o, sizeof(**p));
- else if (!*p)
- {
- o->t_class = -1;
- return opt;
- }
+ if (!odr_initmember(o, p, sizeof(**p)))
+ return opt && odr_ok(o);
if (odr_sequence_of(o, z_IconObjectUnit, &(*p)->iconUnits,
&(*p)->num_iconUnits))
return 1;
{-1, -1, -1, -1, 0}
};
- if (o->direction == ODR_DECODE)
- *p = odr_malloc(o, sizeof(**p));
- else if (!*p)
- return opt;
+ if (!odr_initmember(o, p, sizeof(**p)))
+ return opt && odr_ok(o);
if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
return 1;
*p = 0;
int z_QueryTypeDetails(ODR o, Z_QueryTypeDetails **p, int opt)
{
- static Odr_arm arm[] =
- {
- {ODR_IMPLICIT, ODR_CONTEXT, 0, Z_QueryTypeDetails_private,
- z_PrivateCapabilities},
- {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_QueryTypeDetails_rpn,
- z_RpnCapabilities},
- {ODR_IMPLICIT, ODR_CONTEXT, 2, Z_QueryTypeDetails_iso8777,
- z_Iso8777Capabilities},
- {ODR_IMPLICIT, ODR_CONTEXT, 3, Z_QueryTypeDetails_z3958,
- z_HumanString},
- {ODR_IMPLICIT, ODR_CONTEXT, 4, Z_QueryTypeDetails_erpn,
- z_RpnCapabilities},
- {ODR_IMPLICIT, ODR_CONTEXT, 5, Z_QueryTypeDetails_rankedList,
- z_HumanString},
- {-1, -1, -1, -1, 0}
- };
-
- if (o->direction == ODR_DECODE)
- *p = odr_malloc(o, sizeof(**p));
- else if (!*p)
- return opt;
- if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
- return 1;
- *p = 0;
- return opt && odr_ok(o);
+ static Odr_arm arm[] =
+ {
+ {ODR_IMPLICIT, ODR_CONTEXT, 0, Z_QueryTypeDetails_private,
+ z_PrivateCapabilities},
+ {ODR_IMPLICIT, ODR_CONTEXT, 1, Z_QueryTypeDetails_rpn,
+ z_RpnCapabilities},
+ {ODR_IMPLICIT, ODR_CONTEXT, 2, Z_QueryTypeDetails_iso8777,
+ z_Iso8777Capabilities},
+ {ODR_IMPLICIT, ODR_CONTEXT, 3, Z_QueryTypeDetails_z3958,
+ z_HumanString},
+ {ODR_IMPLICIT, ODR_CONTEXT, 4, Z_QueryTypeDetails_erpn,
+ z_RpnCapabilities},
+ {ODR_IMPLICIT, ODR_CONTEXT, 5, Z_QueryTypeDetails_rankedList,
+ z_HumanString},
+ {-1, -1, -1, -1, 0}
+ };
+
+ if (!odr_initmember(o, p, sizeof(**p)))
+ return opt && odr_ok(o);
+ if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
+ return 1;
+ *p = 0;
+ return opt && odr_ok(o);
}
int z_PrivateCapOperator(ODR o, Z_PrivateCapOperator **p, int opt)
{-1, -1, -1, -1, 0}
};
- if (o->direction == ODR_DECODE)
- *p = odr_malloc(o, sizeof(**p));
- else if (!*p)
- return opt;
+ if (!odr_initmember(o, p, sizeof(**p)))
+ return opt && odr_ok(o);
if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
return 1;
*p = 0;
int z_AccessRestrictions(ODR o, Z_AccessRestrictions **p, int opt)
{
- if (o->direction == ODR_DECODE)
- *p = odr_malloc(o, sizeof(**p));
- else if (!*p)
- return opt;
+ if (!odr_initmember(o, p, sizeof(**p)))
+ return opt && odr_ok(o);
if (odr_sequence_of(o, z_AccessRestrictionsUnit, &(*p)->restrictions,
&(*p)->num_restrictions))
return 1;
int z_DatabaseList(ODR o, Z_DatabaseList **p, int opt)
{
- if (o->direction == ODR_DECODE)
- *p = odr_malloc(o, sizeof(**p));
- else if (!*p)
- return opt;
+ if (!odr_initmember(o, p, sizeof(**p)))
+ return opt && odr_ok(o);
if (odr_sequence_of(o, z_DatabaseName, &(*p)->databases,
&(*p)->num_databases))
return 1;
int z_AttributeCombination(ODR o, Z_AttributeCombination **p, int opt)
{
- if (o->direction == ODR_DECODE)
- *p = odr_malloc(o, sizeof(**p));
- else if (!*p)
- return opt;
+ if (!odr_initmember(o, p, sizeof(**p)))
+ return opt && odr_ok(o);
if (odr_sequence_of(o, z_AttributeOccurrence, &(*p)->occurrences,
&(*p)->num_occurrences))
return 1;
int z_AttributeValueList(ODR o, Z_AttributeValueList **p, int opt)
{
- if (o->direction == ODR_DECODE)
- *p = odr_malloc(o, sizeof(**p));
- else if (!*p)
- return opt;
+ if (!odr_initmember(o, p, sizeof(**p)))
+ return opt && odr_ok(o);
if (odr_sequence_of(o, z_StringOrNumeric, &(*p)->attributes,
&(*p)->num_attributes))
return 1;
int z_Path(ODR o, Z_Path **p, int opt)
{
- if (o->direction == ODR_DECODE)
- *p = odr_malloc(o, sizeof(**p));
- else if (!*p)
- return opt;
+ if (!odr_initmember(o, p, sizeof(**p)))
+ return opt && odr_ok(o);
odr_implicit_settag(o, ODR_CONTEXT, 201);
if (odr_sequence_of(o, z_OtherInformationUnit, &(*p)->list,
&(*p)->num))
int z_ElementInfoList(ODR o, Z_Path **p, int opt)
{
- if (o->direction == ODR_DECODE)
- *p = odr_malloc(o, sizeof(**p));
- else if (!*p)
- return opt;
+ if (!odr_initmember(o, p, sizeof(**p)))
+ return opt && odr_ok(o);
odr_implicit_settag(o, ODR_CONTEXT, 201);
if (odr_sequence_of(o, z_OtherInformationUnit, &(*p)->list,
&(*p)->num))
{-1, -1, -1, -1, 0}
};
- if (o->direction == ODR_DECODE)
- *p = odr_malloc(o, sizeof(**p));
- else if (!*p)
- return opt;
-
+ if (!odr_initmember(o, p, sizeof(**p)))
+ return opt && odr_ok(o);
if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
return 1;
*p = 0;
{-1, -1, -1, -1, 0}
};
- if (o->direction == ODR_DECODE)
- *p = odr_malloc(o, sizeof(**p));
- else if (!*p)
- return opt;
+ if (!odr_initmember(o, p, sizeof(**p)))
+ return opt && odr_ok(o);
if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
return 1;
*p = 0;
int z_ValueSetEnumerated(ODR o, Z_ValueSetEnumerated **p, int opt)
{
- if (o->direction == ODR_DECODE)
- *p = odr_malloc(o, sizeof(**p));
- else if (!*p)
- return opt;
+ if (!odr_initmember(o, p, sizeof(**p)))
+ return opt && odr_ok(o);
if (odr_sequence_of(o, z_ValueDescription, &(*p)->enumerated,
&(*p)->num_enumerated))
return 1;
{-1, -1, -1, -1, 0}
};
- if (o->direction == ODR_DECODE)
- *p = odr_malloc(o, sizeof(**p));
- else if (!*p)
- return opt;
+ if (!odr_initmember(o, p, sizeof(**p)))
+ return opt && odr_ok(o);
if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
return 1;
*p = 0;
{-1, -1, -1, -1, 0}
};
- if (o->direction == ODR_DECODE)
- *p = odr_malloc(o, sizeof(**p));
- else if (!*p)
- return opt && odr_ok(o);
+ if (!odr_initmember(o, p, sizeof(**p)))
+ return opt && odr_ok(o);
if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
return 1;
*p = 0;
{-1, -1, -1, -1, 0}
};
- if (o->direction == ODR_DECODE)
- *p = odr_malloc(o, sizeof(**p));
- else if (!*p)
- return opt;
+ if (!odr_initmember(o, p, sizeof(**p)))
+ return opt && odr_ok(o);
if (odr_choice(o, arm, &(*p)->u, &(*p)->which))
return 1;
*p = 0;
int num_elementSetNames;
char **elementSetNames; /* OPTIONAL */
int num_unitSystems;
- char **unitSystems;
+ char **unitSystems; /* OPTIONAL */
} Z_AccessInfo;
typedef struct Z_DatabaseList
int odr_total(ODR o);
char *odr_errmsg(int n);
Odr_oid *odr_getoidbystr(ODR o, char *str);
+int odr_initmember(ODR o, void *p, int size);
#endif
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: odr_tag.c,v $
- * Revision 1.5 1995-09-29 17:12:27 quinn
+ * Revision 1.6 1995-12-14 16:28:26 quinn
+ * More explain stuff.
+ *
+ * Revision 1.5 1995/09/29 17:12:27 quinn
* Smallish
*
* Revision 1.4 1995/09/27 15:03:00 quinn
}
return 1;
}
+
+int odr_initmember(ODR o, void *p, int size)
+{
+ char **pp = (char **) p;
+
+ if (o->error)
+ return 0;
+ if (o->direction == ODR_DECODE)
+ *pp = odr_malloc(o, size);
+ else if (!*pp)
+ {
+ o->t_class = -1;
+ return 0;
+ }
+ return 1;
+}
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: d1_expout.c,v $
- * Revision 1.1 1995-12-14 11:09:51 quinn
+ * Revision 1.2 1995-12-14 16:28:30 quinn
+ * More explain stuff.
+ *
+ * Revision 1.1 1995/12/14 11:09:51 quinn
* Work on Explain
*
*
static Z_CommonInfo *f_commonInfo(data1_node *n, int select, ODR o)
{
- return 0;
+ Z_CommonInfo *res = odr_malloc(o, sizeof(*res));
+ data1_node *c;
+
+ res->dateAdded = 0;
+ res->dateChanged = 0;
+ res->expiry = 0;
+ res->humanStringLanguage = 0;
+ res->otherInfo = 0;
+
+ for (c = n->child; c; c = c->next)
+ {
+ if (c->which != DATA1N_tag || !c->u.tag.element)
+ {
+ logf(LOG_WARN, "Malformed explain record");
+ return 0;
+ }
+ if (select && !c->u.tag.node_selected)
+ continue;
+ switch (c->u.tag.element->tag->value.numeric)
+ {
+ case 601: res->dateAdded = f_string(c, o); break;
+ case 602: res->dateChanged = f_string(c, o); break;
+ case 603: res->expiry = f_string(c, o); break;
+ case 604: res->humanStringLanguage = f_string(c, o); break;
+ /* otherInfo? */
+ default:
+ logf(LOG_WARN, "Bad child in commonInfo");
+ return 0;
+ }
+ }
+ return res;
}
static Z_AccessInfo *f_accessInfo(data1_node *n, int select, ODR o)
{
- return 0;
+ Z_AccessInfo *res = odr_malloc(o, sizeof(*res));
+ data1_node *c;
+
+ res->num_queryTypesSupported = 0;
+ res->queryTypesSupported = 0;
+ res->num_diagnosticsSets = 0;
+ res->diagnosticsSets = 0;
+ res->num_attributeSetIds = 0;
+ res->attributeSetIds = 0;
+ res->num_schemas = 0;
+ res->schemas = 0;
+ res->num_recordSyntaxes = 0;
+ res->recordSyntaxes = 0;
+ res->num_resourceChallenges = 0;
+ res->resourceChallenges = 0;
+ res->restrictedAccess = 0;
+ res->costInfo = 0;
+ res->num_variantSets = 0;
+ res->variantSets = 0;
+ res->num_elementSetNames = 0;
+ res->elementSetNames = 0;
+ res->num_unitSystems = 0;
+ res->unitSystems = 0;
+
+ for (c = n->child; c; c = c->next)
+ {
+ if (c->which != DATA1N_tag || !c->u.tag.element)
+ {
+ logf(LOG_WARN, "Malformed explain record");
+ return 0;
+ }
+ if (select && !c->u.tag.node_selected)
+ continue;
+ /* switch-statement here */
+ }
+ return res;
+}
+
+static int *f_recordCount(data1_node *c, ODR o, void *which)
+{
+ int *r= odr_malloc(o, sizeof(*r));
+ int *wp = which;
+ char intbuf[64];
+
+ if (!c->child || c->child->which != DATA1N_tag || !c->child->u.tag.element)
+ return 0;
+ if (c->u.tag.element->tag->value.numeric == 210)
+ *wp = Z_Exp_RecordCount_actualNumber;
+ else if (c->u.tag.element->tag->value.numeric == 211)
+ *wp = Z_Exp_RecordCount_approxNumber;
+ else
+ return 0;
+ c = c->child;
+ if (!c->child || c->child->which != DATA1N_data)
+ return 0;
+ sprintf(intbuf, "%.*s", 63, c->child->u.data.data);
+ *r = atoi(intbuf);
+ return r;
}
static Z_ContactInfo *f_contactInfo(data1_node *n, ODR o)
static Z_DatabaseInfo *f_databaseInfo(data1_node *n, int select, ODR o)
{
- return 0;
+ Z_DatabaseInfo *res = odr_malloc(o, sizeof(*res));
+ data1_node *c;
+ static bool_t fl = 0, tr = 1;
+
+ res->commonInfo = 0;
+ res->name = 0;
+ res->explainDatabase = 0;
+ res->num_nicknames = 0;
+ res->nicknames = 0;
+ res->icon = 0;
+ res->userFee = &fl;
+ res->available = &tr;
+ res->titleString = 0;
+ res->num_keywords = 0;
+ res->keywords = 0;
+ res->description = 0;
+ res->associatedDbs = 0;
+ res->subDbs = 0;
+ res->disclaimers = 0;
+ res->news = 0;
+ res->recordCount = 0;
+ res->defaultOrder = 0;
+ res->avRecordSize = 0;
+ res->maxRecordSize = 0;
+ res->hours = 0;
+ res->bestTime = 0;
+ res->lastUpdate = 0;
+ res->updateInterval = 0;
+ res->coverage = 0;
+ res->proprietary = 0;
+ res->copyrightText = 0;
+ res->copyrightNotice = 0;
+ res->producerContactInfo = 0;
+ res->supplierContactInfo = 0;
+ res->submissionContactInfo = 0;
+ res->accessInfo = 0;
+
+ for (c = n->child; c; c = c->next)
+ {
+ if (c->which != DATA1N_tag || !c->u.tag.element)
+ {
+ logf(LOG_WARN, "Malformed explain record");
+ return 0;
+ }
+ if (select && !c->u.tag.node_selected)
+ continue;
+ switch (c->u.tag.element->tag->value.numeric)
+ {
+ case 600: res->commonInfo = f_commonInfo(c, select, o); break;
+ case 102: res->name = f_string(c, o); break;
+ case 226: res->explainDatabase = ODR_NULLVAL; break;
+ case 114:
+ res->num_nicknames = 0; res->nicknames = 0; break; /* fix */
+ case 104: res->icon = 0; break; /* fix */
+ case 201: res->userFee = f_bool(c, o); break;
+ case 202: res->available = f_bool(c, o); break;
+ case 203: res->titleString = f_humstring(c, o); break;
+ case 227: res->num_keywords = 0; res->keywords = 0; break; /* fix */
+ case 113: res->description = f_humstring(c, o); break;
+ case 205: res->associatedDbs = 0; break; /* fix */
+ case 206: res->subDbs = 0; break; /* fix */
+ case 207: res->disclaimers = f_humstring(c, o); break;
+ case 103: res->news = f_humstring(c, o); break;
+ case 209: res->recordCount =
+ f_recordCount(c, o, &res->recordCount_which); break;
+ case 212: res->defaultOrder = f_humstring(c, o); break;
+ case 213: res->avRecordSize = f_integer(c, o); break;
+ case 214: res->maxRecordSize = f_integer(c, o); break;
+ case 215: res->hours = f_humstring(c, o); break;
+ case 216: res->bestTime = f_humstring(c, o); break;
+ case 217: res->lastUpdate = f_string(c, o); break;
+ case 218: res->updateInterval = f_intunit(c, o); break;
+ case 219: res->coverage = f_humstring(c, o); break;
+ case 220: res->proprietary = f_bool(c, o); break;
+ case 221: res->copyrightText = f_humstring(c, o); break;
+ case 222: res->copyrightNotice = f_humstring(c, o); break;
+ case 223: res->producerContactInfo = f_contactInfo(c, o); break;
+ case 224: res->supplierContactInfo = f_contactInfo(c, o); break;
+ case 225: res->submissionContactInfo = f_contactInfo(c, o); break;
+ case 500: res->accessInfo = f_accessInfo(c, select, o); break;
+ default:
+ logf(LOG_WARN, "Unknown element in databaseInfo");
+ }
+ }
+ return res;
}
Z_ExplainRecord *data1_nodetoexplain(data1_node *n, int select, ODR o)
+#
+# This Explain schema is used for our internal management and processing of
+# explain data. On request, records are mapped to the proper Explain ASN.1
+# before transmission.
+#
+
name explain
attset explain.att
tagset explain.tag
elm (4,0)/(4,117) hours -
elm (4,0)/(4,118) dbCombinations -
elm (4,0)/(4,119) addresses -
+
elm (4,0)/(4,500) commonAccessInfo -
elm (4,0)/(4,500)/(4,501) queryTypesSupported -
elm (4,0)/(4,500)/(4,503) diagnosticSets -
-elm (4,0)/(4,500)/(4,503)/(4,504) diagnosticSet -
+elm (4,0)/(4,500)/(4,503)/(4,1000) diagnosticSet -
elm (4,0)/(4,500)/(4,505) attributeSetIds -
-elm (4,0)/(4,500)/(4,505)/(4,506) attributeSetId -
+elm (4,0)/(4,500)/(4,505)/(4,1000) attributeSetId -
elm (4,0)/(4,500)/(4,507) schemas -
-elm (4,0)/(4,500)/(4,507)/(4,508) schema -
+elm (4,0)/(4,500)/(4,507)/(4,1000) schema -
elm (4,0)/(4,500)/(4,509) recordSyntaxes -
-elm (4,0)/(4,500)/(4,509/(4,510) recordSyntax -
+elm (4,0)/(4,500)/(4,509/(4,1000) recordSyntax -
elm (4,0)/(4,500)/(4,511) resourceChallenges -
-elm (4,0)/(4,500)/(4,511)/(4,512) resourceChallenge -
+elm (4,0)/(4,500)/(4,511)/(4,1000) resourceChallenge -
elm (4,0)/(4,500)/(4,513) restrictedAccess -
elm (4,0)/(4,500)/(4,514) costInfo -
+elm (4,0)/(4,500)/(4,515) variantSets -
+elm (4,0)/(4,500)/(4,515)/(4,1000) variantSets -
+elm (4,0)/(4,500)/(4,516) elementSetNames -
+elm (4,0)/(4,500)/(4,516)/(4,1001) elementSetName -
+elm (4,0)/(4,500)/(4,517) unitSystems -
+elm (4,0)/(4,500)/(4,517)/(4,1001) unitSystem -
elm (4,1) databaseInfo -
elm (4,1)/(4,600) databaseCommonInfo -
elm (4,1)/(4,600)/(4,603) expiry DateExpired
elm (4,1)/(4,600)/(4,604) languageCode HumanStringLanguage
elm (4,1)/(4,102) databaseName !
+elm (4,1)/(4,226) explainDatabase -
elm (4,1)/(4,114) nicknames -
+elm (4,1)/(4,114)/(4,1000) nickname -
elm (4,1)/(4,104) icon -
elm (4,1)/(4,201) userFee !
elm (4,1)/(4,202) available Availability
elm (4,1)/(4,203) titleString -
+elm (4,1)/(4,227) keywords -
+elm (4,1)/(4,227)/(4,1000) keyword -
elm (4,1)/(4,113) description -
elm (4,1)/(4,205) associatedDbs -
elm (4,1)/(4,206) subDbs -
elm (4,1)/(4,207) disclaimers -
-elm (4,1)/(4,208) recentNews -
+elm (4,1)/(4,103) recentNews -
elm (4,1)/(4,209) recordCount -
elm (4,1)/(4,209)/(4,210) recordCountActual -
elm (4,1)/(4,209)/(4,211) recordCountApprox -
elm (4,1)/(4,500) databaseAccessInfo -
elm (4,1)/(4,500)/(4,501) queryTypesSupported -
elm (4,1)/(4,500)/(4,503) diagnosticSets -
-elm (4,1)/(4,500)/(4,503)/(4,504) diagnosticSet -
+elm (4,1)/(4,500)/(4,503)/(4,1000) diagnosticSet -
elm (4,1)/(4,500)/(4,505) attributeSetIds -
elm (4,1)/(4,500)/(4,505)/(4,506) attributeSetId -
-elm (4,1)/(4,500)/(4,507) schemas -
-elm (4,1)/(4,500)/(4,507)/(4,508) schema -
+elm (4,1)/(4,500)/(4,1000) schemas -
+elm (4,1)/(4,500)/(4,507)/(4,1000) schema -
elm (4,1)/(4,500)/(4,509) recordSyntaxes -
-elm (4,1)/(4,500)/(4,509/(4,510) recordSyntax -
+elm (4,1)/(4,500)/(4,509/(4,1000) recordSyntax -
elm (4,1)/(4,500)/(4,511) resourceChallenges -
-elm (4,1)/(4,500)/(4,511)/(4,512) resourceChallenge -
+elm (4,1)/(4,500)/(4,511)/(4,1000) resourceChallenge -
elm (4,1)/(4,500)/(4,513) restrictedAccess -
elm (4,1)/(4,500)/(4,514) costInfo -
+elm (4,1)/(4,500)/(4,515) variantSets -
+elm (4,1)/(4,500)/(4,515)/(4,1000) variantSets -
+elm (4,1)/(4,500)/(4,1001) elementSetNames -
+elm (4,1)/(4,500)/(4,516)/(4,1001) elementSetName -
+elm (4,1)/(4,500)/(4,1001) unitSystems -
+elm (4,1)/(4,500)/(4,517)/(4,1001) unitSystem -
tag 205 associatedDbs structured
tag 206 subDbs structured
tag 207 disclaimers string
-tag 208 news string
tag 209 recordCount structured
tag 210 recordCountActual numeric
tag 211 recordCountApprox numeric
tag 223 producerContactInfo structured
tag 224 supplierContactInfo structured
tag 225 submissionContactInfo structured
-
+tag 226 explainDatabase null
+tag 227 keywords string
#
# AccessInfo
tag 500 accessinfo structured
tag 501 queryTypesSupported structured
tag 503 diagnosticSets structured
-tag 504 diagnosticSet oid
tag 505 attributeSetIds structured
-tag 506 attributeSetId oid
tag 507 schemas structured
-tag 508 schema oid
tag 509 recordSyntaxes structured
-tag 510 recordSyntax oid
tag 511 resourceChallenges structured
-tag 512 resourceChallenge oid
tag 513 restrictedAccess structured
tag 514 costInfo structured
+tag 515 variantSets structured
+tag 516 elementSetNames structured
+tag 517 unitSystems structured
tag 600 commonInfo structured
tag 601 dateAdded generalizedtime
tag 602 dateChanged generalizedtime
tag 603 expiry generalizedtime
tag 604 languageCode string
+
+#
+# General tags for list members, etc.
+#
+tag 1000 oid oid
+tag 1001 string string