root/swish_php/swishe.c

Revision 1490, 30.0 kB (checked in by jmruiz, 4 years ago)

Added a couple of lines to swishe.c to free memory.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*
2    +----------------------------------------------------------------------+
3    | PHP version 4.0                                                      |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group             |
6    +----------------------------------------------------------------------+
7    | This source file is subject to version 2.02 of the PHP license,      |
8    | that is bundled with this package in the file LICENSE, and is        |
9    | available at through the world-wide-web at                           |
10    | http://www.php.net/license/2_02.txt.                                 |
11    | If you did not receive a copy of the PHP license and are unable to   |
12    | obtain it through the world-wide-web, please send a note to          |
13    | license@php.net so we can mail you a copy immediately.               |
14    +----------------------------------------------------------------------+
15    | Authors: Jose Ruiz <jmruiz@boe.es>                                   |
16    +----------------------------------------------------------------------+
17  */
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include "php.h"
24 #include "php_ini.h"
25 #include "ext/standard/info.h"
26 #include "php_swishe.h"
27
28 typedef struct {
29     int id;
30     SW_HANDLE swishe_handle;
31 } php_swishe;
32
33 typedef struct {
34     int id;
35     void *swishe_search_handle;
36     SW_HANDLE swishe_handle;
37     php_swishe *swishe;
38 } php_swishe_search;
39
40 typedef struct {
41     int id;
42     SW_RESULTS swishe_results_handle;
43     SW_HANDLE swishe_handle;
44     php_swishe_search *search;
45 } php_swishe_results;
46
47 typedef struct {
48     int id;
49     void *swishe_result_handle;
50     SW_RESULTS swishe_results_handle;
51     SW_HANDLE swishe_handle;
52     php_swishe_results *results;
53 } php_swishe_result;
54
55 /* True global resources - no need for thread safety here */
56 static int le_swishe;
57 static int le_swishe_search;
58 static int le_swishe_results;
59 static int le_swishe_result;
60
61 /* An OO interface as well */
62 static zend_class_entry *swishe_class_entry_ptr;
63 static zend_class_entry *swishe_search_class_entry_ptr;
64 static zend_class_entry *swishe_results_class_entry_ptr;
65 static zend_class_entry *swishe_result_class_entry_ptr;
66
67 #define FETCH_SWISHE() \
68     if (this_ptr) { \
69         if (zend_hash_find(HASH_OF(this_ptr), "swishe_handle", sizeof("swishe_handle"), (void **)&tmp) == FAILURE) { \
70             php_error(E_WARNING, "unable to find my handle property"); \
71             RETURN_FALSE; \
72         } \
73         ZEND_FETCH_RESOURCE(swishe, php_swishe *, tmp, -1, "swishe_handle", le_swishe); \
74     }
75
76 #define FETCH_SEARCH() \
77     if (this_ptr) { \
78         if (zend_hash_find(HASH_OF(this_ptr), "swishe_search_handle", sizeof("swishe_search_handle"), (void **)&tmp) == FAILURE) { \
79             php_error(E_WARNING, "unable to find my search_handle property"); \
80             RETURN_FALSE; \
81         } \
82         ZEND_FETCH_RESOURCE(search, php_swishe_search *, tmp, -1, "swishe_search_handle", le_swishe_search); \
83     }
84
85 #define FETCH_RESULTS() \
86     if (this_ptr) { \
87         if (zend_hash_find(HASH_OF(this_ptr), "swishe_results_handle", sizeof("swishe_results_handle"), (void **)&tmp) == FAILURE) { \
88             php_error(E_WARNING, "unable to find my results_handle property"); \
89             RETURN_FALSE; \
90         } \
91         ZEND_FETCH_RESOURCE(results, php_swishe_results *, tmp, -1, "swishe_results_handle", le_swishe_results); \
92     }
93
94 #define FETCH_RESULT() \
95     if (this_ptr) { \
96         if (zend_hash_find(HASH_OF(this_ptr), "swishe_result_handle", sizeof("swishe_result_handle"), (void **)&tmp) == FAILURE) { \
97             php_error(E_WARNING, "unable to find my result_handle property"); \
98             RETURN_FALSE; \
99         } \
100         ZEND_FETCH_RESOURCE(result, php_swishe_result *, tmp, -1, "swishe_result_handle", le_swishe_result); \
101     }
102 /* If you declare any globals in php_swishe.h uncomment this:
103 ZEND_DECLARE_MODULE_GLOBALS(swishe)
104 */
105
106
107 /* {{{ swishe_functions[]
108  *
109  * Every user visible function must have an entry in swishe_functions[].
110  */
111 function_entry swishe_functions[] = {
112     PHP_FE(confirm_swishe_compiled, NULL)       /* For testing, remove later. */
113     PHP_FE(swishe_open,  NULL)
114     PHP_FE(swishe_close,  NULL)
115     PHP_FE(swishe_index_names,  NULL)
116     PHP_FE(swishe_header_names, NULL)
117     PHP_FE(swishe_header_value, NULL)
118     PHP_FE(swishe_stem, NULL)
119     PHP_FE(swishe_swish_words_by_letter, NULL)
120     PHP_FE(swishe_error,    NULL)
121     PHP_FE(swishe_critical_error,   NULL)
122     PHP_FE(swishe_abort_last_error, NULL)
123     PHP_FE(swishe_error_string, NULL)
124     PHP_FE(swishe_last_error_msg,   NULL)
125     PHP_FE(swishe_query,    NULL)
126     PHP_FE(swishe_set_query,    NULL)
127     PHP_FE(swishe_set_structure,    NULL)
128     PHP_FE(swishe_set_phrase_delimiter, NULL)
129     PHP_FE(swishe_set_search_limit, NULL)
130     PHP_FE(swishe_reset_search_limit,   NULL)
131     PHP_FE(swishe_set_sort, NULL)
132     PHP_FE(swishe_execute,  NULL)
133     PHP_FE(swishe_hits, NULL)
134     PHP_FE(swishe_parsed_words, NULL)
135     PHP_FE(swishe_removed_stopwords,    NULL)
136     PHP_FE(swishe_seek_result,  NULL)
137     PHP_FE(swishe_next_result,  NULL)
138     PHP_FE(swishe_property, NULL)
139     PHP_FE(swishe_result_index_value,   NULL)
140     PHP_FE(swishe,  NULL)
141     {NULL, NULL, NULL}
142 };
143 /* }}} */
144
145 static zend_function_entry php_swishe_class_functions[] = {
146     PHP_FE(swishe,    NULL)
147     PHP_FALIAS(index_names,  swishe_index_names, NULL)
148     PHP_FALIAS(header_names, swishe_header_names, NULL)
149     PHP_FALIAS(header_value, swishe_header_value, NULL)
150     PHP_FALIAS(error, swishe_error, NULL)
151     PHP_FALIAS(critical_error, swishe_critical_error, NULL)
152     PHP_FALIAS(abort_last_error, swishe_abort_last_error, NULL)
153     PHP_FALIAS(error_string, swishe_error_string, NULL)
154     PHP_FALIAS(stem, swishe_stem, NULL)
155     PHP_FALIAS(swish_words_by_letter, swishe_swish_words_by_letter, NULL)
156     PHP_FALIAS(new_search_object, swishe_search, NULL)
157     PHP_FALIAS(query, swishe_query, NULL)
158     {NULL, NULL, NULL}
159 };
160
161 static zend_function_entry php_swishe_search_class_functions[] = {
162     PHP_FALIAS(set_query, swishe_set_query, NULL)
163     PHP_FALIAS(set_structure, swishe_set_structure, NULL)
164     PHP_FALIAS(set_phrase_delimiter, swishe_set_phrase_delimiter, NULL)
165     PHP_FALIAS(set_search_limit, swishe_set_search_limit, NULL)
166     PHP_FALIAS(reset_search_limit, swishe_reset_search_limit, NULL)
167     PHP_FALIAS(set_sort, swishe_set_sort, NULL)
168     PHP_FALIAS(execute, swishe_execute, NULL)
169     {NULL, NULL, NULL}
170 };
171
172 static zend_function_entry php_swishe_results_class_functions[] = {
173     PHP_FALIAS(hits, swishe_hits, NULL)
174     PHP_FALIAS(parsed_words, swishe_parsed_words, NULL)
175     PHP_FALIAS(removed_stopwords, swishe_removed_stopwords, NULL)
176     PHP_FALIAS(seek_result, swishe_seek_result, NULL)
177     PHP_FALIAS(next_result, swishe_next_result, NULL)
178     {NULL, NULL, NULL}
179 };
180
181 static zend_function_entry php_swishe_result_class_functions[] = {
182     PHP_FALIAS(property, swishe_property, NULL)
183     PHP_FALIAS(result_index_value, swishe_result_index_value, NULL)
184     {NULL, NULL, NULL}
185 };
186
187 /* {{{ swishe_module_entry
188  */
189 zend_module_entry swishe_module_entry = {
190 #if ZEND_MODULE_API_NO >= 20010901
191     STANDARD_MODULE_HEADER,
192 #endif
193     "swishe",
194     swishe_functions,
195     PHP_MINIT(swishe),
196     PHP_MSHUTDOWN(swishe),
197     NULL,
198     NULL,
199     PHP_MINFO(swishe),
200 #if ZEND_MODULE_API_NO >= 20010901
201     PHP_SWISHE_VERSION,
202 #endif
203     STANDARD_MODULE_PROPERTIES
204 };
205 /* }}} */
206
207 #ifdef COMPILE_DL_SWISHE
208 ZEND_GET_MODULE(swishe)
209 #endif
210
211 /* {{{ php_swishe_init_globals
212 static void php_swishe_init_globals(zend_swishe_globals *swishe_globals)
213 {
214 }
215 */
216 /* }}} */
217
218 PHP_INI_BEGIN()
219 PHP_INI_END()
220
221
222 /* destroy a resource of type "swishe" */
223 static void _php_swishe_close(zend_rsrc_list_entry *rsrc)
224 {
225 php_swishe *swishe = (php_swishe *)rsrc->ptr;
226
227     SwishClose(swishe->swishe_handle);
228     efree(swishe);
229 }
230
231 /* destroy a resource of type "swishe_search" */
232 static void _php_swishe_search_close(zend_rsrc_list_entry *rsrc)
233 {
234 php_swishe_search *search = (php_swishe_search *)rsrc->ptr;
235
236     Free_Search_Object(search->swishe_search_handle);
237     efree(search);
238 }
239
240 /* destroy a resource of type "swishe_results" */
241 static void _php_swishe_results_close(zend_rsrc_list_entry *rsrc)
242 {
243 php_swishe_results *results = (php_swishe_results *)rsrc->ptr;
244
245     Free_Results_Object(results->swishe_results_handle);
246     efree(results);
247 }
248
249
250 /* destroy a resource of type "swishe_result" */
251 static void _php_swishe_result_close(zend_rsrc_list_entry *rsrc)
252 {
253 php_swishe_result *result = (php_swishe_result *)rsrc->ptr;
254
255     efree(result);
256 }
257
258 /* {{{ PHP_MINIT_FUNCTION
259  */
260 PHP_MINIT_FUNCTION(swishe)
261 {
262     zend_class_entry swishe_class_entry;
263     zend_class_entry swishe_search_class_entry;
264     zend_class_entry swishe_results_class_entry;
265     zend_class_entry swishe_result_class_entry;
266
267     le_swishe = zend_register_list_destructors_ex(_php_swishe_close, NULL, "swishe_handle", module_number);
268     le_swishe_search = zend_register_list_destructors_ex(_php_swishe_search_close, NULL, "swishe_search_handle", module_number);
269     le_swishe_results = zend_register_list_destructors_ex(_php_swishe_results_close, NULL, "swishe_results_handle", module_number);
270     le_swishe_result = zend_register_list_destructors_ex(_php_swishe_result_close, NULL, "swishe_result_handle", module_number);
271
272     /*
273     ZEND_INIT_MODULE_GLOBALS(swishe, php_swishe_init_globals, NULL);
274     */
275     INIT_CLASS_ENTRY(swishe_class_entry, "swishe", php_swishe_class_functions);
276     swishe_class_entry_ptr = zend_register_internal_class(&swishe_class_entry TSRMLS_CC);
277
278     INIT_CLASS_ENTRY(swishe_search_class_entry, "swishe_search", php_swishe_search_class_functions);
279     swishe_search_class_entry_ptr = zend_register_internal_class(&swishe_search_class_entry TSRMLS_CC);
280
281     INIT_CLASS_ENTRY(swishe_results_class_entry, "swishe_results", php_swishe_results_class_functions);
282     swishe_results_class_entry_ptr = zend_register_internal_class(&swishe_results_class_entry TSRMLS_CC);
283
284     INIT_CLASS_ENTRY(swishe_result_class_entry, "swishe_result", php_swishe_result_class_functions);
285     swishe_result_class_entry_ptr = zend_register_internal_class(&swishe_result_class_entry TSRMLS_CC);
286     REGISTER_INI_ENTRIES();
287
288     return SUCCESS;
289 }
290 /* }}} */
291
292 /* {{{ PHP_MSHUTDOWN_FUNCTION
293  */
294 PHP_MSHUTDOWN_FUNCTION(swishe)
295 {
296     UNREGISTER_INI_ENTRIES();
297     return SUCCESS;
298 }
299 /* }}} */
300
301 /* {{{ PHP_MINFO_FUNCTION
302  */
303 PHP_MINFO_FUNCTION(swishe)
304 {
305     php_info_print_table_start();
306     php_info_print_table_header(2, "swishe support", "enabled");
307     php_info_print_table_end();
308
309     DISPLAY_INI_ENTRIES();
310 }
311 /* }}} */
312
313
314 /* Internal functions */
315
316 /* Opens a swish-e handle */
317 static void _php_swishe_open(INTERNAL_FUNCTION_PARAMETERS, int createobject)
318 {
319     int argc = ZEND_NUM_ARGS();
320     char *index_file_list = NULL;
321     int index_file_list_len = 0;
322     php_swishe *swishe;
323
324     if (argc != 1) WRONG_PARAM_COUNT;
325     if (zend_parse_parameters( argc TSRMLS_CC, "s", &index_file_list, &index_file_list_len) == FAILURE)
326         return;
327
328
329     swishe = (php_swishe *) emalloc(sizeof(php_swishe));
330     swishe->swishe_handle = SwishInit( index_file_list );
331     swishe->id = zend_list_insert(swishe,le_swishe);
332
333     if(createobject)
334     {
335         object_init_ex(return_value, swishe_class_entry_ptr);
336         add_property_resource(return_value,"swishe_handle",swishe->id);
337     }
338     else
339     {
340         RETURN_RESOURCE(swishe->id);
341     }
342 }
343
344 /* {{{ proto string confirm_swishe_compiled(string arg)
345    Return a string to confirm that the module is compiled in */
346 PHP_FUNCTION(confirm_swishe_compiled)
347 {
348     char *arg = NULL;
349     int arg_len, len;
350     char string[256];
351
352     if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) ==
353  FAILURE) {
354         return;
355     }
356
357     len = sprintf(string, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "swishe", arg);
358     RETURN_STRINGL(string, len, 1);
359 }
360 /* }}} */
361
362 /* {{{ proto resource swishe_open()
363    SWISHE open */
364 PHP_FUNCTION(swishe_open)
365 {
366     _php_swishe_open(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
367 }
368
369 /* {{{ proto void swishe_close()
370    SWISHE close */
371 PHP_FUNCTION(swishe_close)
372 {
373     if (ZEND_NUM_ARGS() != 1) {
374         WRONG_PARAM_COUNT;
375     }
376     php_error(E_WARNING, "swishe_close: not yet implemented");
377 }
378
379 /* }}} */
380
381
382 /* {{{ proto array swishe_index_names()
383    SWISHE index names */
384 PHP_FUNCTION(swishe_index_names)
385 {
386 zval **id, **tmp;
387 php_swishe *swishe;
388
389 const char **index_name;
390
391     if (ZEND_NUM_ARGS() != 0) {
392         WRONG_PARAM_COUNT;
393     }
394
395     FETCH_SWISHE();
396     if(array_init(return_value) != SUCCESS)
397     {
398         /* do error handling here */
399         RETURN_NULL();
400     }
401     index_name = SwishIndexNames( swishe->swishe_handle );
402     while ( *index_name )
403     {
404        add_next_index_string(return_value,(char *)*index_name,1);
405        *index_name++;
406     }
407 }
408 /* }}} */
409
410 /* {{{ proto array swishe_header_names()
411    SWISHE index header names */
412 PHP_FUNCTION(swishe_header_names)
413 {
414 zval **id, **tmp;
415 php_swishe *swishe;
416
417 const char **header_name;
418
419
420     if (ZEND_NUM_ARGS() != 0) {
421         WRONG_PARAM_COUNT;
422     }
423
424     FETCH_SWISHE();
425     if(array_init(return_value) != SUCCESS)
426     {
427         /* do error handling here */
428         RETURN_NULL();
429     }
430
431     header_name = SwishHeaderNames( swishe->swishe_handle );
432     while ( *header_name )
433     {
434        add_next_index_string(return_value,(char *)*header_name,1);
435        *header_name++;
436     }
437 }
438 /* }}} */
439
440 /* {{{ proto array swishe_header_value(string index_file, string header_name)
441    SWISHE index header value */
442 PHP_FUNCTION(swishe_header_value)
443 {
444 zval **id, **tmp;
445 php_swishe *swishe;
446
447 char *index_file = NULL;
448 char *header_name = NULL;
449 int index_file_len;
450 int header_name_len;
451 int i;
452 SWISH_HEADER_TYPE  header_type;
453 SWISH_HEADER_VALUE head_value;
454 char **string_list;
455
456
457     if (ZEND_NUM_ARGS() != 2) {
458         WRONG_PARAM_COUNT;
459     }
460
461     if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &index_file, &index_file_len, &header_name, &header_name_len) == FAILURE)
462         return;
463
464     FETCH_SWISHE();
465     head_value = SwishHeaderValue( swishe->swishe_handle, index_file, header_name, &header_type );
466
467     /* Convert to data types and return */
468     switch(header_type)
469     {
470         case SWISH_NUMBER:
471             RETURN_LONG(head_value.number);
472             break;
473         case SWISH_STRING:
474             RETURN_STRING((char *)head_value.string,1);
475             break;
476         case SWISH_LIST:
477             if(array_init(return_value) != SUCCESS)
478             {
479                 RETURN_NULL();
480             }
481             string_list = (char **)head_value.string_list;
482             while ( *string_list )
483             {
484                 add_next_index_string(return_value,(char *)*string_list,1);
485                 string_list++;
486             }
487             return;
488             break;
489         case SWISH_BOOL:
490             RETURN_BOOL(head_value.boolean?1:0);
491             break;
492         case SWISH_HEADER_ERROR: /* must check error in this case */
493         default:
494             RETURN_NULL();
495             break;
496     }
497 }
498 /* }}} */
499
500 /* {{{ proto array swishe_stem(string word, string lang)
501    SWISHE stem a word */
502 PHP_FUNCTION(swishe_stem)
503 {
504 int argc = ZEND_NUM_ARGS();
505 zval **id, **tmp;
506 php_swishe *swishe;
507
508 char *word = NULL;
509 char *lang = NULL;
510 int word_len;
511 int lang_len;
512 char *stem;
513
514
515     if (argc <1 || argc > 2) {
516         WRONG_PARAM_COUNT;
517     }
518
519     if (zend_parse_parameters(argc TSRMLS_CC, "s|s", &word, &word_len, &lang, &lang_len) == FAILURE)
520         return;
521
522     FETCH_SWISHE();
523     stem = SwishStemWord( swishe->swishe_handle, word);
524
525     RETURN_STRING((char *)stem,1);
526 }
527 /* }}} */
528
529
530 /* {{{ proto array swishe_swish_words(string word, string lang)
531    SWISHE Get swish words */
532 PHP_FUNCTION(swishe_swish_words_by_letter)
533 {
534 int argc = ZEND_NUM_ARGS();
535 zval **id, **tmp;
536 php_swishe *swishe;
537
538 char *index_file = NULL;
539 char *letter = NULL;
540 int index_file_len;
541 int letter_len;
542 unsigned char c;
543 char *Words,*wtmp;
544 int c2;
545
546     if (argc <1 || argc > 2) {
547         WRONG_PARAM_COUNT;
548     }
549
550     if (zend_parse_parameters(argc TSRMLS_CC, "s|s", &index_file, &index_file_len, &letter, &letter_len) == FAILURE)
551         return;
552
553     if(letter && letter[0])
554     {
555         c = letter[0];
556     }
557     else
558     {
559         c = '*';
560     }
561    
562     FETCH_SWISHE();
563     if(array_init(return_value) != SUCCESS)
564     {
565         RETURN_NULL();
566     }
567     if(c=='*')
568     {
569         for(c2=1;c2<256;c2++)
570         {
571             Words=(char *)SwishWordsByLetter(swishe->swishe_handle,index_file,(unsigned char)c2);
572             for(wtmp=Words;wtmp && wtmp[0];wtmp+=strlen(wtmp)+1)
573             {
574                 add_next_index_string(return_value,(char *)wtmp,1);
575             }
576         }
577     } else {
578         Words=(char *)SwishWordsByLetter(swishe->swishe_handle,index_file,c);
579         for(wtmp=Words;wtmp && wtmp[0];wtmp+=strlen(wtmp)+1)
580         {
581             add_next_index_string(return_value,(char *)wtmp,1);
582         }
583     }
584 }
585 /* }}} */
586
587 /* {{{ proto long swishe_error()
588    SWISHE error */
589 PHP_FUNCTION(swishe_error)
590 {
591 zval **id, **tmp;
592 php_swishe *swishe;
593 long err;
594
595     if (ZEND_NUM_ARGS() != 0) {
596         WRONG_PARAM_COUNT;
597     }
598     FETCH_SWISHE();
599     err = SwishError(swishe->swishe_handle);
600     RETURN_LONG(err);
601 }
602 /* }}} */
603
604 /* {{{ proto bool swishe_critical_error()
605    SWISHE critical error */
606 PHP_FUNCTION(swishe_critical_error)
607 {
608 zval **id, **tmp;
609 php_swishe *swishe;
610 long err;
611
612     if (ZEND_NUM_ARGS() != 0) {
613         WRONG_PARAM_COUNT;
614     }
615     FETCH_SWISHE();
616     err = SwishCriticalError(swishe->swishe_handle);
617     RETURN_BOOL(err?1:0);
618 }
619 /* }}} */
620
621 /* {{{ proto bool swishe_abort_last_error()
622    SWISHE aborts and reports error to STDERR */
623 PHP_FUNCTION(swishe_abort_last_error)
624 {
625     if (ZEND_NUM_ARGS() != 0) {
626         WRONG_PARAM_COUNT;
627     }
628     php_error(E_WARNING, "swishe_abort_last_error: not yet implemented");
629 }
630 /* }}} */
631
632 /* {{{ proto string swishe_error_string()
633    SWISHE error string based on swishe_error  */
634 PHP_FUNCTION(swishe_error_string)
635 {
636 zval **id, **tmp;
637 php_swishe *swishe;
638 char *str;
639
640     if (ZEND_NUM_ARGS() != 0) {
641         WRONG_PARAM_COUNT;
642     }
643     FETCH_SWISHE();
644     str = SwishErrorString(swishe->swishe_handle);
645     RETURN_STRING(str,1);
646 }
647 /* }}} */
648
649 /* {{{ proto string swishe_last_error_msg()
650    SWISHE last error message */
651 PHP_FUNCTION(swishe_last_error_msg)
652 {
653     if (ZEND_NUM_ARGS() != 0) {
654         WRONG_PARAM_COUNT;
655     }
656     php_error(E_WARNING, "swishe_last_error_msg: not yet implemented");
657 }
658 /* }}} */
659
660
661 /* {{{ proto long swishe_query(string query)
662    SWISHE short-cut to avoid creation a search object */
663 PHP_FUNCTION(swishe_query)
664 {
665 int argc = ZEND_NUM_ARGS();
666 zval **id, **tmp;
667 php_swishe *swishe;
668 php_swishe_results *results;
669 char *query = NULL;
670 int query_len = 0;
671 void *swishe_search_handle = NULL;
672
673     if (argc > 1) {
674         WRONG_PARAM_COUNT;
675     }
676
677     if (zend_parse_parameters(argc TSRMLS_CC, "|s", &query, &query_len) == FAILURE)
678         return;
679
680     FETCH_SWISHE();
681     results = (php_swishe_results *) emalloc(sizeof(php_swishe_results));
682     results->search = NULL;
683     results->swishe_handle = swishe->swishe_handle;
684     swishe_search_handle = New_Search_Object( swishe->swishe_handle, query );
685     results->swishe_results_handle = SwishExecute( swishe_search_handle, query );
686     results->id = zend_list_insert(results,le_swishe_results);
687
688     object_init_ex(return_value, swishe_results_class_entry_ptr);
689     add_property_resource(return_value,"swishe_results_handle",results->id);
690 }
691 /* }}} */
692
693 /* {{{ proto void swishe_set_query(string query)
694    SWISHE set query search */
695 PHP_FUNCTION(swishe_set_query)
696 {
697 int argc = ZEND_NUM_ARGS();
698 zval **id, **tmp;
699 php_swishe_search *search;
700 char *query = NULL;
701 int query_len = 0;
702 int rc;
703
704     if (argc != 1) {
705         WRONG_PARAM_COUNT;
706     }
707
708     if (zend_parse_parameters(argc TSRMLS_CC, "s", &query, &query_len) == FAILURE)
709         return;
710
711     FETCH_SEARCH();
712     SwishSetQuery(search->swishe_search_handle, query);
713 }
714 /* }}} */
715
716 /* {{{ proto void swishe_set_structure(long structure)
717    SWISHE set structure bits */
718 PHP_FUNCTION(swishe_set_structure)
719 {
720 int argc = ZEND_NUM_ARGS();
721 zval **id, **tmp;
722 php_swishe_search *search;
723 int structure = 0;
724 int rc;
725
726     if (argc != 1) {
727         WRONG_PARAM_COUNT;
728     }
729
730     if (zend_parse_parameters(argc TSRMLS_CC, "l", &structure) == FAILURE)
731         return;
732
733     FETCH_SEARCH();
734     SwishSetStructure(search->swishe_search_handle, structure);
735 }
736 /* }}} */
737
738 /* {{{ proto void swishe_set_phrase_delimiter()
739    char char) SWISHE set phrase delimiter char */
740 PHP_FUNCTION(swishe_set_phrase_delimiter)
741 {
742 int argc = ZEND_NUM_ARGS();
743 zval **id, **tmp;
744 php_swishe_search *search;
745 char *phrase = NULL;
746 int phrase_len = 0;
747 int rc;
748
749     if (argc != 1) {
750         WRONG_PARAM_COUNT;
751     }
752
753     if (zend_parse_parameters(argc TSRMLS_CC, "s", &phrase, &phrase_len) == FAILURE)
754         return;
755
756     FETCH_SEARCH();
757     if(phrase_len)
758     {
759         SwishPhraseDelimiter(search->swishe_search_handle, phrase[0]);
760     }
761 }
762 /* }}} */
763
764 /* {{{ proto void swishe_set_search_limit(string property, string low, string hi
765 gh)
766    SWISHE set search limits */
767 PHP_FUNCTION(swishe_set_search_limit)
768 {
769 int argc = ZEND_NUM_ARGS();
770 zval **id, **tmp;
771 php_swishe_search *search;
772 char *property = NULL;
773 char *low = NULL;
774 char *high = NULL;
775 int property_len=0;
776 int low_len=0;
777 int high_len=0;
778 int rc;
779
780     if (argc != 3) {
781         WRONG_PARAM_COUNT;
782     }
783
784     if (zend_parse_parameters(argc TSRMLS_CC, "sss", &property, &property_len, &low, &low_len, &high, &high_len) == FAILURE)
785         return;
786
787     FETCH_SEARCH();
788     rc = SwishSetSearchLimit(search->swishe_search_handle, property, low, high);
789
790     RETURN_LONG((long)rc);
791 }
792 /* }}} */
793
794 /* {{{ proto void swishe_reset_search_limit()
795    SWISHE clears search limits */
796 PHP_FUNCTION(swishe_reset_search_limit)
797 {
798 int argc = ZEND_NUM_ARGS();
799 zval **id, **tmp;
800 php_swishe_search *search;
801
802     if (argc != 0) {
803         WRONG_PARAM_COUNT;
804     }
805
806     FETCH_SEARCH();
807     SwishResetSearchLimit(search->swishe_search_handle);
808 }
809 /* }}} */
810
811 /* {{{ proto void swishe_set_sort(string sort_string)
812    SWISHE clears search limits */
813 PHP_FUNCTION(swishe_set_sort)
814 {
815 int argc = ZEND_NUM_ARGS();
816 zval **id, **tmp;
817 php_swishe_search *search;
818 char *sort_string = NULL;
819 int sort_string_len = 0;
820 int rc;
821
822     if (argc != 1) {
823         WRONG_PARAM_COUNT;
824     }
825
826     if (zend_parse_parameters(argc TSRMLS_CC, "s", &sort_string, &sort_string_len) == FAILURE)
827         return;
828
829     FETCH_SEARCH();
830     SwishSetSort(search->swishe_search_handle, sort_string);
831 }
832 /* }}} */
833
834 /* {{{ proto object swishe_execute([string query])
835    SWISHE executes query */
836 PHP_FUNCTION(swishe_execute)
837 {
838 int argc = ZEND_NUM_ARGS();
839 zval **id, **tmp;
840 php_swishe_search *search;
841 php_swishe_results *results;
842 char *query = NULL;
843 int query_len = 0;
844
845     if (argc > 1) {
846         WRONG_PARAM_COUNT;
847     }
848
849     if (zend_parse_parameters(argc TSRMLS_CC, "|s", &query, &query_len) == FAILURE)
850         return;
851
852     FETCH_SEARCH();
853     results = (php_swishe_results *) emalloc(sizeof(php_swishe_results));
854     results->search = search;
855     results->swishe_handle = search->swishe_handle;
856     results->swishe_results_handle = SwishExecute( search->swishe_search_handle, query );
857     results->id = zend_list_insert(results,le_swishe_results);
858
859     object_init_ex(return_value, swishe_results_class_entry_ptr);
860     add_property_resource(return_value,"swishe_results_handle",results->id);
861 }
862 /* }}} */
863
864 /* {{{ proto long swishe_hits()
865    returns number of results */
866 PHP_FUNCTION(swishe_hits)
867 {
868 int argc = ZEND_NUM_ARGS();
869 zval **id, **tmp;
870 php_swishe_results *results;
871 long hits;
872
873
874     if (argc != 0) {
875         WRONG_PARAM_COUNT;
876     }
877
878     FETCH_RESULTS();
879     hits = SwishHits(results->swishe_results_handle);
880     RETURN_LONG(hits);
881 }
882 /* }}} */
883
884 /* {{{ proto array swishe_parsed_words(string index_name)
885    returns array of tokenized words and operators  */
886 PHP_FUNCTION(swishe_parsed_words)
887 {
888 int argc = ZEND_NUM_ARGS();
889 zval **id, **tmp;
890 php_swishe_results *results;
891 char *index_name = NULL;
892 int index_name_len = 0;
893 SWISH_HEADER_VALUE value;
894 char **parsed_words;
895
896     if (argc != 1) {
897         WRONG_PARAM_COUNT;
898     }
899     if (zend_parse_parameters(argc TSRMLS_CC, "s", &index_name, &index_name_len) == FAILURE)
900         return;
901
902     if(index_name_len)
903     {
904        FETCH_RESULTS();
905        value = SwishParsedWords(results->swishe_results_handle,index_name);
906        parsed_words = (char **)value.string_list;
907        if(array_init(return_value) != SUCCESS)
908        {
909            RETURN_NULL();
910        }
911        while ( *parsed_words )
912        {
913            add_next_index_string(return_value,(char *)*parsed_words,1);
914            parsed_words++;
915        }
916     }
917 }
918 /* }}} */
919
920 /* {{{ proto array swishe_removed_stopwords(string index_name)
921    returns array of removed stopwords */
922 PHP_FUNCTION(swishe_removed_stopwords)
923 {
924 int argc = ZEND_NUM_ARGS();
925 zval **id, **tmp;
926 php_swishe_results *results;
927 char *index_name = NULL;
928 int index_name_len = 0;
929 SWISH_HEADER_VALUE value;
930 char **removed_stopwords;
931
932     if (argc != 1) {
933         WRONG_PARAM_COUNT;
934     }
935     if (zend_parse_parameters(argc TSRMLS_CC, "s", &index_name, &index_name_len) == FAILURE)
936         return;
937
938     if(index_name_len)
939     {
940        FETCH_RESULTS();
941        value = SwishRemovedStopwords(results->swishe_results_handle,index_name);
942        removed_stopwords = (char **)value.string_list;
943        if(array_init(return_value) != SUCCESS)
944        {
945            RETURN_NULL();
946        }
947        while ( *removed_stopwords )
948        {
949            add_next_index_string(return_value,(char *)*removed_stopwords,1);
950            removed_stopwords++;
951        }
952     }
953 }
954 /* }}} */
955
956 /* {{{ proto bool swishe_seek_result(long position)
957    seeks to a result */
958 PHP_FUNCTION(swishe_seek_result)
959 {
960 int argc = ZEND_NUM_ARGS();
961 zval **id, **tmp;
962 php_swishe_results *results;
963 long position;
964 int rc;
965
966     if (argc != 1) {
967         WRONG_PARAM_COUNT;
968     }
969     if (zend_parse_parameters(argc TSRMLS_CC, "l", &position) == FAILURE)
970         return;
971
972     FETCH_RESULTS();
973     rc = SwishSeekResult(results->swishe_results_handle,position);
974     RETURN_LONG(rc);
975 }
976 /* }}} */
977
978 /* {{{ proto object swishe_next_result(void)
979    fetches a result and advances pointer */
980 PHP_FUNCTION(swishe_next_result)
981 {
982 int argc = ZEND_NUM_ARGS();
983 zval **id, **tmp;
984 php_swishe_results *results;
985 php_swishe_result *result;
986 void *r;
987
988     if (argc != 0) {
989         WRONG_PARAM_COUNT;
990     }
991
992     FETCH_RESULTS();
993     if(!(r = SwishNextResult(results->swishe_results_handle)))
994     {
995         RETURN_NULL();
996     }
997     result = (php_swishe_result *) emalloc(sizeof(php_swishe_result));
998     result->results = results;
999     result->swishe_handle = results->swishe_handle;
1000     result->swishe_result_handle = r;
1001     result->id = zend_list_insert(result,le_swishe_result);
1002
1003     object_init_ex(return_value, swishe_result_class_entry_ptr);
1004     add_property_resource(return_value,"swishe_result_handle",result->id);
1005 }
1006 /* }}} */
1007
1008 /* {{{ proto string swishe_property(string prop_name)
1009    reads a property from results */
1010 PHP_FUNCTION(swishe_property)
1011 {
1012 int argc = ZEND_NUM_ARGS();
1013 zval **id, **tmp;
1014 php_swishe_result *result;
1015 char *prop_name = NULL;
1016 int prop_name_len;
1017 PropValue *pv;
1018
1019     if (argc != 1) {
1020         WRONG_PARAM_COUNT;
1021     }
1022
1023     if (zend_parse_parameters(argc TSRMLS_CC, "s", &prop_name, &prop_name_len) == FAILURE)
1024         return;
1025
1026     FETCH_RESULT();
1027     if(!(pv = getResultPropValue( result->swishe_result_handle, prop_name, 0 )))
1028     {
1029         RETURN_NULL();
1030     }
1031     switch(pv->datatype)
1032     {
1033         case PROP_INTEGER:
1034             RETURN_LONG((long)pv->value.v_int);
1035             break;
1036         case PROP_ULONG:
1037             RETURN_LONG((long)pv->value.v_ulong);
1038             break;
1039         case PROP_STRING:
1040             RETURN_STRING(pv->value.v_str,1);
1041             break;
1042         case PROP_DATE:
1043             RETURN_LONG((long)pv->value.v_date);
1044             break;
1045         default:
1046             RETURN_NULL();
1047             break;
1048     }
1049 }
1050 /* }}} */
1051
1052 /* {{{ proto string swishe_result_index_value(string prop_name)
1053    returns header value based on the result */
1054 PHP_FUNCTION(swishe_result_index_value)
1055 {
1056 int argc = ZEND_NUM_ARGS();
1057 zval **id, **tmp;
1058 php_swishe_result *result;
1059 char *header_name = NULL;
1060 int header_name_len;
1061 SWISH_HEADER_TYPE  header_type;
1062 SWISH_HEADER_VALUE head_value;
1063 char **string_list;
1064
1065     if (argc != 1) {
1066         WRONG_PARAM_COUNT;
1067     }
1068
1069     if (zend_parse_parameters(argc TSRMLS_CC, "s", &header_name, &header_name_len) == FAILURE)
1070         return;
1071
1072     FETCH_RESULT();
1073     head_value = SwishResultIndexValue( result->swishe_result_handle, header_name, &header_type );
1074     /* Convert to data types and return */
1075     switch(header_type)
1076     {
1077         case SWISH_NUMBER:
1078             RETURN_LONG(head_value.number);
1079             break;
1080         case SWISH_STRING:
1081             RETUR