Пример #1
0
//! Scan a metadata object for strong references in sub-objects and add those to this partition
void Partition::AddMetadataSubs(MDObjectPtr &NewObject, bool ForceFirst)
{
	MDObjectULList::iterator it = NewObject->begin();
	MDObjectULList::iterator itend = NewObject->end();
	while(it != itend)
	{
		if((*it).second->GetRefType() == DICT_REF_STRONG)
		{
			MDObjectPtr Link = (*it).second->GetLink();
			if(Link)
			{
				AddMetadata(Link, ForceFirst);

				// Prevent the new item being top-level (which it may be as we are not added yet)
				// DRAGONS: There is surely a better way than this!!
				TopLevelMetadata.remove(Link);
			}
		}
		else if(!((*it).second->empty()))
		{
			AddMetadataSubs((*it).second, ForceFirst);
		}
		it++;
	}
}
Пример #2
0
/*! Note that any strongly linked objects are also added */
void mxflib::Partition::AddMetadata(MDObjectPtr NewObject, bool ForceFirst /*=false*/)
{
	// Start out without a target
	bool has_target = false;

	// Start out not (strong) reffed
	bool linked = false;

	// Add us to the list of all items - done last if forcing first as the child items will get added first
	if(!ForceFirst) AllMetadata.push_back(NewObject);

	// Add this object to the ref target list if it is one. At the same time any objects
	// linked from this object (before this function was called) are added as well
	// Note: although nothing currently does it it is theoretically possible to
	//       have more than one target entry in a set
	MDObjectULList::iterator it = NewObject->begin();
	while(it != NewObject->end())
	{
		ClassRef RefType = (*it).second->GetRefType();

		if(RefType == ClassRefTarget)
		{
			if((*it).second->Value->GetData().Size != 16)
			{
				error("Metadata Object \"%s/%s\" should be a reference target (a UUID), but has size %d\n",
					  NewObject->Name().c_str(), (*it).second->Name().c_str(), (*it).second->Value->GetData().Size);
			}
			else
			{
				has_target = true;

				UUIDPtr ID = new UUID((*it).second->Value->PutData()->Data);
				RefTargets.insert(std::map<UUID, MDObjectPtr>::value_type(*ID, NewObject));

				// Try and satisfy all refs to this set
				for(;;)
				{
					std::multimap<UUID, MDObjectPtr>::iterator mit = UnmatchedRefs.find(*ID);

					// Exit when no more refs to this object
					if(mit == UnmatchedRefs.end()) break;

					// Sanity check!
					if((*mit).second->GetLink())
					{
						error("Internal error - %s at 0x%s in UnmatchedRefs but already linked!\n", (*mit).second->FullName().c_str() , Int64toHexString((*mit).second->GetLocation(), 8).c_str());
					}

					// Make the link
					(*mit).second->SetLink(NewObject);

					// If we are the tagert of a strong ref we won't get added to the top level
					if((*mit).second->GetRefType() == DICT_REF_STRONG) linked = true;

					// Remove from the unmatched refs map
					UnmatchedRefs.erase(mit);

					// loop for any more refs to this set
				}
			}
		}
		else if(RefType == ClassRefStrong)
		{
			MDObjectPtr Link = (*it).second->GetLink();
			if(Link)
			{
				AddMetadata(Link, ForceFirst);

				// Prevent the new item being top-level (which it may be as we are not added yet)
				// DRAGONS: There is surely a better way than this!!
				TopLevelMetadata.remove(Link);
			}
			// If this item is not a link, it may contain links
			else if((*it).second->size())
			{
				MDObject::iterator subit = (*it).second->begin();
				while(subit != (*it).second->end())
				{
					Link = (*subit).second->GetLink();
					if(Link)
					{
						AddMetadata(Link, ForceFirst);

						// Prevent the new item being top-level (which it may be as we are not added yet)
						// DRAGONS: There is surely a better way than this!!
						TopLevelMetadata.remove(Link);
					}
					subit++;
				}
			}
		} 
		else if(!((*it).second->empty()))
		{
			AddMetadataSubs((*it).second, ForceFirst);
		}

		it++;
	}

	// Add any forced-first items after thier children
	if(ForceFirst) AllMetadata.push_front(NewObject);

	// If we are not yet (strong) reffed then we are top level
	if(!linked)
	{
		if(ForceFirst) TopLevelMetadata.push_front(NewObject);
		else TopLevelMetadata.push_back(NewObject);
	}

	// Satisfy, or record as un-matched, all outgoing references
	ProcessChildRefs(NewObject);
}
Пример #3
0
//! Load any metadictionaties that are in the list of currently loaded objects
bool mxflib::Partition::LoadMetadict(void)
{
	bool Ret = true;

	/* Search for the metadictionary */
	MDObjectList::iterator it = AllMetadata.begin();
	while(it != AllMetadata.end())
	{
		if((*it)->IsA(MetaDictionary_UL))
		{
			/* We need to set up a symbol space for this metadictionary
			   At the moment we attach it to one named with the instance ID of this metadictionary item */
			std::string SymSpaceName = (*it)->GetString(InstanceUID_UL);

			// If there was no InstanceUID, add a random symspace
			if(SymSpaceName.empty()) SymSpaceName = RandomUL()->GetString();
			
			// See if we already have this symbol space (may have already loaded a copy of this metadictionary) - if not, build it
            SymbolSpacePtr SymSpace = SymbolSpace::FindSymbolSpace(SymSpaceName);
			if(!SymSpace) SymSpace = new SymbolSpace(SymSpaceName);
			
			// Load the metdictionary and update the running status
			if(!LoadMetadictionary(*it, SymSpace)) Ret = false;
		}
		else if((*it)->IsA(Root_UL))
		{
			// FIXME: Use UL when ready
			//MDObjectPtr RootExtensions = (*it)->Child(RootExtensions_UL);
			MDObjectPtr RootExtensions = (*it)->Child("RootExtensions");
			if(RootExtensions)
			{
				MDObject::iterator Ext_it = RootExtensions->begin();
				while(Ext_it != RootExtensions->end())
				{
					// Get the actual data group
					MDObjectPtr ExtensionGroup = (*Ext_it).second->GetRef();

					if(!ExtensionGroup)
					{
						error("Broken link in ExtensionGroup reference at %s\n", (*Ext_it).second->GetSourceLocation().c_str());
					}
					else
					{
						/* We need to set up a symbol space for this metadictionary */
						// FIXME: Use UL when ready
						//std::string SymSpaceName = ExtensionGroup->GetString(SymbolSpace_UL);
						std::string SymSpaceName = ExtensionGroup->GetString("SymbolSpace");

						// If there was no SymbolSpace property, add a random symspace
						if(SymSpaceName.empty()) SymSpaceName = RandomUL()->GetString();
						
						// See if we already have this symbol space (may have already loaded a copy of this metadictionary) - if not, build it
						SymbolSpacePtr SymSpace = SymbolSpace::FindSymbolSpace(SymSpaceName);
						if(!SymSpace) SymSpace = new SymbolSpace(SymSpaceName);
						
						// Load the metdictionary and update the running status
						if(!LoadMetadictionary(ExtensionGroup, SymSpace)) Ret = false;
					}

					Ext_it++;
				}
			}
		}

		it++;
	}

	return Ret;
}
Пример #4
0
//! Satisfy, or record as un-matched, all outgoing references
void mxflib::Partition::ProcessChildRefs(MDObjectPtr ThisObject)
{
	MDObjectULList::iterator it = ThisObject->begin();
	while(it != ThisObject->end())
	{
		// Only try to match references if not already matched
		if(!(*it).second->GetLink())
		{
			ClassRef Ref = (*it).second->GetRefType();
			if(IsRefSource(Ref))
			{
				if(!(*it).second->Value)
				{
					if(Ref != ClassRefGlobal)
					{
						error("Metadata Object \"%s/%s\" should be a reference source (a UUID), but has no valid value\n",
							  ThisObject->Name().c_str(), (*it).second->Name().c_str());
					}
				}
				// Container for child items
				else if((*it).second->Value->GetData().Size == 0)
				{
					// Recurse to add refs for our children
					if((*it).second->size()) ProcessChildRefs((*it).second);
				}
				else if((*it).second->Value->GetData().Size != 16)
				{
					if(Ref == ClassRefGlobal)
					{
						error("Metadata Object \"%s/%s\" should be a global reference (a UL or UUID), but has size %d\n",
							  ThisObject->Name().c_str(), (*it).second->Name().c_str(), (*it).second->Value->GetData().Size);
					}
					else
					{
						error("Metadata Object \"%s/%s\" should be a reference source (a UUID), but has size %d\n",
							  ThisObject->Name().c_str(), (*it).second->Name().c_str(), (*it).second->Value->GetData().Size);
					}
				}
				else
				{
					UUIDPtr ID = new UUID((*it).second->Value->PutData()->Data);
					std::map<UUID, MDObjectPtr>::iterator mit = RefTargets.find(*ID);

					if(mit == RefTargets.end())
					{
						// Not matched yet, so add to the list of outstanding refs
						UnmatchedRefs.insert(std::multimap<UUID, MDObjectPtr>::value_type(*ID, (*it).second));
					}
					else
					{
						// Make the link
						(*it).second->SetLink((*mit).second);

						// If we have made a strong ref, remove the target from the top level
						if(Ref == DICT_REF_STRONG) TopLevelMetadata.remove((*mit).second);
					}
				}
			}
		}

		it++;
	}
}
Пример #5
0
//! Dump an object and any physical or logical children
void DumpObject(MDObjectPtr Object, std::string Prefix)
{
	if(DumpLocation) printf("0x%s : ", Int64toHexString(Object->GetLocation(),8).c_str());

	if(Object->IsModified()) printf("%s%s is *MODIFIED*\n", Object->FullName().c_str(), Prefix.c_str() );

#ifdef OPTION3ENABLED
	if(ShowBaseline)
	{
		if(!Object->IsBaseline())
		{
			if(Object->GetBaselineUL())
			{
				MDOTypePtr BaselineClass = MDOType::Find(Object->GetBaselineUL());
				if(BaselineClass)
				{
					printf("%sBaseline: %s\n", Prefix.c_str(), BaselineClass->Name().c_str());
				}
				else
				{
					printf("%sNote: Current dictionary does not contain a set with the baseline UL used to wrap this non-baseline class\n", Prefix.c_str());
					printf("%sBaseline: %s\n", Prefix.c_str(), Object->GetBaselineUL()->GetString().c_str());
				}
				Prefix += "  ";
			}
			else
			{
				printf("%sNote: Current dictionary flags this class as non-baseline, but it is not wrapped in a baseline class\n", Prefix.c_str());
			}
		}
		else
		{
			if(Object->GetBaselineUL())
			{
				printf("%sNote: Current dictionary flags this class as baseline, but it is wrapped as a non-baseline class\n", Prefix.c_str());

				MDOTypePtr BaselineClass = MDOType::Find(Object->GetBaselineUL());
				if(BaselineClass)
				{
					printf("%sBaseline: %s\n", Prefix.c_str(), BaselineClass->Name().c_str());
				}
				else
				{
					printf("%sNote: Current dictionary does not contain a set with the baseline UL used to wrap this non-baseline class\n", Prefix.c_str());
					printf("%sBaseline: %s\n", Prefix.c_str(), Object->GetBaselineUL()->GetString().c_str());
				}
				Prefix += "  ";
			}
		}
	}
#endif // OPTION3ENABLED

	if(Object->GetLink())
	{
		if(Object->GetRefType() == ClassRefStrong)
		{
			printf("%s%s = %s\n", Prefix.c_str(), Object->Name().c_str(), Object->GetString().c_str());

			if(DumpLocation) printf("0x%s : ", Int64toHexString(Object->GetLocation(),8).c_str());
			printf("%s%s -> Strong Reference to %s\n", Prefix.c_str(), Object->Name().c_str(), Object->GetLink()->Name().c_str());

			DumpObject(Object->GetLink(), Prefix + "  ");
		}
		else if(Object->GetRefType() == ClassRefGlobal)
		{
			if(FollowGlobals)
			{
				printf("%s%s = %s\n", Prefix.c_str(), Object->Name().c_str(), Object->GetString().c_str());

				if(DumpLocation) printf("0x%s : ", Int64toHexString(Object->GetLocation(),8).c_str());
				printf("%s%s -> Global Reference to %s\n", Prefix.c_str(), Object->Name().c_str(), Object->GetLink()->Name().c_str());

				DumpObject(Object->GetLink(), Prefix + "  ");
			}
			else
			{
				printf("%s%s -> Global Reference to %s, %s\n", Prefix.c_str(), Object->Name().c_str(), Object->GetLink()->Name().c_str(), Object->GetString().c_str());
			}
		}
		else if(Object->GetRefType() == ClassRefMeta)
		{
			std::string TargetName = Object->GetLink()->GetString(MetaDefinitionName_UL, Object->GetLink()->Name());
			printf("%s%s -> MetaDictionary Reference to %s %s\n", Prefix.c_str(), Object->Name().c_str(), TargetName.c_str(), Object->GetString().c_str());
		}
		else if(Object->GetRefType() == ClassRefDict)
		{
			std::string TargetName = Object->GetLink()->GetString(DefinitionObjectName_UL, Object->GetLink()->Name());
			printf("%s%s -> Dictionary Reference to %s %s\n", Prefix.c_str(), Object->Name().c_str(), TargetName.c_str(), Object->GetString().c_str());
		}
		else
		{
			printf("%s%s -> Weak Reference to %s %s\n", Prefix.c_str(), Object->Name().c_str(), Object->GetLink()->Name().c_str(), Object->GetString().c_str());
		}
	}
	else
	{
		if(Object->IsDValue())
		{
			printf("%s%s = <Unknown>\n", Prefix.c_str(), Object->Name().c_str());
		}
		else
		{
			// Check first for values that are not reference batches
			if(Object->IsAValue())
			{
//if(Object->Name().find("Unknown") == std::string::npos)
				printf("%s%s = %s\n", Prefix.c_str(), Object->Name().c_str(), Object->GetString().c_str());
//else			printf("%s%s\n", Prefix.c_str(), Object->Name().c_str());
if(Object->GetRefType() == ClassRefMeta)
	printf("%s%s is an unsatisfied MetaRef\n", Prefix.c_str(), Object->Name().c_str());
else if(Object->GetRefType() == ClassRefDict)
	printf("%s%s is an unsatisfied DictRef\n", Prefix.c_str(), Object->Name().c_str());
			}
			else
			{
				printf("%s%s\n", Prefix.c_str(), Object->Name().c_str());
				MDObjectULList::iterator it = Object->begin();

				if(!SortedDump)
				{
					/* Dump Objects in the order stored */
					while(it != Object->end())
					{
						DumpObject((*it).second, Prefix + "  ");
						it++;
					}
				}
				else
				{
					/* Dump Objects in alphabetical order - to allow easier file comparisons */
					std::multimap<std::string, MDObjectPtr> ChildMap;
					std::multimap<std::string, MDObjectPtr>::iterator CM_Iter;

					while(it != Object->end())
					{
						ChildMap.insert(std::multimap<std::string, MDObjectPtr>::value_type((*it).second->Name(), (*it).second));
						it++;
					}

					CM_Iter = ChildMap.begin();
					while(CM_Iter != ChildMap.end())
					{
						DumpObject((*CM_Iter).second, Prefix + "  ");
						CM_Iter++;
					}
				}
			}
		}
	}

	return;
}
Пример #6
0
//! Get the offset to add to lines in field 2
int ANCVBISource::Field2Offset(void)
{
	if(F2Offset >= 0) return F2Offset;

	MDObjectPtr Descriptor = MasterSource->GetDescriptor();
	if(!Descriptor)
	{
		error("EssenceDescriptor not defined for master source of ANCVBISource before calling Field2Offset()\n");
		F2Offset = 0;
		return F2Offset;
	}

	// If this is a multpile descriptor, locate the video
	// DRAGONS: If we can't find a picture descriptor we will drop through with the MultipleDescriptor and give a "does not have a VideoLineMap" error
	if(Descriptor->IsA(MultipleDescriptor_UL))
	{
		MDObject::iterator it = Descriptor->begin();
		while(it != Descriptor->end())
		{
			if((*it).second->IsA(GenericPictureEssenceDescriptor_UL))
			{
				Descriptor = (*it).second;
				break;
			}
			it++;
		}
	}


	/* Check if this is interlaced essence */

	if(Descriptor->IsDValue(FrameLayout_UL))
	{
		warning("EssenceDescriptor for ANCVBISource does not have a valid FrameLayout\n");
		F2Offset = 0;
		return F2Offset;
	}

	if(Descriptor->GetInt(FrameLayout_UL) != 1)
	{
		F2Offset = 0;
		return F2Offset;
	}

	
	/* Calculate F1 to F2 distance from Video Line Map */

	MDObjectPtr VideoLineMap = Descriptor->Child(VideoLineMap_UL);
	if(!VideoLineMap)
	{
		error("EssenceDescriptor for ANCVBISource does not have a valid VideoLineMap\n");
		F2Offset = 0;
		return F2Offset;
	}

	MDObjectPtr F1Entry = VideoLineMap->Child(0);
	MDObjectPtr F2Entry = VideoLineMap->Child(1);
	if((!F1Entry) || (!F2Entry))
	{
		error("EssenceDescriptor for ANCVBISource does not have a valid VideoLineMap\n");
		F2Offset = 0;
		return F2Offset;
	}

	F2Offset = static_cast<int>(F2Entry->GetInt() - F1Entry->GetInt());
	return F2Offset;
}