Encode

 view release on metacpan or  search on metacpan

Encode.xs  view on Meta::CPAN

#if ENCODE_XS_PROFILE >= 2
            Perl_warn(aTHX_
                  "more=%d, sdone=%d, sleft=%d, SvLEN(dst)=%d\n",
                  more, sdone, sleft, SvLEN(dst));
#endif
            if (sdone != 0) { /* has src ever been processed ? */
#if   ENCODE_XS_USEFP == 2
                more = (1.0*tlen*SvLEN(dst)+sdone-1)/sdone
                    - SvLEN(dst);
#elif ENCODE_XS_USEFP
                more = (STRLEN)((1.0*SvLEN(dst)+1)/sdone * sleft);
#else
            /* safe until SvLEN(dst) == MAX_INT/16 */
                more = (16*SvLEN(dst)+1)/sdone/16 * sleft;
#endif
            }
            more += UTF8_MAXLEN; /* insurance policy */
            d = (U8 *) SvGROW(dst, SvLEN(dst) + more);
            /* dst need to grow need MORE bytes! */
            if (ddone >= SvLEN(dst)) {
                Perl_croak(aTHX_ "Destination couldn't be grown.");
            }
            dlen = SvLEN(dst)-ddone-1;
            d   += ddone;
            s   += slen;
            slen = tlen-sdone;
            continue;
        }

    case ENCODE_NOREP:
        /* encoding */	
        if (dir == enc->f_utf8) {
        STRLEN clen;
        UV ch =
            utf8n_to_uvchr(s+slen, (tlen-sdone-slen),
                   &clen, UTF8_ALLOW_ANY|UTF8_CHECK_ONLY);
        /* if non-representable multibyte prefix at end of current buffer - break*/
        if (clen > tlen - sdone - slen) break;
        if (check & ENCODE_DIE_ON_ERR) {
            Perl_croak(aTHX_ ERR_ENCODE_NOMAP,
                   (UV)ch, enc->name[0]);
            return &PL_sv_undef; /* never reaches but be safe */
        }
        if (encode_ckWARN(check, WARN_UTF8)) {
            Perl_warner(aTHX_ packWARN(WARN_UTF8),
                ERR_ENCODE_NOMAP, (UV)ch, enc->name[0]);
        }
        if (check & ENCODE_RETURN_ON_ERR){
            goto ENCODE_SET_SRC;
        }
        if (check & (ENCODE_PERLQQ|ENCODE_HTMLCREF|ENCODE_XMLCREF)){
            STRLEN sublen;
            char *substr;
            SV* subchar = 
            (fallback_cb != &PL_sv_undef)
		? do_fallback_cb(aTHX_ ch, fallback_cb)
		: newSVpvf(check & ENCODE_PERLQQ ? "\\x{%04" UVxf "}" :
                 check & ENCODE_HTMLCREF ? "&#%" UVuf ";" :
                 "&#x%" UVxf ";", (UV)ch);
            substr = SvPV(subchar, sublen);
            if (SvUTF8(subchar) && sublen && !utf8_to_bytes((U8 *)substr, &sublen)) { /* make sure no decoded string gets in */
                SvREFCNT_dec(subchar);
                croak("Wide character");
            }
            sdone += slen + clen;
            ddone += dlen + sublen;
            sv_catpvn(dst, substr, sublen);
            SvREFCNT_dec(subchar);
        } else {
            /* fallback char */
            sdone += slen + clen;
            ddone += dlen + enc->replen;
            sv_catpvn(dst, (char*)enc->rep, enc->replen);
        }
        }
        /* decoding */
        else {
        if (check & ENCODE_DIE_ON_ERR){
            Perl_croak(aTHX_ ERR_DECODE_NOMAP,
                              enc->name[0], (UV)s[slen]);
            return &PL_sv_undef; /* never reaches but be safe */
        }
        if (encode_ckWARN(check, WARN_UTF8)) {
            Perl_warner(
            aTHX_ packWARN(WARN_UTF8),
            ERR_DECODE_NOMAP,
               	        enc->name[0], (UV)s[slen]);
        }
        if (check & ENCODE_RETURN_ON_ERR){
            goto ENCODE_SET_SRC;
        }
        if (check &
            (ENCODE_PERLQQ|ENCODE_HTMLCREF|ENCODE_XMLCREF)){
            STRLEN sublen;
            char *substr;
            SV* subchar = 
            (fallback_cb != &PL_sv_undef)
		? do_fallback_cb(aTHX_ (UV)s[slen], fallback_cb) 
		: newSVpvf("\\x%02" UVXf, (UV)s[slen]);
            substr = SvPVutf8(subchar, sublen);
            sdone += slen + 1;
            ddone += dlen + sublen;
            sv_catpvn(dst, substr, sublen);
            SvREFCNT_dec(subchar);
        } else {
            sdone += slen + 1;
            ddone += dlen + strlen(FBCHAR_UTF8);
            sv_catpvn(dst, FBCHAR_UTF8, strlen(FBCHAR_UTF8));
        }
        }
        /* settle variables when fallback */
        d    = (U8 *)SvEND(dst);
        dlen = SvLEN(dst) - ddone - 1;
        s    = sorig + sdone;
        slen = tlen - sdone;
        break;

        default:
            Perl_croak(aTHX_ "Unexpected code %d converting %s %s",
                   code, (dir == enc->f_utf8) ? "to" : "from",
                   enc->name[0]);

