size_t wxConvAuto::ToWChar(wchar_t *dst, size_t dstLen, const char *src, size_t srcLen) const { // we check BOM and create the appropriate conversion the first time we're // called but we also need to ensure that the BOM is skipped not only // during this initial call but also during the first call with non-NULL // dst as typically we're first called with NULL dst to calculate the // needed buffer size wxConvAuto *self = const_cast<wxConvAuto *>(this); if ( !m_conv ) { self->InitFromInput(&src, &srcLen); if ( dst ) self->m_consumedBOM = true; } if ( !m_consumedBOM && dst ) { self->m_consumedBOM = true; SkipBOM(&src, &srcLen); } // try to convert using the auto-detected encoding size_t rc = m_conv->ToWChar(dst, dstLen, src, srcLen); if ( rc == wxCONV_FAILED && m_bomType == BOM_None ) { // if the conversion failed but we didn't really detect anything and // simply tried UTF-8 by default, retry it using the fall-back if ( m_encDefault != wxFONTENCODING_MAX ) { if ( m_ownsConv ) delete m_conv; self->m_conv = new wxCSConv(m_encDefault == wxFONTENCODING_DEFAULT ? GetFallbackEncoding() : m_encDefault); self->m_ownsConv = true; rc = m_conv->ToWChar(dst, dstLen, src, srcLen); } } return rc; }
/***************************************************************************** * OpenDecoder: probe the decoder and return score ***************************************************************************** * Tries to launch a decoder and return score so that the interface is able * to chose. *****************************************************************************/ static int OpenDecoder( vlc_object_t *p_this ) { decoder_t *p_dec = (decoder_t*)p_this; decoder_sys_t *p_sys; vlc_value_t val; if( p_dec->fmt_in.i_codec != VLC_FOURCC('s','u','b','t') && p_dec->fmt_in.i_codec != VLC_FOURCC('s','s','a',' ') ) { return VLC_EGENERIC; } p_dec->pf_decode_sub = DecodeBlock; /* Allocate the memory needed to store the decoder's structure */ if( ( p_dec->p_sys = p_sys = (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL ) { msg_Err( p_dec, "out of memory" ); return VLC_ENOMEM; } /* init of p_sys */ p_sys->i_align = 0; p_sys->iconv_handle = (vlc_iconv_t)-1; p_sys->b_autodetect_utf8 = VLC_FALSE; p_sys->b_ass = VLC_FALSE; p_sys->i_original_height = -1; p_sys->i_original_width = -1; p_sys->pp_ssa_styles = NULL; p_sys->i_ssa_styles = 0; if( p_dec->fmt_in.subs.psz_encoding && *p_dec->fmt_in.subs.psz_encoding ) { msg_Dbg( p_dec, "using demux suggested character encoding: %s", p_dec->fmt_in.subs.psz_encoding ); if( strcmp( p_dec->fmt_in.subs.psz_encoding, "UTF-8" ) ) p_sys->iconv_handle = vlc_iconv_open( "UTF-8", p_dec->fmt_in.subs.psz_encoding ); } else { var_Create( p_dec, "subsdec-encoding", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); var_Get( p_dec, "subsdec-encoding", &val ); if( !strcmp( val.psz_string, DEFAULT_NAME ) ) { const char *psz_charset = GetFallbackEncoding(); p_sys->b_autodetect_utf8 = var_CreateGetBool( p_dec, "subsdec-autodetect-utf8" ); p_sys->iconv_handle = vlc_iconv_open( "UTF-8", psz_charset ); msg_Dbg( p_dec, "using fallback character encoding: %s", psz_charset ); } else if( !strcmp( val.psz_string, "UTF-8" ) ) { msg_Dbg( p_dec, "using enforced character encoding: UTF-8" ); } else if( val.psz_string ) { msg_Dbg( p_dec, "using enforced character encoding: %s", val.psz_string ); p_sys->iconv_handle = vlc_iconv_open( "UTF-8", val.psz_string ); if( p_sys->iconv_handle == (vlc_iconv_t)-1 ) { msg_Warn( p_dec, "unable to do requested conversion" ); } } if( val.psz_string ) free( val.psz_string ); } var_Create( p_dec, "subsdec-align", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); var_Get( p_dec, "subsdec-align", &val ); p_sys->i_align = val.i_int; if( p_dec->fmt_in.i_codec == VLC_FOURCC('s','s','a',' ') && var_CreateGetBool( p_dec, "subsdec-formatted" ) ) { if( p_dec->fmt_in.i_extra > 0 ) ParseSSAHeader( p_dec ); } return VLC_SUCCESS; }
size_t wxConvAuto::ToWChar(wchar_t *dst, size_t dstLen, const char *src, size_t srcLen) const { // we check BOM and create the appropriate conversion the first time we're // called but we also need to ensure that the BOM is skipped not only // during this initial call but also during the first call with non-NULL // dst as typically we're first called with NULL dst to calculate the // needed buffer size wxConvAuto *self = const_cast<wxConvAuto *>(this); if ( !m_conv ) { if ( !self->InitFromInput(src, srcLen) ) { // there is not enough data to determine whether we have a BOM or // not, so fail for now -- the caller is supposed to call us again // with more data return wxCONV_FAILED; } } if ( !m_consumedBOM ) { SkipBOM(&src, &srcLen); if ( srcLen == 0 ) { // there is nothing left except the BOM so we'd return 0 below but // this is unexpected: decoding a non-empty string must either fail // or return something non-empty, in particular this would break // the code in wxTextInputStream::NextChar() // // so still return an error as we need some more data to be able to // decode it return wxCONV_FAILED; } } // try to convert using the auto-detected encoding size_t rc = m_conv->ToWChar(dst, dstLen, src, srcLen); if ( rc == wxCONV_FAILED && m_bomType == BOM_None ) { // if the conversion failed but we didn't really detect anything and // simply tried UTF-8 by default, retry it using the fall-back if ( m_encDefault != wxFONTENCODING_MAX ) { if ( m_ownsConv ) delete m_conv; self->m_conv = new wxCSConv(m_encDefault == wxFONTENCODING_DEFAULT ? GetFallbackEncoding() : m_encDefault); self->m_ownsConv = true; rc = m_conv->ToWChar(dst, dstLen, src, srcLen); } } // don't skip the BOM again the next time if we really consumed it if ( rc != wxCONV_FAILED && dst && !m_consumedBOM ) self->m_consumedBOM = true; return rc; }