Added default parameters for refid to request functions.
[yazpp-moved-to-github.git] / src / yaz-z-assoc.cpp
1 /*
2  * Copyright (c) 1998-1999, Index Data.
3  * See the file LICENSE for details.
4  * Sebastian Hammer, Adam Dickmeiss
5  * 
6  * $Log: yaz-z-assoc.cpp,v $
7  * Revision 1.7  2000-05-10 11:36:58  ian
8  * Added default parameters for refid to request functions.
9  * Added default parameter for result set name to search and present request.
10  * Commented out forced logging of PDU contents.
11  * Added send_deleteResultSetRequest
12  *
13  * Revision 1.6  1999/12/06 13:52:45  adam
14  * Modified for new location of YAZ header files. Experimental threaded
15  * operation.
16  *
17  * Revision 1.5  1999/11/10 10:02:34  adam
18  * Work on proxy.
19  *
20  * Revision 1.4  1999/09/13 12:53:44  adam
21  * Proxy removes OtherInfo Proxy Address and Session ID. Other
22  * Otherinfo remains untouched.
23  *
24  * Revision 1.3  1999/04/21 12:09:01  adam
25  * Many improvements. Modified to proxy server to work with "sessions"
26  * based on cookies.
27  *
28  * Revision 1.2  1999/04/20 10:30:05  adam
29  * Implemented various stuff for client and proxy. Updated calls
30  * to ODR to reflect new name parameter.
31  *
32  * Revision 1.1  1999/04/09 11:46:57  adam
33  * Added object Yaz_Z_Assoc. Much more functional client.
34  *
35  */
36
37 #include <assert.h>
38
39 #include <yaz/log.h>
40 #include <yaz-z-assoc.h>
41 #include <yaz/otherinfo.h>
42
43 int Yaz_Z_Assoc::yaz_init_func()
44 {
45     nmem_init();
46     return 1;
47 }
48
49 int Yaz_Z_Assoc::yaz_init_flag = Yaz_Z_Assoc::yaz_init_func();
50
51 Yaz_Z_Assoc::Yaz_Z_Assoc(IYaz_PDU_Observable *the_PDU_Observable)
52 {
53     m_PDU_Observable = the_PDU_Observable;
54     m_odr_in = odr_createmem (ODR_DECODE);
55     m_odr_out = odr_createmem (ODR_ENCODE);
56     m_odr_print = odr_createmem (ODR_PRINT);
57     m_log = LOG_DEBUG;
58 }
59
60 Yaz_Z_Assoc::~Yaz_Z_Assoc()
61 {
62     m_PDU_Observable->destroy();
63     delete m_PDU_Observable;
64     odr_destroy (m_odr_print);
65     odr_destroy (m_odr_out);
66     odr_destroy (m_odr_in);
67 }
68
69 void Yaz_Z_Assoc::recv_PDU(const char *buf, int len)
70 {
71     logf (m_log, "recv_PDU len=%d", len);
72     Z_APDU *apdu = decode_Z_PDU (buf, len);
73     if (apdu)
74     {
75         recv_Z_PDU (apdu);
76     }
77 }
78
79 Z_APDU *Yaz_Z_Assoc::create_Z_PDU(int type)
80 {
81     Z_APDU *apdu = zget_APDU(m_odr_out, type);
82     if (apdu->which == Z_APDU_initRequest)
83     {
84         Z_InitRequest * p = apdu->u.initRequest;
85         char *newName = (char*) odr_malloc(m_odr_out, 50);
86         strcpy (newName, p->implementationName);
87         strcat (newName, " YAZ++");
88         p->implementationName = newName;
89     }
90     return apdu;
91 }
92
93 int Yaz_Z_Assoc::send_Z_PDU(Z_APDU *apdu)
94 {
95     char *buf;
96     int len;
97     if (encode_Z_PDU(apdu, &buf, &len) > 0)
98         return m_PDU_Observable->send_PDU(buf, len);
99     return -1;
100 }
101
102 Z_APDU *Yaz_Z_Assoc::decode_Z_PDU(const char *buf, int len)
103 {
104     Z_APDU *apdu;
105
106     odr_reset (m_odr_in);
107     odr_setbuf (m_odr_in, (char*) buf, len, 0);
108
109     if (!z_APDU(m_odr_in, &apdu, 0, 0))
110     {
111         logf(LOG_LOG, "ODR error on incoming PDU: %s [near byte %d] ",
112              odr_errmsg(odr_geterror(m_odr_in)),
113              odr_offset(m_odr_in));
114         logf(LOG_LOG, "PDU dump:");
115         odr_dumpBER(log_file(), buf, len);
116         return 0;
117     }
118     else
119     {
120         // z_APDU(m_odr_print, &apdu, 0, "decode");
121         return apdu;
122     }
123 }
124
125 int Yaz_Z_Assoc::encode_Z_PDU(Z_APDU *apdu, char **buf, int *len)
126 {
127     if (!z_APDU(m_odr_out, &apdu, 0, 0))
128     {
129         logf (LOG_LOG, "yaz_Z_Assoc::encode_Z_PDU failed");
130         return -1;
131     }
132     // z_APDU(m_odr_print, &apdu, 0, "encode");
133     *buf = odr_getbuf (m_odr_out, len, 0);
134     odr_reset (m_odr_out);
135     return *len;
136 }
137
138 void Yaz_Z_Assoc::client(const char *addr)
139 {
140     m_PDU_Observable->connect (this, addr);
141 }
142
143 void Yaz_Z_Assoc::close()
144 {
145     m_PDU_Observable->close ();
146 }
147
148 void Yaz_Z_Assoc::server(const char *addr)
149 {
150     m_PDU_Observable->listen (this, addr);
151 }
152
153 ODR Yaz_Z_Assoc::odr_encode()
154 {
155     return m_odr_out;
156 }
157
158 ODR Yaz_Z_Assoc::odr_decode()
159 {
160     return m_odr_in;
161 }
162 ODR Yaz_Z_Assoc::odr_print()
163 {
164     return m_odr_print;
165 }
166
167 void Yaz_Z_Assoc::timeout(int timeout)
168 {
169     m_PDU_Observable->idleTime(timeout);
170 }
171
172
173 void Yaz_Z_Assoc::get_otherInfoAPDU(Z_APDU *apdu, Z_OtherInformation ***oip)
174 {
175     switch (apdu->which)
176     {
177     case Z_APDU_initRequest:
178         *oip = &apdu->u.initRequest->otherInfo;
179         break;
180     case Z_APDU_searchRequest:
181         *oip = &apdu->u.searchRequest->otherInfo;
182         break;
183     case Z_APDU_presentRequest:
184         *oip = &apdu->u.presentRequest->otherInfo;
185         break;
186     case Z_APDU_sortRequest:
187         *oip = &apdu->u.sortRequest->otherInfo;
188         break;
189     case Z_APDU_scanRequest:
190         *oip = &apdu->u.scanRequest->otherInfo;
191         break;
192     case Z_APDU_initResponse:
193         *oip = &apdu->u.initResponse->otherInfo;
194         break;
195     case Z_APDU_searchResponse:
196         *oip = &apdu->u.searchResponse->otherInfo;
197         break;
198     case Z_APDU_presentResponse:
199         *oip = &apdu->u.presentResponse->otherInfo;
200         break;
201     case Z_APDU_sortResponse:
202         *oip = &apdu->u.sortResponse->otherInfo;
203         break;
204     case Z_APDU_scanResponse:
205         *oip = &apdu->u.scanResponse->otherInfo;
206         break;
207     default:
208         *oip = 0;
209         break;
210     }
211 }
212
213 void Yaz_Z_Assoc::set_otherInformationString (
214     Z_APDU *apdu,
215     int oidval, int categoryValue,
216     const char *str)
217 {
218     Z_OtherInformation **otherInformation;
219     get_otherInfoAPDU(apdu, &otherInformation);
220     if (!otherInformation)
221         return;
222     set_otherInformationString(otherInformation, oidval, categoryValue, str);
223 }
224
225 void Yaz_Z_Assoc::set_otherInformationString (
226     Z_OtherInformation **otherInformation,
227     int oidval, int categoryValue,
228     const char *str)
229 {
230     int oid[OID_SIZE];
231     struct oident ent;
232     ent.proto = PROTO_Z3950;
233     ent.oclass = CLASS_USERINFO;
234     ent.value = (oid_value) oidval;
235     if (!oid_ent_to_oid (&ent, oid))
236         return ;
237     set_otherInformationString(otherInformation, oid, categoryValue, str);
238 }
239
240 void Yaz_Z_Assoc::set_otherInformationString (
241     Z_OtherInformation **otherInformation,
242     int *oid, int categoryValue, const char *str)
243 {
244     Z_OtherInformationUnit *oi =
245         update_otherInformation(otherInformation, 1, oid, categoryValue, 0);
246     if (!oi)
247         return;
248     oi->information.characterInfo = odr_strdup (odr_encode(), str);
249 }
250
251 Z_OtherInformationUnit *Yaz_Z_Assoc::update_otherInformation (
252     Z_OtherInformation **otherInformationP, int createFlag,
253     int *oid, int categoryValue, int deleteFlag)
254 {
255     return yaz_oi_update (otherInformationP,
256                           (createFlag ? odr_encode() : 0),
257                           oid, categoryValue, deleteFlag);
258 }
259
260 Z_ReferenceId* Yaz_Z_Assoc::getRefID(char* str)
261 {
262     Z_ReferenceId* id = NULL;
263
264     if ( str )
265     {
266         id = (Z_ReferenceId*) odr_malloc (m_odr_out, sizeof(*id));
267         id->size = id->len = strlen(str);
268         id->buf = (unsigned char *) str;
269     }
270
271     return id;
272 }
273