[omniORB] _unchecked_narrow in omniORB4

Lars Immisch lars@ibp.de
Fri, 2 Nov 2001 17:06:59 +0100


Dear Duncan,

a while ago we talked about unchecked_narrow for omniORB4; you said it would  
be no big deal and you would add it before the release.

I needed it, so I patched omniORB3.0.4. Attached is a patch against the latest  
version from cvs in the omi3_develop branch.

The modification was indeed pleasantly simple :-)

The patch is tested and works fine. It can be applied with patch -p 0 <  
unchecked_narrow.patch from the omni root directory.

I'd be pleased if you accept it.

Thanks,

- Lars

Index: src/lib/omniORB2/omniidl_be/cxx/header/template.py
===================================================================
RCS file: /cvsroot/omni/src/lib/omniORB2/omniidl_be/cxx/header/template.py,v
retrieving revision 1.3.2.19
diff -u -w -r1.3.2.19 src/lib/omniORB2/omniidl_be/cxx/header/template.py
--- src/lib/omniORB2/omniidl_be/cxx/header/template.py	2001/08/20 13:48:01	 
1.3.2.19
+++ src/lib/omniORB2/omniidl_be/cxx/header/template.py	2001/10/22 11:11:08
@@ -301,6 +301,7 @@
 
   static _ptr_type _duplicate(_ptr_type);
   static _ptr_type _narrow(CORBA::Object_ptr);
+  static _ptr_type _unchecked_narrow(CORBA::Object_ptr);
   static _ptr_type _nil();
 
   static inline size_t _alignedSize(_ptr_type, size_t);
Index: src/lib/omniORB2/omniidl_be/cxx/skel/template.py
===================================================================
RCS file: /cvsroot/omni/src/lib/omniORB2/omniidl_be/cxx/skel/template.py,v
retrieving revision 1.1.2.11
diff -u -w -r1.1.2.11 src/lib/omniORB2/omniidl_be/cxx/skel/template.py
--- src/lib/omniORB2/omniidl_be/cxx/skel/template.py	2001/04/27 11:03:56	 
1.1.2.11
+++ src/lib/omniORB2/omniidl_be/cxx/skel/template.py	2001/10/22 11:11:09
@@ -138,7 +138,6 @@
   return obj;
 }
 
-
 @name@_ptr
 @name@::_narrow(CORBA::Object_ptr obj)
 {
@@ -147,6 +146,13 @@
   return e ? e : _nil();
 }
 
+@name@_ptr
+@name@::_unchecked_narrow(CORBA::Object_ptr obj)
+{
+  if( !obj || obj->_NP_is_nil() || obj->_NP_is_pseudo() ) return _nil();
+  _ptr_type e = (_ptr_type) obj->_PR_getobj()->_uncheckedNarrow(_PD_repoId);
+  return e ? e : _nil();
+}
 
 @name@_ptr
 @name@::_nil()
Index: src/lib/omniORB2/orbcore/omniObjRef.cc
===================================================================
RCS file: /cvsroot/omni/src/lib/omniORB2/orbcore/omniObjRef.cc,v
retrieving revision 1.1.2.7
diff -u -w -r1.1.2.7 src/lib/omniORB2/orbcore/omniObjRef.cc
--- src/lib/omniORB2/orbcore/omniObjRef.cc	2001/05/04 16:53:08	1.1.2.7
+++ src/lib/omniORB2/orbcore/omniObjRef.cc	2001/10/22 11:11:10
@@ -195,6 +195,38 @@
   return target;
 }
 
+void*
+omniObjRef::_uncheckedNarrow(const char* repoId)
+{
+  ASSERT_OMNI_TRACEDMUTEX_HELD(*omni::internalLock, 0);
+  OMNIORB_ASSERT(repoId && *repoId);
+
+  // Attempt to narrow the reference using static type info.
+  void* target = _ptrToObjRef(repoId);
+
+  if( target ) {
+    omni::duplicateObjRef(this);
+  }
+  else {
+      omniObjRef* objref;
+
+      omni::internalLock->lock();
+
+      if( _localId() )
+	objref = omni::createObjRef(pd_mostDerivedRepoId, repoId, _localId());
+      else
+	objref = omni::createObjRef(pd_mostDerivedRepoId, repoId,
+				    pd_iopprofiles, 0, 1);
+
+      omni::internalLock->unlock();
+
+      if( objref ) {
+	target = objref->_ptrToObjRef(repoId);
+	OMNIORB_ASSERT(target);
+      }
+  }
+  return target;
+}
 
 void
 omniObjRef::_assertExistsAndTypeVerified()
Index: include/omniORB3/omniObjRef.h
===================================================================
RCS file: /cvsroot/omni/include/omniORB3/omniObjRef.h,v
retrieving revision 1.1.2.4
diff -u -w -r1.1.2.4 include/omniORB3/omniObjRef.h
--- include/omniORB3/omniObjRef.h	2000/03/01 17:57:42	1.1.2.4
+++ include/omniORB3/omniObjRef.h	2001/10/22 11:11:15
@@ -126,6 +126,19 @@
   //  This function is thread-safe.
   //  Does not throw any exceptions.
 
+  void* _uncheckedNarrow(const char* repoId);
+  // If the actual type of the object can be widened to the requested
+  // interface type identified by the IR repository ID <repoId>, return
+  // a valid object reference.  Otherwise, return 0.  The return value is
+  // of type void* and can be casted to the T_ptr type of the interface
+  // T directly.  We do not contact the object itself to check the
+  // inheritance relation, so subsequent operations on this object
+  // may fail because it actually does not implement the interface.
+  //  <repoId> must be a type for which there exists
+  // a proxy object factory.
+  //  This function is thread-safe.
+  //  Does not throw any exceptions.
+
   void _assertExistsAndTypeVerified();
   // If pd_flags.object_exists is zero, contact the object and verify
   // that it exists.