summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbrunsch <brunsch@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-08-26 20:54:51 +0000
committerbrunsch <brunsch@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>1998-08-26 20:54:51 +0000
commit48adba463ee71680888f6605e13cea24af661b17 (patch)
tree8cbd00fda46e90abb00b0358c099ce39c6fbb748
parent89fc6f92698d858075cd67e91126b01775f16a34 (diff)
downloadATCD-48adba463ee71680888f6605e13cea24af661b17.tar.gz
decodes stringified iors
-rw-r--r--TAO/utils/catior/catior.cpp445
-rw-r--r--TAO/utils/catior/catior.dsp91
-rw-r--r--TAO/utils/catior/catior.dsw29
3 files changed, 565 insertions, 0 deletions
diff --git a/TAO/utils/catior/catior.cpp b/TAO/utils/catior/catior.cpp
new file mode 100644
index 00000000000..6ac37cdd06e
--- /dev/null
+++ b/TAO/utils/catior/catior.cpp
@@ -0,0 +1,445 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// TAO/Utils/catior
+//
+// = FILENAME
+// catior.cpp
+//
+// = DESCRIPTION
+// Reads stringified IORs and outputs the encoded information
+//
+// = AUTHORS
+// Jeff Hopper <jhopper@nosc.mil>
+//
+// ============================================================================
+
+#include "ace/Get_Opt.h"
+#include <tao/corba.h>
+#include <tao/debug.h>
+#include <tao/typecode.h>
+#include <tao/iiop_object.h>
+
+// Destringify URL style IIOP objref.
+static CORBA::Object_ptr
+iiop_string_to_object (CORBA::String string,
+ CORBA::Environment &env)
+{
+ // NIL objref encodes as just "iiop:" ... which has already been
+ // removed, so we see it as an empty string.
+
+ if (!string || !*string)
+ return 0;
+
+ // type ID not encoded in this string ... makes narrowing rather
+ // expensive, though it does ensure that type-safe narrowing code
+ // gets thoroughly excercised/debugged! Without a typeID, the
+ // _narrow will be required to make an expensive remote "is_a" call.
+
+ IIOP_Object *data;
+
+ // null type ID.
+ ACE_NEW_RETURN (data, IIOP_Object ((char *) 0), 0);
+
+ // Remove the "N.N//" prefix, and verify the version's one
+ // that we accept
+
+ if (isdigit (string [0]) && isdigit (string [2]) && string [1] == '.'
+ && string [3] == '/' && string [4] == '/')
+ {
+ data->profile.iiop_version.major = (char) (string [0] - '0');
+ data->profile.iiop_version.minor = (char) (string [2] - '0');
+ string += 5;
+ }
+ else
+ {
+ env.exception (new CORBA_DATA_CONVERSION (CORBA::COMPLETED_NO));
+ data->_decr_refcnt ();
+ return 0;
+ }
+
+ if (data->profile.iiop_version.major != IIOP::MY_MAJOR
+ || data->profile.iiop_version.minor > IIOP::MY_MINOR)
+ {
+ env.exception (new CORBA_DATA_CONVERSION (CORBA::COMPLETED_NO));
+ data->_decr_refcnt ();
+ return 0;
+ }
+
+ // Pull off the "hostname:port/" part of the objref
+
+ char *cp = ACE_OS::strchr (string, ':');
+ if (cp == 0)
+ {
+ env.exception (new CORBA_DATA_CONVERSION (CORBA::COMPLETED_NO));
+ data->_decr_refcnt ();
+ return 0;
+ }
+
+ data->profile.host = CORBA::string_alloc (1 + cp - string);
+ for (cp = data->profile.host;
+ *string != ':';
+ *cp++ = *string++)
+ continue;
+
+ *cp = 0;
+ string++;
+
+ cp = ACE_OS::strchr ((char *) string, '/');
+
+ if (cp == 0)
+ {
+ env.exception (new CORBA_DATA_CONVERSION (CORBA::COMPLETED_NO));
+ CORBA::string_free (data->profile.host);
+ data->profile.host = 0;
+ data->_decr_refcnt ();
+ return 0;
+ }
+
+ data->profile.port = (short) ACE_OS::atoi ((char *) string);
+ data->profile.object_addr (0);
+ string = ++cp;
+
+ // Parse the object key
+ TAO_POA::decode_string_to_sequence (data->profile.object_key,
+ string);
+
+ // Create the CORBA level proxy.
+ TAO_ServantBase *servant =
+ TAO_ORB_Core_instance ()->orb ()->_get_collocated_servant (data);
+
+ // This will increase the ref_count on data by one
+ CORBA_Object *obj = new CORBA_Object (data, servant, servant != 0);
+
+ // Set the ref_count on data to 1, which is correct, because only
+ // obj has now a reference to it.
+ // data->_decr_refcnt ();
+
+ return obj;
+}
+
+CORBA::Boolean
+catior(CORBA::String str,
+ CORBA::Environment &env)
+{
+ // Unhex the bytes, and make a CDR deencapsulation stream from the
+ // resulting data.
+
+ ACE_Message_Block mb (ACE_OS::strlen ((char *) str) / 2 + 1
+ + CDR::MAX_ALIGNMENT);
+
+ CDR::mb_align (&mb);
+
+ char *buffer = mb.rd_ptr ();
+ char *tmp = (char *) str;
+ size_t len = 0;
+
+ CORBA::Boolean continue_decoding;
+ // the prefix of the IOR must be removed,
+ // and the string must start with the encapsulation byte
+ //
+ while (tmp [0] && tmp [1])
+ {
+ u_char byte;
+
+ if (!(isxdigit (tmp [0]) && isxdigit (tmp [1])))
+ break;
+
+ byte = (u_char) (ACE::hex2byte (tmp [0]) << 4);
+ byte |= ACE::hex2byte (tmp [1]);
+
+ buffer [len++] = byte;
+ tmp += 2;
+ }
+
+ if (tmp [0] && !isspace (tmp [0]))
+ {
+ env.exception (new CORBA::BAD_PARAM (CORBA::COMPLETED_NO));
+ return CORBA::B_FALSE;
+ }
+
+ // Create deencapsulation stream ... then unmarshal objref from that
+ // stream.
+
+ CORBA::Boolean byteOrder;
+
+ {
+ TAO_InputCDR encapStream(&mb);
+ continue_decoding = encapStream.read_boolean(byteOrder);
+ }
+
+ mb.rd_ptr (1);
+ mb.wr_ptr (2*len-1);
+ TAO_InputCDR stream (&mb, byteOrder);
+
+ if (byteOrder == CORBA::B_TRUE)
+ cout << "The Byte Order:\tLittle Endian " << endl;
+ else
+ cout << "The Byte Order:\tBig Endian " << endl;
+
+
+ // First, read the type hint. This will be the type_id encoded in an
+ // object reference.
+ CORBA::String type_hint;
+ if ((continue_decoding = stream.decode (CORBA::_tc_string, &type_hint, 0, env))
+ == CORBA::B_FALSE)
+ {
+ ACE_DEBUG ((LM_DEBUG, "cannot read type id\n"));
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+ cout << "The Type Id:\t" << type_hint << endl;
+
+ // release any memory associated with the type_hint
+ CORBA::string_free (type_hint);
+
+ // Read the profiles, discarding all until an IIOP profile comes by.
+ // Once we see an IIOP profile, ignore any further ones.
+ //
+ // XXX this will need to change someday to let different protocol
+ // code be accessed, not just IIOP. Protocol modules will be
+ // dynamically loaded from shared libraries via ORB_init (), and we
+ // just need to be able to access such preloaded libraries here as
+ // we unmarshal objrefs.
+
+ CORBA::ULong profiles = 0;
+ // IIOP_Object *objdata = 0;
+
+ // get the count of profiles that follow
+ if( (continue_decoding = stream.read_ulong (profiles)) == CORBA::B_FALSE)
+ {
+ ACE_DEBUG ((LM_DEBUG, "cannot read the profile count\n"));
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+ CORBA::ULong profile_counter = 0;
+
+ // No profiles means a NIL objref.
+ if (profiles == 0)
+ {
+ return CORBA_TypeCode::TRAVERSE_CONTINUE;
+ }
+ else
+ while (profiles-- != 0)
+ {
+ cout << "Profile Count:\t" << ++profile_counter << endl;
+
+ // We keep decoding until we find a valid IIOP profile.
+ CORBA::ULong tag;
+
+ // get the profile ID tag
+ if ( (continue_decoding = stream.read_ulong (tag)) == CORBA::B_FALSE)
+ {
+ ACE_DEBUG ((LM_DEBUG, "cannot read profile tag\n"));
+ continue;
+ }
+
+ if (tag != TAO_IOP_TAG_INTERNET_IOP)
+ {
+ continue_decoding = stream.skip_string ();
+ ACE_DEBUG ((LM_DEBUG, "unknown tag %d skipping\n", tag));
+ continue;
+ }
+
+ // OK, we've got an IIOP profile. It's going to be
+ // encapsulated ProfileData. Create a new decoding stream and
+ // context for it, and tell the "parent" stream that this data
+ // isn't part of it any more.
+
+ CORBA::ULong encap_len;
+ // ProfileData is encoded as a sequence of octet. So first get
+ // the length of the sequence.
+ if ( (continue_decoding = stream.read_ulong (encap_len)) == CORBA::B_FALSE)
+ {
+ ACE_DEBUG ((LM_DEBUG, "cannot read encap length\n"));
+ continue;
+ }
+
+ // Create the decoding stream from the encapsulation in the
+ // buffer, and skip the encapsulation.
+ TAO_InputCDR str(stream, encap_len);
+
+ continue_decoding = str.good_bit ()
+ && stream.skip_bytes(encap_len);
+
+ if (!continue_decoding)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "problem decoding encapsulated stream, "
+ "len = %d\n", encap_len));
+ continue;
+ }
+
+ // Read and verify major, minor versions, ignoring IIOP
+ // profiles whose versions we don't understand.
+ //
+ // XXX this doesn't actually go back and skip the whole
+ // encapsulation...
+ CORBA::Octet iiop_version_major, iiop_version_minor;
+ if (!(str.read_octet (iiop_version_major)
+ && iiop_version_major == IIOP::MY_MAJOR
+ && str.read_octet (iiop_version_minor)
+ && iiop_version_minor <= IIOP::MY_MINOR))
+ {
+ ACE_DEBUG ((LM_DEBUG, "detected new v%d.%d IIOP profile",
+ iiop_version_major,
+ iiop_version_minor));
+ continue;
+ }
+
+ cout << "IIOP Version:\t" << dec << (int)iiop_version_major << ".";
+ cout << (int)iiop_version_minor << endl;
+
+ // Get host and port
+ CORBA::UShort port_number;
+ CORBA::String hostname;
+ if (str.decode (CORBA::_tc_string,
+ &hostname,
+ 0,
+ env) != CORBA::TypeCode::TRAVERSE_CONTINUE
+ || !str.read_ushort (port_number))
+ {
+ ACE_DEBUG ((LM_DEBUG, "error decoding IIOP host/port"));
+ return CORBA::TypeCode::TRAVERSE_STOP;
+ }
+
+ cout << "Host Name:\t" << hostname << endl;
+ cout << "Port Number:\t" << port_number << endl;
+ CORBA::string_free(hostname);
+
+ // ... and object key.
+ cout << "Object Key:\t" << endl;
+ CORBA::ULong objKeyLength = 0;
+ continue_decoding = str.read_ulong(objKeyLength);
+
+ cout << "Object Key Length:\t" << objKeyLength << endl;
+
+ CORBA::Octet anOctet;
+ CORBA::String objKey = CORBA::string_alloc(objKeyLength+1);
+
+ short counter = -1;
+ for(unsigned int i=0;i<objKeyLength;i++)
+ {
+ if(++counter == 8) { cout << endl; counter = 0; }
+ str.read_octet(anOctet);
+ cout << hex << (int)anOctet << " ";
+ objKey[i] = (char)anOctet;
+ }
+ objKey[i] = '\0';
+
+ cout << endl << "The Object Key as string:" << endl << objKey << endl;
+ CORBA::string_free(objKey);
+
+ }
+
+ return CORBA::B_TRUE;
+
+}
+
+int
+main(int argc, char* argv[])
+{
+ ACE_Get_Opt get_opt (argc, argv, "f:n:");
+
+ CORBA::ORB_ptr orb_ptr = TAO_ORB_Core_instance()->orb();
+
+ CORBA::Environment env;
+ orb_ptr->init_orb_globals(env);
+
+
+ char opt;
+ while ((opt = get_opt ()) != EOF)
+ {
+ switch (opt)
+ {
+ case 'n':
+ {
+ // read the CosName from the NamingService
+ // convert the object_ptr to a CORBA::String_var
+ // via the call to object_to_string
+ cout << "opening a connection to the NamingService" << endl;
+ cout << "resolving the CosName " << get_opt.optarg << endl;
+ }
+ break;
+ case 'f':
+ {
+ // read the file into a CORBA::String_var
+ cout << "reading the file " << get_opt.optarg << endl;
+
+ ifstream ifstr (get_opt.optarg);
+
+ if(!ifstr.good())
+ {
+ ifstr.close();
+ return -1;
+ }
+
+ char ch;
+ ACE_CString aString;
+ while(!ifstr.eof())
+ {
+ ifstr.get(ch);
+ aString += ch;
+ }
+
+ cout << endl;
+ cout << "here is the IOR " << endl << aString << endl << endl;
+
+ CORBA::String str;
+ if(aString.find("IOR:") == 0)
+ {
+ cout << "decoding an IOR:" << endl;
+
+ // strip the IOR: off the string
+ ACE_CString prefix = "IOR:";
+ short prefixLength = prefix.length();
+
+ ACE_CString subString = aString.substring(prefixLength,aString.length()-prefixLength);
+ subString[subString.length()-1] = '\0';
+ str = subString.rep();
+ }
+ else if (aString.find("iiop:") == 0)
+ {
+ cout << "decoding an IIOP IOR " << endl;
+
+ ACE_CString prefix = "IIOP:";
+ short prefixLength = prefix.length() + 1;
+ cout << "prefix length = " << prefixLength << endl;
+ cout << aString.substring(prefixLength,aString.length()-prefixLength) << endl;
+ str = aString.rep();
+ }
+ else
+ {
+ cout << "Don't know how to decode this IOR " << endl;
+ return -1;
+ }
+
+ CORBA::Boolean b = catior(str, env);
+
+
+ if (b == CORBA::B_TRUE)
+ cout << "catior returned true " << endl;
+ else
+ cout << "catior returned false" << endl;
+
+ ifstr.close();
+
+ }
+ break;
+ case '?':
+ default:
+ ACE_DEBUG ((LM_DEBUG,
+ "Usage: %s "
+ "-f filename "
+ "-n CosName "
+ "\n"
+ "Reads an IOR "
+ "and dumps the contents to stdout "
+ "\n",
+ argv[0]));
+ return -1;
+ }
+ }
+
+ return 0;
+} \ No newline at end of file
diff --git a/TAO/utils/catior/catior.dsp b/TAO/utils/catior/catior.dsp
new file mode 100644
index 00000000000..85dd7fd180c
--- /dev/null
+++ b/TAO/utils/catior/catior.dsp
@@ -0,0 +1,91 @@
+# Microsoft Developer Studio Project File - Name="catior" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 5.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=catior - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "catior.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "catior.mak" CFG="catior - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "catior - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "catior - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "catior - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /GX /O2 /I "..\..\..\\" /I "..\..\\" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 ace.lib tao.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\\" /libpath:"..\..\\"
+
+!ELSEIF "$(CFG)" == "catior - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ""
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /Zi /Od /I "..\..\..\\" /I "..\..\\" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 aced.lib TAOd.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\ace" /libpath:"..\..\tao"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "catior - Win32 Release"
+# Name "catior - Win32 Debug"
+# Begin Source File
+
+SOURCE=.\catior.cpp
+# End Source File
+# End Target
+# End Project
diff --git a/TAO/utils/catior/catior.dsw b/TAO/utils/catior/catior.dsw
new file mode 100644
index 00000000000..09a9c7d68df
--- /dev/null
+++ b/TAO/utils/catior/catior.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 5.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "catior"=.\catior.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+