/* Namazu.xs # Copyright (C) 1999-2006 NOKUBI Takatsugu All rights reserved. # This is free software with ABSOLUTELY NO WARRANTY. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA $Id: Namazu.xs 268 2006-06-09 05:48:57Z knok $ */ #ifdef __cplusplus extern "C" { #endif #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include #include #include #include #include #include #include #include #include #include #include #ifdef __cplusplus } #endif /* for old perl (< 5.004_04?) */ #if !defined(PL_na) && defined(na) #define PL_na na #endif #if !defined(PL_sv_undef) && defined(sv_undef) #define PL_sv_undef sv_undef #endif #if !defined(SvPV_nolen) /* for perl 5.005 */ #define SvPV_nolen(x) SvPV(x, PL_na) #endif #define SEARCH_NAMAZU_FIELDS 5 #define SCORE "//score" #define SCORE_LEN strlen(SCORE) #define DATE "//date" #define DATE_LEN strlen(DATE) #define RANK "//rank" #define RANK_LEN strlen(RANK) #define DOCID "//docid" #define DOCID_LEN strlen(DOCID) #define IDXID "//idxid" #define IDXID_LEN strlen(IDXID) static int status = 0; AV * call_search_main_c(char *query, int maxget) { AV *retar; NmzResult hlist; char result[SEARCH_NAMAZU_FIELDS][BUFSIZE]; int i; status = 0; retar = newAV(); hlist = nmz_search(query); av_extend(retar, hlist.num - 1); status = hlist.stat; for (i = 0; i < hlist.num; i ++) { if (i < maxget) { SV *ohlist = perl_eval_pv("new Search::Namazu::Result", TRUE); dSP; nmz_get_field_data(hlist.data[i].idxid, hlist.data[i].docid, "uri", result[0]); nmz_get_field_data(hlist.data[i].idxid, hlist.data[i].docid, "summary", result[1]); nmz_get_field_data(hlist.data[i].idxid, hlist.data[i].docid, "title", result[2]); nmz_get_field_data(hlist.data[i].idxid, hlist.data[i].docid, "author", result[3]); nmz_get_field_data(hlist.data[i].idxid, hlist.data[i].docid, "size", result[4]); ENTER; SAVETMPS; PUSHMARK(SP); PUSHs(ohlist); PUSHs(sv_2mortal(newSViv(hlist.data[i].score))); PUSHs(sv_2mortal(newSVpv(result[0], strlen(result[0])))); PUSHs(sv_2mortal(newSViv(hlist.data[i].date))); PUSHs(sv_2mortal(newSViv(hlist.data[i].rank))); PUSHs(sv_2mortal(newSVpv(result[1], strlen(result[1])))); PUSHs(sv_2mortal(newSVpv(result[2], strlen(result[2])))); PUSHs(sv_2mortal(newSVpv(result[3], strlen(result[3])))); PUSHs(sv_2mortal(newSVpv(result[4], strlen(result[4])))); PUTBACK; perl_call_method("set", G_DISCARD); SvREFCNT_inc(ohlist); av_store(retar, i, ohlist); FREETMPS; LEAVE; } else { av_store(retar, i, &PL_sv_undef); } } nmz_free_hlist(hlist); return retar; } AV * call_search_main_fields_c(char *query, int maxget, AV *fields) { AV *retar; HV *stash; char **fstr; int *fsize; NmzResult hlist; int i; int flen; retar = newAV(); flen = av_len(fields); if (flen < 0 || maxget <= 0 || query == NULL) return retar; status = 0; fstr = (char **) malloc(sizeof(char *) * (flen + 1)); fsize = (int *) malloc(sizeof(int) * (flen + 1)); for (i = 0; i <= flen; i ++) { SV **x; x = av_fetch(fields, i, 0); fstr[i] = SvPV_nolen(*x); fsize[i] = SvCUR(*x); } hlist = nmz_search(query); av_extend(retar, hlist.num - 1); status = hlist.stat; stash = gv_stashpv("Search::Namazu::ResultXS", 0); for (i = 0; i < hlist.num; i ++) { if (i < maxget) { HV *hash; SV *ref; SV *score, *date, *rank, *docid, *idxid; int j; char fcont[BUFSIZE]; hash = newHV(); for (j = 0; j <= flen; j ++) { nmz_get_field_data(hlist.data[i].idxid, hlist.data[i].docid, fstr[j], fcont); hv_store(hash, fstr[j], fsize[j], newSVpv(fcont, strlen(fcont)), 0); } score = newSViv(hlist.data[i].score); date = newSViv(hlist.data[i].date); rank = newSViv(hlist.data[i].rank); docid = newSViv(hlist.data[i].docid); idxid = newSViv(hlist.data[i].idxid); hv_store(hash, SCORE, SCORE_LEN, score, 0); hv_store(hash, DATE, DATE_LEN, date, 0); hv_store(hash, RANK, RANK_LEN, rank, 0); hv_store(hash, DOCID, IDXID_LEN, docid, 0); hv_store(hash, IDXID, IDXID_LEN, idxid, 0); ref = newRV_inc((SV*) hash); sv_bless(ref, stash); av_store(retar, i, ref); } else { av_store(retar, i, &PL_sv_undef); } } nmz_free_hlist(hlist); free(fstr); free(fsize); return retar; } MODULE = Search::Namazu PACKAGE = Search::Namazu PROTOTYPES: DISABLE void call_search_main(query, maxget) SV *query int maxget PPCODE: char *qstr; char buffer[BUFSIZE]; char cqstr[BUFSIZE * 2]; AV *retar; int i; qstr = SvPV(query, PL_na); strncpy(buffer, qstr, BUFSIZE); buffer[BUFSIZE - 1] = '\0'; nmz_codeconv_query(buffer); strcpy(cqstr, buffer); retar = call_search_main_c(cqstr, maxget); #if ! defined(PERL_VERSION) || (PERL_VERSION == 6 && PERL_SUBVERSION == 0) { /* workaround for only one result */ SPAGAIN; } #endif /* PERL_VERSION */ while (av_len(retar) >= 0) { XPUSHs(av_shift(retar)); } nmz_free_internal(); SV* call_search_main_ref(query, maxget) SV *query int maxget CODE: char *qstr; char buffer[BUFSIZE]; char cqstr[BUFSIZE * 2]; AV *retar; int i; qstr = SvPV(query, PL_na); strncpy(buffer, qstr, BUFSIZE); buffer[BUFSIZE - 1] = '\0'; nmz_codeconv_query(buffer); strcpy(cqstr, buffer); retar = call_search_main_c(cqstr, maxget); nmz_free_internal(); RETVAL = newRV_inc((SV*) retar); OUTPUT: RETVAL SV* call_search_main_fields(query, maxget, fieldref) SV *query int maxget SV *fieldref CODE: char *qstr; char buffer[BUFSIZE]; char cqstr[BUFSIZE * 2]; AV *retar; AV *fields; int i; fields = (AV *) SvRV(fieldref); qstr = SvPV(query, PL_na); strncpy(buffer, qstr, BUFSIZE); buffer[BUFSIZE - 1] = '\0'; nmz_codeconv_query(buffer); strcpy(cqstr, buffer); retar = call_search_main_fields_c(cqstr, maxget, fields); nmz_free_internal(); RETVAL = newRV_inc((SV*) retar); OUTPUT: RETVAL int nmz_addindex(index) SV *index PREINIT: char *tmp; CODE: tmp = SvPV(index, PL_na); RETVAL = nmz_add_index(tmp); OUTPUT: RETVAL void nmz_sortbydate() CODE: nmz_set_sortmethod(SORT_BY_DATE); void nmz_sortbyscore() CODE: nmz_set_sortmethod(SORT_BY_SCORE); void nmz_setsortfield(field) SV * field CODE: nmz_set_sortfield(SvPV_nolen(field)); void nmz_sortbyfield() CODE: nmz_set_sortmethod(SORT_BY_FIELD); void nmz_descendingsort() CODE: nmz_set_sortorder(DESCENDING); void nmz_ascendingsort() CODE: nmz_set_sortorder(ASCENDING); int nmz_setlang(lang) SV *lang PREINIT: char *tmp; CODE: tmp = SvPV(lang, PL_na); RETVAL = nmz_set_lang(tmp); OUTPUT: RETVAL void nmz_setmaxhit(max) int max CODE: nmz_set_maxhit(max); int nmz_getstatus() CODE: RETVAL = status; OUTPUT: RETVAL MODULE = Search::Namazu PACKAGE = Search::Namazu::ResultXS PREFIX = res_ SV * res_new() CODE: HV *self; HV *stash; SV *ref; stash = gv_stashpv("Search::Namazu::ResultXS", 0); self = newHV(); ref = newRV_inc((SV*) self); sv_bless(ref, stash); RETVAL = ref; OUTPUT: RETVAL void res_set(self, key, val) SV *self SV *key SV *val CODE: HV *hash; hash = (HV *) SvRV(self); hv_store(hash, SvPV_nolen(key), SvCUR(key), val, 0); SV * res_get(self, key) SV *self SV *key CODE: HV *hash; SV **ret; hash = (HV *) SvRV(self); ret = hv_fetch(hash, SvPV_nolen(key), SvCUR(key), 0); if (ret == NULL) { RETVAL = &PL_sv_undef; } else { RETVAL = SvREFCNT_inc(*ret); } OUTPUT: RETVAL SV * res_score(self) SV *self CODE: HV *hash; SV **ret; hash = (HV *) SvRV(self); ret = hv_fetch(hash, SCORE, SCORE_LEN, 0); if (ret == NULL) { RETVAL = &PL_sv_undef; } else { RETVAL = SvREFCNT_inc(*ret); } OUTPUT: RETVAL SV * res_date(self) SV *self CODE: HV *hash; SV **ret; hash = (HV *) SvRV(self); ret = hv_fetch(hash, DATE, DATE_LEN, 0); if (ret == NULL) { RETVAL = &PL_sv_undef; } else { RETVAL = SvREFCNT_inc(*ret); } OUTPUT: RETVAL SV * res_rank(self) SV *self CODE: HV *hash; SV **ret; hash = (HV *) SvRV(self); ret = hv_fetch(hash, RANK, RANK_LEN, 0); if (ret == NULL) { RETVAL = &PL_sv_undef; } else { RETVAL = SvREFCNT_inc(*ret); } OUTPUT: RETVAL SV * res_docid(self) SV *self CODE: HV *hash; SV **ret; hash = (HV *) SvRV(self); ret = hv_fetch(hash, DOCID, DOCID_LEN, 0); if (ret == NULL) { RETVAL = &PL_sv_undef; } else { RETVAL = SvREFCNT_inc(*ret); } OUTPUT: RETVAL SV * res_idxid(self) SV *self CODE: HV *hash; SV **ret; hash = (HV *) SvRV(self); ret = hv_fetch(hash, IDXID, IDXID_LEN, 0); if (ret == NULL) { RETVAL = &PL_sv_undef; } else { RETVAL = SvREFCNT_inc(*ret); } OUTPUT: RETVAL