ZOOM: only supply clientIP for InitRequest
[yaz-moved-to-github.git] / src / cql_sortkeys.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) Index Data
3  * See the file LICENSE for details.
4  */
5 /**
6  * \file cql_sortkeys.c
7  * \brief CQL sortkeys utilities
8  *
9  */
10 #if HAVE_CONFIG_H
11 #include <config.h>
12 #endif
13
14 #include <assert.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <yaz/wrbuf.h>
18 #include <yaz/cql.h>
19
20 static void pr_n(void (*pr)(const char *buf, void *client_data),
21                  const char *buf, int len, void *client_data)
22 {
23     char tmp[4];
24     int left = len;
25
26     while (left > 0)
27     {
28         if (left >= sizeof(tmp))
29         {
30             memcpy(tmp, buf, sizeof(tmp)-1);
31             tmp[sizeof(tmp)-1] = '\0';
32             left = left - (sizeof(tmp)-1);
33         }
34         else
35         {
36             memcpy(tmp, buf, left);
37             tmp[left] = '\0';
38             left = 0;
39         }
40         pr(tmp, client_data);
41     }
42 }
43
44 static int cql_sort_modifiers(struct cql_node *cn,
45                               void (*pr)(const char *buf, void *client_data),
46                                void *client_data)
47 {
48     int ascending = 1;
49     int caseSensitive = 0;
50     const char *missingValue = "highValue";
51     for (; cn; cn = cn->u.st.modifiers)
52     {
53         const char *indx = cn->u.st.index;
54         if (!strncmp(indx, "sort.", 5))
55             indx = indx + 5;
56         if (!strcmp(indx, "ignoreCase"))
57             caseSensitive = 0;
58         else if (!strcmp(indx, "respectCase"))
59             caseSensitive = 1;
60         else if (!strcmp(indx, "ascending"))
61             ascending = 1;
62         else if (!strcmp(indx, "descending"))
63             ascending = 0;
64         else if (!strcmp(indx, "missingOmit"))
65             missingValue = "omit";
66         else if (!strcmp(indx, "missingFail"))
67             missingValue = "abort";
68         else if (!strcmp(indx, "missingLow"))
69             missingValue = "lowValue";
70         else if (!strcmp(indx, "missingHigh"))
71             missingValue = "highValue";
72         else
73             return -1;
74     }
75     pr(ascending ? "1" : "0", client_data);
76     pr(",", client_data);
77     pr(caseSensitive ? "1" : "0", client_data);
78     pr(",", client_data);
79     pr(missingValue, client_data);
80     return 0;
81 }
82
83 int cql_sortby_to_sortkeys(struct cql_node *cn,
84                            void (*pr)(const char *buf, void *client_data),
85                            void *client_data)
86 {
87     int r = 0;
88     if (cn && cn->which == CQL_NODE_SORT)
89     {
90         for (; cn; cn = cn->u.sort.next)
91         {
92             const char *indx = cn->u.sort.index;
93
94             if (indx)
95             {
96                 const char *s = strchr(indx, '.');
97                 if (s)
98                 {
99                     pr(s+1, client_data);
100                     pr(",", client_data);
101                     pr_n(pr, indx, s - indx, client_data);
102                 }
103                 else
104                 {
105                     pr(indx, client_data);
106                     pr(",", client_data);
107                 }
108                 pr(",", client_data);
109                 r = cql_sort_modifiers(cn->u.sort.modifiers, pr, client_data);
110                 if (r)
111                     break;
112                 if (cn->u.sort.next)
113                     pr(" ", client_data);
114             }
115         }
116     }
117     return r;
118 }
119
120 int cql_sortby_to_sortkeys_buf(struct cql_node *cn, char *out, int max)
121 {
122     struct cql_buf_write_info info;
123     int r;
124
125     info.off = 0;
126     info.max = max;
127     info.buf = out;
128     r = cql_sortby_to_sortkeys(cn, cql_buf_write_handler, &info);
129     if (info.off >= 0)
130         info.buf[info.off] = '\0';
131     return r;
132 }
133
134 /*
135  * Local variables:
136  * c-basic-offset: 4
137  * c-file-style: "Stroustrup"
138  * indent-tabs-mode: nil
139  * End:
140  * vim: shiftwidth=4 tabstop=8 expandtab
141  */
142