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