f453abdfab37d325879c52e1417054a118176872
[idzebra-moved-to-github.git] / index / api_swig.c
1 #include <idzebra/api_swig.h>
2 #include <stdarg.h>
3
4 #define DEFAULT_APPROX_LIMIT 2000000000
5
6 /* == Internal structures ================================================== */
7
8 struct idzebra_swig_service {
9   ZebraService zs;
10   Res res;
11 };
12
13 struct idzebra_swig_session {
14   ZebraHandle zh;
15   Res res;
16 };
17
18 /* == API errors, debug ==================================================== */
19 static Res api_error = 0;
20 const char* api_error_context = 0;
21 void api_add_error(const char *fmt, ...); 
22 void api_clear_error(void); 
23 void free_array(const char **args);
24
25
26 /* == API init, destroy  =================================================== */
27 void idzebra_api_init(void) 
28 {
29   yaz_log_init_prefix("API_SWIG");
30   yaz_log(YLOG_LOG, "IDZebra API initialized");
31 }
32
33 /* == Service start/stop =================================================== */
34
35 IDZebraService idzebra_start (RES_LIST)
36 {
37   IDZebraService srv = xmalloc(sizeof(*srv));
38
39   ARGS_INIT;
40   API_SET_CONTEXT;
41
42   ARGS_PARSE ("configName", 
43               "chdir", 
44               "modulePath", 
45               "profilePath",
46               "register",
47               "shadow",
48               "isam",
49               "keyTmpDir",
50               "setTmpDir",
51               "lockDir");
52   
53   srv->res = func_res;
54   srv->zs = zebra_start_res(res_get(func_res,"configName"), NULL, srv->res);
55
56   func_res = 0; 
57   ARGS_DONE;
58
59   return (srv);
60 }
61
62 IDZEBRA_RES idzebra_stop(IDZebraService srv) 
63 {
64   ZEBRA_RES rv = zebra_stop(srv->zs);
65   res_close (srv->res);
66   xfree (srv);
67   return (rv);
68 }
69
70 /* == Session open/close =================================================== */
71 IDZebraSession idzebra_open (IDZebraService srv, RES_LIST)
72 {
73   IDZebraSession sess = xmalloc(sizeof(*sess));
74
75   ARGS_INIT;
76   API_SET_CONTEXT;
77
78   ARGS_PARSE  ("tempfiles", 
79                "openRW", 
80                "memmax",
81                "encoding",
82                "estimatehits",
83                "staticrank");
84
85   sess->res = func_res;
86   sess->zh = zebra_open(srv->zs, sess->res);
87
88   /* Function resources are kept for session (zh->res->over_res); */
89   func_res = 0; 
90   ARGS_DONE;
91
92   return (sess);
93 }
94
95 IDZEBRA_RES idzebra_close(IDZebraSession sess) 
96 {
97   ZEBRA_RES rv = zebra_close (sess->zh);
98   res_close (sess->res);
99   xfree (sess);
100   return (rv);
101 }
102 /* == Sample function == =================================================== */
103 IDZEBRA_RES idzebra_samplefunc(IDZebraSession sess, RES_LIST)
104 {
105   ARGS_INIT;
106   API_SET_CONTEXT;
107   ARGS_PARSE("strucc");
108   ARGS_PROCESS(ARG_MODE_OPTIONAL,"encoding");
109   ARGS_APPLY;
110
111   res_dump (sess->res,0);
112
113   //  ARGS_REVOKE;
114   {                                                              
115   const char **used;                                             
116   res_remove_over(temp_res);                                     
117   used = (const char **) res_get_array(local, "_used");                          args_use(sess, sess->res, 0, ARG_MODE_FORCE, used);            
118   free_array(used);                                              
119   }                                                              
120   ARGS_DONE;
121   return (ZEBRA_OK);
122
123
124
125 /* 
126 -------------------------------------------------------------------------------
127  Utility functions for argument handling
128 -------------------------------------------------------------------------------
129 */
130 void arg_parse_res (Res r, 
131                     const char **valid_args, 
132                     Res skip,
133                     char *name, char *value)
134 {
135   if ((name) && (value)) {
136       int i = 0;
137       int gotit = 0;
138       while (valid_args[i]) {
139         if (!strcmp(name, valid_args[i])) {
140           res_set(r, name, value);
141           gotit = 1;
142           break;
143         }
144         i++;
145       }
146       if (!gotit)
147         yaz_log (YLOG_DEBUG, "skip: %s=%s",name, value);
148         res_add (skip, name, value);
149   }
150 }
151
152 void args_parse_res (Res r, 
153                      const char **valid_args, 
154                      Res skip,
155                      char **args)
156 {
157   char *argname;
158   char *argvalue;
159   int i = 0;
160   if (args) {
161     while (args[i] && args[i+1]) {
162       argname = args[i++];
163       argvalue = args[i++];
164       arg_parse_res (r, valid_args, skip, argname, argvalue);
165     }
166   }
167 }
168
169 /* == special resource handlers ============================================ */
170
171 void idzebra_res_encoding (ZebraHandle zh, const char *value) 
172 {
173   if (value)
174     zebra_octet_term_encoding(zh, value);
175   else
176     zebra_octet_term_encoding(zh, "ISO-8859-1");
177   
178 }
179
180 void idzebra_res_estimatehits (ZebraHandle zh, const char *value) 
181 {
182   int val = 0;
183   if (value)
184     if (! (sscanf(value, "%d", &val) == 1)) 
185       api_add_error( "Expected integer value for 'estimatehits'");
186
187   zebra_set_approx_limit(zh, val);
188 }
189
190 /*
191 void idzebra_res_staticrank (ZebraHandle zh, const char *value) 
192 {
193   int val = 0;
194   if (value)
195     if (! (sscanf(value, "%d", &val) == 1)) 
196       api_add_error( "Expected integer value for 'estimatehits'");
197   
198   sess->zh->m_staticrank = val;
199 }
200 */
201
202 /* == applying and revoking call-scope resources =========================== */
203
204 void arg_use (ZebraHandle zh,
205               Res r,
206               Res rr,
207               int mode,
208               const char *name)
209 {
210   if (name) {
211     const char *value = res_get(r, name);
212     int gotit = 0;
213
214     /* in FORCE mode resource is used with default value also */
215     if ((value) || (mode & ARG_MODE_FORCE)) {
216
217       /* encoding */
218       if (!strcmp(name,"encoding")) {
219         idzebra_res_encoding(zh, value);
220         gotit = 1;
221       }
222
223       /* estimatehits */
224       else if (!strcmp(name,"estimatehits")) {
225         idzebra_res_estimatehits(zh, value);
226         gotit = 1;
227       }
228
229       /* staticrank */
230       /*
231       else if (!strcmp(name,"staticrank")) {
232         idzebra_res_staticrank(zh, value);
233         gotit = 1;
234       }
235       */
236       
237       /* collects provided arguments in order to revoke them 
238          at the end of the function */
239       if (gotit) {
240         if (! (mode & ARG_MODE_FORCE)) res_add(r, "_used", name);
241         if ( (rr) && (name) && (value) ) res_add(rr, name, value);
242       }
243   } else {
244       /* value missing */
245       if (mode & ARG_MODE_MANDATORY)
246         api_add_error( "Missing mandatory argument '%s'", name);
247     }
248   }
249 }
250
251 void args_use (IDZebraSession sess,
252                Res r,
253                Res rr,
254                int mode,
255                const char **args)
256 {
257   int i = 0;
258   if (args) {
259     while (args[i]) {
260       arg_use (sess->zh, r, rr, mode, args[i++]);
261     }
262   }
263 }
264
265 /* == API errors =========================================================== */
266
267 void api_add_error(const char *fmt, ...) 
268 {
269
270   va_list ap;
271   char buf[4096];  
272   const char *context;
273   va_start(ap, fmt);
274
275 #ifdef WIN32
276   _vsnprintf(buf, sizeof(buf)-1, fmt, ap);
277 #else
278 /* !WIN32 */
279 #if HAVE_VSNPRINTF
280   vsnprintf(buf, sizeof(buf), fmt, ap);
281 #else
282   vsprintf(buf, fmt, ap);
283 #endif
284 #endif
285
286   va_end (ap);
287
288   if (! api_error)
289     api_error = res_open(0,0);
290
291   if (api_error_context)
292     context = api_error_context;
293   else
294     context = "<unknown>";
295       
296   res_add(api_error, context, buf);
297 }
298
299 char **api_errors(void)
300 {
301   static char **res = 0;
302
303   res = res_2_array(api_error);
304   if (!res) {
305     res = xmalloc(sizeof(char *));
306     res[0] = 0 ;
307   }
308   return (&res[0]);
309
310 }
311
312
313 int api_check_error(void)
314 {
315   if (api_error)
316     return (1);
317   else
318     return (0);
319 }
320
321 void api_clear_error(void) 
322 {
323   if (api_error)
324     res_close(api_error);
325   api_error = 0;
326 }
327
328 void free_array(const char **args)
329 {
330   int i = 0;
331   if (args) {
332     while (args[i]) {
333       xfree((char *) args[i]);
334       i++;
335     }
336     xfree (args);
337   }
338 }
339 /*
340  * Local variables:
341  * c-basic-offset: 4
342  * indent-tabs-mode: nil
343  * End:
344  * vim: shiftwidth=4 tabstop=8 expandtab
345  */
346