Added second part of helper functions for CharSetandLanguageNegotaiation-3 Model.
[yaz-moved-to-github.git] / zutil / charneg.c
1 /* 
2  $ $Id: charneg.c,v 1.2 2002-05-19 15:39:54 oleg Exp $
3  * Helper functions for Character Set and Language Negotiation - 3
4  */
5
6 #include <stdio.h>
7 #include <yaz/otherinfo.h>
8 #include <yaz/z-charneg.h>
9 #include <yaz/charneg.h>
10
11 static Z_External* z_ext_record2(ODR o, int oid_class, int oid_value,
12         const char *buf, int len)
13 {
14         Z_External *p;
15         oident oid;
16                 
17         if (!(p = (Z_External *)odr_malloc(o, sizeof(*p)))) return 0;
18         
19         p->descriptor = 0;
20         p->indirect_reference = 0;
21         
22         oid.proto = PROTO_Z3950;
23         oid.oclass = oid_class;
24         oid.value = oid_value;
25         p->direct_reference = odr_oiddup(o, oid_getoidbyent(&oid));
26         
27         p->which = Z_External_octet;
28         if (!(p->u.octet_aligned = (Odr_oct *)odr_malloc(o, sizeof(Odr_oct)))) {
29                 return 0;
30         }
31         if (!(p->u.octet_aligned->buf = (unsigned char *)odr_malloc(o, len))) {
32                 return 0;
33         }
34         p->u.octet_aligned->len = p->u.octet_aligned->size = len;
35         memcpy(p->u.octet_aligned->buf, buf, len);
36         
37         return p;
38 }
39 static Z_OriginProposal_0 *z_get_OriginProposal_0(ODR o, const char *charset)
40 {
41         Z_OriginProposal_0 *p0 =
42                                 (Z_OriginProposal_0*)odr_malloc(o, sizeof(*p0));
43         Z_PrivateCharacterSet *pc =
44                                 (Z_PrivateCharacterSet *)odr_malloc(o, sizeof(*pc));
45
46         memset(p0, 0, sizeof(*p0));
47         memset(pc, 0, sizeof(*pc));
48                         
49         p0->which = Z_OriginProposal_0_private;
50         p0->u.zprivate = pc;
51         
52         pc->which = Z_PrivateCharacterSet_externallySpecified;
53         pc->u.externallySpecified =
54                         z_ext_record2(o, CLASS_RECSYN, VAL_NOP, charset, (strlen(charset)+1));
55         
56         return p0;
57 }
58 static Z_OriginProposal *z_get_OriginProposal(ODR o, const char **charsets,
59         int num_charsets, const char **langs, int num_langs, int selected)
60 {       
61         int i;
62         Z_OriginProposal *p = (Z_OriginProposal *) odr_malloc(o, sizeof(*p));
63                 
64         memset(p, 0, sizeof(*p));
65
66         p->recordsInSelectedCharSets = (bool_t *)odr_malloc(o, sizeof(bool_t));
67         *p->recordsInSelectedCharSets = (selected) ? 1:0;
68
69         if (charsets && num_charsets) {         
70         
71                 p->num_proposedCharSets = num_charsets;
72                 p->proposedCharSets = 
73                         (Z_OriginProposal_0**) odr_malloc(o,
74                                 num_charsets*sizeof(Z_OriginProposal_0*));
75
76                 for (i = 0; i<num_charsets; i++) {
77
78                         p->proposedCharSets[i] =
79                                 z_get_OriginProposal_0(o, charsets[i]);
80                         
81                 }
82         }
83         if (langs && num_langs) {
84         
85                 p->num_proposedlanguages = num_langs;
86
87                 p->proposedlanguages = 
88                         (char **) odr_malloc(o, num_langs*sizeof(char *));
89
90                 for (i = 0; i<num_langs; i++) {
91
92                         p->proposedlanguages[i] = (char *)langs[i];
93                         
94                 }
95         }
96         return p;
97 }
98 static Z_CharSetandLanguageNegotiation *z_get_CharSetandLanguageNegotiation(ODR o)
99 {
100         Z_CharSetandLanguageNegotiation *p =
101                 (Z_CharSetandLanguageNegotiation *) odr_malloc(o, sizeof(*p));
102         
103         memset(p, 0, sizeof(*p));
104         
105         return p;
106 }
107 Z_External *yaz_set_proposal_charneg(ODR o, const char **charsets, int num_charsets,
108         const char **langs, int num_langs, int selected)
109 {
110         Z_External *p = (Z_External *)odr_malloc(o, sizeof(*p));
111         oident oid;
112         
113         p->descriptor = 0;
114         p->indirect_reference = 0;      
115
116         oid.proto = PROTO_Z3950;
117         oid.oclass = CLASS_NEGOT;
118         oid.value = VAL_CHARNEG3;
119         p->direct_reference = odr_oiddup(o, oid_getoidbyent(&oid));
120
121         p->which = Z_External_charSetandLanguageNegotiation;
122         p->u.charNeg3 = z_get_CharSetandLanguageNegotiation(o);
123         p->u.charNeg3->which = Z_CharSetandLanguageNegotiation_proposal;
124         p->u.charNeg3->u.proposal =
125                 z_get_OriginProposal(o, charsets, num_charsets,
126                         langs, num_langs, selected);
127
128         return p;
129 }
130 static Z_TargetResponse *z_get_TargetResponse(ODR o, const char *charset,
131         const char *lang, int selected)
132 {       
133         int i;
134         Z_TargetResponse *p = (Z_TargetResponse *) odr_malloc(o, sizeof(*p));
135         Z_PrivateCharacterSet *pc =
136                                 (Z_PrivateCharacterSet *)odr_malloc(o, sizeof(*pc));
137                 
138         memset(p, 0, sizeof(*p));
139         memset(pc, 0, sizeof(*pc));
140         
141         p->recordsInSelectedCharSets = (bool_t *)odr_malloc(o, sizeof(bool_t));
142         *p->recordsInSelectedCharSets = (selected) ? 1:0;
143         p->selectedLanguage = (char *)odr_strdup(o, lang);
144         
145         p->which = Z_TargetResponse_private;
146         p->u.zprivate = pc;
147         
148         pc->which = Z_PrivateCharacterSet_externallySpecified;
149         pc->u.externallySpecified =
150                         z_ext_record2(o, CLASS_RECSYN, VAL_NOP, charset, (strlen(charset)+1));
151         return p;
152 }
153 Z_External *yaz_set_response_charneg(ODR o, const char *charset,
154         const char *lang, int selected)
155 {
156         Z_External *p = (Z_External *)odr_malloc(o, sizeof(*p));
157         oident oid;
158         
159         p->descriptor = 0;
160         p->indirect_reference = 0;      
161
162         oid.proto = PROTO_Z3950;
163         oid.oclass = CLASS_NEGOT;
164         oid.value = VAL_CHARNEG3;
165         p->direct_reference = odr_oiddup(o, oid_getoidbyent(&oid));
166
167         p->which = Z_External_charSetandLanguageNegotiation;
168         p->u.charNeg3 = z_get_CharSetandLanguageNegotiation(o);
169         p->u.charNeg3->which = Z_CharSetandLanguageNegotiation_response;
170         p->u.charNeg3->u.response = z_get_TargetResponse(o, charset, lang, selected);
171
172         return p;
173 }
174 Z_CharSetandLanguageNegotiation *yaz_get_charneg_record(Z_OtherInformation *p)
175 {
176         Z_External *pext;
177         int i;
178         
179         if(!p)
180                 return 0;
181         
182         for (i=0; i<p->num_elements; i++) {
183         
184                 if ((p->list[i]->which == Z_OtherInfo_externallyDefinedInfo) &&
185                                         (pext = p->list[i]->information.externallyDefinedInfo)) {
186                                         
187                         oident *ent = oid_getentbyoid(pext->direct_reference);
188                         
189                         if (ent && ent->value == VAL_CHARNEG3 && ent->oclass == CLASS_NEGOT &&
190                                 pext->which == Z_External_charSetandLanguageNegotiation) {
191                                 
192                                 return pext->u.charNeg3;
193                         }
194                 }
195         }
196         
197         return 0;
198 }
199 void yaz_get_proposal_charneg(NMEM mem, Z_CharSetandLanguageNegotiation *p, char **charsets,
200         int *num_charsets, char **langs, int *num_langs, int *selected)
201 {
202         int i;
203         Z_OriginProposal *pro = p->u.proposal;
204         
205         if (pro->num_proposedCharSets && charsets && num_charsets) {
206         
207                 *num_charsets = pro->num_proposedCharSets;
208         
209                 charsets = (char **)nmem_malloc(mem, pro->num_proposedCharSets * sizeof(char *));
210                 
211                 for (i=0; i<pro->num_proposedCharSets; i++) {
212                 
213                         if (pro->proposedCharSets[i]->which == Z_OriginProposal_0_private &&
214                                 pro->proposedCharSets[i]->u.zprivate->which == Z_PrivateCharacterSet_externallySpecified) {
215                                         
216                                 Z_External *pext =
217                                         pro->proposedCharSets[i]->u.zprivate->u.externallySpecified;
218                                 
219                                 if (pext->which == Z_External_octet) {
220                         
221                                         charsets[i] = (char *)nmem_malloc(mem, pext->u.octet_aligned->len * sizeof(char));
222                                         
223                                         memcpy (charsets[i], pext->u.octet_aligned->buf, pext->u.octet_aligned->len);
224                                         
225                                 }
226                         }
227                 }
228         }
229
230         if (pro->num_proposedlanguages && langs && num_langs) {
231
232                 *num_langs = pro->num_proposedlanguages;
233         
234                 langs = (char **)nmem_malloc(mem, pro->num_proposedlanguages * sizeof(char *));
235                 
236                 for (i=0; i<pro->num_proposedlanguages; i++) {
237
238                         langs[i] = (char *)nmem_malloc(mem, strlen(pro->proposedlanguages[i])+1);
239                         memcpy (langs[i], pro->proposedlanguages[i], strlen(pro->proposedlanguages[i])+1);              
240                 }
241         }
242         
243         if(pro->recordsInSelectedCharSets && selected) {
244         
245                 *selected = *pro->recordsInSelectedCharSets;
246                 
247         }
248 }
249 void yaz_get_response_charneg(NMEM mem, Z_CharSetandLanguageNegotiation *p,
250         char **charset, char **lang, int *selected)
251 {
252         Z_TargetResponse *res = p->u.response;
253         
254         if (charset && res->which == Z_TargetResponse_private &&
255                 res->u.zprivate->which == Z_PrivateCharacterSet_externallySpecified) {
256
257                 Z_External *pext = res->u.zprivate->u.externallySpecified;
258                                 
259                 if (pext->which == Z_External_octet) {
260                         
261                         *charset = (char *)nmem_malloc(mem, pext->u.octet_aligned->len * sizeof(char));
262                         memcpy (*charset, pext->u.octet_aligned->buf, pext->u.octet_aligned->len);
263                 }       
264         }
265
266         if (lang && res->selectedLanguage) {
267         
268                 *lang = (char *)nmem_malloc(mem, strlen(res->selectedLanguage)+1);
269                 memcpy (*lang, res->selectedLanguage, strlen(res->selectedLanguage)+1);
270         
271         }
272
273         if(selected && res->recordsInSelectedCharSets) {
274         
275                 *selected = *res->recordsInSelectedCharSets;
276
277         }
278 }