f1ec5882e3745a3094b3a72361f07f3d6acaa1fc
[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.7 2007-05-06 20:12:20 adam Exp $
6  */
7
8 /**
9  * \file oid_db.c
10  * \brief OID Database
11  */
12 #if HAVE_CONFIG_H
13 #include <config.h>
14 #endif
15
16 #include <stdlib.h>
17 #include <string.h>
18 #include <ctype.h>
19
20 #include <yaz/yaz-util.h>
21 #include <yaz/odr.h>
22 #include <yaz/oid_util.h>
23 #include <yaz/oid_db.h>
24
25 struct yaz_oid_db {
26      struct yaz_oid_entry *entries;
27      struct yaz_oid_db *next;
28      int xmalloced;
29 };
30
31 struct yaz_oid_db standard_db_l = {
32     yaz_oid_standard_entries, 0, 0
33 };
34 yaz_oid_db_t standard_db = &standard_db_l;
35
36 yaz_oid_db_t yaz_oid_std(void)
37 {
38     return standard_db;
39 }
40
41 const int *yaz_string_to_oid(yaz_oid_db_t oid_db,
42                              int oclass, const char *name)
43 {
44     for (; oid_db; oid_db = oid_db->next)
45     {
46         struct yaz_oid_entry *e;
47         if (oclass != CLASS_GENERAL)
48         {
49             for (e = oid_db->entries; e->name; e++)
50             {
51                 if (!yaz_matchstr(e->name, name) && oclass == e->oclass)
52                     return e->oid;
53             }
54         }
55         for (e = oid_db->entries; e->name; e++)
56         {
57             if (!yaz_matchstr(e->name, name))
58                 return e->oid;
59         }
60     }
61     return 0;
62 }
63
64 int *yaz_string_to_oid_nmem(yaz_oid_db_t oid_list,
65                             int oclass, const char *name, NMEM nmem)
66 {
67     const int *oid = yaz_string_to_oid(oid_list, oclass, name);
68     if (oid)
69         return odr_oiddup_nmem(nmem, oid);
70     return odr_getoidbystr_nmem(nmem, name);
71 }
72
73 int *yaz_string_to_oid_odr(yaz_oid_db_t oid_list,
74                            int oclass, const char *name, ODR o)
75 {
76     return yaz_string_to_oid_nmem(oid_list, oclass, name, odr_getmem(o));
77 }
78
79 const char *yaz_oid_to_string(yaz_oid_db_t oid_db,
80                               const int *oid, int *oclass)
81 {
82     if (!oid)
83         return 0;
84     for (; oid_db; oid_db = oid_db->next)
85     {
86         struct yaz_oid_entry *e = oid_db->entries;
87         for (; e->name; e++)
88         {
89             if (!oid_oidcmp(e->oid, oid))
90             {
91                 if (oclass)
92                     *oclass = e->oclass;
93                 return e->name;
94             }
95         }
96     }
97     return 0;
98 }
99
100 const char *yaz_oid_to_string_buf(const int *oid, int *oclass, char *buf)
101 {
102     const char *p = yaz_oid_to_string(standard_db, oid, oclass);
103     if (p)
104         return p;
105     if (oclass)
106         *oclass = CLASS_GENERAL;
107     return oid_oid_to_dotstring(oid, buf);
108 }
109
110 int yaz_oid_is_iso2709(const int *oid)
111 {
112     if (oid_oidlen(oid) == 6 && oid[0] == 1 && oid[1] == 2
113         && oid[2] == 840 && oid[3] == 10003 && oid[4] == 5 
114         && oid[5] <= 29 && oid[5] != 16)
115         return 1;
116     return 0;
117 }
118
119 int yaz_oid_add(yaz_oid_db_t oid_db, int oclass, const char *name,
120                 const int *new_oid)
121 {
122     const int *oid = yaz_string_to_oid(oid_db, oclass, name);
123     if (!oid)
124     {
125         struct yaz_oid_entry *ent;
126         int *alloc_oid;
127
128         while (oid_db->next)
129             oid_db = oid_db->next;
130         oid_db->next = (struct yaz_oid_db *) xmalloc(sizeof(*oid_db->next));
131         oid_db = oid_db->next;
132
133         oid_db->next = 0;
134         oid_db->xmalloced = 1;
135         oid_db->entries = ent = (struct yaz_oid_entry *) xmalloc(2 * sizeof(*ent));
136
137         alloc_oid = (int *)
138             xmalloc(sizeof(*alloc_oid) * (oid_oidlen(new_oid)+1));
139         oid_oidcpy(alloc_oid, new_oid);
140         ent[0].oid = alloc_oid;
141         ent[0].name = xstrdup(name);
142         ent[0].oclass = oclass;
143
144         ent[1].oid = 0;
145         ent[1].name = 0;
146         ent[1].oclass = CLASS_NOP;
147         return 0;
148     }
149     return -1;
150 }
151
152 yaz_oid_db_t yaz_oid_db_new(void)
153 {
154     yaz_oid_db_t p = (yaz_oid_db_t) xmalloc(sizeof(*p));
155     p->entries = 0;
156     p->next = 0;
157     p->xmalloced = 1;
158     return p;
159 }
160
161 void yaz_oid_db_destroy(yaz_oid_db_t oid_db)
162 {
163     while (oid_db)
164     {
165         yaz_oid_db_t p = oid_db;
166
167         oid_db = oid_db->next;
168         if (p->xmalloced)
169         {
170             struct yaz_oid_entry *e = p->entries;
171             for (; e->name; e++)
172                 xfree (e->name);
173             xfree(p->entries);
174             xfree(p);
175         }
176     }
177 }
178
179 void yaz_oid_trav(yaz_oid_db_t oid_db,
180                   void (*func)(const int *oid,
181                                int oclass, const char *name,
182                                void *client_data),
183                   void *client_data)
184 {
185     for (; oid_db; oid_db = oid_db->next)
186     {
187         struct yaz_oid_entry *e = oid_db->entries;
188         
189         for (; e->name; e++)
190             func(e->oid, e->oclass, e->name, client_data);
191     }
192 }
193
194 /*
195  * Local variables:
196  * c-basic-offset: 4
197  * indent-tabs-mode: nil
198  * End:
199  * vim: shiftwidth=4 tabstop=8 expandtab
200  */
201