Dont return value in void function
[yaz-moved-to-github.git] / src / srwutil.c
1 /*
2  * Copyright (C) 1995-2005, Index Data ApS
3  * See the file LICENSE for details.
4  *
5  * $Id: srwutil.c,v 1.35 2006-02-01 20:28:44 adam Exp $
6  */
7 /**
8  * \file srwutil.c
9  * \brief Implements SRW/SRU utilities.
10  */
11
12 #include <stdlib.h>
13 #include <yaz/srw.h>
14 #include <yaz/yaz-iconv.h>
15
16 static int hex_digit (int ch)
17 {
18     if (ch >= '0' && ch <= '9')
19         return ch - '0';
20     else if (ch >= 'a' && ch <= 'f')
21         return ch - 'a'+10;
22     else if (ch >= 'A' && ch <= 'F')
23         return ch - 'A'+10;
24     return 0;
25 }
26
27 int yaz_uri_array(const char *path, ODR o, char ***name, char ***val)
28 {
29     int no = 2;
30     const char *cp;
31     *name = 0;
32     if (*path == '?')
33         path++;
34     if (!*path)
35         return no;
36     cp = path;
37     while ((cp = strchr(cp, '&')))
38     {
39         cp++;
40         no++;
41     }
42     *name = odr_malloc(o, no * sizeof(char*));
43     *val = odr_malloc(o, no * sizeof(char*));
44
45     for (no = 0; *path; no++)
46     {
47         const char *p1 = strchr(path, '=');
48         size_t i = 0;
49         char *ret;
50         if (!p1)
51             break;
52
53         (*name)[no] = odr_malloc(o, (p1-path)+1);
54         memcpy((*name)[no], path, p1-path);
55         (*name)[no][p1-path] = '\0';
56
57         path = p1 + 1;
58         p1 = strchr(path, '&');
59         if (!p1)
60             p1 = strlen(path) + path;
61         (*val)[no] = ret = odr_malloc(o, p1 - path + 1);
62         while (*path && *path != '&')
63         {
64             if (*path == '+')
65             {
66                 ret[i++] = ' ';
67                 path++;
68             }
69             else if (*path == '%' && path[1] && path[2])
70             {
71                 ret[i++] = hex_digit (path[1])*16 + hex_digit (path[2]);
72                 path = path + 3;
73             }
74             else
75                 ret[i++] = *path++;
76         }
77         ret[i] = '\0';
78
79         if (*path)
80             path++;
81     }
82     (*name)[no] = 0;
83     (*val)[no] = 0;
84     return no;
85 }
86
87 char *yaz_uri_val(const char *path, const char *name, ODR o)
88 {
89     size_t nlen = strlen(name);
90     if (*path != '?')
91         return 0;
92     path++;
93     while (path && *path)
94     {
95         const char *p1 = strchr(path, '=');
96         if (!p1)
97             break;
98         if ((size_t)(p1 - path) == nlen && !memcmp(path, name, nlen))
99         {
100             size_t i = 0;
101             char *ret;
102             
103             path = p1 + 1;
104             p1 = strchr(path, '&');
105             if (!p1)
106                 p1 = strlen(path) + path;
107             ret = (char *) odr_malloc(o, p1 - path + 1);
108             while (*path && *path != '&')
109             {
110                 if (*path == '+')
111                 {
112                     ret[i++] = ' ';
113                     path++;
114                 }
115                 else if (*path == '%' && path[1] && path[2])
116                 {
117                     ret[i++] = hex_digit (path[1])*16 + hex_digit (path[2]);
118                     path = path + 3;
119                 }
120                 else
121                     ret[i++] = *path++;
122             }
123             ret[i] = '\0';
124             return ret;
125         }
126         path = strchr(p1, '&');
127         if (path)
128             path++;
129     }
130     return 0;
131 }
132
133 void yaz_uri_val_int(const char *path, const char *name, ODR o, int **intp)
134 {
135     const char *v = yaz_uri_val(path, name, o);
136     if (v)
137         *intp = odr_intdup(o, atoi(v));
138 }
139
140 void yaz_mk_srw_diagnostic(ODR o, Z_SRW_diagnostic *d, 
141                            const char *uri, const char *message,
142                            const char *details)
143 {
144     d->uri = odr_strdup(o, uri);
145     if (message)
146         d->message = odr_strdup(o, message);
147     else
148         d->message = 0;
149     if (details)
150         d->details = odr_strdup(o, details);
151     else
152         d->details = 0;
153 }
154
155 void yaz_mk_std_diagnostic(ODR o, Z_SRW_diagnostic *d, 
156                            int code, const char *details)
157 {
158     char uri[40];
159     
160     sprintf(uri, "info:srw/diagnostic/1/%d", code);
161     yaz_mk_srw_diagnostic(o, d, uri, 0, details);
162 }
163
164 void yaz_add_srw_diagnostic_uri(ODR o, Z_SRW_diagnostic **d,
165                                 int *num, const char *uri,
166                                 const char *message, const char *details)
167 {
168     Z_SRW_diagnostic *d_new;
169     d_new = (Z_SRW_diagnostic *) odr_malloc (o, (*num + 1)* sizeof(**d));
170     if (*num)
171         memcpy (d_new, *d, *num *sizeof(**d));
172     *d = d_new;
173
174     yaz_mk_srw_diagnostic(o, *d + *num, uri, message, details);
175     (*num)++;
176 }
177
178 void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d,
179                             int *num, int code, const char *addinfo)
180 {
181     char uri[40];
182     
183     sprintf(uri, "info:srw/diagnostic/1/%d", code);
184     yaz_add_srw_diagnostic_uri(o, d, num, uri, 0, addinfo);
185 }
186
187 int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
188                    Z_SOAP **soap_package, ODR decode, char **charset)
189 {
190     if (!strcmp(hreq->method, "POST"))
191     {
192         const char *content_type = z_HTTP_header_lookup(hreq->headers,
193                                                         "Content-Type");
194         if (content_type && 
195             (!yaz_strcmp_del("text/xml", content_type, "; ") ||
196              !yaz_strcmp_del("text/plain", content_type, "; ")))
197         {
198             char *db = "Default";
199             const char *p0 = hreq->path, *p1;
200             int ret = -1;
201             const char *charset_p = 0;
202             
203             static Z_SOAP_Handler soap_handlers[4] = {
204 #if HAVE_XML2
205                 {"http://www.loc.gov/zing/srw/", 0,
206                  (Z_SOAP_fun) yaz_srw_codec},
207                 {"http://www.loc.gov/zing/srw/v1.0/", 0,
208                  (Z_SOAP_fun) yaz_srw_codec},
209                 {"http://www.loc.gov/zing/srw/update/", 0,
210                  (Z_SOAP_fun) yaz_ucp_codec},
211 #endif
212                 {0, 0, 0}
213             };
214             
215             if (*p0 == '/')
216                 p0++;
217             p1 = strchr(p0, '?');
218             if (!p1)
219                 p1 = p0 + strlen(p0);
220             if (p1 != p0)
221             {
222                 db = (char*) odr_malloc(decode, p1 - p0 + 1);
223                 memcpy (db, p0, p1 - p0);
224                 db[p1 - p0] = '\0';
225             }
226
227             if (charset && (charset_p = strstr(content_type, "; charset=")))
228             {
229                 int i = 0;
230                 charset_p += 10;
231                 while (i < 20 && charset_p[i] &&
232                        !strchr("; \n\r", charset_p[i]))
233                     i++;
234                 *charset = (char*) odr_malloc(decode, i+1);
235                 memcpy(*charset, charset_p, i);
236                 (*charset)[i] = '\0';
237             }
238             ret = z_soap_codec(decode, soap_package, 
239                                &hreq->content_buf, &hreq->content_len,
240                                soap_handlers);
241             if (ret == 0 && (*soap_package)->which == Z_SOAP_generic)
242             {
243                 *srw_pdu = (Z_SRW_PDU*) (*soap_package)->u.generic->p;
244                 
245                 if ((*srw_pdu)->which == Z_SRW_searchRetrieve_request &&
246                     (*srw_pdu)->u.request->database == 0)
247                     (*srw_pdu)->u.request->database = db;
248
249                 if ((*srw_pdu)->which == Z_SRW_explain_request &&
250                     (*srw_pdu)->u.explain_request->database == 0)
251                     (*srw_pdu)->u.explain_request->database = db;
252
253                 if ((*srw_pdu)->which == Z_SRW_scan_request &&
254                     (*srw_pdu)->u.scan_request->database == 0)
255                     (*srw_pdu)->u.scan_request->database = db;
256
257                 if ((*srw_pdu)->which == Z_SRW_update_request &&
258                     (*srw_pdu)->u.update_request->database == 0)
259                     (*srw_pdu)->u.update_request->database = db;
260
261                 return 0;
262             }
263             return 1;
264         }
265     }
266     return 2;
267 }
268
269 /**
270   http://www.loc.gov/z3950/agency/zing/srw/service.html
271 */ 
272 int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
273                    Z_SOAP **soap_package, ODR decode, char **charset,
274                    Z_SRW_diagnostic **diag, int *num_diag)
275 {
276 #if HAVE_XML2
277     static Z_SOAP_Handler soap_handlers[2] = {
278         {"http://www.loc.gov/zing/srw/", 0,
279          (Z_SOAP_fun) yaz_srw_codec},
280         {0, 0, 0}
281     };
282 #endif
283     const char *content_type = z_HTTP_header_lookup(hreq->headers,
284                                                     "Content-Type");
285     /*
286       SRU GET: allow any content type.
287       SRU POST: we support "application/x-www-form-urlencoded";
288       not  "multipart/form-data" .
289     */
290     if (!strcmp(hreq->method, "GET") 
291         ||
292         (!strcmp(hreq->method, "POST") 
293          && content_type &&
294          !yaz_strcmp_del("application/x-www-form-urlencoded",
295                          content_type, "; ")
296             )
297         )
298     {
299         char *db = "Default";
300         const char *p0 = hreq->path, *p1;
301 #if HAVE_XML2
302         const char *operation = 0;
303         char *version = 0;
304         char *query = 0;
305         char *pQuery = 0;
306         char *sortKeys = 0;
307         char *stylesheet = 0;
308         char *scanClause = 0;
309         char *pScanClause = 0;
310         char *recordXPath = 0;
311         char *recordSchema = 0;
312         char *recordPacking = "xml";  /* xml packing is default for SRU */
313         char *maximumRecords = 0;
314         char *startRecord = 0;
315         char *maximumTerms = 0;
316         char *responsePosition = 0;
317         char *extraRequestData = 0;
318 #endif
319         char **uri_name;
320         char **uri_val;
321
322         if (charset)
323             *charset = 0;
324         if (*p0 == '/')
325             p0++;
326         p1 = strchr(p0, '?');
327         if (!p1)
328             p1 = p0 + strlen(p0);
329         if (p1 != p0)
330         {
331             db = (char*) odr_malloc(decode, p1 - p0 + 1);
332             memcpy (db, p0, p1 - p0);
333             db[p1 - p0] = '\0';
334         }
335         if (!strcmp(hreq->method, "POST"))
336             p1 = hreq->content_buf;
337         yaz_uri_array(p1, decode, &uri_name, &uri_val);
338 #if HAVE_XML2
339         if (uri_name)
340         {
341             int i;
342             for (i = 0; uri_name[i]; i++)
343             {
344                 char *n = uri_name[i];
345                 char *v = uri_val[i];
346                 if (!strcmp(n, "query"))
347                     query = v;
348                 else if (!strcmp(n, "x-pquery"))
349                     pQuery = v;
350                 else if (!strcmp(n, "operation"))
351                     operation = v;
352                 else if (!strcmp(n, "stylesheet"))
353                     stylesheet = v;
354                 else if (!strcmp(n, "sortKeys"))
355                     sortKeys = v;
356                 else if (!strcmp(n, "recordXPath"))
357                     recordXPath = v;
358                 else if (!strcmp(n, "recordSchema"))
359                     recordSchema = v;
360                 else if (!strcmp(n, "recordPacking"))
361                     recordPacking = v;
362                 else if (!strcmp(n, "version"))
363                     version = v;
364                 else if (!strcmp(n, "scanClause"))
365                     scanClause = v;
366                 else if (!strcmp(n, "x-pScanClause"))
367                     pScanClause = v;
368                 else if (!strcmp(n, "maximumRecords"))
369                     maximumRecords = v;
370                 else if (!strcmp(n, "startRecord"))
371                     startRecord = v;
372                 else if (!strcmp(n, "maximumTerms"))
373                     maximumTerms = v;
374                 else if (!strcmp(n, "responsePosition"))
375                     responsePosition = v;
376                 else if (!strcmp(n, "extraRequestData"))
377                     extraRequestData = v;
378                 else
379                     yaz_add_srw_diagnostic(decode, diag, num_diag, 8, n);
380             }
381         }
382         if (!version)
383         {
384             if (uri_name)
385                 yaz_add_srw_diagnostic(decode, diag, num_diag, 7, "version");
386             version = "1.1";
387         }
388         if (strcmp(version, "1.1"))
389             yaz_add_srw_diagnostic(decode, diag, num_diag, 5, "1.1");
390         if (!operation)
391         {
392             if (uri_name)
393                 yaz_add_srw_diagnostic(decode, diag, num_diag, 7, "operation");
394             operation = "explain";
395         }
396         if (!strcmp(operation, "searchRetrieve"))
397         {
398             Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request);
399
400             sr->srw_version = version;
401             *srw_pdu = sr;
402             if (query)
403             {
404                 sr->u.request->query_type = Z_SRW_query_type_cql;
405                 sr->u.request->query.cql = query;
406             }
407             else if (pQuery)
408             {
409                 sr->u.request->query_type = Z_SRW_query_type_pqf;
410                 sr->u.request->query.pqf = pQuery;
411             }
412             else
413                 yaz_add_srw_diagnostic(decode, diag, num_diag, 7, "query");
414
415             if (sortKeys)
416             {
417                 sr->u.request->sort_type = Z_SRW_sort_type_sort;
418                 sr->u.request->sort.sortKeys = sortKeys;
419             }
420             sr->u.request->recordXPath = recordXPath;
421             sr->u.request->recordSchema = recordSchema;
422             sr->u.request->recordPacking = recordPacking;
423             sr->u.request->stylesheet = stylesheet;
424
425             if (maximumRecords)
426                 sr->u.request->maximumRecords =
427                     odr_intdup(decode, atoi(maximumRecords));
428             if (startRecord)
429                 sr->u.request->startRecord =
430                     odr_intdup(decode, atoi(startRecord));
431
432             sr->u.request->database = db;
433
434             (*soap_package) = odr_malloc(decode, sizeof(**soap_package));
435             (*soap_package)->which = Z_SOAP_generic;
436             
437             (*soap_package)->u.generic =
438                 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
439             
440             (*soap_package)->u.generic->p = sr;
441             (*soap_package)->u.generic->ns = soap_handlers[0].ns;
442             (*soap_package)->u.generic->no = 0;
443             
444             (*soap_package)->ns = "SRU";
445
446             return 0;
447         }
448         else if (!strcmp(operation, "explain"))
449         {
450             /* Transfer SRU explain parameters to common struct */
451             /* http://www.loc.gov/z3950/agency/zing/srw/explain.html */
452             Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
453
454             sr->srw_version = version;
455             *srw_pdu = sr;
456             sr->u.explain_request->recordPacking = recordPacking;
457             sr->u.explain_request->database = db;
458
459             sr->u.explain_request->stylesheet = stylesheet;
460
461             (*soap_package) = odr_malloc(decode, sizeof(**soap_package));
462             (*soap_package)->which = Z_SOAP_generic;
463             
464             (*soap_package)->u.generic =
465                 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
466             
467             (*soap_package)->u.generic->p = sr;
468             (*soap_package)->u.generic->ns = soap_handlers[0].ns;
469             (*soap_package)->u.generic->no = 0;
470             
471             (*soap_package)->ns = "SRU";
472
473             return 0;
474         }
475         else if (!strcmp(operation, "scan"))
476         {
477             /* Transfer SRU scan parameters to common struct */
478             /* http://www.loc.gov/z3950/agency/zing/srw/scan.html */
479             Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request);
480
481             sr->srw_version = version;
482             *srw_pdu = sr;
483
484             if (scanClause)
485             {
486                 sr->u.scan_request->query_type = Z_SRW_query_type_cql;
487                 sr->u.scan_request->scanClause.cql = scanClause;
488             }
489             else if (pScanClause)
490             {
491                 sr->u.scan_request->query_type = Z_SRW_query_type_pqf;
492                 sr->u.scan_request->scanClause.pqf = pScanClause;
493             }
494             else
495                 yaz_add_srw_diagnostic(decode, diag, num_diag, 7,
496                                        "scanClause");
497             sr->u.scan_request->database = db;
498
499             if (maximumTerms)
500                 sr->u.scan_request->maximumTerms =
501                     odr_intdup(decode, atoi(maximumTerms));
502             if (responsePosition)
503                 sr->u.scan_request->responsePosition =
504                     odr_intdup(decode, atoi(responsePosition));
505
506             sr->u.scan_request->stylesheet = stylesheet;
507
508             (*soap_package) = odr_malloc(decode, sizeof(**soap_package));
509             (*soap_package)->which = Z_SOAP_generic;
510             
511             (*soap_package)->u.generic =
512                 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
513             
514             (*soap_package)->u.generic->p = sr;
515             (*soap_package)->u.generic->ns = soap_handlers[0].ns;
516             (*soap_package)->u.generic->no = 0;
517             
518             (*soap_package)->ns = "SRU";
519
520             return 0;
521         }
522         else
523         {
524             /* unsupported operation ... */
525             /* Act as if we received a explain request and throw diagnostic. */
526
527             Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request);
528
529             sr->srw_version = version;
530             *srw_pdu = sr;
531             sr->u.explain_request->recordPacking = recordPacking;
532             sr->u.explain_request->database = db;
533
534             sr->u.explain_request->stylesheet = stylesheet;
535
536             (*soap_package) = odr_malloc(decode, sizeof(**soap_package));
537             (*soap_package)->which = Z_SOAP_generic;
538             
539             (*soap_package)->u.generic =
540                 odr_malloc(decode, sizeof(*(*soap_package)->u.generic));
541             
542             (*soap_package)->u.generic->p = sr;
543             (*soap_package)->u.generic->ns = soap_handlers[0].ns;
544             (*soap_package)->u.generic->no = 0;
545             
546             (*soap_package)->ns = "SRU";
547
548             yaz_add_srw_diagnostic(decode, diag, num_diag, 4, operation);
549             return 0;
550         }
551 #endif
552         return 1;
553     }
554     return 2;
555 }
556
557 Z_SRW_extra_record *yaz_srw_get_extra_record(ODR o)
558 {
559     Z_SRW_extra_record *res = (Z_SRW_extra_record *)
560         odr_malloc(o, sizeof(*res));
561     res->type = 1;
562     res->recordReviewCode = 0;
563     res->recordReviewNote = 0;
564     res->recordId = 0;
565     res->nonDupRecordId = 0;
566     res->recordLockStatus = 0;
567     res->recordOldVersion = 0;
568     return res;
569 }
570
571 Z_SRW_PDU *yaz_srw_get(ODR o, int which)
572 {
573     Z_SRW_PDU *sr = (Z_SRW_PDU *) odr_malloc(o, sizeof(*o));
574
575     sr->srw_version = odr_strdup(o, "1.1");
576     sr->which = which;
577     switch(which)
578     {
579     case Z_SRW_searchRetrieve_request:
580         sr->u.request = (Z_SRW_searchRetrieveRequest *)
581             odr_malloc(o, sizeof(*sr->u.request));
582         sr->u.request->query_type = Z_SRW_query_type_cql;
583         sr->u.request->query.cql = 0;
584         sr->u.request->sort_type = Z_SRW_sort_type_none;
585         sr->u.request->sort.none = 0;
586         sr->u.request->startRecord = 0;
587         sr->u.request->maximumRecords = 0;
588         sr->u.request->recordSchema = 0;
589         sr->u.request->recordPacking = 0;
590         sr->u.request->recordXPath = 0;
591         sr->u.request->database = 0;
592         sr->u.request->resultSetTTL = 0;
593         sr->u.request->stylesheet = 0;
594         break;
595     case Z_SRW_searchRetrieve_response:
596         sr->u.response = (Z_SRW_searchRetrieveResponse *)
597             odr_malloc(o, sizeof(*sr->u.response));
598         sr->u.response->numberOfRecords = 0;
599         sr->u.response->resultSetId = 0;
600         sr->u.response->resultSetIdleTime = 0;
601         sr->u.response->records = 0;
602         sr->u.response->num_records = 0;
603         sr->u.response->diagnostics = 0;
604         sr->u.response->num_diagnostics = 0;
605         sr->u.response->nextRecordPosition = 0;
606         sr->u.response->extra_records = 0;
607         break;
608     case Z_SRW_explain_request:
609         sr->u.explain_request = (Z_SRW_explainRequest *)
610             odr_malloc(o, sizeof(*sr->u.explain_request));
611         sr->u.explain_request->recordPacking = 0;
612         sr->u.explain_request->database = 0;
613         sr->u.explain_request->stylesheet = 0;
614         break;
615     case Z_SRW_explain_response:
616         sr->u.explain_response = (Z_SRW_explainResponse *)
617             odr_malloc(o, sizeof(*sr->u.explain_response));
618         sr->u.explain_response->record.recordData_buf = 0;
619         sr->u.explain_response->record.recordData_len = 0;
620         sr->u.explain_response->record.recordSchema = 0;
621         sr->u.explain_response->record.recordPosition = 0;
622         sr->u.explain_response->record.recordPacking =
623             Z_SRW_recordPacking_string;
624         sr->u.explain_response->diagnostics = 0;
625         sr->u.explain_response->num_diagnostics = 0;
626         sr->u.explain_response->extra_record = 0;
627         break;
628     case Z_SRW_scan_request:
629         sr->u.scan_request = (Z_SRW_scanRequest *)
630             odr_malloc(o, sizeof(*sr->u.scan_request));
631         sr->u.scan_request->database = 0;
632         sr->u.scan_request->stylesheet = 0;
633         sr->u.scan_request->maximumTerms = 0;
634         sr->u.scan_request->responsePosition = 0;
635         sr->u.scan_request->query_type = Z_SRW_query_type_cql;
636         sr->u.scan_request->scanClause.cql = 0;
637         break;
638     case Z_SRW_scan_response:
639         sr->u.scan_response = (Z_SRW_scanResponse *)
640             odr_malloc(o, sizeof(*sr->u.scan_response));
641         sr->u.scan_response->terms = 0;
642         sr->u.scan_response->num_terms = 0;
643         sr->u.scan_response->diagnostics = 0;
644         sr->u.scan_response->num_diagnostics = 0;
645     case Z_SRW_update_request:
646         sr->u.update_request = (Z_SRW_updateRequest *)
647             odr_malloc(o, sizeof(*sr->u.update_request));
648         sr->u.update_request->database = 0;
649         sr->u.update_request->stylesheet = 0;
650         sr->u.update_request->record.recordSchema = 0;
651         sr->u.update_request->record.recordPacking = Z_SRW_recordPacking_XML;
652         sr->u.update_request->recordId = 0;
653         sr->u.update_request->recordVersion = 0;
654         sr->u.update_request->recordOldVersion = 0;
655         sr->u.update_request->record.recordData_buf = 0;
656         sr->u.update_request->record.recordData_len = 0;
657         sr->u.update_request->extra_record = 0;
658         sr->u.update_request->extraRequestData = 0;
659         sr->u.request->database = 0;
660         break;
661     case Z_SRW_update_response:
662         sr->u.update_response = (Z_SRW_updateResponse *)
663             odr_malloc(o, sizeof(*sr->u.update_response));
664         sr->u.update_response->operationStatus = 0;
665         sr->u.update_response->recordId = 0;
666         sr->u.update_response->recordVersion = 0;
667         sr->u.update_response->recordChecksum = 0;
668         sr->u.update_response->record.recordData_buf = 0;
669         sr->u.update_response->record.recordData_len = 0;
670         sr->u.update_response->record.recordSchema = 0;
671         sr->u.update_response->record.recordPacking =
672             Z_SRW_recordPacking_XML;
673         sr->u.update_response->extra_record = 0;
674         sr->u.update_response->extraResponseData = 0;
675         sr->u.update_response->diagnostics = 0;
676         sr->u.update_response->num_diagnostics = 0;
677     }
678     return sr;
679 }
680
681 /* bib1:srw */
682 static int srw_bib1_map[] = {
683     1, 1,
684     2, 2,
685     3, 11,
686     4, 35,
687     5, 12,
688     6, 38,
689     7, 30,
690     8, 32,
691     9, 29,
692     108, 10,  /* Malformed query : Syntax error */
693     10, 10,
694     11, 12,
695     11, 23,
696     12, 60,
697     13, 61,
698     13, 62,
699     14, 63,
700     14, 64,
701     14, 65,
702     15, 68,
703     15, 69,
704     16, 70,
705     17, 70,
706     18, 50,
707     19, 55,
708     20, 56, 
709     21, 52,
710     22, 50,
711     23, 3,
712     24, 66,
713     25, 66,
714     26, 66,
715     27, 51,
716     28, 52,
717     29, 52,
718     30, 51,
719     31, 57,
720     32, 58,
721     33, 59,
722     100, 1, /* bad map */
723     101, 3,
724     102, 3,
725     103, 3,
726     104, 3,
727     105, 3, 
728     106, 66,
729     107, 11,
730     108, 13,
731     108, 14,
732     108, 25,
733     108, 26,
734     108, 27,
735     108, 45,
736         
737     109, 2,
738     110, 37,
739     111, 1,
740     112, 58,
741     113, 10,
742     114, 16,
743     115, 16,
744     116, 16,
745     117, 19,
746     117, 20,
747     118, 22,
748     119, 32,
749     119, 31,
750     120, 28,
751     121, 15,
752     122, 32,
753     123, 22,
754     123, 17,
755     123, 18,
756     124, 24,
757     125, 36,
758     126, 36, 
759     127, 36,
760     128, 51,
761     129, 39,
762     130, 43,
763     131, 40,
764     132, 42,
765     201, 44,
766     201, 33,
767     201, 34,
768     202, 41,
769     203, 43,
770     205, 1,  /* bad map */
771     206, 1,  /* bad map */
772     207, 89,
773     208, 1,  /* bad map */
774     209, 80,
775     210, 80,
776     210, 81,
777     211, 84,
778     212, 85,
779     213, 92,
780     214, 90,
781     215, 91,
782     216, 92,
783     217, 63,
784     218, 1,  /* bad map */
785     219, 1,  /* bad map */
786     220, 1,  /* bad map */
787     221, 1,  /* bad map */
788     222, 3,
789     223, 1,  /* bad map */
790     224, 1,  /* bad map */
791     225, 1,  /* bad map */
792     226, 1,  /* bad map */
793     227, 66,
794     228, 1,  /* bad map */
795     229, 36,
796     230, 83,
797     231, 89,
798     232, 1,
799     233, 1, /* bad map */
800     234, 1, /* bad map */
801     235, 2,
802     236, 3, 
803     237, 82,
804     238, 67,
805     239, 66,
806     240, 1, /* bad map */
807     241, 1, /* bad map */
808     242, 70,
809     243, 1, /* bad map */
810     244, 66,
811     245, 10,
812     246, 10,
813     247, 10,
814     1001, 1, /* bad map */
815     1002, 1, /* bad map */
816     1003, 1, /* bad map */
817     1004, 1, /* bad map */
818     1005, 1, /* bad map */
819     1006, 1, /* bad map */
820     1007, 100,
821     1008, 1, 
822     1009, 1,
823     1010, 3,
824     1011, 3,
825     1012, 3,
826     1013, 3,
827     1014, 3,
828     1015, 3,
829     1015, 3,
830     1016, 3,
831     1017, 3,
832     1018, 2,
833     1019, 2,
834     1020, 2,
835     1021, 3,
836     1022, 3,
837     1023, 3,
838     1024, 16,
839     1025, 3,
840     1026, 64,
841     1027, 1,
842     1028, 65,
843     1029, 1,
844     1040, 1,
845     /* 1041-1065 */
846     1066, 66,
847     1066, 67,
848     0
849 };
850
851 int yaz_diag_bib1_to_srw (int code)
852 {
853     const int *p = srw_bib1_map;
854     while (*p)
855     {
856         if (code == p[0])
857             return p[1];
858         p += 2;
859     }
860     return 1;
861 }
862
863 int yaz_diag_srw_to_bib1(int code)
864 {
865     const int *p = srw_bib1_map;
866     while (*p)
867     {
868         if (code == p[1])
869             return p[0];
870         p += 2;
871     }
872     return 1;
873 }
874
875 /*
876  * Local variables:
877  * c-basic-offset: 4
878  * indent-tabs-mode: nil
879  * End:
880  * vim: shiftwidth=4 tabstop=8 expandtab
881  */
882