Beispiel #1
0
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;
}
Beispiel #2
0
EbmlElement *
kax_file_c::read_next_level1_element_internal(uint32_t wanted_id) {
  if (m_segment_end && (m_in->getFilePointer() >= m_segment_end))
    return nullptr;

  m_resynced         = false;
  m_resync_start_pos = 0;

  // Read the next ID.
  int64_t search_start_pos = m_in->getFilePointer();
  vint_c actual_id         = vint_c::read_ebml_id(m_in);
  m_in->setFilePointer(search_start_pos, seek_beginning);

  if (m_debug_read_next)
    mxinfo(boost::format("kax_file::read_next_level1_element(): search at %1% for %|4$x| act id %|2$x| is_valid %3%\n") % search_start_pos % actual_id.m_value % actual_id.is_valid() % wanted_id);

  // If no valid ID was read then re-sync right away. No other tests
  // can be run.
  if (!actual_id.is_valid())
    return resync_to_level1_element(wanted_id);


  // Easiest case: next level 1 element following the previous one
  // without any element inbetween.
  if (   (wanted_id == actual_id.m_value)
      || (   (0 == wanted_id)
          && (   is_level1_element_id(actual_id)
              || is_global_element_id(actual_id)))) {
    EbmlElement *l1 = read_one_element();
    if (l1)
      return l1;
  }

  // If a specific level 1 is wanted then look for next ID by skipping
  // other level 1 or special elements. If that files fallback to a
  // byte-for-byte search for the ID.
  if ((0 != wanted_id) && (is_level1_element_id(actual_id) || is_global_element_id(actual_id))) {
    m_in->setFilePointer(search_start_pos, seek_beginning);
    EbmlElement *l1 = read_one_element();

    if (l1) {
      int64_t element_size = get_element_size(l1);
      bool ok              = (0 != element_size) && m_in->setFilePointer2(l1->GetElementPosition() + element_size, seek_beginning);

      if (m_debug_read_next)
        mxinfo(boost::format("kax_file::read_next_level1_element(): other level 1 element %1% new pos %2% fsize %3% epos %4% esize %5%\n")
               % EBML_NAME(l1)  % (l1->GetElementPosition() + element_size) % m_file_size
               % l1->GetElementPosition() % element_size);

      delete l1;

      return ok ? read_next_level1_element(wanted_id) : nullptr;
    }
  }

  // Last case: no valid ID found. Try a byte-for-byte search for the
  // next wanted/level 1 ID. Also try to locate at least three valid
  // ID/sizes, not just one ID.
  m_in->setFilePointer(search_start_pos, seek_beginning);
  return resync_to_level1_element(wanted_id);
}