CosNaming::NamingContext_ptr TAO_Hash_Naming_Context::get_context (const CosNaming::Name &name) { CosNaming::NamingContext_var result = CosNaming::NamingContext::_nil (); // Create compound name to be resolved, i.e., // (<name> - last component). To avoid copying, we can just reuse // <name>'s buffer, since we will not be modifying it. CORBA::ULong name_len = name.length (); CosNaming::Name comp_name (name.maximum (), name_len - 1, const_cast<CosNaming::NameComponent*> (name.get_buffer ())); try { CORBA::Object_var context = this->resolve (comp_name); // Try narrowing object reference to the NamingContext type. result = CosNaming::NamingContext::_narrow (context.in ()); } catch (CosNaming::NamingContext::NotFound& ex) { // Add the last component of the name, which was stripped before // the call to resolve. CORBA::ULong const rest_len = ex.rest_of_name.length () + 1; ex.rest_of_name.length (rest_len); ex.rest_of_name[rest_len - 1] = name[name_len - 1]; throw; } if (CORBA::is_nil (result.in ())) { CosNaming::Name rest; rest.length (2); rest[0] = name[name_len - 2]; rest[1] = name[name_len - 1]; throw CosNaming::NamingContext::NotFound( CosNaming::NamingContext::not_context, rest); } // Finally, if everything went smoothly, just return the resolved // context. return result._retn (); }
CORBA::Object_ptr TAO_Hash_Naming_Context::resolve (const CosNaming::Name& n) { // Check to make sure this object didn't have <destroy> method // invoked on it. if (this->destroyed_) throw CORBA::OBJECT_NOT_EXIST (); // Get the length of the name. CORBA::ULong const name_len = n.length (); // Check for invalid name. if (name_len == 0) throw CosNaming::NamingContext::InvalidName(); // Resolve the first component of the name. // Stores the binding type for the first name component. CosNaming::BindingType type; // Stores the object reference bound to the first name component. CORBA::Object_var result; { ACE_READ_GUARD_THROW_EX (TAO_SYNCH_RW_MUTEX, ace_mon, this->lock_, CORBA::INTERNAL ()); if (this->context_->find (n[0].id, n[0].kind, result.out (), type) == -1) throw CosNaming::NamingContext::NotFound (CosNaming::NamingContext::missing_node, n); } // If the name we have to resolve is a compound name, we need to // resolve it recursively. if (name_len > 1) { CosNaming::NamingContext_var context = CosNaming::NamingContext::_nil (); if (type == CosNaming::ncontext) { // Narrow to NamingContext. context = CosNaming::NamingContext::_narrow (result.in ()); } else // The first name component wasn't bound to a NamingContext. throw CosNaming::NamingContext::NotFound( CosNaming::NamingContext::not_context, n); // If narrow failed... if (CORBA::is_nil (context.in ())) throw CosNaming::NamingContext::NotFound( CosNaming::NamingContext::not_context, n); else { // Successfully resolved the first name component, need to // recursively call resolve on <n> without the first component. // We need a name just like <n> but without the first // component. Instead of copying data we can reuse <n>'s // buffer since we will only be using it for 'in' parameters // (no modifications). CosNaming::Name rest_of_name (n.maximum () - 1, n.length () - 1, const_cast<CosNaming::NameComponent*> (n.get_buffer ()) + 1); // If there are any exceptions, they will propagate up. try { CORBA::Object_ptr resolved_ref; resolved_ref = context->resolve (rest_of_name); return resolved_ref; } catch (const CORBA::SystemException&) { throw CosNaming::NamingContext::CannotProceed (context.in (), rest_of_name); } } } else { ACE_READ_GUARD_THROW_EX (TAO_SYNCH_RW_MUTEX, ace_mon, this->lock_, CORBA::INTERNAL ()); if (this->context_->find (n[0].id, n[0].kind, result.out (), type) == -1) throw CosNaming::NamingContext::NotFound (CosNaming::NamingContext::missing_node, n); } // If the name we had to resolve was simple, we just need to return // the result. return result._retn (); }