CORBA_IORUtil.cpp
Go to the documentation of this file.
00001 // -*- C++ -*-
00018 #include <iostream>
00019 #include <sstream>
00020 #include <rtm/CORBA_IORUtil.h>
00021 
00022 #define POA_NAME_SEP            '\xff'
00023 #define TRANSIENT_SUFFIX_SEP    '\xfe'
00024 #define TRANSIENT_SUFFIX_SIZE   8
00025 
00026 namespace CORBA_IORUtil
00027 {
00028 
00029 #ifdef ORB_IS_OMNIORB
00030   typedef _CORBA_Unbounded_Sequence_Octet OctetUSequence;
00031   typedef _CORBA_Unbounded_Sequence_String StringUSequence;
00032 #endif
00033 
00034 #ifndef ORB_IS_RTORB
00035   // prototype of static functions 
00036   static void print_key(std::stringstream& s, OctetUSequence& key);
00037   
00038   static void print_omni_key(std::stringstream& sstr, OctetUSequence& key);
00039 
00040   static int get_poa_info(OctetUSequence& key, StringUSequence& poas_out,
00041                           int& transient_out, OctetUSequence& id_out);
00042 
00043   static void print_tagged_components(std::stringstream& sstr,
00044                                       IOP::MultipleComponentProfile& comps);
00045 #endif // ORB_IS_RTORB
00046 
00047 
00055   bool toIOR(const char* iorstr, IOP::IOR& ior)
00056   {
00057 #ifndef ORB_IS_RTORB
00058     if (iorstr == 0) { return false; }
00059     size_t size = strlen(iorstr);
00060 
00061     if (size < 4)
00062       {
00063         return false;
00064         throw CORBA::MARSHAL(0,CORBA::COMPLETED_NO);
00065       }
00066 
00067     const char* p = iorstr;
00068 
00069     if (p[0] != 'I' || p[1] != 'O' || p[2] != 'R' || p[3] != ':')
00070       {
00071         return false;
00072         throw CORBA::MARSHAL(0,CORBA::COMPLETED_NO);
00073       }
00074 
00075     // IOR:xxyyzz......
00076     // "IOR:" occupies 4 digits.
00077     // two digits express one byte, and all byte sequence express IOR profile
00078     size = (size - 4) / 2;  // how many octets are there in the string
00079     p += 4;
00080 
00081     cdrMemoryStream buf((CORBA::ULong)size, 0);
00082     for (int i(0); i < (int)size; ++i)
00083       {
00084         CORBA::Octet v;
00085         // upper digit
00086         int j(i * 2);
00087         if      (p[j] >= '0' && p[j] <= '9') { v = ((p[j] - '0') << 4);      }
00088         else if (p[j] >= 'a' && p[j] <= 'f') { v = ((p[j] - 'a' + 10) << 4); }
00089         else if (p[j] >= 'A' && p[j] <= 'F') { v = ((p[j] - 'A' + 10) << 4); }
00090         else                                 { return false;                 }
00091         // lower digit
00092         int k(j + 1);
00093         if      (p[k] >= '0' && p[k] <= '9') { v += (p[k] - '0');            }
00094         else if (p[k] >= 'a' && p[k] <= 'f') { v += (p[k] - 'a' + 10);       }
00095         else if (p[k] >= 'A' && p[k] <= 'F') { v += (p[k] - 'A' + 10);       }
00096         else                                 { return false;                 }
00097         // push_back to buffer
00098         buf.marshalOctet(v);
00099       }
00100 
00101     buf.rewindInputPtr();
00102     CORBA::Boolean b = buf.unmarshalBoolean();
00103     buf.setByteSwapFlag(b);
00104 
00105     ior.type_id = IOP::IOR::unmarshaltype_id(buf);
00106     ior.profiles <<= buf;
00107     return true;
00108 #else // ORB_IS_RTORB
00109     // RtORB does not supports this function
00110     return false;
00111 #endif // ORB_IS_RTORB
00112   }
00113 
00121   bool toString(IOP::IOR& ior, std::string& iorstr)
00122   {
00123 #ifndef ORB_IS_RTORB
00124     cdrMemoryStream buf(CORBA::ULong(0),CORBA::Boolean(1));
00125     buf.marshalBoolean(omni::myByteOrder);
00126     buf.marshalRawString(ior.type_id);
00127     ior.profiles >>= buf;
00128 
00129     // turn the encapsulation into a hex string with "IOR:" prepended
00130     buf.rewindInputPtr();
00131     size_t s = buf.bufSize();
00132     CORBA::Char* data = (CORBA::Char *)buf.bufPtr();
00133     
00134     char *result = new char[4 + s * 2 + 1];
00135     result[4 + s * 2] = '\0';
00136     result[0] = 'I';
00137     result[1] = 'O';
00138     result[2] = 'R';
00139     result[3] = ':';
00140 
00141     for (int i(0); i < (int)s; ++i)
00142       {
00143         int j = 4 + i * 2;
00144         int v = (data[i] & 0xf0);
00145 
00146         v = v >> 4;
00147         if (v < 10)
00148           {
00149             result[j] = '0' + v;
00150           }
00151         else
00152           {
00153             result[j] = 'a' + (v - 10);
00154           }
00155         v = ((data[i] & 0xf));
00156         if (v < 10)
00157           {
00158             result[j+1] = '0' + v;
00159           }
00160         else
00161           {
00162             result[j+1] = 'a' + (v - 10);
00163           }
00164       }
00165     iorstr = result;
00166     delete result;
00167     return true;
00168 #else // ORB_IS_RTORB
00169     // RtORB does not this function.
00170     return false;
00171 #endif // ORB_IS_RTORB
00172   }
00173 
00181   bool replaceEndpoint(std::string& iorstr, const std::string& endpoint)
00182   {
00183 #ifndef ORB_IS_RTORB
00184     try
00185       {
00186         IOP::IOR ior;
00187         toIOR(iorstr.c_str(), ior);
00188 
00189         for (unsigned long count(0); count < ior.profiles.length(); ++count)
00190           {
00191 
00192             if (ior.profiles[count].tag == IOP::TAG_INTERNET_IOP)
00193               {
00194                 IIOP::ProfileBody pBody;
00195                 IIOP::unmarshalProfile(ior.profiles[count], pBody);
00196                 pBody.address.host = endpoint.c_str();
00197 
00198                 IOP::TaggedProfile profile;
00199                 // profile_data is cctet sequence
00200                 IIOP::encodeProfile(pBody, profile);
00201                 CORBA::ULong max = profile.profile_data.maximum();
00202                 CORBA::ULong len = profile.profile_data.length();
00203                 CORBA::Octet* buf = profile.profile_data.get_buffer(1);
00204                 // replace is not standard function
00205                 ior.profiles[count].profile_data.replace(max, len, buf, 1);
00206               }
00207           }
00208         return toString(ior, iorstr);
00209 
00210       }
00211     catch(...)
00212       {
00213         return false;
00214       }
00215 #endif // ORB_IS_RTORB
00216     return false;
00217   }
00218 
00226   std::string formatIORinfo(const char* iorstr)
00227   {
00228     std::stringstream retstr;
00229 #ifndef ORB_IS_RTORB
00230     IOP::IOR ior;
00231     toIOR(iorstr, ior);
00232 
00233     if (ior.profiles.length() == 0 && strlen(ior.type_id) == 0)
00234       {
00235         retstr << "IOR is a nil object reference." << std::endl;
00236         retstr << iorstr << std::endl;
00237         return retstr.str();
00238       }
00239 
00240     retstr << "IOR information" << std::endl; 
00241     retstr << "  Type ID: \"" << (const char*) ior.type_id
00242            << "\"" << std::endl;;
00243     retstr << "  Profiles:" << std::endl;;
00244     for (unsigned long count=0; count < ior.profiles.length(); ++count)
00245       {
00246         retstr << "    " << count + 1 << ". ";
00247         if (ior.profiles[count].tag == IOP::TAG_INTERNET_IOP)
00248           {
00249             IIOP::ProfileBody pBody;
00250             IIOP::unmarshalProfile(ior.profiles[count], pBody);
00251             
00252             retstr << "IIOP " << (int) pBody.version.major << "."
00253                    << (int) pBody.version.minor << " ";
00254             retstr << (const char*) pBody.address.host 
00255                    << " " << pBody.address.port << std::endl;
00256             
00257             print_omni_key(retstr, pBody.object_key);
00258             print_key(retstr, pBody.object_key);
00259             print_tagged_components(retstr, pBody.components);
00260             
00261             retstr << std::endl;
00262           }
00263         else if (ior.profiles[count].tag == IOP::TAG_MULTIPLE_COMPONENTS)
00264           {
00265             
00266             retstr << "Multiple Component Profile ";
00267             IIOP::ProfileBody pBody;
00268             IIOP::unmarshalMultiComponentProfile(ior.profiles[count],
00269                                                  pBody.components);
00270             print_tagged_components(retstr, pBody.components);
00271             
00272             retstr << std::endl;
00273             
00274           }
00275         else
00276           {
00277             retstr << "Unrecognised profile tag: 0x"
00278                    << std::hex
00279                    << (unsigned)(ior.profiles[count].tag)
00280                    << std::dec
00281                    << std::endl;
00282           }
00283       }
00284 #else // ORB_IS_RTORB
00285     retstr << "RtORB does't support formatIORinfo() function." << std::endl;
00286 #endif // ORB_IS_RTORB
00287     return retstr.str();
00288   }
00289 
00290 
00291 #ifndef ORB_IS_RTORB
00292   //------------------------------------------------------------
00293   // static functions
00294 
00295   static void print_key(std::stringstream& sstr, OctetUSequence& key)
00296   {
00297     // Output key as text
00298     sstr << "       Object Key: \"";
00299     for(unsigned int j = 0; j < key.length(); ++j)
00300       {
00301         if( (char) key[j] >= ' ' && (char) key[j] <= '~')
00302           {
00303             sstr << (char) key[j];
00304           }
00305         else
00306           {
00307             sstr << ".";
00308           }
00309       }
00310     sstr << "\"";
00311 
00312     // Output key in hexadecimal form.
00313     sstr << " = 0x";
00314     for(unsigned int j(0); j < key.length(); ++j)
00315       {
00316         int v = (key[j] & 0xf0) >> 4;
00317         if (v < 10) { sstr << (char)('0' + v); }
00318         else        { sstr << (char)('a' + (v - 10)); }
00319         v = key[j] & 0xf;
00320         if (v < 10) { sstr << (char)('0' + v); }
00321         else        { sstr << (char)('a' + (v - 10)); }
00322       }
00323     sstr << "  (" << key.length() << " bytes)" << std::endl;
00324   }
00325 
00326   static void print_omni_key(std::stringstream& sstr, OctetUSequence& key)
00327   {
00328     StringUSequence poas;
00329     int is_transient;
00330     OctetUSequence id;
00331     
00332     if(get_poa_info(key, poas, is_transient, id))
00333       {
00334         sstr << "       POA(" << (char*)poas[0];
00335         for(unsigned i(1); i < poas.length(); ++i)
00336           {
00337             sstr << '/' << (char*)poas[i];
00338           }
00339         sstr << ") ";
00340       }
00341     else
00342       {
00343         if(key.length() != sizeof(omniOrbBoaKey))
00344           {
00345             return;
00346           }
00347         sstr << "BOA ";
00348       }
00349     print_key(sstr, id);
00350   }
00351   
00352   static int get_poa_info(OctetUSequence& key, StringUSequence& poas_out,
00353                           int& transient_out, OctetUSequence& id_out)
00354   {
00355     const char* k = (const char*) key.NP_data();
00356     int len = key.length();
00357     const char* kend = k + len;
00358     
00359     poas_out.length(1);
00360     poas_out[0] = CORBA::string_dup("root");
00361     
00362     if(*k != TRANSIENT_SUFFIX_SEP && *k != POA_NAME_SEP) { return 0; }
00363     
00364     while(k < kend && *k == POA_NAME_SEP)
00365       {
00366         ++k;
00367         const char* name = k;
00368         
00369         while(k < kend && *k && *k != POA_NAME_SEP 
00370               && *k != TRANSIENT_SUFFIX_SEP)
00371           {
00372             ++k;
00373           }
00374         if(k == kend)  { return 0; }
00375     
00376         char* nm = new char[k - name + 1];
00377         memcpy(nm, name, k - name);
00378         nm[k - name] = '\0';
00379         poas_out.length(poas_out.length() + 1);
00380         poas_out[poas_out.length() - 1] = nm;
00381       }
00382     if(k == kend)  { return 0; }
00383     
00384     transient_out = 0;
00385     if(*k == TRANSIENT_SUFFIX_SEP)
00386       {
00387         transient_out = 1;
00388         k += TRANSIENT_SUFFIX_SIZE + 1;
00389       }
00390     if(k >= kend || *k)  { return 0; }
00391     k++;
00392 
00393     id_out.length(kend - k);
00394     memcpy(id_out.NP_data(), k, kend - k);
00395 
00396     return 1;
00397   }
00398 
00399   static void print_tagged_components(std::stringstream& sstr,
00400                                       IOP::MultipleComponentProfile& components)
00401   {
00402     CORBA::ULong total(components.length());
00403     
00404     for (CORBA::ULong index(0); index < total; ++index)
00405       {
00406         try
00407           {
00408             CORBA::String_var content;
00409             content = IOP::dumpComponent(components[index]);
00410             char* p = content;
00411             char* q;
00412             do
00413               {
00414                 q = strchr(p,'\n');
00415                 if (q)
00416                   {
00417                     *q++ = '\0';
00418                   }
00419                 sstr << "       " << (const char*) p << std::endl;
00420                 p = q;
00421               } while (q);
00422           }
00423         catch (CORBA::MARSHAL& ex)
00424           {
00425             sstr << "       Broken component" << std::endl;
00426           }
00427       }
00428   }
00429 #endif // ORB_IS_RTORB
00430 };


openrtm_aist
Author(s): Noriaki Ando
autogenerated on Thu Aug 27 2015 14:16:37