void FreezeScript::AssignVisitor::visitDictionary(const DictionaryDataPtr& dest) { Slice::TypePtr type = dest->getType(); DictionaryDataPtr d = DictionaryDataPtr::dynamicCast(_src); if(d && isCompatible(type, _src->getType())) { DataMap& srcMap = d->getElements(); DataMap destMap; Slice::DictionaryPtr dictType = Slice::DictionaryPtr::dynamicCast(type); assert(dictType); Slice::TypePtr keyType = dictType->keyType(); Slice::TypePtr valueType = dictType->valueType(); string typeName = typeToString(type); for(DataMap::const_iterator p = srcMap.begin(); p != srcMap.end(); ++p) { DataPtr key = _factory->create(keyType, false); Destroyer<DataPtr> keyDestroyer(key); DataPtr value = _factory->create(valueType, false); Destroyer<DataPtr> valueDestroyer(value); AssignVisitor keyVisitor(p->first, _factory, _errorReporter, _convert, typeName + " key"); key->visit(keyVisitor); AssignVisitor valueVisitor(p->second, _factory, _errorReporter, _convert, typeName + " value"); value->visit(valueVisitor); DataMap::const_iterator q = destMap.find(key); if(q != destMap.end()) { error("duplicate dictionary key in " + typeToString(dictType)); } else { destMap.insert(DataMap::value_type(key, value)); keyDestroyer.release(); valueDestroyer.release(); } } DataMap& m = dest->getElements(); m.swap(destMap); } else { typeMismatchError(type, _src->getType()); } }
void FreezeScript::SliceVisitor::visitDictionary(const Slice::DictionaryPtr& v) { if(v->isLocal()) { return; } string scoped = v->scoped(); if(ignoreType(scoped)) { return; } _out.newline(); _out.newline(); _out << "<!-- dictionary " << scoped << " -->"; _out << se("dump") << attr("type", scoped) << ee; }
void FreezeScript::TransformVisitor::visitDictionary(const DictionaryDataPtr& dest) { Slice::TypePtr type = dest->getType(); if(_info->doDefaultTransform(type)) { DictionaryDataPtr d = DictionaryDataPtr::dynamicCast(_src); if(d && isCompatible(type, _src->getType())) { DataMap& srcMap = d->getElements(); DataMap destMap; Slice::DictionaryPtr dictType = Slice::DictionaryPtr::dynamicCast(type); assert(dictType); Slice::TypePtr keyType = dictType->keyType(); Slice::TypePtr valueType = dictType->valueType(); string typeName = typeToString(type); for(DataMap::const_iterator p = srcMap.begin(); p != srcMap.end(); ++p) { DataPtr key = _info->getDataFactory()->create(keyType, false); Destroyer<DataPtr> keyDestroyer(key); DataPtr value = _info->getDataFactory()->create(valueType, false); Destroyer<DataPtr> valueDestroyer(value); TransformVisitor keyVisitor(p->first, _info, typeName + " key"); key->visit(keyVisitor); try { TransformVisitor valueVisitor(p->second, _info, typeName + " value"); value->visit(valueVisitor); } catch(const ClassNotFoundException& ex) { // // If transformation of the dictionary value fails because a class // could not be found, then we invoke purgeObjects() to determine // whether we should ignore the situation (and remove the element // from the dictionary) or raise the exception again. // if(!_info->purgeObjects()) { throw; } warning("purging element of dictionary " + typeToString(dictType) + " due to missing class type " + ex.id); continue; } DataMap::const_iterator q = destMap.find(key); if(q != destMap.end()) { warning("duplicate dictionary key in " + typeToString(dictType)); } else { destMap.insert(DataMap::value_type(key, value)); keyDestroyer.release(); valueDestroyer.release(); } } DataMap& m = dest->getElements(); m.swap(destMap); } else { typeMismatchError(type, _src->getType()); } } _info->executeCustomTransform(dest, _src); }