Make Variant-1 OID definition. Fix OID for Espec-1
[yaz-moved-to-github.git] / src / oid_db.c
1 /*
2  * Copyright (C) 1995-2007, Index Data ApS
3  * See the file LICENSE for details.
4  *
5  * $Id: oid_db.c,v 1.3 2007-04-13 13:58:00 adam Exp $
6  */
7
8 /**
9  * \brief OID Database
10  */
11 #if HAVE_CONFIG_H
12 #include <config.h>
13 #endif
14
15 #include <stdlib.h>
16 #include <string.h>
17 #include <ctype.h>
18
19 #include <yaz/yaz-util.h>
20 #include <yaz/odr.h>
21 #include <yaz/oid_util.h>
22 #include <yaz/oid_db.h>
23
24 struct yaz_oid_entry {
25     int oclass;
26     int oid[OID_SIZE];
27     char *name;
28 };
29
30 #define Z3950_PREFIX 1, 2, 840, 10003
31
32 static struct yaz_oid_entry standard_list[] =
33 {
34     /* General definitions */
35     {CLASS_TRANSYN, {2, 1, 1,-1}, "BER" },
36     {CLASS_TRANSYN, {1, 0, 2709, 1, 1,-1},  "ISO2709"},
37     {CLASS_GENERAL, {1, 0, 10161, 2, 1,-1},  OID_STR_ILL_1 },
38     {CLASS_ABSYN,  {2, 1,-1}, "Z-APDU"}, 
39     {CLASS_APPCTX, {1, 1,-1}, "Z-BASIC"},
40     {CLASS_ATTSET, {Z3950_PREFIX, 3, 1,-1}, "Bib-1"},
41     {CLASS_ATTSET, {Z3950_PREFIX, 3, 2,-1}, "Exp-1"},
42     {CLASS_ATTSET, {Z3950_PREFIX, 3, 3,-1}, "Ext-1"},
43     {CLASS_ATTSET, {Z3950_PREFIX, 3, 4,-1}, "CCL-1"},
44     {CLASS_ATTSET, {Z3950_PREFIX, 3, 5,-1}, "GILS"},
45     {CLASS_ATTSET, {Z3950_PREFIX, 3, 5,-1}, "GILS-attset"},
46     {CLASS_ATTSET, {Z3950_PREFIX, 3, 6,-1}, "STAS-attset"},
47     {CLASS_ATTSET, {Z3950_PREFIX, 3, 7,-1}, "Collections-attset"},
48     {CLASS_ATTSET, {Z3950_PREFIX, 3, 8,-1}, "CIMI-attset"},
49     {CLASS_ATTSET, {Z3950_PREFIX, 3, 9,-1}, "Geo-attset"},
50     {CLASS_ATTSET, {Z3950_PREFIX, 3, 10,-1}, "ZBIG"},
51     {CLASS_ATTSET, {Z3950_PREFIX, 3, 11,-1}, "Util"},
52     {CLASS_ATTSET, {Z3950_PREFIX, 3, 12,-1}, "XD-1"},
53     {CLASS_ATTSET, {Z3950_PREFIX, 3, 13,-1}, "Zthes"},
54     {CLASS_ATTSET, {Z3950_PREFIX, 3, 14,-1}, "Fin-1"},
55     {CLASS_ATTSET, {Z3950_PREFIX, 3, 15,-1}, "Dan-1"},
56     {CLASS_ATTSET, {Z3950_PREFIX, 3, 16,-1}, "Holdings"},
57     {CLASS_ATTSET, {Z3950_PREFIX, 3, 17,-1}, "MARC"},
58     {CLASS_ATTSET, {Z3950_PREFIX, 3, 18,-1}, "Bib-2"},
59     {CLASS_ATTSET, {Z3950_PREFIX, 3, 19,-1}, "ZeeRex"},
60     /* New applications should use Zthes-1 instead of this Satan-spawn */
61     {CLASS_ATTSET, {Z3950_PREFIX, 3,1000, 81,1,-1}, "Thesaurus-attset"},
62     {CLASS_ATTSET, {Z3950_PREFIX, 3,1000, 81,2,-1}, "IDXPATH"},
63     {CLASS_ATTSET, {Z3950_PREFIX, 3,1000, 81,3,-1}, "EXTLITE"},
64     {CLASS_DIAGSET, {Z3950_PREFIX, 4, 1,-1}, OID_STR_BIB1},
65     {CLASS_DIAGSET, {Z3950_PREFIX, 4, 2,-1}, OID_STR_DIAG1},
66     {CLASS_DIAGSET, {Z3950_PREFIX, 4, 3,-1}, "Diag-ES"},
67     {CLASS_DIAGSET,  {Z3950_PREFIX, 4, 3,-1}, "Diag-General"},
68     {CLASS_RECSYN, {Z3950_PREFIX, 5, 1,-1}, "Unimarc"},
69     {CLASS_RECSYN, {Z3950_PREFIX, 5, 2,-1}, "Intermarc"},
70     {CLASS_RECSYN, {Z3950_PREFIX, 5, 3,-1}, "CCF"},
71     {CLASS_RECSYN, {Z3950_PREFIX, 5, 10,-1}, OID_STR_USMARC},
72     /* MARC21 is just an alias for the original USmarc */
73     {CLASS_RECSYN, {Z3950_PREFIX, 5, 10,-1}, "MARC21"},
74     {CLASS_RECSYN, {Z3950_PREFIX, 5, 11,-1}, "UKmarc"},
75     {CLASS_RECSYN, {Z3950_PREFIX, 5, 12,-1}, "Normarc"},
76     {CLASS_RECSYN, {Z3950_PREFIX, 5, 13,-1}, "Librismarc"},
77     {CLASS_RECSYN, {Z3950_PREFIX, 5, 14,-1}, "Danmarc"},
78     {CLASS_RECSYN, {Z3950_PREFIX, 5, 15,-1}, "Finmarc"},
79     {CLASS_RECSYN, {Z3950_PREFIX, 5, 16,-1}, "MAB"},
80     {CLASS_RECSYN, {Z3950_PREFIX, 5, 17,-1}, "Canmarc"},
81     {CLASS_RECSYN, {Z3950_PREFIX, 5, 18,-1}, "SBN"},
82     {CLASS_RECSYN, {Z3950_PREFIX, 5, 19,-1}, "Picamarc"},
83     {CLASS_RECSYN, {Z3950_PREFIX, 5, 20,-1}, "Ausmarc"},
84     {CLASS_RECSYN, {Z3950_PREFIX, 5, 21,-1}, "Ibermarc"},
85     {CLASS_RECSYN, {Z3950_PREFIX, 5, 22,-1}, "Carmarc"},
86     {CLASS_RECSYN, {Z3950_PREFIX, 5, 23,-1}, "Malmarc"},
87     {CLASS_RECSYN, {Z3950_PREFIX, 5, 24,-1}, "JPmarc"},
88     {CLASS_RECSYN, {Z3950_PREFIX, 5, 25,-1}, "SWEmarc"},
89     {CLASS_RECSYN, {Z3950_PREFIX, 5, 26,-1}, "SIGLEmarc"},
90     {CLASS_RECSYN, {Z3950_PREFIX, 5, 27,-1}, "ISDSmarc"},
91     {CLASS_RECSYN, {Z3950_PREFIX, 5, 28,-1}, "RUSmarc"},
92     {CLASS_RECSYN, {Z3950_PREFIX, 5, 29,-1}, "Hunmarc"},
93     {CLASS_RECSYN, {Z3950_PREFIX, 5, 30,-1}, "NACSIS-CATP"},
94     {CLASS_RECSYN, {Z3950_PREFIX, 5, 31,-1}, "FINMARC2000"},
95     {CLASS_RECSYN, {Z3950_PREFIX, 5, 32,-1}, "MARC21-fin"},
96     {CLASS_RECSYN, {Z3950_PREFIX, 5, 100,-1}, OID_STR_EXPLAIN},
97     {CLASS_RECSYN, {Z3950_PREFIX, 5, 101,-1}, OID_STR_SUTRS},
98     {CLASS_RECSYN, {Z3950_PREFIX, 5, 102,-1}, OID_STR_OPAC},
99     {CLASS_RECSYN, {Z3950_PREFIX, 5, 103,-1}, OID_STR_SUMMARY},
100     {CLASS_RECSYN, {Z3950_PREFIX, 5, 104,-1}, "GRS-0"},
101     {CLASS_RECSYN, {Z3950_PREFIX, 5, 105,-1}, OID_STR_GRS1 },
102     {CLASS_RECSYN, {Z3950_PREFIX, 5, 106,-1}, OID_STR_EXTENDED},
103     {CLASS_RECSYN, {Z3950_PREFIX, 5, 107,-1}, "Fragment"},
104     {CLASS_RECSYN, {Z3950_PREFIX, 5, 109,1,-1}, "pdf"},
105     {CLASS_RECSYN, {Z3950_PREFIX, 5, 109,2,-1}, OID_STR_POSTSCRIPT},
106     {CLASS_RECSYN, {Z3950_PREFIX, 5, 109,3,-1}, OID_STR_HTML},
107     {CLASS_RECSYN, {Z3950_PREFIX, 5, 109,4,-1}, "tiff"},
108     {CLASS_RECSYN, {Z3950_PREFIX, 5, 109,5,-1}, "gif"},
109     {CLASS_RECSYN, {Z3950_PREFIX, 5, 109,6,-1}, "jpeg"},
110     {CLASS_RECSYN, {Z3950_PREFIX, 5, 109,7,-1}, "png"},
111     {CLASS_RECSYN, {Z3950_PREFIX, 5, 109,8,-1}, "mpeg"},
112     {CLASS_RECSYN, {Z3950_PREFIX, 5, 109,9,-1}, "sgml"},
113     {CLASS_RECSYN, {Z3950_PREFIX, 5, 110,1,-1}, "tiff-b"},
114     {CLASS_RECSYN, {Z3950_PREFIX, 5, 110,2,-1}, "wav"},
115     {CLASS_RECSYN, {Z3950_PREFIX, 5, 111,-1}, "SQL-RS"},
116     {CLASS_RECSYN, {Z3950_PREFIX, 5, 1000, 81, 2,-1}, OID_STR_SOIF},
117     {CLASS_RECSYN, {Z3950_PREFIX, 5, 109, 10,-1}, OID_STR_XML },
118     {CLASS_RECSYN, {Z3950_PREFIX, 5, 109, 10,-1}, "application-XML"},
119     {CLASS_RECSYN, {Z3950_PREFIX, 5, 109, 11,-1}, OID_STR_APPLICATION_XML },
120     {CLASS_RESFORM, {Z3950_PREFIX, 7, 1,-1}, "Resource-1"},
121     {CLASS_RESFORM, {Z3950_PREFIX, 7, 2,-1}, "Resource-2"},
122     {CLASS_RESFORM, {Z3950_PREFIX, 7, 1000, 81, 1,-1}, "UNIverse-Resource-Report"},
123     {CLASS_ACCFORM, {Z3950_PREFIX, 8, 1,-1}, "Prompt-1"},
124     {CLASS_ACCFORM, {Z3950_PREFIX, 8, 2,-1}, "Des-1"},
125     {CLASS_ACCFORM, {Z3950_PREFIX, 8, 3,-1}, "Krb-1"},
126     {CLASS_EXTSERV, {Z3950_PREFIX, 9, 1,-1}, "Pers. set"},
127     {CLASS_EXTSERV, {Z3950_PREFIX, 9, 2,-1}, "Pers. query"},
128     {CLASS_EXTSERV, {Z3950_PREFIX, 9, 3,-1}, "Per'd query"},
129     {CLASS_EXTSERV, {Z3950_PREFIX, 9, 4,-1},  OID_STR_ITEMORDER },
130     {CLASS_EXTSERV, {Z3950_PREFIX, 9, 5,-1}, "DB. Update (first version)"},
131     {CLASS_EXTSERV, {Z3950_PREFIX, 9, 5,1,-1}, "DB. Update (second version)"},
132     {CLASS_EXTSERV, {Z3950_PREFIX, 9, 5, 1, 1,-1}, OID_STR_EXT_UPDATE},
133     {CLASS_EXTSERV, {Z3950_PREFIX, 9, 6,-1}, "exp. spec."},
134     {CLASS_EXTSERV, {Z3950_PREFIX, 9, 7,-1}, "exp. inv."},
135     {CLASS_EXTSERV, {Z3950_PREFIX, 9, 1000, 81, 1,-1}, OID_STR_ADMIN},
136     {CLASS_USERINFO, {Z3950_PREFIX, 10, 1,-1}, "searchResult-1"},
137     {CLASS_USERINFO, {Z3950_PREFIX, 10, 2,-1}, "CharSetandLanguageNegotiation"},
138     {CLASS_USERINFO, {Z3950_PREFIX, 10, 3,-1},  OID_STR_USERINFO_1},
139     {CLASS_USERINFO, {Z3950_PREFIX, 10, 4,-1}, "MultipleSearchTerms-1"},
140     {CLASS_USERINFO, {Z3950_PREFIX, 10, 5,-1}, "MultipleSearchTerms-2"},
141     {CLASS_USERINFO, {Z3950_PREFIX, 10, 6,-1}, "DateTime"},
142     {CLASS_USERINFO, {Z3950_PREFIX, 10, 1000, 81, 1,-1}, OID_STR_PROXY},
143     {CLASS_USERINFO, {Z3950_PREFIX, 10, 1000, 81, 2,-1}, OID_STR_COOKIE},
144     {CLASS_USERINFO, {Z3950_PREFIX, 10, 1000, 81, 3,-1},  OID_STR_CLIENT_IP },
145     {CLASS_ELEMSPEC, {Z3950_PREFIX, 11, 1,-1}, "Espec-1"},
146     {CLASS_VARSET, {Z3950_PREFIX, 12, 1,-1}, OID_STR_VARIANT_1},
147     {CLASS_SCHEMA, {Z3950_PREFIX, 13, 1,-1}, "WAIS-schema"},
148     {CLASS_SCHEMA, {Z3950_PREFIX, 13, 2,-1}, "GILS-schema"},
149     {CLASS_SCHEMA, {Z3950_PREFIX, 13, 3,-1}, "Collections-schema"},
150     {CLASS_SCHEMA, {Z3950_PREFIX, 13, 4,-1}, "Geo-schema"},
151     {CLASS_SCHEMA, {Z3950_PREFIX, 13, 5,-1}, "CIMI-schema"},
152     {CLASS_SCHEMA, {Z3950_PREFIX, 13, 6,-1}, "Update ES"},
153     {CLASS_SCHEMA, {Z3950_PREFIX, 13, 7,-1}, "Holdings"},
154     {CLASS_SCHEMA, {Z3950_PREFIX, 13, 8,-1}, "Zthes"},
155     {CLASS_SCHEMA, {Z3950_PREFIX, 13, 1000, 81, 1,-1}, "thesaurus-schema"},
156     {CLASS_SCHEMA, {Z3950_PREFIX, 13, 1000, 81, 2,-1}, "Explain-schema"},
157     {CLASS_TAGSET, {Z3950_PREFIX, 14, 1,-1}, "TagsetM"},
158     {CLASS_TAGSET, {Z3950_PREFIX, 14, 2,-1}, "TagsetG"},
159     {CLASS_TAGSET, {Z3950_PREFIX, 14, 3,-1}, "STAS-tagset"},
160     {CLASS_TAGSET, {Z3950_PREFIX, 14, 4,-1}, "GILS-tagset"},
161     {CLASS_TAGSET, {Z3950_PREFIX, 14, 5,-1}, "Collections-tagset"},
162     {CLASS_TAGSET, {Z3950_PREFIX, 14, 6,-1}, "CIMI-tagset"},
163     {CLASS_TAGSET, {Z3950_PREFIX, 14, 1000, 81, 1,-1}, "thesaurus-tagset"}, 
164     {CLASS_TAGSET, {Z3950_PREFIX, 14, 1000, 81, 2,-1}, "Explain-tagset"},
165     {CLASS_TAGSET, {Z3950_PREFIX, 14, 8,-1}, "Zthes-tagset"},
166     {CLASS_NEGOT, {Z3950_PREFIX, 15, 3,-1}, OID_STR_CHARNEG_3 },
167     {CLASS_NEGOT, {Z3950_PREFIX, 15, 4,-1}, OID_STR_CHARNEG_4 },
168     {CLASS_NEGOT, {Z3950_PREFIX, 15, 1000, 81, 1, -1}, OID_STR_ID_CHARSET },
169     {CLASS_USERINFO, {1, 2, 840, 1003, 16,  2, -1}, "CQL"},
170     {CLASS_GENERAL, {1,0,10646,1,0,2,-1}, "UCS-2"},
171     {CLASS_GENERAL, {1,0,10646,1,0,4,-1}, "UCS-4"},
172     {CLASS_GENERAL, {1,0,10646,1,0,5,-1}, "UTF-16"},
173     {CLASS_GENERAL, {1,0,10646,1,0,8,-1}, "UTF-8"},
174     {CLASS_USERINFO, {Z3950_PREFIX, 10, 1000, 17, 1, -1}, "OCLC-userInfo"},
175     {CLASS_EXTSERV, {Z3950_PREFIX, 9, 1000,105,4,-1}, OID_STR_XMLES },
176     {CLASS_NOP, {-1}, 0}
177 };
178
179 struct yaz_oid_db {
180     struct yaz_oid_entry *entries;
181     struct yaz_oid_db *next;
182     int xmalloced;
183 };
184
185 struct yaz_oid_db standard_db_l = {
186     standard_list, 0, 0
187 };
188
189 yaz_oid_db_t standard_db = &standard_db_l;
190
191 yaz_oid_db_t yaz_oid_std(void)
192 {
193     return standard_db;
194 }
195
196 const int *yaz_string_to_oid(yaz_oid_db_t oid_db,
197                              int oclass, const char *name)
198 {
199     for (; oid_db; oid_db = oid_db->next)
200     {
201         struct yaz_oid_entry *e = oid_db->entries;
202         for (; e->name; e++)
203         {
204             if (!yaz_matchstr(e->name, name)
205                 && (oclass == CLASS_GENERAL || oclass == e->oclass))
206                 return e->oid;
207         }
208     }
209     return 0;
210 }
211
212 int *yaz_string_to_oid_nmem(yaz_oid_db_t oid_list,
213                             int oclass, const char *name, NMEM nmem)
214 {
215     const int *oid = yaz_string_to_oid(oid_list, oclass, name);
216     if (oid)
217         return odr_oiddup_nmem(nmem, oid);
218     return odr_getoidbystr_nmem(nmem, name);
219 }
220
221 int *yaz_string_to_oid_odr(yaz_oid_db_t oid_list,
222                            int oclass, const char *name, ODR o)
223 {
224     return yaz_string_to_oid_nmem(oid_list, oclass, name, odr_getmem(o));
225 }
226
227 const char *yaz_oid_to_string(yaz_oid_db_t oid_db,
228                               const int *oid, int *oclass)
229 {
230     if (!oid)
231         return 0;
232     for (; oid_db; oid_db = oid_db->next)
233     {
234         struct yaz_oid_entry *e = oid_db->entries;
235         for (; e->name; e++)
236         {
237             if (!oid_oidcmp(e->oid, oid))
238             {
239                 if (oclass)
240                     *oclass = e->oclass;
241                 return e->name;
242             }
243         }
244     }
245     return 0;
246 }
247
248 const char *yaz_oid_to_string_buf(const int *oid, int *oclass, char *buf)
249 {
250     const char *p = yaz_oid_to_string(standard_db, oid, oclass);
251     if (p)
252         return p;
253     if (oclass)
254         *oclass = CLASS_GENERAL;
255     return oid_oid_to_dotstring(oid, buf);
256 }
257
258 int yaz_oid_is_iso2709(const int *oid)
259 {
260     if (oid_oidlen(oid) == 6 && oid[0] == 1 && oid[1] == 2
261         && oid[2] == 840 && oid[3] == 10003 && oid[4] == 5 
262         && oid[5] <= 29 && oid[5] != 16)
263         return 1;
264     return 0;
265 }
266
267 int yaz_oid_add(yaz_oid_db_t oid_db, int oclass, const char *name,
268                 const int *new_oid)
269 {
270     const int *oid = yaz_string_to_oid(oid_db, oclass, name);
271     if (!oid)
272     {
273         struct yaz_oid_entry *ent;
274
275         while (oid_db->next)
276             oid_db = oid_db->next;
277         oid_db->next = xmalloc(sizeof(*oid_db->next));
278         oid_db = oid_db->next;
279
280         oid_db->next = 0;
281         oid_db->xmalloced = 1;
282         oid_db->entries = ent = xmalloc(2 * sizeof(*ent));
283         ent[0].oclass = oclass;
284         oid_oidcpy(ent[0].oid, new_oid);
285         ent[0].name = xstrdup(name);
286         ent[1].oclass = CLASS_NOP;
287         ent[1].oid[0] = -1;
288         ent[1].name = 0;
289         return 0;
290     }
291     return -1;
292 }
293
294 yaz_oid_db_t yaz_oid_db_new(void)
295 {
296     yaz_oid_db_t p = xmalloc(sizeof(*p));
297     p->entries = 0;
298     p->next = 0;
299     p->xmalloced = 1;
300     return p;
301 }
302
303 void yaz_oid_db_destroy(yaz_oid_db_t oid_db)
304 {
305     while (oid_db)
306     {
307         yaz_oid_db_t p = oid_db;
308
309         oid_db = oid_db->next;
310         if (p->xmalloced)
311         {
312             struct yaz_oid_entry *e = p->entries;
313             for (; e->name; e++)
314                 xfree (e->name);
315             xfree(p->entries);
316             xfree(p);
317         }
318     }
319 }
320
321 void yaz_oid_trav(yaz_oid_db_t oid_db,
322                   void (*func)(const int *oid,
323                                int oclass, const char *name,
324                                void *client_data),
325                   void *client_data)
326 {
327     for (; oid_db; oid_db = oid_db->next)
328     {
329         struct yaz_oid_entry *e = oid_db->entries;
330         
331         for (; e->name; e++)
332             func(e->oid, e->oclass, e->name, client_data);
333     }
334 }
335