| 1 | #ifdef __cplusplus |
|---|
| 2 | extern "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 | |
|---|
| 14 | int 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 | |
|---|
| 25 | int da_free(int dpi){ |
|---|
| 26 | delete INT2PTR(Darts::DoubleArray *, dpi); |
|---|
| 27 | } |
|---|
| 28 | |
|---|
| 29 | int 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 | |
|---|
| 38 | int 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 | |
|---|
| 46 | static SV * |
|---|
| 47 | do_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 | |
|---|
| 68 | SV *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 | |
|---|
| 99 | MODULE = Text::Darts PACKAGE = Text::Darts |
|---|
| 100 | |
|---|
| 101 | int |
|---|
| 102 | xs_make(av) |
|---|
| 103 | AV *av |
|---|
| 104 | CODE: |
|---|
| 105 | RETVAL = da_make(av); |
|---|
| 106 | OUTPUT: |
|---|
| 107 | RETVAL |
|---|
| 108 | |
|---|
| 109 | int |
|---|
| 110 | xs_free(dpi) |
|---|
| 111 | int dpi; |
|---|
| 112 | CODE: |
|---|
| 113 | RETVAL = da_free(dpi); |
|---|
| 114 | OUTPUT: |
|---|
| 115 | RETVAL |
|---|
| 116 | |
|---|
| 117 | int |
|---|
| 118 | xs_open(filename) |
|---|
| 119 | char *filename |
|---|
| 120 | CODE: |
|---|
| 121 | RETVAL = da_open(filename); |
|---|
| 122 | OUTPUT: |
|---|
| 123 | RETVAL |
|---|
| 124 | |
|---|
| 125 | SV * |
|---|
| 126 | xs_gsub(dpi, src, callback) |
|---|
| 127 | int dpi; |
|---|
| 128 | SV *src; |
|---|
| 129 | SV *callback; |
|---|
| 130 | CODE: |
|---|
| 131 | RETVAL = da_gsub(dpi, src, callback); |
|---|
| 132 | OUTPUT: |
|---|
| 133 | RETVAL |
|---|
| 134 | |
|---|
| 135 | int |
|---|
| 136 | xs_search(dpi, str) |
|---|
| 137 | int dpi; |
|---|
| 138 | char *str; |
|---|
| 139 | CODE: |
|---|
| 140 | RETVAL = da_search(dpi, str); |
|---|
| 141 | OUTPUT: |
|---|
| 142 | RETVAL |
|---|