예제 #1
0
파일: EbmlMaster.cpp 프로젝트: ares89/vlc
std::vector<std::string> EbmlMaster::FindAllMissingElements()
{	
	assert(Context.GetSize() != 0);

	std::vector<std::string> missingElements;

	for (size_t ChildElementNo = 0; ChildElementNo < ElementList.size(); ChildElementNo++) {
   		EbmlElement *childElement = ElementList[ChildElementNo];
		if (!childElement->ValueIsSet()) {
			std::string missingValue;
			missingValue = "The Child Element \"";
			missingValue.append(EBML_NAME(childElement));
			missingValue.append("\" of EbmlMaster \"");
			missingValue.append(EBML_NAME(this));
			missingValue.append("\", does not have a value set.");
			missingElements.push_back(missingValue);
		}

		if (childElement->IsMaster()) {
			EbmlMaster *childMaster = (EbmlMaster *)childElement;

			std::vector<std::string> childMissingElements = childMaster->FindAllMissingElements();
			for (size_t s = 0; s < childMissingElements.size(); s++)
				missingElements.push_back(childMissingElements[s]);
		}
	}
	unsigned int EltIdx;
	for (EltIdx = 0; EltIdx < EBML_CTX_SIZE(Context); EltIdx++) {
		if (EBML_CTX_IDX(Context,EltIdx).IsMandatory()) {
			if (FindElt(EBML_CTX_IDX_INFO(Context,EltIdx)) == NULL) {
				std::string missingElement;
				missingElement = "Missing element \"";
                missingElement.append(EBML_INFO_NAME(EBML_CTX_IDX_INFO(Context,EltIdx)));
				missingElement.append("\" in EbmlMaster \"");
                missingElement.append(EBML_INFO_NAME(*EBML_CTX_MASTER(Context)));
				missingElement.append("\"");
				missingElements.push_back(missingElement);
			}
		}
	}

	return missingElements;
}
예제 #2
0
파일: Ebml_parser.cpp 프로젝트: IAPark/vlc
EbmlElement *EbmlParser::Get( int n_call )
{
    int i_ulev = 0;
    EbmlElement *p_prev = NULL;

    if( mi_user_level != mi_level )
    {
        return NULL;
    }
    if( m_got )
    {
        EbmlElement *ret = m_got;
        m_got = NULL;

        return ret;
    }

    p_prev = m_el[mi_level];
    if( m_el[mi_level] )
    {
        m_el[mi_level]->SkipData( *m_es, EBML_CONTEXT(m_el[mi_level]) );

    }

    // If the parent is a segment, use the segment context when creating children
    // (to prolong their lifetime), otherwise just continue as normal
    EbmlSemanticContext e_context =
            EBML_CTX_MASTER( EBML_CONTEXT(m_el[mi_level - 1]) ) == EBML_CTX_MASTER( Context_KaxSegmentVLC )
            ? Context_KaxSegmentVLC
            : EBML_CONTEXT(m_el[mi_level - 1]);

    /* Ignore unknown level 0 or 1 elements */
    m_el[mi_level] = m_es->FindNextElement( e_context,
                                            i_ulev, UINT64_MAX,
                                            (  mb_dummy | (mi_level > 1) ), 1 );
    if( i_ulev > 0 )
    {
        if( p_prev )
        {
            if( !mb_keep )
            {
                if( MKV_IS_ID( p_prev, KaxBlockVirtual ) )
                    static_cast<KaxBlockVirtualWorkaround*>(p_prev)->Fix(); // !! WARNING : TODO !! this is undefined-behavior
                delete p_prev;
            }
            mb_keep = false;
        }
        while( i_ulev > 0 )
        {
            if( mi_level == 1 )
            {
                mi_level = 0;
                return NULL;
            }

            delete m_el[mi_level - 1];
            m_got = m_el[mi_level -1] = m_el[mi_level];
            m_el[mi_level] = NULL;

            mi_level--;
            i_ulev--;
        }
        return NULL;
    }
    else if( m_el[mi_level] == NULL )
    {
        msg_Dbg( p_demux,"MKV/Ebml Parser: m_el[mi_level] == NULL" );
    }
    else if( m_el[mi_level]->IsDummy() && !mb_dummy )
    {
        bool b_bad_position = false;
        /* We got a dummy element but don't want those...
         * perform a sanity check */
        if( !mi_level )
        {
            msg_Err(p_demux, "Got invalid lvl 0 element... Aborting");
            return NULL;
        }

        if( p_prev && p_prev->IsFiniteSize() &&
            p_prev->GetEndPosition() != m_el[mi_level]->GetElementPosition() &&
            mi_level > 1 )
        {
            msg_Err( p_demux, "Dummy Element at unexpected position... corrupted file?" );
            b_bad_position = true;
        }

        if( n_call < M_EL_MAXSIZE && !b_bad_position && m_el[mi_level]->IsFiniteSize() &&
            ( !m_el[mi_level-1]->IsFiniteSize() ||
              m_el[mi_level]->GetEndPosition() <= m_el[mi_level-1]->GetEndPosition() ) )
        {
            /* The element fits inside its upper element */
            msg_Warn( p_demux, "Dummy element found %" PRIu64 "... skipping it",
                      m_el[mi_level]->GetElementPosition() );
            return Get( ++n_call );
        }
        else
        {
            /* Too large, misplaced or M_EL_MAXSIZE successive dummy elements */
            msg_Err( p_demux,
                     "Dummy element too large or misplaced at %" PRIu64 "... skipping to next upper element",
                     m_el[mi_level]->GetElementPosition() );

            if( mi_level >= 1 &&
                m_el[mi_level]->GetElementPosition() >= m_el[mi_level-1]->GetEndPosition() )
            {
                msg_Err(p_demux, "This element is outside its known parent... upping level");
                delete m_el[mi_level - 1];
                m_got = m_el[mi_level -1] = m_el[mi_level];
                m_el[mi_level] = NULL;

                mi_level--;
                return NULL;
            }

            delete m_el[mi_level];
            delete p_prev;

            m_el[mi_level] = NULL;
            m_el[mi_level - 1]->SkipData( *m_es, EBML_CONTEXT(m_el[mi_level - 1]) );
            return Get();
        }
    }

    if( p_prev )
    {
        if( !mb_keep )
        {
            if( MKV_IS_ID( p_prev, KaxBlockVirtual ) )
                static_cast<KaxBlockVirtualWorkaround*>(p_prev)->Fix();
            delete p_prev;
        }
        mb_keep = false;
    }
    return m_el[mi_level];
}