diff options
author | brunsch <brunsch@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-08-26 20:54:51 +0000 |
---|---|---|
committer | brunsch <brunsch@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 1998-08-26 20:54:51 +0000 |
commit | 48adba463ee71680888f6605e13cea24af661b17 (patch) | |
tree | 8cbd00fda46e90abb00b0358c099ce39c6fbb748 | |
parent | 89fc6f92698d858075cd67e91126b01775f16a34 (diff) | |
download | ATCD-48adba463ee71680888f6605e13cea24af661b17.tar.gz |
decodes stringified iors
-rw-r--r-- | TAO/utils/catior/catior.cpp | 445 | ||||
-rw-r--r-- | TAO/utils/catior/catior.dsp | 91 | ||||
-rw-r--r-- | TAO/utils/catior/catior.dsw | 29 |
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>
+{{{
+}}}
+
+###############################################################################
+
|