X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=ext%2FEncode%2Fencengine.c;h=4ea0667d0b79d8027971fb3a10b5cbf50c0fede9;hb=0bb78401313e0347fd894143d813c3036c2eccb4;hp=a73be737e2e07979ca96fedff054fbce3389ad10;hpb=017e2addf6da99b3f648d9518de5a848be394ab8;p=p5sagit%2Fp5-mst-13.2.git diff --git a/ext/Encode/encengine.c b/ext/Encode/encengine.c index a73be73..4ea0667 100644 --- a/ext/Encode/encengine.c +++ b/ext/Encode/encengine.c @@ -91,44 +91,68 @@ we add a flag to re-add the removed byte to the source we could handle #define U8 U8 #include "encode.h" -STRLEN -translate(encpage_t *enc, const U8 *src, STRLEN slen, U8 *dst, STRLEN dlen) +int +do_encode(encpage_t * enc, const U8 * src, STRLEN * slen, U8 * dst, + STRLEN dlen, STRLEN * dout, int approx, const U8 *term, STRLEN tlen) { - const U8 *send = src+slen; - U8 *dend = dst+dlen; - U8 *dptr = dst; - while (src < send) - { - encpage_t *e = enc; - U8 byte = *src++; - while (byte > e->max) - e++; - if (byte >= e->min) - { - STRLEN n = e->dlen; - if (n) - { - const U8 *out = e->seq+n*(byte - e->min); - STRLEN n = *out++; - if (dptr+n <= dend) - { - if (dst) - Copy(out,dptr,n,U8); - dptr += n; - } - else - { - /* No room */ - } - } - enc = e->next; + const U8 *s = src; + const U8 *send = s + *slen; + const U8 *last = s; + U8 *d = dst; + U8 *dend = d + dlen, *dlast = d; + int code = 0; + while (s < send) { + encpage_t *e = enc; + U8 byte = *s; + while (byte > e->max) + e++; + if (byte >= e->min && e->slen && (approx || !(e->slen & 0x80))) { + const U8 *cend = s + (e->slen & 0x7f); + if (cend <= send) { + STRLEN n; + if ((n = e->dlen)) { + const U8 *out = e->seq + n * (byte - e->min); + U8 *oend = d + n; + if (dst) { + if (oend <= dend) { + while (d < oend) + *d++ = *out++; + } + else { + /* Out of space */ + code = ENCODE_NOSPACE; + break; + } + } + else + d = oend; + } + enc = e->next; + s++; + if (s == cend) { + if (approx && (e->slen & 0x80)) + code = ENCODE_FALLBACK; + last = s; + if (term && (STRLEN)(d-dlast) == tlen && memEQ(dlast, term, tlen)) { + code = ENCODE_FOUND_TERM; + break; + } + dlast = d; + } + } + else { + /* partial source character */ + code = ENCODE_PARTIAL; + break; + } + } + else { + /* Cannot represent */ + code = ENCODE_NOREP; + break; + } } - else - { - /* Cannot represent */ - } - } - return dptr-dst; + *slen = last - src; + *dout = d - dst; + return code; } - -