/*! DRAGONS: We use the current UTF16String GetString trait to ensure that we always have the correct handling, * even if the user wants these strings handled differently (i.e. we do it their way!) */ std::list<std::string> SplitStringArray(const MDObjectPtr &Array) { std::list<std::string> Ret; // Quit early if an invalid parameter if(!Array) return Ret; // Build a working string static MDTypePtr ValType = MDType::Find("UTF16String"); MDObjectPtr Value = ValType ? new MDObject(ValType) : NULL; if(!Value) { error("Can't build UTF16String value required by SplitStringArray() - need this type to be defined in the dictionary file\n"); return Ret; } // Assemble the data value (which may be an array of sub-values) DataChunkPtr Data = Array->PutData(); // Get a pointer to the start of the data UInt8 *pData = Data->Data; // The number of bytes of data to split size_t BytesLeft = Data->Size; while(BytesLeft > 1) { // Find the end of the current string size_t Len = 0; UInt8 *p = pData; while(BytesLeft > 1) { BytesLeft -= 2; Len += 2; UInt16 Char = GetU16(p); p += 2; // End when we find a null if(Char == 0) break; } // Copy this string to the working value Value->SetValue(pData, Len); // Read out the traits-formatted version of the string Ret.push_back(Value->GetString()); // Move the pointer forward to the next value after the string terminator pData = p; } return Ret; }
//! 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; }
//! 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; }