Encode.xs  view on Meta::CPAN

        /* Copy as far as was successful */
        Move(s, d, len, U8);
        d += len;
        s = (U8 *) e_or_where_failed;

        /* Are done if it was valid, or we are accepting partial characters and
         * the only error is that the final bytes form a partial character */
        if (    LIKELY(valid)
            || (   stop_at_partial
                && is_utf8_valid_partial_char_flags(s, e, flags)))
        {
            break;
        }

        /* Here, was not valid.  If is 'strict', and is legal extended UTF-8,
         * we know it is a code point whose value we can calculate, just not
         * one accepted under strict.  Otherwise, it is malformed in some way.
         * In either case, the system function can calculate either the code
         * point, or the best substitution for it */
        uv = utf8n_to_uvchr(s, e - s, &ulen, UTF8_ALLOW_ANY);

        /*
         * Here, we are looping through the input and found an error.
         * 'uv' is the code point in error if calculable, or the REPLACEMENT
         *      CHARACTER if not.
         * 'ulen' is how many bytes of input this iteration of the loop
         *        consumes */

        if (!encode && (check & (ENCODE_DIE_ON_ERR|ENCODE_WARN_ON_ERR|ENCODE_PERLQQ)))
            for (i=0; i<ulen; ++i) sprintf(esc+4*i, "\\x%02X", s[i]);
        if (check & ENCODE_DIE_ON_ERR){
            if (encode)
                Perl_croak(aTHX_ ERR_ENCODE_NOMAP, uv, (strict ? "UTF-8" : "utf8"));
            else
                Perl_croak(aTHX_ ERR_DECODE_STR_NOMAP, (strict ? "UTF-8" : "utf8"), esc);
        }
        if (encode_ckWARN(check, WARN_UTF8)) {
            if (encode)
                Perl_warner(aTHX_ packWARN(WARN_UTF8),
                            ERR_ENCODE_NOMAP, uv, (strict ? "UTF-8" : "utf8"));
            else
                Perl_warner(aTHX_ packWARN(WARN_UTF8),
                            ERR_DECODE_STR_NOMAP, (strict ? "UTF-8" : "utf8"), esc);
        }
        if (check & ENCODE_RETURN_ON_ERR) {
                break;
        }
        if (check & (ENCODE_PERLQQ|ENCODE_HTMLCREF|ENCODE_XMLCREF)){
            STRLEN sublen;
            char *substr;
            SV* subchar;
            if (encode) {
                subchar =
                    (fallback_cb != &PL_sv_undef)
                    ? do_fallback_cb(aTHX_ uv, fallback_cb)
                    : newSVpvf(check & ENCODE_PERLQQ
                        ? (ulen == 1 ? "\\x%02" UVXf : "\\x{%04" UVXf "}")
                        :  check & ENCODE_HTMLCREF ? "&#%" UVuf ";"
                        : "&#x%" UVxf ";", uv);
                substr = SvPV(subchar, sublen);
                if (SvUTF8(subchar) && sublen && !utf8_to_bytes((U8 *)substr, &sublen)) { /* make sure no decoded string gets in */
                    SvREFCNT_dec(subchar);
                    croak("Wide character");
                }
            } else {
                if (fallback_cb != &PL_sv_undef) {
                    /* in decode mode we have sequence of wrong bytes */
                    subchar = do_bytes_fallback_cb(aTHX_ s, ulen, fallback_cb);
                } else {
                    char *ptr = esc;
                    /* ENCODE_PERLQQ is already stored in esc */
                    if (check & (ENCODE_HTMLCREF|ENCODE_XMLCREF))
                        for (i=0; i<ulen; ++i) ptr += sprintf(ptr, ((check & ENCODE_HTMLCREF) ? "&#%u;" : "&#x%02X;"), s[i]);
                    subchar = newSVpvn(esc, strlen(esc));
                }
                substr = SvPVutf8(subchar, sublen);
            }
            dlen += sublen - ulen;
            SvCUR_set(dst, d-(U8 *)SvPVX(dst));
            *SvEND(dst) = '\0';
            sv_catpvn(dst, substr, sublen);
            SvREFCNT_dec(subchar);
            d = (U8 *) SvGROW(dst, dlen) + SvCUR(dst);
        } else {
            STRLEN fbcharlen = strlen(FBCHAR_UTF8);
            dlen += fbcharlen - ulen;
            if (SvLEN(dst) < dlen) {
                SvCUR_set(dst, d-(U8 *)SvPVX(dst));
                d = (U8 *) sv_grow(dst, dlen) + SvCUR(dst);
            }
            memcpy(d, FBCHAR_UTF8, fbcharlen);
            d += fbcharlen;
        }
        s += ulen;
    }
    SvCUR_set(dst, d-(U8 *)SvPVX(dst));
    *SvEND(dst) = '\0';

    return s;
}

static SV *
find_encoding(pTHX_ SV *enc)
{
    dSP;
    I32 count;
    SV *m_enc;
    SV *obj = &PL_sv_undef;
#ifndef SV_NOSTEAL
    U32 tmp;
#endif

    ENTER;
    SAVETMPS;
    PUSHMARK(sp);

    m_enc = sv_newmortal();
#ifndef SV_NOSTEAL
    tmp = SvFLAGS(enc) & SVs_TEMP;
    SvTEMP_off(enc);
    sv_setsv_flags(m_enc, enc, 0);



( run in 0.557 second using v1.01-cache-2.11-cpan-3c2a17b8caa )