root/lang/perl/Text-Darts/trunk/Darts.xs @ 5359

Revision 3501, 2.6 kB (checked in by dankogai, 5 years ago)

v0.02; practical enough to PAUSE?

Line 
1#ifdef __cplusplus
2extern "C" {
3#endif
4#include "EXTERN.h"
5#include "perl.h"
6#include "XSUB.h"
7#ifdef __cplusplus
8}
9#endif
10
11#include <darts.h>
12#define MAX_NMATCH 1024
13
14int da_make(AV *av){
15    Darts::DoubleArray *dp = new Darts::DoubleArray;
16    std::vector <Darts::DoubleArray::key_type *> keys;
17    int i, l;
18    for (i = 0, l = av_len(av)+1; i < l; i++){
19        keys.push_back(SvPV_nolen(AvARRAY(av)[i]));
20    }
21    dp->build(keys.size(), &keys[0], 0, 0);
22    return PTR2IV(dp);
23}
24
25int da_free(int dpi){
26    delete INT2PTR(Darts::DoubleArray *, dpi);
27}
28
29int da_open(char *filename){
30    Darts::DoubleArray *dp = new Darts::DoubleArray;
31    if (dp->open(filename) == -1){
32        delete dp;
33        return 0;
34    }
35    return PTR2IV(dp);
36}
37
38int da_search(int dpi, char *str){
39    Darts::DoubleArray *dp = INT2PTR(Darts::DoubleArray *, dpi);
40    Darts::DoubleArray::result_pair_type  result_pair [MAX_NMATCH];
41    size_t num = dp->commonPrefixSearch(str, result_pair, sizeof(result_pair));
42    return num;
43}
44
45
46static SV *
47do_callback(SV *callback, SV *s){
48    dSP;
49    int argc;
50    SV *retval;
51    ENTER;
52    SAVETMPS;
53    PUSHMARK(sp);
54    XPUSHs(s);
55    PUTBACK;
56    argc = call_sv(callback, G_SCALAR);
57    SPAGAIN;
58    if (argc != 1){
59        croak("fallback sub must return scalar!");
60    }
61    retval = newSVsv(POPs);
62    PUTBACK;
63    FREETMPS;
64    LEAVE;
65    return retval;
66}
67
68SV *da_gsub(int dpi, SV *src, SV *callback){
69    SV *result = newSV(0);
70    Darts::DoubleArray *dp = INT2PTR(Darts::DoubleArray *, dpi);
71    Darts::DoubleArray::result_pair_type  result_pair[MAX_NMATCH];
72
73    char *head = SvPV_nolen(src);
74    char *tail = head + SvCUR(src);
75
76    while (head < tail) {
77        size_t size =
78            dp->commonPrefixSearch(head,result_pair, sizeof(result_pair));
79        size_t seekto = 0;       
80        if (size) {
81            for (size_t i = 0; i < size; ++i) {
82                if (seekto < result_pair[i].length)
83                    seekto = result_pair[i].length;
84            }
85            if (seekto) {
86                SV *ret = do_callback(callback, newSVpvn(head, seekto));
87                sv_catsv(result, ret);
88                head += seekto;
89            }
90        }
91        if (seekto == 0) {
92            sv_catpvn(result, head, 1);
93            ++head;
94        }
95    }
96    return result;
97}
98
99MODULE = Text::Darts            PACKAGE = Text::Darts           
100
101int
102xs_make(av)
103   AV *av
104CODE:
105   RETVAL = da_make(av);
106OUTPUT:
107   RETVAL
108
109int
110xs_free(dpi)
111    int  dpi;
112CODE:
113    RETVAL = da_free(dpi);
114OUTPUT:
115    RETVAL
116
117int
118xs_open(filename)
119   char *filename
120CODE:
121   RETVAL = da_open(filename);
122OUTPUT:
123   RETVAL
124
125SV *
126xs_gsub(dpi, src, callback)
127   int dpi;
128   SV *src;
129   SV *callback;
130CODE:
131   RETVAL = da_gsub(dpi, src, callback);
132OUTPUT:
133   RETVAL
134
135int
136xs_search(dpi, str)
137    int  dpi;
138    char *str;
139CODE:
140    RETVAL = da_search(dpi, str);
141OUTPUT:
142    RETVAL
Note: See TracBrowser for help on using the browser.