Deep-Encode
view release on metacpan or search on metacpan
inline bool is_utf8(char *z, STRLEN m){
return _is_utf8( (U8 *)(z), (U8*)(z + m));
}
typedef struct pp_args{
char type;
char fastinit;
int noskip;
int argc;
int str_pos;
int counter;
char *method;
CV *meth1;
CV *meth2;
p_callback callback;
SV* argv[10 + 2];
} *pp_func;
void utf8_check_encoding_cb( pp_func pf, SV *data){
char *ptr;
STRLEN data_len;
if (!pf->counter)
return;
ptr = SvPV( data, data_len);
if (!is_utf8( ptr, data_len ))
pf->counter = 0;
}
void utf8_upgrade_cb( pp_func pf, SV * data){
if (!SvUTF8(data)){
(void) sv_utf8_upgrade( data );
++(pf->counter);
};
}
void utf8_downgrade_cb( pp_func pf, SV * data){
if (SvUTF8(data)){
(void) sv_utf8_downgrade( data , 0);
++(pf->counter);
};
}
void utf8_off_cb( pp_func pf, SV * data){
if (SvUTF8(data)){
SvUTF8_off(data);
++(pf->counter);
};
}
void utf8_on_cb( pp_func pf, SV * data){
if (!SvUTF8(data)){
SvUTF8_on(data);
++(pf->counter);
}
}
void from_to_cb( pp_func pf, SV * data){
int ret_list_size;
SV *decoded_sv;
dSP;
ENTER;
SAVETMPS;
if ( ! pf->fastinit ){
GV * method_glob;
HV * encoding_stash;
pf->meth1 = 0;
pf->meth2 = 0;
pf->fastinit = -1;
encoding_stash = SvSTASH( SvRV( pf->argv[0] ) );
method_glob = gv_fetchmeth( encoding_stash, "decode", 6, 0 );
pf->meth1 = GvCV( method_glob );
encoding_stash = SvSTASH( SvRV( pf->argv[1] ) );
method_glob = gv_fetchmeth( encoding_stash, "encode", 6, 0 );
pf->meth2 = GvCV( method_glob );
if ( pf->meth1 && pf->meth2 ){
pf->fastinit = 1;
};
};
PUSHMARK(SP);
XPUSHs( pf->argv[0] ); /*first encoding */
XPUSHs( data );
PUTBACK;
if ( pf->fastinit == 1 ){
ret_list_size = call_sv( (SV *) pf->meth1, G_SCALAR);
}
else {
ret_list_size = call_method("decode", G_SCALAR);
};
SPAGAIN;
if (ret_list_size != 1){
croak( "A big trouble");
}
decoded_sv = POPs;
PUTBACK;
PUSHMARK(SP);
XPUSHs( pf->argv[1] );
XPUSHs( decoded_sv );
PUTBACK;
if ( pf->fastinit == 1 ){
ret_list_size = call_sv( (SV *) pf->meth2, G_SCALAR);
}
else {
ret_list_size = call_method("encode", G_SCALAR);
}
SPAGAIN;
if (ret_list_size != 1){
croak( "A big trouble");
}
decoded_sv = POPs;
sv_setsv( data , decoded_sv );
PUTBACK;
FREETMPS;
LEAVE;
}
void from_to_cb_00( pp_func pf, SV * data){
int ret_list_size;
SV *decoded_sv;
dSP;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs( pf->argv[0] ); /*first encoding */
XPUSHs( data );
PUTBACK;
ret_list_size = call_method("decode", G_SCALAR);
SPAGAIN;
if (ret_list_size != 1){
croak( "A big trouble");
}
decoded_sv = POPs;
PUTBACK;
PUSHMARK(SP);
XPUSHs( pf->argv[1] );
XPUSHs( decoded_sv );
PUTBACK;
ret_list_size = call_method("encode", G_SCALAR);
SPAGAIN;
if (ret_list_size != 1){
croak( "A big trouble");
}
decoded_sv = POPs;
sv_setsv( data , decoded_sv );
PUTBACK;
FREETMPS;
LEAVE;
}
/*static U8* good_encoding=",cp1251,latin1,utf8,windows1251,cp866,"; */
SV *find_encoding(pp_func pfunc, SV* encoding )
{
int ret_list;
SV *enc_obj;
dSP;
enc_obj = 0;
if ( SvROK(encoding) && sv_isobject( encoding )) {
enc_obj = encoding;
};
if ( !enc_obj ) {
PUSHMARK(SP);
XPUSHs(encoding);
PUTBACK;
ret_list = call_pv("Encode::find_encoding", G_SCALAR);
SPAGAIN;
if (ret_list != 1)
croak( "Big trouble with Encode::find_encoding");
enc_obj = POPs;
if (!SvOK(enc_obj)) {
if ( SvPOK(encoding) )
croak("Unknown encoding '%.*s'", SvCUR(encoding), SvPV_nolen(encoding));
else
croak("Unknown encoding ??? (is not string)");
};
PUTBACK;
};
if (! pfunc->noskip ){
SV *name_sv;
char *name;
STRLEN name_len;
PUSHMARK(SP);
XPUSHs(enc_obj);
PUTBACK;
ret_list = call_method("name", G_SCALAR);
SPAGAIN;
if (ret_list != 1)
croak( "Big trouble with Encode::find_encoding");
name_sv = POPs;
PUTBACK;
name = SvPV(name_sv, name_len);
switch( name_len ){
case 6:
if (strEQ("cp1251", name ))
return enc_obj;
break;
case 5:
if (strEQ("cp866", name ))
return enc_obj;
break;
( run in 0.558 second using v1.01-cache-2.11-cpan-2398b32b56e )