New Z39.50 OID utilities: yaz_oidval_to_z3950oid, yaz_str_to_z3950oid
[yaz-moved-to-github.git] / zutil / otherinfo.c
1 /*
2  * Copyright (c) 1999-2001, Index Data
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  *
6  * $Log: otherinfo.c,v $
7  * Revision 1.5  2001-09-24 21:51:56  adam
8  * New Z39.50 OID utilities: yaz_oidval_to_z3950oid, yaz_str_to_z3950oid
9  * and yaz_z3950oid_to_str.
10  *
11  * Revision 1.4  1999/11/30 13:47:12  adam
12  * Improved installation. Moved header files to include/yaz.
13  *
14  * Revision 1.3  1999/11/10 09:06:40  adam
15  * Fixed yaz_oi_update so that it ignores NULL pointer.
16  *
17  * Revision 1.2  1999/09/13 12:51:35  adam
18  * Fixed bug in yaz_oi_update and added delete option.
19  *
20  * Revision 1.1  1999/06/08 10:10:16  adam
21  * New sub directory zutil. Moved YAZ Compiler to be part of YAZ tree.
22  *
23  * Revision 1.1  1999/04/26 07:25:25  adam
24  * Implemented OtherInfo utility.
25  *
26  */
27
28 #include <stdio.h>
29 #include <string.h>
30
31 #include <yaz/otherinfo.h>
32
33 void yaz_oi_APDU(Z_APDU *apdu, Z_OtherInformation ***oip)
34 {
35     switch (apdu->which)
36     {
37     case Z_APDU_initRequest:
38         *oip = &apdu->u.initRequest->otherInfo;
39         break;
40     case Z_APDU_searchRequest:
41         *oip = &apdu->u.searchRequest->otherInfo;
42         break;
43     case Z_APDU_presentRequest:
44         *oip = &apdu->u.presentRequest->otherInfo;
45         break;
46     case Z_APDU_sortRequest:
47         *oip = &apdu->u.sortRequest->otherInfo;
48         break;
49     case Z_APDU_scanRequest:
50         *oip = &apdu->u.scanRequest->otherInfo;
51         break;
52     case Z_APDU_extendedServicesRequest:
53         *oip = &apdu->u.extendedServicesRequest->otherInfo;
54         break;
55     case Z_APDU_deleteResultSetRequest:
56         *oip = &apdu->u.deleteResultSetRequest->otherInfo;
57         break;
58     case Z_APDU_initResponse:
59         *oip = &apdu->u.initResponse->otherInfo;
60         break;
61     case Z_APDU_searchResponse:
62         *oip = &apdu->u.searchResponse->otherInfo;
63         break;
64     case Z_APDU_presentResponse:
65         *oip = &apdu->u.presentResponse->otherInfo;
66         break;
67     case Z_APDU_sortResponse:
68         *oip = &apdu->u.sortResponse->otherInfo;
69         break;
70     case Z_APDU_scanResponse:
71         *oip = &apdu->u.scanResponse->otherInfo;
72         break;
73     case Z_APDU_extendedServicesResponse:
74         *oip = &apdu->u.extendedServicesResponse->otherInfo;
75         break;
76     case Z_APDU_deleteResultSetResponse:
77         *oip = &apdu->u.deleteResultSetResponse->otherInfo;
78         break;
79     default:
80         *oip = 0;
81         break;
82     }
83 }
84
85 Z_OtherInformationUnit *yaz_oi_update (
86     Z_OtherInformation **otherInformationP, ODR odr,
87     int *oid, int categoryValue, int delete_flag)
88 {
89     int i;
90     Z_OtherInformation *otherInformation;
91
92     if (!otherInformationP)
93         return 0;
94     otherInformation = *otherInformationP;
95     if (!otherInformation)
96     {
97         if (!odr)
98             return 0;
99         otherInformation = *otherInformationP = (Z_OtherInformation *)
100             odr_malloc (odr, sizeof(*otherInformation));
101         otherInformation->num_elements = 0;
102         otherInformation->list = 0;
103     }
104     for (i = 0; i<otherInformation->num_elements; i++)
105     {
106         if (!oid)
107         {
108             if (!otherInformation->list[i]->category)
109                 return otherInformation->list[i];
110         }
111         else
112         {
113             if (otherInformation->list[i]->category &&
114                 categoryValue ==
115                 *otherInformation->list[i]->category->categoryValue &&
116                 !oid_oidcmp (oid, otherInformation->list[i]->category->
117                              categoryTypeId))
118             {
119                 Z_OtherInformationUnit *this_list = otherInformation->list[i];
120
121                 if (delete_flag)
122                 {
123                     (otherInformation->num_elements)--;
124                     while (i < otherInformation->num_elements)
125                     {
126                         otherInformation->list[i] =
127                             otherInformation->list[i+1];
128                         i++;
129                     }
130                 }
131                 return this_list;
132             }
133         }
134     }
135     if (!odr)
136         return 0;
137     else
138     {
139         Z_OtherInformationUnit **newlist = (Z_OtherInformationUnit**)
140             odr_malloc(odr, (otherInformation->num_elements+1) *
141                        sizeof(*newlist));
142         for (i = 0; i<otherInformation->num_elements; i++)
143             newlist[i] = otherInformation->list[i];
144         otherInformation->list = newlist;
145         
146         otherInformation->list[i] = (Z_OtherInformationUnit*)
147             odr_malloc (odr, sizeof(Z_OtherInformationUnit));
148         if (oid)
149         {
150             otherInformation->list[i]->category = (Z_InfoCategory*)
151                 odr_malloc (odr, sizeof(Z_InfoCategory));
152             otherInformation->list[i]->category->categoryTypeId = (int*)
153                 odr_oiddup (odr, oid);
154             otherInformation->list[i]->category->categoryValue = (int*)
155                 odr_malloc (odr, sizeof(int));
156             *otherInformation->list[i]->category->categoryValue =
157                 categoryValue;
158         }
159         else
160             otherInformation->list[i]->category = 0;
161         otherInformation->list[i]->which = Z_OtherInfo_characterInfo;
162         otherInformation->list[i]->information.characterInfo = 0;
163         
164         otherInformation->num_elements = i+1;
165         return otherInformation->list[i];
166     }
167 }
168
169 void yaz_oi_set_string_oid (
170     Z_OtherInformation **otherInformation, ODR odr,
171     int *oid, int categoryValue,
172     const char *str)
173 {
174     Z_OtherInformationUnit *oi =
175         yaz_oi_update(otherInformation, odr, oid, categoryValue, 0);
176     if (!oi)
177         return;
178     oi->which = Z_OtherInfo_characterInfo;
179     oi->information.characterInfo = odr_strdup (odr, str);
180 }
181
182 void yaz_oi_set_string_oidval (
183     Z_OtherInformation **otherInformation, ODR odr,
184     int oidval, int categoryValue,
185     const char *str)
186 {
187     int oid[OID_SIZE];
188     struct oident ent;
189     ent.proto = PROTO_Z3950;
190     ent.oclass = CLASS_USERINFO;
191     ent.value = (oid_value) oidval;
192     if (!oid_ent_to_oid (&ent, oid))
193         return ;
194     yaz_oi_set_string_oid(otherInformation,
195                           odr, oid, categoryValue, str);
196 }
197
198 char *yaz_oi_get_string_oid (
199     Z_OtherInformation **otherInformation,
200     int *oid, int categoryValue, int delete_flag)
201 {
202     Z_OtherInformationUnit *oi;
203     
204     if ((oi = yaz_oi_update(otherInformation, 0, oid, 1, delete_flag)) &&
205         oi->which == Z_OtherInfo_characterInfo)
206         return oi->information.characterInfo;
207     return 0;
208 }
209
210 char *yaz_oi_get_string_oidval(Z_OtherInformation **otherInformation,
211                                int oidval, int categoryValue, int delete_flag)
212 {
213     int oid[OID_SIZE];
214     struct oident ent;
215     ent.proto = PROTO_Z3950;
216     ent.oclass = CLASS_USERINFO;
217     ent.value = (oid_value) oidval;
218
219     if (!oid_ent_to_oid (&ent, oid))
220         return 0;
221     return yaz_oi_get_string_oid (otherInformation, oid, categoryValue,
222                                   delete_flag);
223 }
224