void FreezeScript::TransformVisitor::visitStruct(const StructDataPtr& dest) { Slice::TypePtr type = dest->getType(); if(_info->doDefaultTransform(type)) { StructDataPtr s = StructDataPtr::dynamicCast(_src); if(s && isCompatible(type, _src->getType())) { // // Transform members with the same name. // DataMemberMap srcMap = s->getMembers(); DataMemberMap destMap = dest->getMembers(); string typeName = typeToString(type); for(DataMemberMap::iterator p = destMap.begin(); p != destMap.end(); ++p) { DataMemberMap::iterator q = srcMap.find(p->first); if(q != srcMap.end()) { string context = typeName + " member " + p->first + " value"; TransformVisitor v(q->second, _info, context); p->second->visit(v); } } } else { typeMismatchError(type, _src->getType()); } } _info->executeCustomTransform(dest, _src); }
void FreezeScript::AssignVisitor::visitStruct(const StructDataPtr& dest) { Slice::StructPtr type = Slice::StructPtr::dynamicCast(dest->getType()); assert(type); StructDataPtr src = StructDataPtr::dynamicCast(_src); if(src && isCompatible(type, src->getType())) { // // Assign members with the same name. // DataMemberMap srcMap = src->getMembers(); DataMemberMap destMap = dest->getMembers(); string typeName = typeToString(type); for(DataMemberMap::iterator p = destMap.begin(); p != destMap.end(); ++p) { DataMemberMap::iterator q = srcMap.find(p->first); if(q != srcMap.end()) { string context = typeName + " member " + p->first + " value"; AssignVisitor v(q->second, _factory, _errorReporter, _convert, context); p->second->visit(v); } } } else { typeMismatchError(type, _src->getType()); } }
void FreezeScript::TransformVisitor::visitObject(const ObjectRefPtr& dest) { // // Support struct->class and class->class transforms. // Slice::TypePtr type = dest->getType(); ObjectRefPtr src = ObjectRefPtr::dynamicCast(_src); StructDataPtr s = StructDataPtr::dynamicCast(_src); if(!src && !s) { typeMismatchError(type, _src->getType()); } else if(_info->doDefaultTransform(type)) { if(src) { // // class->class transform // ObjectDataPtr srcValue = src->getValue(); Slice::TypePtr srcType = src->getType(); if(!srcValue) { // // Allow a nil value from type Object. // if(Slice::BuiltinPtr::dynamicCast(srcType) || isCompatible(type, srcType)) { dest->setValue(0); } else { typeMismatchError(type, srcType); } } else { Slice::TypePtr srcValueType = srcValue->getType(); if(isCompatible(type, srcValueType)) { // // If the types are in the same Slice unit, then we can simply // copy the reference. Otherwise, we check the object map to // see if an equivalent object has already been created, and // if not, then we have to create one. // if(type->unit().get() == srcValueType->unit().get()) { dest->setValue(srcValue); } else { ObjectDataMap& objectDataMap = _info->getObjectDataMap(); ObjectDataMap::iterator p = objectDataMap.find(srcValue.get()); if(p != objectDataMap.end() && p->second) { dest->setValue(p->second); } else { // // If the type has been renamed, we need to get its equivalent // in the new Slice definitions. // Slice::TypePtr newType = _info->getRenamedType(srcValueType); if(!newType) { string name = typeToString(srcValueType); Slice::TypeList l = type->unit()->lookupType(name, false); if(l.empty()) { throw ClassNotFoundException(name); } newType = l.front(); } // // Use createObject() so that an initializer is invoked if necessary. // DataPtr newObj = _info->getDataFactory()->createObject(newType, false); ObjectRefPtr newRef = ObjectRefPtr::dynamicCast(newObj); assert(newRef); ObjectDataPtr newValue = newRef->getValue(); try { transformObject(newValue, srcValue); } catch(...) { newObj->destroy(); throw; } dest->setValue(newValue); newObj->destroy(); } } } else { typeMismatchError(type, srcValueType); } } } else { // // struct->class transform // Slice::TypePtr srcType = _src->getType(); if(isCompatible(type, srcType)) { // // If the type has been renamed, we need to get its equivalent // in the new Slice definitions. // Slice::TypePtr newType = _info->getRenamedType(srcType); if(!newType) { string name = typeToString(srcType); Slice::TypeList l = type->unit()->lookupType(name, false); if(l.empty()) { throw ClassNotFoundException(name); } newType = l.front(); } // // Use createObject() so that an initializer is invoked if necessary. // DataPtr newObj = _info->getDataFactory()->createObject(newType, false); ObjectRefPtr newRef = ObjectRefPtr::dynamicCast(newObj); assert(newRef); ObjectDataPtr newValue = newRef->getValue(); try { // // Transform members with the same name. // DataMemberMap srcMap = s->getMembers(); DataMemberMap destMap = newValue->getMembers(); string typeName = typeToString(type); for(DataMemberMap::iterator p = destMap.begin(); p != destMap.end(); ++p) { DataMemberMap::iterator q = srcMap.find(p->first); if(q != srcMap.end()) { string context = typeName + " member " + p->first + " value"; TransformVisitor v(q->second, _info, context); p->second->visit(v); } } } catch(...) { newObj->destroy(); throw; } dest->setValue(newValue); newObj->destroy(); } else { typeMismatchError(type, srcType); } } } _info->executeCustomTransform(dest, _src); }
bool FreezeScript::invokeGlobalFunction(const Ice::CommunicatorPtr& communicator, const string& name, const DataList& args, DataPtr& result, const DataFactoryPtr& factory, const ErrorReporterPtr& errorReporter) { // // Global function. // if(name == "typeOf") { if(args.size() != 1) { errorReporter->error("typeOf() requires one argument"); } result = factory->createString(typeToString(args.front()->getType()), false); return true; } else if(name == "generateUUID") { if(args.size() != 0) { errorReporter->error("generateUUID() accepts no arguments"); } result = factory->createString(IceUtil::generateUUID(), false); return true; } else if(name == "stringToIdentity") { StringDataPtr str; if(args.size() > 0) { str = StringDataPtr::dynamicCast(args.front()); } if(args.size() != 1 || !str) { errorReporter->error("stringToIdentity() requires a string argument"); } // // Parse the identity string. // string idstr = str->stringValue(); Ice::Identity id; try { id = communicator->stringToIdentity(idstr); } catch(const Ice::IdentityParseException& ex) { errorReporter->error("error in stringToIdentity():\n" + ex.str); } // // Create a data representation of Ice::Identity. // Slice::UnitPtr unit = str->getType()->unit(); Slice::TypeList l = unit->lookupType("::Ice::Identity", false); assert(!l.empty()); DataPtr identity = factory->create(l.front(), false); StringDataPtr member; member = StringDataPtr::dynamicCast(identity->getMember("name")); assert(member); member->setValue(id.name); member = StringDataPtr::dynamicCast(identity->getMember("category")); assert(member); member->setValue(id.category); result = identity; return true; } else if(name == "identityToString") { StructDataPtr identity; if(args.size() > 0) { identity = StructDataPtr::dynamicCast(args.front()); } if(identity) { Slice::TypePtr argType = identity->getType(); Slice::StructPtr st = Slice::StructPtr::dynamicCast(argType); if(!st || st->scoped() != "::Ice::Identity") { identity = 0; } } if(args.size() != 1 || !identity) { errorReporter->error("identityToString() requires a argument of type ::Ice::Identity"); } // // Compose the identity. // Ice::Identity id; StringDataPtr member; member = StringDataPtr::dynamicCast(identity->getMember("name")); assert(member); id.name = member->stringValue(); member = StringDataPtr::dynamicCast(identity->getMember("category")); assert(member); id.category = member->stringValue(); result = factory->createString(communicator->identityToString(id), false); return true; } else if(name == "stringToProxy") { StringDataPtr str; if(args.size() > 0) { str = StringDataPtr::dynamicCast(args.front()); } if(args.size() != 1 || !str) { errorReporter->error("stringToProxy() requires a string argument"); } // // Parse the proxy; // string sprx = str->stringValue(); Ice::ObjectPrx prx; try { prx = factory->getCommunicator()->stringToProxy(sprx); } catch(const Ice::ProxyParseException& ex) { errorReporter->error("error in stringToProxy():\n" + ex.str); } Slice::UnitPtr unit = str->getType()->unit(); ProxyDataPtr p = ProxyDataPtr::dynamicCast(factory->create(unit->builtin(Slice::Builtin::KindObjectProxy), false)); p->setValue(prx); result = p; return true; } else if(name == "proxyToString") { ProxyDataPtr prx; if(args.size() > 0) { prx = ProxyDataPtr::dynamicCast(args.front()); } if(args.size() != 1 || !prx) { errorReporter->error("proxyToString() requires a proxy argument"); } result = factory->createString(prx->toString(), false); return true; } else if(name == "lowercase") { StringDataPtr str; if(args.size() > 0) { str = StringDataPtr::dynamicCast(args.front()); } if(args.size() != 1 || !str) { errorReporter->error("lowercase() requires a string argument"); } string val = IceUtilInternal::toLower(str->stringValue()); result = factory->createString(val, false); return true; } return false; }