Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

Codeset_Manager.cpp

Go to the documentation of this file.
00001 #include "tao_pch.h"
00002 
00003 // $Id: Codeset_Manager.cpp,v 1.1.8.4 2003/05/08 14:44:51 phil Exp $
00004 #include "tao/Codeset_Manager.h"
00005 #include "tao/debug.h"
00006 #include "tao/CDR.h"
00007 #include "tao/TAO_Server_Request.h"
00008 #include "tao/operation_details.h"
00009 #include "tao/Transport.h"
00010 #include "tao/Profile.h"
00011 #include "tao/Exception.h"
00012 #include "tao/corbafwd.h"
00013 #include "tao/Codeset_Translator_Factory.h"
00014 #include "tao/TAO_Server_Request.h"
00015 #include "tao/Tagged_Components.h"
00016 
00017 #include "ace/Dynamic_Service.h"
00018 #include "ace/Codeset_Registry.h"
00019 
00020 ACE_RCSID(tao, Codeset_Manager, "$Id: Codeset_Manager.cpp,v 1.1.8.4 2003/05/08 14:44:51 phil Exp $")
00021 
00022 
00023 /// NCS for char is defaulted to ISO 8859-1:1987; Latin Alphabet No. 1
00024 CONV_FRAME::CodeSetId
00025 TAO_Codeset_Manager::default_char_codeset = TAO_DEFAULT_CHAR_CODESET_ID;
00026 /// NCS for wchar is not defaulted by the CORBA specification, but a default
00027 /// may be set here if desired
00028 CONV_FRAME::CodeSetId
00029 TAO_Codeset_Manager::default_wchar_codeset = TAO_DEFAULT_WCHAR_CODESET_ID;
00030 
00031 TAO_Codeset_Manager::TAO_Codeset_Manager()
00032   :codeset_info_ (),
00033    char_factories_ (),
00034    wchar_factories_ ()
00035 {
00036   this->codeset_info_.ForCharData.native_code_set =
00037     TAO_Codeset_Manager::default_char_codeset;
00038   this->codeset_info_.ForWcharData.native_code_set =
00039     TAO_Codeset_Manager::default_wchar_codeset;
00040 }
00041 
00042 TAO_Codeset_Manager::~TAO_Codeset_Manager()
00043 {
00044   // Cleanup the character map
00045   TAO_CodesetFactorySetItor cf_end = this->char_factories_.end ();
00046   TAO_CodesetFactorySetItor cf_iter = this->char_factories_.begin ();
00047   for (;cf_iter != cf_end; ++cf_iter)
00048     delete *cf_iter;
00049 
00050   this->char_factories_.reset ();
00051 
00052   // Cleanup the wide character map
00053   cf_end = this->wchar_factories_.end ();
00054   cf_iter = this->wchar_factories_.begin ();
00055   for (;cf_iter != cf_end; ++cf_iter)
00056     delete *cf_iter;
00057 
00058   this->wchar_factories_.reset ();
00059 }
00060 
00061 void
00062 TAO_Codeset_Manager::set_codeset (TAO_Tagged_Components& tc) const
00063 {
00064   tc.set_code_sets (this->codeset_info_);
00065 }
00066 
00067 void
00068 TAO_Codeset_Manager::set_tcs(TAO_Profile &theProfile,
00069                              TAO_Transport &trans)
00070 {
00071    /// If tcs is already set on the transport then donot process,
00072    /// use existing transport as CDR have translators set.
00073    if (trans.is_tcs_set())
00074      {
00075        if(TAO_debug_level > 2)
00076          ACE_DEBUG((LM_DEBUG,
00077                     ACE_LIB_TEXT("(%P|%t) Codeset_Manager::set_tcs ")
00078                     ACE_LIB_TEXT("transport already set\n")));
00079        return;
00080      }
00081 
00082    TAO_Tagged_Components& theTaggedComp = theProfile.tagged_components();
00083 
00084    CONV_FRAME::CodeSetComponentInfo remote;
00085    /// Get the codeset component
00086    if (theTaggedComp.get_code_sets(remote) == 0 )
00087    {
00088      if(TAO_debug_level > 2)
00089        ACE_DEBUG((LM_DEBUG,
00090                   ACE_LIB_TEXT("(%P|%t) Codeset_Manager::set_tcs ")
00091                   ACE_LIB_TEXT("No codeset componnet in profile\n")));
00092      remote.ForCharData.native_code_set =
00093        TAO_Codeset_Manager::default_char_codeset;
00094      remote.ForWcharData.native_code_set =
00095        TAO_Codeset_Manager::default_wchar_codeset;
00096    }
00097 
00098    CONV_FRAME::CodeSetId tcs = computeTCS (remote.ForCharData,
00099                                            this->codeset_info_.ForCharData);
00100    if (TAO_debug_level > 2)
00101      ACE_DEBUG ((LM_DEBUG,
00102                  ACE_LIB_TEXT("(%P|%t) Codeset_Manager::set_tcs ")
00103                  ACE_LIB_TEXT("setting char translator(%08x)\n"),
00104                  tcs));
00105    trans.char_translator(this->get_char_trans (tcs));
00106 
00107    tcs = computeTCS (remote.ForWcharData,
00108                      this->codeset_info_.ForWcharData);
00109 
00110    if (TAO_debug_level > 2)
00111      ACE_DEBUG ((LM_DEBUG,
00112                  ACE_LIB_TEXT("(%P|%t) Codeset_Manager::set_tcs ")
00113                  ACE_LIB_TEXT("setting wchar translator (%08x)\n"),
00114                  tcs));
00115    trans.wchar_translator(this->get_wchar_trans (tcs));
00116 }
00117 
00118 void
00119 TAO_Codeset_Manager::process_service_context (TAO_ServerRequest &request)
00120 {
00121   if (request.transport()->is_tcs_set())
00122     return;
00123 
00124   // Get the service Context from an object of TAO_ServerRequest
00125   // and set the TCS values on the Transport
00126   TAO_Service_Context &service_cntx = request.request_service_context ();
00127   IOP::ServiceContext context;
00128   context.context_id = IOP::CodeSets;
00129   CONV_FRAME::CodeSetId tcs_c = TAO_Codeset_Manager::default_char_codeset;
00130   CONV_FRAME::CodeSetId tcs_w = TAO_Codeset_Manager::default_wchar_codeset;
00131 
00132   if (service_cntx.get_context(context))
00133     {
00134       // Convert the Service Context to Codeset Context
00135       const char *buffer =
00136         ACE_reinterpret_cast(const char*,context.context_data.get_buffer ());
00137 
00138       TAO_InputCDR cdr (buffer,context.context_data.length ());
00139       CORBA::Boolean byte_order;
00140       if (cdr >> TAO_InputCDR::to_boolean (byte_order))
00141         {
00142           cdr.reset_byte_order (ACE_static_cast (int, byte_order));
00143           cdr >> tcs_c;
00144           cdr >> tcs_w;
00145         }
00146     }
00147 
00148   if (TAO_debug_level > 2)
00149     ACE_DEBUG ((LM_DEBUG,
00150                 ACE_LIB_TEXT("(%P|%t) Codeset_Manager::process_service_context ")
00151                 ACE_LIB_TEXT("using tcsc = %08x, tcsw = %08x\n"),
00152                 tcs_c,tcs_w));
00153 
00154   request.transport()->char_translator(this->get_char_trans (tcs_c));
00155   request.transport()->wchar_translator(this->get_wchar_trans (tcs_w));
00156 }
00157 
00158 void
00159 TAO_Codeset_Manager::generate_service_context (TAO_Operation_Details &opd,
00160                                                TAO_Transport &trans)
00161 {
00162   TAO_Service_Context &service_cntx = opd.request_service_context ();
00163   CONV_FRAME::CodeSetContext codeset_cntx;
00164 
00165   // Generating codeset context
00166   // Assuming the TCS values from Transport will be defaulted
00167   TAO_Codeset_Translator_Factory *tf = trans.char_translator();
00168   codeset_cntx.char_data = tf ? tf->tcs() :
00169     this->codeset_info_.ForCharData.native_code_set;
00170   tf = trans.wchar_translator();
00171   codeset_cntx.wchar_data = tf ? tf->tcs() :
00172     this->codeset_info_.ForWcharData.native_code_set;
00173   if (TAO_debug_level > 2)
00174     ACE_DEBUG ((LM_DEBUG,
00175                 ACE_LIB_TEXT("(%P|%t) Codeset_Manager::generate_service_context ")
00176                 ACE_LIB_TEXT("using tcs_c = %08x, tcs_w = %08x\n"),
00177                 codeset_cntx.char_data,
00178                 codeset_cntx.wchar_data));
00179 
00180   TAO_OutputCDR codeset_cdr;
00181   codeset_cdr << TAO_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER);
00182   codeset_cdr << codeset_cntx;
00183 
00184   service_cntx.set_context (IOP::CodeSets,codeset_cdr);
00185 }
00186 
00187 /// Checks whether the NCS is a part of CCS
00188 int
00189 TAO_Codeset_Manager::isElementOf (CONV_FRAME::CodeSetId id,
00190                                   CONV_FRAME::CodeSetComponent &cs_comp)
00191 {
00192   for (CORBA::ULong i=0L;
00193        i < cs_comp.conversion_code_sets.length();
00194        ++i )
00195     {
00196       if (id == cs_comp.conversion_code_sets[i])
00197         return 1;
00198     }
00199   return 0;
00200 }
00201 
00202 /// Find the Intersection of Client and Server CCS's
00203 CONV_FRAME::CodeSetId
00204 TAO_Codeset_Manager::intersectionOf (CONV_FRAME::CodeSetComponent &cs_comp1,
00205                                      CONV_FRAME::CodeSetComponent &cs_comp2)
00206 {
00207   for(CORBA::ULong index=0L;
00208        index < cs_comp1.conversion_code_sets.length();
00209        ++index )
00210     if (this->isElementOf(cs_comp1.conversion_code_sets[index], cs_comp2))
00211       return cs_comp1.conversion_code_sets[index];
00212   return 0;
00213 }
00214 
00215 int
00216 TAO_Codeset_Manager::isCompatible(CONV_FRAME::CodeSetId cs1,
00217                                   CONV_FRAME::CodeSetId cs2 )
00218 {
00219   // Call the is_compatible method of ACE_Codeset_Registry
00220   return ACE_Codeset_Registry::is_compatible(cs1,cs2);
00221 }
00222 
00223 /// returns the TCS for Char / Wchar
00224 CONV_FRAME::CodeSetId
00225 TAO_Codeset_Manager::computeTCS (CONV_FRAME::CodeSetComponent &remote,
00226                                  CONV_FRAME::CodeSetComponent &local )
00227 {
00228   if (remote.native_code_set == local.native_code_set)
00229     return local.native_code_set;
00230 
00231   if (this->isElementOf (remote.native_code_set, local))
00232     return remote.native_code_set;
00233 
00234   if (this->isElementOf (local.native_code_set, remote))
00235     return local.native_code_set;
00236 
00237   CONV_FRAME::CodeSetId tcs;
00238   if ((tcs = this->intersectionOf (remote, local)) == 0)
00239     if (isCompatible (local.native_code_set, remote.native_code_set))
00240       return remote.native_code_set;
00241     else
00242       {
00243         ACE_DECLARE_NEW_CORBA_ENV;
00244         ACE_THROW_RETURN(CORBA::CODESET_INCOMPATIBLE(),0);
00245       }
00246   return tcs;
00247 }
00248 
00249 void
00250 TAO_Codeset_Manager::set_ncs_c (CONV_FRAME::CodeSetId ncs)
00251 {
00252   this->codeset_info_.ForCharData.native_code_set = ncs;
00253 }
00254 
00255 void
00256 TAO_Codeset_Manager::set_ncs_w (CONV_FRAME::CodeSetId ncs,int mb)
00257 {
00258   this->codeset_info_.ForWcharData.native_code_set = ncs;
00259   ACE_OutputCDR::wchar_maxbytes(mb);
00260 }
00261 
00262 int
00263 TAO_Codeset_Manager::add_char_translator (const char *name)
00264 {
00265   TAO_Codeset_Item *item = 0;
00266   ACE_NEW_RETURN (item, TAO_Codeset_Item (name), -1);
00267   if (this->char_factories_.insert (item) == -1)
00268     ACE_ERROR_RETURN ((LM_ERROR,
00269                 ACE_LIB_TEXT ("(%P|%t) Unable to add Codeset ")
00270                 ACE_LIB_TEXT ("factories for %s: %p\n"),
00271                 name), -1);
00272   return 0;
00273 }
00274 
00275 int
00276 TAO_Codeset_Manager::add_wchar_translator (const char *name)
00277 {
00278   TAO_Codeset_Item *item = 0;
00279   ACE_NEW_RETURN (item, TAO_Codeset_Item (name), -1);
00280   if (this->wchar_factories_.insert (item) == -1)
00281     ACE_ERROR_RETURN ((LM_ERROR,
00282                 ACE_LIB_TEXT ("(%P|%t) Unable to add Codeset ")
00283                 ACE_LIB_TEXT ("factories for %s: %p\n"),
00284                 name),-1);
00285   return 0;
00286 }
00287 
00288 void
00289 TAO_Codeset_Manager::configure_codeset_factories()
00290 {
00291   if (init_codeset_factories_i (this->char_factories_,
00292                                 this->codeset_info_.ForCharData) == -1)
00293       ACE_ERROR ((LM_ERROR,
00294                   ACE_LIB_TEXT ("TAO (%P|%t) failed to init char ")
00295                   ACE_LIB_TEXT ("codeset factories\n")));
00296   if (init_codeset_factories_i (this->wchar_factories_,
00297                                 this->codeset_info_.ForWcharData) == -1)
00298       ACE_ERROR ((LM_ERROR,
00299                   ACE_LIB_TEXT ("TAO (%P|%t) failed to init wchar ")
00300                   ACE_LIB_TEXT ("codeset factories\n")));
00301   if (this->codeset_info_.ForWcharData.native_code_set == 0)
00302     ACE_OutputCDR::wchar_maxbytes(0); // disallow wchar when no ncs_w set
00303 }
00304 
00305 /// Initialise the specific type codeset factories
00306 int
00307 TAO_Codeset_Manager::init_codeset_factories_i (TAO_CodesetFactorySet& factset,
00308                                                CONV_FRAME::CodeSetComponent& cs_comp)
00309 {
00310   TAO_CodesetFactorySetItor end = factset.end ();
00311   TAO_CodesetFactorySetItor iter = factset.begin ();
00312 
00313   CONV_FRAME::CodeSetId ncs = cs_comp.native_code_set;
00314   cs_comp.conversion_code_sets.length(ACE_static_cast(CORBA::ULong,
00315                                                       factset.size()));
00316   CORBA::ULong index;
00317 
00318   for (index=0; iter != end; iter++)
00319     {
00320       const char *name = (*iter)->codeset_name ();
00321       TAO_Codeset_Translator_Factory *trans =
00322         ACE_Dynamic_Service<TAO_Codeset_Translator_Factory>::instance (name);
00323       if (trans == 0)
00324         {
00325           ACE_ERROR ((LM_ERROR,
00326                       ACE_LIB_TEXT ("TAO (%P|%t) Unable to load ")
00327                       ACE_LIB_TEXT ("CodeSet <%s>, %p\n"),
00328                       ACE_TEXT_CHAR_TO_TCHAR(name), ""));
00329           continue;
00330         }
00331       if (trans->ncs() == ncs)
00332         {
00333           (*iter)->factory (trans);
00334           cs_comp.conversion_code_sets[index++] = trans->tcs();
00335           if (TAO_debug_level > 2)
00336             ACE_DEBUG ((LM_DEBUG,
00337                         ACE_LIB_TEXT ("TAO (%P|%t) Loaded CodeSet <%s>, ")
00338                         ACE_LIB_TEXT ("ncs = %08x tcs = %08x\n"),
00339                         ACE_TEXT_CHAR_TO_TCHAR(name),
00340                         trans->ncs(),trans->tcs()));
00341         }
00342     }
00343   cs_comp.conversion_code_sets.length(index);
00344   return 0;
00345 }
00346 
00347 TAO_Codeset_Translator_Factory *
00348 TAO_Codeset_Manager::get_char_trans (CONV_FRAME::CodeSetId tcs)
00349 {
00350   if (this->codeset_info_.ForCharData.native_code_set == tcs)
00351     return 0;
00352   return this->get_translator_i (this->char_factories_,tcs);
00353 }
00354 
00355 TAO_Codeset_Translator_Factory *
00356 TAO_Codeset_Manager::get_wchar_trans (CONV_FRAME::CodeSetId tcs)
00357 {
00358   if (this->codeset_info_.ForWcharData.native_code_set == tcs)
00359     return 0;
00360   return this->get_translator_i (this->wchar_factories_,tcs);
00361 }
00362 
00363 TAO_Codeset_Translator_Factory *
00364 TAO_Codeset_Manager::get_translator_i (TAO_CodesetFactorySet& factset,
00365                                        CONV_FRAME::CodeSetId tcs)
00366 {
00367   TAO_CodesetFactorySetItor end = factset.end ();
00368   TAO_CodesetFactorySetItor iter = factset.begin ();
00369 
00370   for (; iter != end; iter++)
00371     {
00372       TAO_Codeset_Translator_Factory *fact = (*iter)->factory ();
00373       if (fact && tcs == fact->tcs())
00374           return fact;
00375     }
00376 
00377   return 0;
00378 }
00379 
00380 
00381 //---------------------------------------------------------------------
00382 // Codeset Item
00383 TAO_Codeset_Item::TAO_Codeset_Item (const char *name)
00384   :   name_ (0),
00385       factory_ (0)
00386 {
00387   if (name)
00388     name_ = ACE_OS::strdup(name);
00389 }
00390 
00391 TAO_Codeset_Item::~TAO_Codeset_Item (void)
00392 {
00393   delete [] this->name_;
00394 }
00395 
00396 const char *
00397 TAO_Codeset_Item::codeset_name (void)
00398 {
00399   return this->name_;
00400 }
00401 
00402 TAO_Codeset_Translator_Factory *
00403 TAO_Codeset_Item::factory (void)
00404 {
00405   return this->factory_;
00406 }
00407 
00408 void
00409 TAO_Codeset_Item::factory (TAO_Codeset_Translator_Factory *factory)
00410 {
00411   this->factory_ = factory;
00412 }
00413 
00414 // End of Codeset Item Class
00415 
00416 
00417 
00418 #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
00419 
00420 template class ACE_Dynamic_Service<TAO_Codeset_Translator_Factory>;
00421 
00422 template class ACE_Node<TAO_Codeset_Item*>;
00423 template class ACE_Unbounded_Set<TAO_Codeset_Item*>;
00424 template class ACE_Unbounded_Set_Iterator<TAO_Codeset_Item*>;
00425 
00426 #elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
00427 
00428 #pragma instantiate ACE_Dynamic_Service<TAO_Codeset_Translator_Factory>
00429 #pragma instantiate ACE_Node<TAO_Codeset_Item*>
00430 ///
00431 #pragma instantiate ACE_Unbounded_Set<TAO_Codeset_Item*>
00432 #pragma instantiate ACE_Unbounded_Set_Iterator<TAO_Codeset_Item*>
00433 
00434 #  endif

Generated on Mon Jun 16 13:48:05 2003 for TAO by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002