Implemented various stuff for client and proxy. Updated calls
[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.2  1999-04-20 10:30:05  adam
8  * Implemented various stuff for client and proxy. Updated calls
9  * to ODR to reflect new name parameter.
10  *
11  * Revision 1.1  1999/04/09 11:46:57  adam
12  * Added object Yaz_Z_Assoc. Much more functional client.
13  *
14  */
15
16 #include <assert.h>
17
18 #include <log.h>
19 #include <yaz-z-assoc.h>
20
21 int Yaz_Z_Assoc::yaz_init_func()
22 {
23     logf (LOG_LOG, "nmem_init");
24     nmem_init();
25     logf (LOG_LOG, "done");
26     return 1;
27 }
28
29 int Yaz_Z_Assoc::yaz_init_flag = Yaz_Z_Assoc::yaz_init_func();
30
31 Yaz_Z_Assoc::Yaz_Z_Assoc(IYaz_PDU_Observable *the_PDU_Observable)
32 {
33     m_PDU_Observable = the_PDU_Observable;
34     m_odr_in = odr_createmem (ODR_DECODE);
35     m_odr_out = odr_createmem (ODR_ENCODE);
36     m_odr_print = odr_createmem (ODR_PRINT);
37 }
38
39 Yaz_Z_Assoc::~Yaz_Z_Assoc()
40 {
41     m_PDU_Observable->destroy();
42     delete m_PDU_Observable;
43     odr_destroy (m_odr_print);
44     odr_destroy (m_odr_out);
45     odr_destroy (m_odr_in);
46 }
47
48 void Yaz_Z_Assoc::recv_PDU(const char *buf, int len)
49 {
50     logf (LOG_LOG, "recv_PDU len=%d", len);
51     Z_APDU *apdu = decode_Z_PDU (buf, len);
52     if (apdu)
53         recv_Z_PDU (apdu);
54 }
55
56 Z_APDU *Yaz_Z_Assoc::create_Z_PDU(int type)
57 {
58     return zget_APDU(m_odr_out, type);
59 }
60
61 int Yaz_Z_Assoc::send_Z_PDU(Z_APDU *apdu)
62 {
63     char *buf;
64     int len;
65     logf (LOG_LOG, "Yaz_Z_Assoc:send_Z_PDU");
66     if (encode_Z_PDU(apdu, &buf, &len) > 0)
67         return m_PDU_Observable->send_PDU(buf, len);
68     return -1;
69 }
70
71 Z_APDU *Yaz_Z_Assoc::decode_Z_PDU(const char *buf, int len)
72 {
73     Z_APDU *apdu;
74
75     odr_reset (m_odr_in);
76     odr_setbuf (m_odr_in, (char*) buf, len, 0);
77
78     if (!z_APDU(m_odr_in, &apdu, 0, 0))
79     {
80         logf(LOG_LOG, "ODR error on incoming PDU: %s [near byte %d] ",
81              odr_errmsg(odr_geterror(m_odr_in)),
82              odr_offset(m_odr_in));
83         logf(LOG_LOG, "PDU dump:");
84         odr_dumpBER(log_file(), buf, len);
85         return 0;
86     }
87     else
88     {
89         logf (LOG_LOG, "decoded ok");
90         return apdu;
91     }
92 }
93
94 int Yaz_Z_Assoc::encode_Z_PDU(Z_APDU *apdu, char **buf, int *len)
95 {
96     if (!z_APDU(m_odr_out, &apdu, 0, 0))
97     {
98         logf (LOG_LOG, "yaz_Z_Assoc::encode_Z_PDU failed");
99         return -1;
100     }
101     *buf = odr_getbuf (m_odr_out, len, 0);
102     odr_reset (m_odr_out);
103     return *len;
104 }
105
106 void Yaz_Z_Assoc::connectNotify()
107 {
108     logf (LOG_LOG, "connectNotify");
109 }
110
111 void Yaz_Z_Assoc::failNotify()
112 {
113     logf (LOG_LOG, "failNotify");
114 }
115
116 void Yaz_Z_Assoc::timeoutNotify()
117 {
118     logf (LOG_LOG, "timeoutNotify");
119 }
120
121 void Yaz_Z_Assoc::client(const char *addr)
122 {
123     m_PDU_Observable->connect (this, addr);
124 }
125
126 void Yaz_Z_Assoc::close()
127 {
128     m_PDU_Observable->close ();
129 }
130
131 void Yaz_Z_Assoc::server(const char *addr)
132 {
133     m_PDU_Observable->listen (this, addr);
134 }
135
136 ODR Yaz_Z_Assoc::odr_encode()
137 {
138     return m_odr_out;
139 }
140
141 ODR Yaz_Z_Assoc::odr_decode()
142 {
143     return m_odr_in;
144 }
145 ODR Yaz_Z_Assoc::odr_print()
146 {
147     return m_odr_print;
148 }
149
150 Z_OtherInformationUnit *Yaz_Z_Assoc::update_otherInformation (
151     Z_OtherInformation **otherInformationP, int createFlag,
152     int *oid, int categoryValue)
153 {
154     int i;
155     Z_OtherInformation *otherInformation = *otherInformationP;
156     if (!otherInformation)
157     {
158         if (!createFlag)
159             return 0;
160         otherInformation = *otherInformationP = (Z_OtherInformation *)
161             odr_malloc (odr_encode(), sizeof(*otherInformation));
162         otherInformation->num_elements = 0;
163         otherInformation->list = (Z_OtherInformationUnit **)
164             odr_malloc (odr_encode(), 8*sizeof(*otherInformation));
165         for (i = 0; i<8; i++)
166             otherInformation->list[i] = 0;
167     }
168     for (i = 0; i<otherInformation->num_elements; i++)
169     {
170         assert (otherInformation->list[i]);
171         if (!oid)
172         {
173             if (!otherInformation->list[i]->category)
174                 return otherInformation->list[i];
175         }
176         else
177         {
178             if (otherInformation->list[i]->category &&
179                 categoryValue ==
180                 *otherInformation->list[i]->category->categoryValue &&
181                 !oid_oidcmp (oid, otherInformation->list[i]->category->
182                              categoryTypeId))
183                 return otherInformation->list[i];
184         }
185     }
186     if (!createFlag)
187         return 0;
188     otherInformation->list[i] = (Z_OtherInformationUnit*)
189         odr_malloc (odr_encode(), sizeof(Z_OtherInformationUnit));
190     if (oid)
191     {
192         otherInformation->list[i]->category = (Z_InfoCategory*)
193             odr_malloc (odr_encode(), sizeof(Z_InfoCategory));
194         otherInformation->list[i]->category->categoryTypeId = (int*)
195             odr_oiddup (odr_encode(), oid);
196         otherInformation->list[i]->category->categoryValue = (int*)
197             odr_malloc (odr_encode(), sizeof(int));
198         *otherInformation->list[i]->category->categoryValue =
199             categoryValue;
200     }
201     else
202         otherInformation->list[i]->category = 0;
203     otherInformation->list[i]->which = Z_OtherInfo_characterInfo;
204     otherInformation->list[i]->information.characterInfo = 0;
205     
206     otherInformation->num_elements = i+1;
207     return otherInformation->list[i];
208 }
209