00001
00002
00003 #include "tao/TAO_Server_Request.h"
00004 #include "tao/operation_details.h"
00005 #include "tao/Transport.h"
00006 #include "tao/Profile.h"
00007 #include "tao/SystemException.h"
00008 #include "tao/debug.h"
00009 #include "tao/CDR.h"
00010 #include "tao/ORB_Core.h"
00011
00012 #include "tao/Codeset/Codeset_Descriptor.h"
00013 #include "tao/Codeset/Codeset_Manager_i.h"
00014 #include "tao/Codeset/Codeset_Translator_Factory.h"
00015 #include "tao/Codeset/Codeset.h"
00016 #include "tao/Codeset/CodeSetContextC.h"
00017 #include "tao/Codeset/Codeset_Service_Context_Handler.h"
00018
00019 #include "ace/Dynamic_Service.h"
00020 #include "ace/Codeset_Registry.h"
00021 #include "ace/OS_NS_string.h"
00022 #include "ace/Service_Config.h"
00023
00024
00025 ACE_RCSID (Codeset,
00026 Codeset_Manager_i,
00027 "$Id: Codeset_Manager_i.cpp 84860 2009-03-17 10:17:38Z johnnyw $")
00028
00029
00030
00031
00032
00033
00034
00035 #define TAO_CODESET_ID_ISO8859_1 0x00010001U
00036 #define TAO_CODESET_ID_UNICODE 0x00010109U
00037 #define TAO_CODESET_ID_XOPEN_UTF_8 0x05010001U
00038
00039
00040
00041
00042
00043 #if (defined TAO_DEFAULT_CHAR_CODESET_ID)
00044 # undef TAO_DEFAULT_CHAR_CODESET_ID
00045 #endif
00046
00047 #if (defined TAO_DEFAULT_WCHAR_CODESET_ID)
00048 # undef TAO_DEFAULT_WCHAR_CODESET_ID
00049 #endif
00050
00051
00052 #define TAO_DEFAULT_CHAR_CODESET_ID TAO_CODESET_ID_ISO8859_1
00053 #define TAO_DEFAULT_WCHAR_CODESET_ID TAO_CODESET_ID_UNICODE
00054
00055
00056
00057 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00058
00059
00060 CONV_FRAME::CodeSetId
00061 TAO_Codeset_Manager_i::default_char_codeset = TAO_DEFAULT_CHAR_CODESET_ID;
00062
00063
00064 CONV_FRAME::CodeSetId
00065 TAO_Codeset_Manager_i::default_wchar_codeset = TAO_DEFAULT_WCHAR_CODESET_ID;
00066
00067 TAO_Codeset_Manager_i::TAO_Codeset_Manager_i (void)
00068 : codeset_info_ (),
00069 char_descriptor_ (),
00070 wchar_descriptor_ ()
00071 {
00072 char_descriptor_.ncs(TAO_Codeset_Manager_i::default_char_codeset);
00073 char_descriptor_.add_translator (ACE_TEXT ("UTF8_Latin1_Factory"));
00074
00075 wchar_descriptor_.ncs(TAO_Codeset_Manager_i::default_wchar_codeset);
00076 wchar_descriptor_.add_translator (ACE_TEXT ("UTF16_BOM_Factory"));
00077
00078 }
00079
00080 TAO_Codeset_Manager_i::~TAO_Codeset_Manager_i (void)
00081 {
00082 }
00083
00084 TAO_Codeset_Descriptor_Base *
00085 TAO_Codeset_Manager_i::char_codeset_descriptor (void)
00086 {
00087 return &this->char_descriptor_;
00088 }
00089
00090 TAO_Codeset_Descriptor_Base *
00091 TAO_Codeset_Manager_i::wchar_codeset_descriptor (void)
00092 {
00093 return &this->wchar_descriptor_;
00094 }
00095
00096 void
00097 TAO_Codeset_Manager_i::set_codeset (TAO_Tagged_Components& tc) const
00098 {
00099 tc.set_code_sets (this->codeset_info_);
00100 }
00101
00102 void
00103 TAO_Codeset_Manager_i::set_tcs (TAO_Profile &theProfile,
00104 TAO_Transport &trans)
00105 {
00106
00107
00108 TAO_Tagged_Components& theTaggedComp = theProfile.tagged_components ();
00109
00110 CONV_FRAME::CodeSetComponentInfo remote;
00111
00112
00113 if (theTaggedComp.get_code_sets(remote) == 0 )
00114 {
00115 if (trans.is_tcs_set ())
00116 {
00117 if(TAO_debug_level > 2)
00118 ACE_DEBUG ((LM_DEBUG,
00119 ACE_TEXT ("TAO (%P|%t) - Codeset_Manager_i::set_tcs, ")
00120 ACE_TEXT ("transport already set\n")));
00121 return;
00122 }
00123 if (TAO_debug_level > 2)
00124 ACE_DEBUG ((LM_DEBUG,
00125 ACE_TEXT ("TAO (%P|%t) - Codeset_Manager_i::set_tcs, ")
00126 ACE_TEXT ("No codeset component in profile\n")));
00127
00128
00129
00130 remote.ForCharData.native_code_set =
00131 TAO_CODESET_ID_XOPEN_UTF_8;
00132 remote.ForWcharData.native_code_set =
00133 TAO_CODESET_ID_UNICODE;
00134
00135 trans.char_translator
00136 (this->get_char_trans
00137 (TAO_Codeset_Manager_i::default_char_codeset));
00138 trans.wchar_translator
00139 (this->get_wchar_trans
00140 (TAO_Codeset_Manager_i::default_wchar_codeset));
00141 }
00142 else
00143 {
00144 CONV_FRAME::CodeSetId tcs =
00145 computeTCS (remote.ForCharData,
00146 this->codeset_info_.ForCharData);
00147 if (TAO_debug_level > 2)
00148 ACE_DEBUG ((LM_DEBUG,
00149 ACE_TEXT("TAO (%P|%t) - Codeset_Manager_i::set_tcs, ")
00150 ACE_TEXT("setting char translator (%08x)\n"),
00151 tcs));
00152 trans.char_translator(this->get_char_trans (tcs));
00153
00154 tcs = computeTCS (remote.ForWcharData,
00155 this->codeset_info_.ForWcharData);
00156
00157 if (TAO_debug_level > 2)
00158 ACE_DEBUG ((LM_DEBUG,
00159 ACE_TEXT("TAO (%P|%t) - Codeset_Manager_i::set_tcs, ")
00160 ACE_TEXT("setting wchar translator (%08x)\n"),
00161 tcs));
00162 trans.wchar_translator(this->get_wchar_trans (tcs));
00163 }
00164 }
00165
00166 void
00167 TAO_Codeset_Manager_i::process_service_context (TAO_ServerRequest &request)
00168 {
00169
00170
00171 TAO_Service_Context &service_cntx = request.request_service_context ();
00172 IOP::ServiceContext context;
00173 context.context_id = IOP::CodeSets;
00174
00175
00176
00177 CONV_FRAME::CodeSetId tcs_c = TAO_CODESET_ID_XOPEN_UTF_8;
00178 CONV_FRAME::CodeSetId tcs_w = TAO_CODESET_ID_UNICODE;
00179
00180 if (service_cntx.get_context(context))
00181 {
00182
00183 const char *buffer =
00184 reinterpret_cast<const char*> (context.context_data.get_buffer ());
00185
00186 TAO_InputCDR cdr (buffer,context.context_data.length ());
00187 CORBA::Boolean byte_order;
00188
00189 if (cdr >> TAO_InputCDR::to_boolean (byte_order))
00190 {
00191 cdr.reset_byte_order (static_cast<int> (byte_order));
00192 cdr >> tcs_c;
00193 cdr >> tcs_w;
00194 }
00195 }
00196 else
00197 {
00198 if (request.transport()->is_tcs_set())
00199 return;
00200 if (TAO_debug_level > 0)
00201 ACE_DEBUG ((LM_DEBUG,
00202 ACE_TEXT("TAO (%P|%t) - ")
00203 ACE_TEXT("Codeset_Manager_i::process_service_context ")
00204 ACE_TEXT("no codeset context in request, using defaults\n")
00205 ));
00206 tcs_c = TAO_Codeset_Manager_i::default_char_codeset;
00207 tcs_w = TAO_Codeset_Manager_i::default_wchar_codeset;
00208 }
00209 if (TAO_debug_level > 2)
00210 {
00211 ACE_CString tcs_c_locale;
00212 ACE_CString tcs_w_locale;
00213 ACE_Codeset_Registry::registry_to_locale (tcs_c, tcs_c_locale, 0, 0);
00214 ACE_Codeset_Registry::registry_to_locale (tcs_w, tcs_w_locale, 0, 0);
00215 ACE_DEBUG ((LM_DEBUG,
00216 ACE_TEXT ("TAO (%P|%t) - Codeset_Manager_i::")
00217 ACE_TEXT ("process_service_context, ")
00218 ACE_TEXT ("using tcsc <%C> (%08x), tcsw <%C> (%08x)\n"),
00219 tcs_c_locale.c_str (), tcs_c, tcs_w_locale.c_str (), tcs_w));
00220 }
00221
00222 request.transport()->char_translator(this->get_char_trans (tcs_c));
00223 request.transport()->wchar_translator(this->get_wchar_trans (tcs_w));
00224 }
00225
00226 void
00227 TAO_Codeset_Manager_i::generate_service_context (TAO_Operation_Details &opd,
00228 TAO_Transport &trans)
00229 {
00230 TAO_Service_Context &service_cntx = opd.request_service_context ();
00231 CONV_FRAME::CodeSetContext codeset_cntx;
00232
00233
00234
00235 TAO_Codeset_Translator_Factory *tf =
00236 dynamic_cast<TAO_Codeset_Translator_Factory*>(trans.char_translator());
00237
00238 codeset_cntx.char_data =
00239 tf ? tf->tcs () : this->codeset_info_.ForCharData.native_code_set;
00240
00241 tf =
00242 dynamic_cast<TAO_Codeset_Translator_Factory*>(trans.wchar_translator());
00243
00244 codeset_cntx.wchar_data =
00245 tf ? tf->tcs () : this->codeset_info_.ForWcharData.native_code_set;
00246
00247 if (TAO_debug_level > 2)
00248 {
00249 ACE_CString tcs_c_locale;
00250 ACE_CString tcs_w_locale;
00251 ACE_Codeset_Registry::registry_to_locale (codeset_cntx.char_data, tcs_c_locale, 0, 0);
00252 ACE_Codeset_Registry::registry_to_locale (codeset_cntx.wchar_data, tcs_w_locale, 0, 0);
00253 ACE_DEBUG ((LM_DEBUG,
00254 ACE_TEXT ("TAO (%P|%t) - Codeset_Manager_i::")
00255 ACE_TEXT ("generate_service_context, ")
00256 ACE_TEXT ("using tcs_c <%C> (%08x), tcs_w <%C> (%08x)\n"),
00257 tcs_c_locale.c_str (),
00258 codeset_cntx.char_data,
00259 tcs_w_locale.c_str (),
00260 codeset_cntx.wchar_data));
00261 }
00262
00263 TAO_OutputCDR codeset_cdr;
00264 if ((codeset_cdr << TAO_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)) &&
00265 (codeset_cdr << codeset_cntx))
00266 {
00267 service_cntx.set_context (IOP::CodeSets,codeset_cdr);
00268 }
00269 }
00270
00271
00272 int
00273 TAO_Codeset_Manager_i::isElementOf (CONV_FRAME::CodeSetId id,
00274 CONV_FRAME::CodeSetComponent &cs_comp)
00275 {
00276 for (CORBA::ULong i = 0L;
00277 i < cs_comp.conversion_code_sets.length ();
00278 ++i )
00279 {
00280 if (id == cs_comp.conversion_code_sets[i])
00281 return 1;
00282 }
00283
00284 return 0;
00285 }
00286
00287
00288 CONV_FRAME::CodeSetId
00289 TAO_Codeset_Manager_i::intersectionOf (CONV_FRAME::CodeSetComponent &cs_comp1,
00290 CONV_FRAME::CodeSetComponent &cs_comp2)
00291 {
00292 for(CORBA::ULong index = 0L;
00293 index < cs_comp1.conversion_code_sets.length();
00294 ++index )
00295 {
00296 if (this->isElementOf(cs_comp1.conversion_code_sets[index], cs_comp2))
00297 {
00298 return cs_comp1.conversion_code_sets[index];
00299 }
00300 }
00301
00302 return 0;
00303 }
00304
00305 int
00306 TAO_Codeset_Manager_i::isCompatible(CONV_FRAME::CodeSetId cs1,
00307 CONV_FRAME::CodeSetId cs2 )
00308 {
00309
00310 return ACE_Codeset_Registry::is_compatible(cs1,cs2);
00311 }
00312
00313
00314 CONV_FRAME::CodeSetId
00315 TAO_Codeset_Manager_i::computeTCS (CONV_FRAME::CodeSetComponent &remote,
00316 CONV_FRAME::CodeSetComponent &local)
00317 {
00318 if (remote.native_code_set == local.native_code_set)
00319 {
00320 return local.native_code_set;
00321 }
00322
00323 if (this->isElementOf (remote.native_code_set, local))
00324 {
00325 return remote.native_code_set;
00326 }
00327
00328 if (this->isElementOf (local.native_code_set, remote))
00329 {
00330 return local.native_code_set;
00331 }
00332
00333 CONV_FRAME::CodeSetId tcs;
00334
00335 if ((tcs = this->intersectionOf (remote, local)) == 0)
00336 {
00337 if (isCompatible (local.native_code_set, remote.native_code_set))
00338 {
00339 return remote.native_code_set;
00340 }
00341 else
00342 {
00343 throw ::CORBA::CODESET_INCOMPATIBLE ();
00344 }
00345 }
00346
00347 return tcs;
00348 }
00349
00350 void
00351 TAO_Codeset_Manager_i::open(TAO_ORB_Core& core)
00352 {
00353 #if 0
00354
00355 TAO_Codeset_Translator_Factory *fact =
00356 ACE_Dynamic_Service<TAO_Codeset_Translator_Factory>::
00357 instance ("UTF8_Latin1_Factory");
00358 if (fact == 0)
00359 ACE_Service_Config::process_directive
00360 (ACE_DYNAMIC_SERVICE_DIRECTIVE ("UTF8_Latin1_Factory",
00361 "TAO_Codeset",
00362 "_make_TAO_UTF8_Latin1_Factory",
00363 ""));
00364 else
00365 {
00366 if (TAO_debug_level > 2)
00367 ACE_DEBUG ((LM_DEBUG,
00368 ACE_TEXT("TAO (%P|%t) - Codeset_Manager_i::open skipping ")
00369 ACE_TEXT("redundant load of UTF8_Latin1_Factory\n")
00370 ));
00371 }
00372
00373 fact = ACE_Dynamic_Service<TAO_Codeset_Translator_Factory>::
00374 instance ("UTF16_BOM_Factory");
00375 if (fact == 0)
00376 ACE_Service_Config::process_directive
00377 (ACE_DYNAMIC_SERVICE_DIRECTIVE ("UTF16_BOM_Factory",
00378 "TAO_Codeset",
00379 "_make_TAO_UTF16_BOM_Factory",
00380 ""));
00381 else
00382 {
00383 if (TAO_debug_level > 2)
00384 ACE_DEBUG ((LM_DEBUG,
00385 ACE_TEXT("TAO (%P|%t) - Codeset_Manager_i::open skipping ")
00386 ACE_TEXT("redundant load of UTF16_BOM_Factory\n")
00387 ));
00388 }
00389 #endif
00390
00391 TAO_Codeset_Service_Context_Handler* h = 0;
00392 ACE_NEW (h,
00393 TAO_Codeset_Service_Context_Handler());
00394 core.service_context_registry ().bind (IOP::CodeSets, h);
00395
00396
00397 this->codeset_info_.ForCharData.native_code_set =
00398 this->char_descriptor_.ncs();
00399 this->codeset_info_.ForWcharData.native_code_set =
00400 this->wchar_descriptor_.ncs();
00401 ACE_OutputCDR::wchar_maxbytes(this->wchar_descriptor_.max_bytes());
00402
00403 if (init_ccs (this->char_descriptor_,
00404 this->codeset_info_.ForCharData) == -1)
00405 {
00406 if (TAO_debug_level)
00407 ACE_ERROR ((LM_ERROR,
00408 ACE_TEXT ("TAO (%P|%t) - Codeset_Manager_i::")
00409 ACE_TEXT ("configure_codeset_factories, failed to init ")
00410 ACE_TEXT ("char codeset factories\n")));
00411 }
00412
00413 if (init_ccs (this->wchar_descriptor_,
00414 this->codeset_info_.ForWcharData) == -1)
00415 {
00416 if (TAO_debug_level)
00417 ACE_ERROR ((LM_ERROR,
00418 ACE_TEXT ("TAO (%P|%t) - Codeset_Manager_i::")
00419 ACE_TEXT ("configure_codeset_factories, failed to init ")
00420 ACE_TEXT ("wchar codeset factories\n")));
00421 }
00422 }
00423
00424
00425 int
00426 TAO_Codeset_Manager_i::init_ccs (TAO_Codeset_Descriptor& cd,
00427 CONV_FRAME::CodeSetComponent& cs_comp)
00428 {
00429 cs_comp.conversion_code_sets.length
00430 (static_cast<CORBA::ULong> (cd.num_translators()));
00431
00432 CORBA::ULong index;
00433 TAO_Codeset_Descriptor::Translator_Node *tlist = cd.translators();
00434
00435 for (index = 0; tlist; tlist = tlist->next_)
00436 {
00437 tlist->translator_factory_ =
00438 ACE_Dynamic_Service<TAO_Codeset_Translator_Factory>::instance
00439 (tlist->name_);
00440
00441 if (tlist->translator_factory_ == 0)
00442 {
00443 if (TAO_debug_level)
00444 ACE_ERROR ((LM_ERROR,
00445 ACE_TEXT ("TAO (%P|%t) - Codeset_Manager_i::")
00446 ACE_TEXT ("init_ccs, Unable to load ")
00447 ACE_TEXT ("code set translator <%s>, %m\n"),
00448 tlist->name_));
00449 continue;
00450 }
00451
00452 if (tlist->translator_factory_->ncs() != cs_comp.native_code_set)
00453 {
00454 if (TAO_debug_level)
00455 ACE_ERROR ((LM_ERROR,
00456 ACE_TEXT ("TAO (%P|%t) - Codeset_Manager_i::")
00457 ACE_TEXT ("init_ccs, codeset translator <%s> ")
00458 ACE_TEXT ("has wrong ncs (%d), %m\n"),
00459 tlist->name_,
00460 tlist->translator_factory_->ncs()));
00461 tlist->translator_factory_ = 0;
00462 continue;
00463 }
00464
00465
00466 if (tlist->translator_factory_->tcs() == cs_comp.native_code_set)
00467 continue;
00468
00469 cs_comp.conversion_code_sets[index++] =
00470 tlist->translator_factory_->tcs();
00471 if (TAO_debug_level > 2)
00472 {
00473 ACE_DEBUG ((LM_DEBUG,
00474 ACE_TEXT ("TAO (%P|%t) - Codeset_Manager_i::")
00475 ACE_TEXT ("init_ccs, Loaded Codeset translator ")
00476 ACE_TEXT ("<%s>, ncs = %08x tcs = %08x\n"),
00477 tlist->name_,
00478 tlist->translator_factory_->ncs(),
00479 tlist->translator_factory_->tcs()
00480 ));
00481 }
00482 }
00483
00484 cs_comp.conversion_code_sets.length(index);
00485 return 0;
00486 }
00487
00488 TAO_Codeset_Translator_Base *
00489 TAO_Codeset_Manager_i::get_char_trans (CONV_FRAME::CodeSetId tcs)
00490 {
00491 if (this->codeset_info_.ForCharData.native_code_set == tcs)
00492 return 0;
00493 return this->get_translator_i (this->char_descriptor_,tcs);
00494 }
00495
00496 TAO_Codeset_Translator_Base *
00497 TAO_Codeset_Manager_i::get_wchar_trans (CONV_FRAME::CodeSetId tcs)
00498 {
00499 if (tcs == this->codeset_info_.ForWcharData.native_code_set &&
00500 tcs != ACE_CODESET_ID_ISO_UTF_16)
00501 return 0;
00502 return this->get_translator_i (this->wchar_descriptor_,tcs);
00503 }
00504
00505 TAO_Codeset_Translator_Base *
00506 TAO_Codeset_Manager_i::get_translator_i (TAO_Codeset_Descriptor& cd,
00507 CONV_FRAME::CodeSetId tcs)
00508 {
00509 for (TAO_Codeset_Descriptor::Translator_Node *tlist = cd.translators();
00510 tlist; tlist = tlist->next_)
00511 {
00512 TAO_Codeset_Translator_Factory *fact = tlist->translator_factory_;
00513 if (fact && tcs == fact->tcs ())
00514 return fact;
00515 }
00516 return 0;
00517 }
00518
00519 void
00520 TAO_Codeset_Manager_i::get_ncs (CONV_FRAME::CodeSetId &ncsc,
00521 CONV_FRAME::CodeSetId &ncsw)
00522 {
00523 ncsc = this->char_descriptor_.ncs();
00524 ncsw = this->wchar_descriptor_.ncs();
00525 }
00526
00527 TAO_END_VERSIONED_NAMESPACE_DECL