Added yp2::util split_zurl and get_vhost_otherinfo.
[metaproxy-moved-to-github.git] / src / util.cpp
1 /* $Id: util.cpp,v 1.6 2006-01-17 13:34:51 adam Exp $
2    Copyright (c) 2005, Index Data.
3
4 %LICENSE%
5  */
6
7 #include "config.hpp"
8
9 #include <yaz/odr.h>
10 #include <yaz/pquery.h>
11 #include <yaz/otherinfo.h>
12 #include "util.hpp"
13
14
15 bool yp2::util::pqf(ODR odr, Z_APDU *apdu, const std::string &q) {
16     YAZ_PQF_Parser pqf_parser = yaz_pqf_create();
17     
18     Z_RPNQuery *rpn = yaz_pqf_parse(pqf_parser, odr, q.c_str());
19     if (!rpn)
20     {
21         yaz_pqf_destroy(pqf_parser);
22         return false;
23     }
24     yaz_pqf_destroy(pqf_parser);
25     Z_Query *query = (Z_Query *) odr_malloc(odr, sizeof(Z_Query));
26     query->which = Z_Query_type_1;
27     query->u.type_1 = rpn;
28     
29     apdu->u.searchRequest->query = query;
30     return true;
31 }
32
33 int yp2::util::get_vhost_otherinfo(Z_OtherInformation **otherInformation,
34                                    bool remove_flag,
35                                    std::list<std::string> &vhosts)
36 {
37     int cat;
38     for (cat = 1; ; cat++)
39     {
40         // check virtual host
41         const char *vhost =
42             yaz_oi_get_string_oidval(otherInformation,
43                                      VAL_PROXY, 
44                                      cat /* categoryValue */,
45                                      remove_flag /* delete flag */);
46         if (!vhost)
47             break;
48         vhosts.push_back(std::string(vhost));
49     }
50     --cat;
51     return cat;
52 }
53
54 void yp2::util::split_zurl(std::string zurl, std::string &host,
55                            std::list<std::string> &db)
56 {
57     const char *zurl_cstr = zurl.c_str();
58     const char *sep = strchr(zurl_cstr, '/');
59     
60     if (sep)
61     {
62         host = std::string(zurl_cstr, sep - zurl_cstr);
63
64         const char *cp1 = sep+1;
65         while(1)
66         {
67             const char *cp2 = strchr(cp1, '+');
68             if (cp2)
69                 db.push_back(std::string(cp1, cp2 - cp1));
70             else
71             {
72                 db.push_back(std::string(cp1));
73                 break;
74             }
75             cp1 = cp2+1;
76         }
77     }
78     else
79     {
80         host = zurl;
81     }
82 }
83
84 bool yp2::util::set_databases_from_zurl(ODR odr, std::string zurl,
85                                         int *db_num, char ***db_strings)
86 {
87     std::string host;
88     std::list<std::string> dblist;
89
90     split_zurl(zurl, host, dblist);
91    
92     if (dblist.size() == 0)
93         return false;
94     *db_num = dblist.size();
95     *db_strings = (char **) odr_malloc(odr, sizeof(char*) * (*db_num));
96
97     std::list<std::string>::const_iterator it = dblist.begin();
98     for (int i = 0; it != dblist.end(); it++, i++)
99         (*db_strings)[i] = odr_strdup(odr, it->c_str());
100     return true;
101 }
102
103 yp2::odr::odr(int type)
104 {
105     m_odr = odr_createmem(type);
106 }
107
108 yp2::odr::odr()
109 {
110     m_odr = odr_createmem(ODR_ENCODE);
111 }
112
113 yp2::odr::~odr()
114 {
115     odr_destroy(m_odr);
116 }
117
118 yp2::odr::operator ODR() const
119 {
120     return m_odr;
121 }
122
123 Z_APDU *yp2::odr::create_close(Z_APDU *in_apdu,
124                                int reason, const char *addinfo)
125 {
126     Z_APDU *apdu = create_APDU(Z_APDU_close, in_apdu);
127     
128     *apdu->u.close->closeReason = reason;
129     if (addinfo)
130         apdu->u.close->diagnosticInformation = odr_strdup(m_odr, addinfo);
131     return apdu;
132 }
133
134 Z_APDU *yp2::odr::create_APDU(int type, Z_APDU *in_apdu)
135 {
136     return yp2::util::create_APDU(m_odr, type, in_apdu);
137 }
138
139 Z_APDU *yp2::util::create_APDU(ODR odr, int type, Z_APDU *in_apdu)
140 {
141     Z_APDU *out_apdu = zget_APDU(odr, type);
142
143     Z_ReferenceId **id_to = yp2::util::get_referenceId(out_apdu);
144     *id_to = 0;
145     if (in_apdu)
146     {
147         Z_ReferenceId **id_from = yp2::util::get_referenceId(in_apdu);
148         if (id_from && *id_from && id_to)
149         {
150             *id_to = (Z_ReferenceId*) odr_malloc (odr, sizeof(**id_to));
151             (*id_to)->size = (*id_to)->len = (*id_from)->len;
152             (*id_to)->buf = (unsigned char*) odr_malloc(odr, (*id_to)->len);
153             memcpy((*id_to)->buf, (*id_from)->buf, (*id_to)->len);
154         }
155         else if (id_to)
156             *id_to = 0;
157     }
158     return out_apdu;
159 }
160
161 Z_APDU *yp2::odr::create_initResponse(Z_APDU *in_apdu,
162                                       int error, const char *addinfo)
163 {
164     Z_APDU *apdu = create_APDU(Z_APDU_initResponse, in_apdu);
165     if (error)
166     {
167         apdu->u.initResponse->userInformationField =
168             zget_init_diagnostics(m_odr, error, addinfo);
169         *apdu->u.initResponse->result = 0;
170     }
171     return apdu;
172 }
173
174 Z_APDU *yp2::odr::create_searchResponse(Z_APDU *in_apdu,
175                                         int error, const char *addinfo)
176 {
177     Z_APDU *apdu = create_APDU(Z_APDU_searchResponse, in_apdu);
178     if (error)
179     {
180         Z_Records *rec = (Z_Records *) odr_malloc(m_odr, sizeof(Z_Records));
181         *apdu->u.searchResponse->searchStatus = 0;
182         apdu->u.searchResponse->records = rec;
183         rec->which = Z_Records_NSD;
184         rec->u.nonSurrogateDiagnostic =
185             zget_DefaultDiagFormat(m_odr, error, addinfo);
186         
187     }
188     return apdu;
189 }
190
191 Z_APDU *yp2::odr::create_presentResponse(Z_APDU *in_apdu,
192                                          int error, const char *addinfo)
193 {
194     Z_APDU *apdu = create_APDU(Z_APDU_presentResponse, in_apdu);
195     if (error)
196     {
197         Z_Records *rec = (Z_Records *) odr_malloc(m_odr, sizeof(Z_Records));
198         apdu->u.presentResponse->records = rec;
199         rec->which = Z_Records_NSD;
200         rec->u.nonSurrogateDiagnostic =
201             zget_DefaultDiagFormat(m_odr, error, addinfo);
202     }
203     return apdu;
204 }
205
206 Z_APDU *yp2::odr::create_scanResponse(Z_APDU *in_apdu,
207                                       int error, const char *addinfo)
208 {
209     Z_APDU *apdu = create_APDU(Z_APDU_scanResponse, in_apdu);
210     if (error)
211     {
212         Z_ScanResponse *res = apdu->u.scanResponse;
213         res->entries = (Z_ListEntries *) odr_malloc(m_odr, sizeof(*res->entries));
214         *res->scanStatus = Z_Scan_failure;
215
216         res->entries->num_entries = 0;
217         res->entries->entries = 0;
218         res->entries->num_nonsurrogateDiagnostics = 1;
219         res->entries->nonsurrogateDiagnostics = (Z_DiagRec **)
220             odr_malloc(m_odr, sizeof(Z_DiagRec *));
221         res->entries->nonsurrogateDiagnostics[0] = 
222             zget_DiagRec(m_odr, error, addinfo);
223     }
224     return apdu;
225 }
226
227 Z_ReferenceId **yp2::util::get_referenceId(Z_APDU *apdu)
228 {
229     switch (apdu->which)
230     {
231     case  Z_APDU_initRequest:
232         return &apdu->u.initRequest->referenceId; 
233     case  Z_APDU_initResponse:
234         return &apdu->u.initResponse->referenceId;
235     case  Z_APDU_searchRequest:
236         return &apdu->u.searchRequest->referenceId;
237     case  Z_APDU_searchResponse:
238         return &apdu->u.searchResponse->referenceId;
239     case  Z_APDU_presentRequest:
240         return &apdu->u.presentRequest->referenceId;
241     case  Z_APDU_presentResponse:
242         return &apdu->u.presentResponse->referenceId;
243     case  Z_APDU_deleteResultSetRequest:
244         return &apdu->u.deleteResultSetRequest->referenceId;
245     case  Z_APDU_deleteResultSetResponse:
246         return &apdu->u.deleteResultSetResponse->referenceId;
247     case  Z_APDU_accessControlRequest:
248         return &apdu->u.accessControlRequest->referenceId;
249     case  Z_APDU_accessControlResponse:
250         return &apdu->u.accessControlResponse->referenceId;
251     case  Z_APDU_resourceControlRequest:
252         return &apdu->u.resourceControlRequest->referenceId;
253     case  Z_APDU_resourceControlResponse:
254         return &apdu->u.resourceControlResponse->referenceId;
255     case  Z_APDU_triggerResourceControlRequest:
256         return &apdu->u.triggerResourceControlRequest->referenceId;
257     case  Z_APDU_resourceReportRequest:
258         return &apdu->u.resourceReportRequest->referenceId;
259     case  Z_APDU_resourceReportResponse:
260         return &apdu->u.resourceReportResponse->referenceId;
261     case  Z_APDU_scanRequest:
262         return &apdu->u.scanRequest->referenceId;
263     case  Z_APDU_scanResponse:
264         return &apdu->u.scanResponse->referenceId;
265     case  Z_APDU_sortRequest:
266         return &apdu->u.sortRequest->referenceId;
267     case  Z_APDU_sortResponse:
268         return &apdu->u.sortResponse->referenceId;
269     case  Z_APDU_segmentRequest:
270         return &apdu->u.segmentRequest->referenceId;
271     case  Z_APDU_extendedServicesRequest:
272         return &apdu->u.extendedServicesRequest->referenceId;
273     case  Z_APDU_extendedServicesResponse:
274         return &apdu->u.extendedServicesResponse->referenceId;
275     case  Z_APDU_close:
276         return &apdu->u.close->referenceId;
277     }
278     return 0;
279 }
280
281
282 /*
283  * Local variables:
284  * c-basic-offset: 4
285  * indent-tabs-mode: nil
286  * c-file-style: "stroustrup"
287  * End:
288  * vim: shiftwidth=4 tabstop=8 expandtab
289  */