Assorted 2.15 fixes.
[p5sagit/p5-mst-13.2.git] / ext / Encode / encengine.c
index a73be73..4ea0667 100644 (file)
@@ -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;
 }
-
-