Merge pull request #2216 from jwillemsen/jwi-cxxversionchecks
[ACE_TAO.git] / TAO / tao / Codeset / Codeset_Manager_i.cpp
blobb1841d9da1946c79d44362dfa615eb71190fa6d9
1 // -*- C++ -*-
2 #include "tao/TAO_Server_Request.h"
3 #include "tao/operation_details.h"
4 #include "tao/Transport.h"
5 #include "tao/Profile.h"
6 #include "tao/SystemException.h"
7 #include "tao/debug.h"
8 #include "tao/CDR.h"
9 #include "tao/ORB_Core.h"
11 #include "tao/Codeset/Codeset_Descriptor.h"
12 #include "tao/Codeset/Codeset_Manager_i.h"
13 #include "tao/Codeset/Codeset_Translator_Factory.h"
14 #include "tao/Codeset/Codeset.h"
15 #include "tao/Codeset/CodeSetContextC.h"
16 #include "tao/Codeset/Codeset_Service_Context_Handler.h"
18 #include "ace/Dynamic_Service.h"
19 #include "ace/Codeset_Registry.h"
20 #include "ace/OS_NS_string.h"
21 #include "ace/Service_Config.h"
23 // These numbers are assigned by the OpenGroup, a database is
24 // available at
26 // ftp://ftp.opengroup.org/pub/code_set_registry/
28 #define TAO_CODESET_ID_ISO8859_1 0x00010001U
29 #define TAO_CODESET_ID_UNICODE 0x00010109U
30 #define TAO_CODESET_ID_XOPEN_UTF_8 0x05010001U
32 // These are the default codesets that TAO declares, of course they
33 // will be different on each platform, once the complete support for
34 // character sets is implemented
36 #if (defined TAO_DEFAULT_CHAR_CODESET_ID)
37 # undef TAO_DEFAULT_CHAR_CODESET_ID
38 #endif /* defined TAO_DEFAULT_CHAR_CODESET_ID */
40 #if (defined TAO_DEFAULT_WCHAR_CODESET_ID)
41 # undef TAO_DEFAULT_WCHAR_CODESET_ID
42 #endif /* defined TAO_DEFAULT_WCHAR_CODESET_ID */
44 //#define TAO_DEFAULT_CHAR_CODESET_ID TAO_CODESET_ID_XOPEN_UTF_8
45 #define TAO_DEFAULT_CHAR_CODESET_ID TAO_CODESET_ID_ISO8859_1
46 #define TAO_DEFAULT_WCHAR_CODESET_ID TAO_CODESET_ID_UNICODE
48 // ****************************************************************
50 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
52 /// NCS for char is defaulted to ISO 8859-1:1987; Latin Alphabet No. 1
53 CONV_FRAME::CodeSetId
54 TAO_Codeset_Manager_i::default_char_codeset = TAO_DEFAULT_CHAR_CODESET_ID;
55 /// NCS for wchar is not defaulted by the CORBA specification, but a default
56 /// may be set here if desired
57 CONV_FRAME::CodeSetId
58 TAO_Codeset_Manager_i::default_wchar_codeset = TAO_DEFAULT_WCHAR_CODESET_ID;
60 TAO_Codeset_Manager_i::TAO_Codeset_Manager_i ()
61 : codeset_info_ (),
62 char_descriptor_ (),
63 wchar_descriptor_ ()
65 char_descriptor_.ncs(TAO_Codeset_Manager_i::default_char_codeset);
66 char_descriptor_.add_translator (ACE_TEXT ("UTF8_Latin1_Factory"));
68 wchar_descriptor_.ncs(TAO_Codeset_Manager_i::default_wchar_codeset);
69 wchar_descriptor_.add_translator (ACE_TEXT ("UTF16_BOM_Factory"));
72 TAO_Codeset_Descriptor_Base *
73 TAO_Codeset_Manager_i::char_codeset_descriptor ()
75 return &this->char_descriptor_;
78 TAO_Codeset_Descriptor_Base *
79 TAO_Codeset_Manager_i::wchar_codeset_descriptor ()
81 return &this->wchar_descriptor_;
84 void
85 TAO_Codeset_Manager_i::set_codeset (TAO_Tagged_Components& tc) const
87 tc.set_code_sets (this->codeset_info_);
90 void
91 TAO_Codeset_Manager_i::set_tcs (TAO_Profile &theProfile,
92 TAO_Transport &trans)
94 /// If tcs is already set on the transport then do not process,
95 /// use existing transport as CDR have translators set.
96 TAO_Tagged_Components& theTaggedComp = theProfile.tagged_components ();
98 CONV_FRAME::CodeSetComponentInfo remote;
100 /// Get the codeset component
101 if (theTaggedComp.get_code_sets(remote) == 0 )
103 if (trans.is_tcs_set ())
105 if(TAO_debug_level > 2)
106 TAOLIB_DEBUG ((LM_DEBUG,
107 ACE_TEXT ("TAO (%P|%t) - Codeset_Manager_i::set_tcs, ")
108 ACE_TEXT ("transport already set\n")));
109 return;
111 if (TAO_debug_level > 2)
112 TAOLIB_DEBUG ((LM_DEBUG,
113 ACE_TEXT ("TAO (%P|%t) - Codeset_Manager_i::set_tcs, ")
114 ACE_TEXT ("No codeset component in profile\n")));
116 // These are the "fallback" codeset ids for use if no context is
117 // available
118 remote.ForCharData.native_code_set =
119 TAO_CODESET_ID_XOPEN_UTF_8;
120 remote.ForWcharData.native_code_set =
121 TAO_CODESET_ID_UNICODE;
123 trans.char_translator
124 (this->get_char_trans
125 (TAO_Codeset_Manager_i::default_char_codeset));
126 trans.wchar_translator
127 (this->get_wchar_trans
128 (TAO_Codeset_Manager_i::default_wchar_codeset));
130 else
132 CONV_FRAME::CodeSetId tcs =
133 computeTCS (remote.ForCharData,
134 this->codeset_info_.ForCharData);
135 if (TAO_debug_level > 2)
136 TAOLIB_DEBUG ((LM_DEBUG,
137 ACE_TEXT("TAO (%P|%t) - Codeset_Manager_i::set_tcs, ")
138 ACE_TEXT("setting char translator (%08x)\n"),
139 tcs));
140 trans.char_translator(this->get_char_trans (tcs));
142 tcs = computeTCS (remote.ForWcharData,
143 this->codeset_info_.ForWcharData);
145 if (TAO_debug_level > 2)
146 TAOLIB_DEBUG ((LM_DEBUG,
147 ACE_TEXT("TAO (%P|%t) - Codeset_Manager_i::set_tcs, ")
148 ACE_TEXT("setting wchar translator (%08x)\n"),
149 tcs));
150 trans.wchar_translator(this->get_wchar_trans (tcs));
154 void
155 TAO_Codeset_Manager_i::process_service_context (TAO_ServerRequest &request)
157 // Get the service Context from an object of TAO_ServerRequest
158 // and set the TCS values on the Transport
159 TAO_Service_Context &service_cntx = request.request_service_context ();
160 IOP::ServiceContext context;
161 context.context_id = IOP::CodeSets;
163 // These are the "fallback" codeset ids for use if no other codeset
164 // can be computed based on our local set and those in the context
165 CONV_FRAME::CodeSetId tcs_c = TAO_CODESET_ID_XOPEN_UTF_8;
166 CONV_FRAME::CodeSetId tcs_w = TAO_CODESET_ID_UNICODE;
168 if (service_cntx.get_context(context))
170 // Convert the Service Context to Codeset Context
171 const char *buffer =
172 reinterpret_cast<const char*> (context.context_data.get_buffer ());
174 TAO_InputCDR cdr (buffer,context.context_data.length ());
175 CORBA::Boolean byte_order;
177 if (cdr >> TAO_InputCDR::to_boolean (byte_order))
179 cdr.reset_byte_order (static_cast<int> (byte_order));
180 cdr >> tcs_c;
181 cdr >> tcs_w;
184 else
186 if (request.transport()->is_tcs_set())
187 return;
188 if (TAO_debug_level > 0)
189 TAOLIB_DEBUG ((LM_DEBUG,
190 ACE_TEXT("TAO (%P|%t) - ")
191 ACE_TEXT("Codeset_Manager_i::process_service_context, ")
192 ACE_TEXT("no codeset context in request, using defaults\n")));
193 tcs_c = TAO_Codeset_Manager_i::default_char_codeset;
194 tcs_w = TAO_Codeset_Manager_i::default_wchar_codeset;
196 if (TAO_debug_level > 2)
198 ACE_CString tcs_c_locale;
199 ACE_CString tcs_w_locale;
200 ACE_Codeset_Registry::registry_to_locale (tcs_c, tcs_c_locale, 0, 0);
201 ACE_Codeset_Registry::registry_to_locale (tcs_w, tcs_w_locale, 0, 0);
202 TAOLIB_DEBUG ((LM_DEBUG,
203 ACE_TEXT ("TAO (%P|%t) - Codeset_Manager_i::")
204 ACE_TEXT ("process_service_context, ")
205 ACE_TEXT ("using tcsc <%C> (%08x), tcsw <%C> (%08x)\n"),
206 tcs_c_locale.c_str (), tcs_c, tcs_w_locale.c_str (), tcs_w));
209 request.transport()->char_translator(this->get_char_trans (tcs_c));
210 request.transport()->wchar_translator(this->get_wchar_trans (tcs_w));
213 void
214 TAO_Codeset_Manager_i::generate_service_context (TAO_Operation_Details &opd,
215 TAO_Transport &trans)
217 TAO_Service_Context &service_cntx = opd.request_service_context ();
218 CONV_FRAME::CodeSetContext codeset_cntx;
220 // Generating codeset context
221 // Assuming the TCS values from Transport will be defaulted
222 TAO_Codeset_Translator_Factory *tf =
223 dynamic_cast<TAO_Codeset_Translator_Factory*>(trans.char_translator());
225 codeset_cntx.char_data =
226 tf ? tf->tcs () : this->codeset_info_.ForCharData.native_code_set;
228 tf =
229 dynamic_cast<TAO_Codeset_Translator_Factory*>(trans.wchar_translator());
231 codeset_cntx.wchar_data =
232 tf ? tf->tcs () : this->codeset_info_.ForWcharData.native_code_set;
234 if (TAO_debug_level > 2)
236 ACE_CString tcs_c_locale;
237 ACE_CString tcs_w_locale;
238 ACE_Codeset_Registry::registry_to_locale (codeset_cntx.char_data, tcs_c_locale, 0, 0);
239 ACE_Codeset_Registry::registry_to_locale (codeset_cntx.wchar_data, tcs_w_locale, 0, 0);
240 TAOLIB_DEBUG ((LM_DEBUG,
241 ACE_TEXT ("TAO (%P|%t) - Codeset_Manager_i::")
242 ACE_TEXT ("generate_service_context, ")
243 ACE_TEXT ("using tcs_c <%C> (%08x), tcs_w <%C> (%08x)\n"),
244 tcs_c_locale.c_str (),
245 codeset_cntx.char_data,
246 tcs_w_locale.c_str (),
247 codeset_cntx.wchar_data));
250 TAO_OutputCDR codeset_cdr;
251 if ((codeset_cdr << TAO_OutputCDR::from_boolean (TAO_ENCAP_BYTE_ORDER)) &&
252 (codeset_cdr << codeset_cntx))
254 service_cntx.set_context (IOP::CodeSets,codeset_cdr);
258 /// Checks whether the NCS is a part of CCS
260 TAO_Codeset_Manager_i::isElementOf (CONV_FRAME::CodeSetId id,
261 CONV_FRAME::CodeSetComponent &cs_comp)
263 for (CORBA::ULong i = 0L;
264 i < cs_comp.conversion_code_sets.length ();
265 ++i )
267 if (id == cs_comp.conversion_code_sets[i])
268 return 1;
271 return 0;
274 /// Find the Intersection of Client and Server CCS's
275 CONV_FRAME::CodeSetId
276 TAO_Codeset_Manager_i::intersectionOf (CONV_FRAME::CodeSetComponent &cs_comp1,
277 CONV_FRAME::CodeSetComponent &cs_comp2)
279 for(CORBA::ULong index = 0L;
280 index < cs_comp1.conversion_code_sets.length();
281 ++index )
283 if (this->isElementOf(cs_comp1.conversion_code_sets[index], cs_comp2))
285 return cs_comp1.conversion_code_sets[index];
289 return 0;
293 TAO_Codeset_Manager_i::isCompatible(CONV_FRAME::CodeSetId cs1,
294 CONV_FRAME::CodeSetId cs2 )
296 // Call the is_compatible method of ACE_Codeset_Registry
297 return ACE_Codeset_Registry::is_compatible(cs1,cs2);
300 /// returns the TCS for Char / Wchar
301 CONV_FRAME::CodeSetId
302 TAO_Codeset_Manager_i::computeTCS (CONV_FRAME::CodeSetComponent &remote,
303 CONV_FRAME::CodeSetComponent &local)
305 if (remote.native_code_set == local.native_code_set)
307 return local.native_code_set;
310 if (this->isElementOf (remote.native_code_set, local))
312 return remote.native_code_set;
315 if (this->isElementOf (local.native_code_set, remote))
317 return local.native_code_set;
320 CONV_FRAME::CodeSetId tcs;
322 if ((tcs = this->intersectionOf (remote, local)) == 0)
324 if (isCompatible (local.native_code_set, remote.native_code_set))
326 return remote.native_code_set;
328 else
330 throw ::CORBA::CODESET_INCOMPATIBLE ();
334 return tcs;
337 void
338 TAO_Codeset_Manager_i::open(TAO_ORB_Core& core)
340 #if 0
341 // These translators help comply with the CORBA 3.0.2 specification
342 TAO_Codeset_Translator_Factory *fact =
343 ACE_Dynamic_Service<TAO_Codeset_Translator_Factory>::
344 instance ("UTF8_Latin1_Factory");
345 if (fact == 0)
346 ACE_Service_Config::process_directive
347 (ACE_DYNAMIC_VERSIONED_SERVICE_DIRECTIVE ("UTF8_Latin1_Factory",
348 "TAO_Codeset",
349 TAO_VERSION,
350 "_make_TAO_UTF8_Latin1_Factory",
351 ""));
352 else
354 if (TAO_debug_level > 2)
355 TAOLIB_DEBUG ((LM_DEBUG,
356 ACE_TEXT("TAO (%P|%t) - Codeset_Manager_i::open skipping ")
357 ACE_TEXT("redundant load of UTF8_Latin1_Factory\n")
361 fact = ACE_Dynamic_Service<TAO_Codeset_Translator_Factory>::
362 instance ("UTF16_BOM_Factory");
363 if (fact == 0)
364 ACE_Service_Config::process_directive
365 (ACE_DYNAMIC_VERSIONED_SERVICE_DIRECTIVE ("UTF16_BOM_Factory",
366 "TAO_Codeset",
367 TAO_VERSION,
368 "_make_TAO_UTF16_BOM_Factory",
369 ""));
370 else
372 if (TAO_debug_level > 2)
373 TAOLIB_DEBUG ((LM_DEBUG,
374 ACE_TEXT("TAO (%P|%t) - Codeset_Manager_i::open skipping ")
375 ACE_TEXT("redundant load of UTF16_BOM_Factory\n")
378 #endif
380 TAO_Codeset_Service_Context_Handler* h = 0;
381 ACE_NEW (h,
382 TAO_Codeset_Service_Context_Handler());
383 core.service_context_registry ().bind (IOP::CodeSets, h);
385 // add in from the service configurator
386 this->codeset_info_.ForCharData.native_code_set =
387 this->char_descriptor_.ncs();
388 this->codeset_info_.ForWcharData.native_code_set =
389 this->wchar_descriptor_.ncs();
390 ACE_OutputCDR::wchar_maxbytes(this->wchar_descriptor_.max_bytes());
392 if (init_ccs (this->char_descriptor_,
393 this->codeset_info_.ForCharData) == -1)
395 if (TAO_debug_level)
396 TAOLIB_ERROR ((LM_ERROR,
397 ACE_TEXT ("TAO (%P|%t) - Codeset_Manager_i::")
398 ACE_TEXT ("configure_codeset_factories, failed to init ")
399 ACE_TEXT ("char codeset factories\n")));
402 if (init_ccs (this->wchar_descriptor_,
403 this->codeset_info_.ForWcharData) == -1)
405 if (TAO_debug_level)
406 TAOLIB_ERROR ((LM_ERROR,
407 ACE_TEXT ("TAO (%P|%t) - Codeset_Manager_i::")
408 ACE_TEXT ("configure_codeset_factories, failed to init ")
409 ACE_TEXT ("wchar codeset factories\n")));
413 // Initialise the specific type codeset factories
415 TAO_Codeset_Manager_i::init_ccs (TAO_Codeset_Descriptor& cd,
416 CONV_FRAME::CodeSetComponent& cs_comp)
418 cs_comp.conversion_code_sets.length
419 (static_cast<CORBA::ULong> (cd.num_translators()));
421 CORBA::ULong index;
422 TAO_Codeset_Descriptor::Translator_Node *tlist = cd.translators();
424 for (index = 0; tlist; tlist = tlist->next_)
426 tlist->translator_factory_ =
427 ACE_Dynamic_Service<TAO_Codeset_Translator_Factory>::instance
428 (tlist->name_);
430 if (tlist->translator_factory_ == 0)
432 if (TAO_debug_level)
433 TAOLIB_ERROR ((LM_ERROR,
434 ACE_TEXT ("TAO (%P|%t) - Codeset_Manager_i::")
435 ACE_TEXT ("init_ccs, Unable to load ")
436 ACE_TEXT ("code set translator <%s>, %m\n"),
437 tlist->name_));
438 continue;
441 if (tlist->translator_factory_->ncs() != cs_comp.native_code_set)
443 if (TAO_debug_level)
444 TAOLIB_ERROR ((LM_ERROR,
445 ACE_TEXT ("TAO (%P|%t) - Codeset_Manager_i::")
446 ACE_TEXT ("init_ccs, codeset translator <%s> ")
447 ACE_TEXT ("has wrong ncs (%d), %m\n"),
448 tlist->name_,
449 tlist->translator_factory_->ncs()));
450 tlist->translator_factory_ = 0;
451 continue;
454 // this is a special case for the utf16 bom translator.
455 if (tlist->translator_factory_->tcs() == cs_comp.native_code_set)
456 continue;
458 cs_comp.conversion_code_sets[index++] =
459 tlist->translator_factory_->tcs();
460 if (TAO_debug_level > 2)
462 TAOLIB_DEBUG ((LM_DEBUG,
463 ACE_TEXT ("TAO (%P|%t) - Codeset_Manager_i::")
464 ACE_TEXT ("init_ccs, Loaded Codeset translator ")
465 ACE_TEXT ("<%s>, ncs = %08x tcs = %08x\n"),
466 tlist->name_,
467 tlist->translator_factory_->ncs(),
468 tlist->translator_factory_->tcs()
473 cs_comp.conversion_code_sets.length(index);
474 return 0;
477 TAO_Codeset_Translator_Base *
478 TAO_Codeset_Manager_i::get_char_trans (CONV_FRAME::CodeSetId tcs)
480 if (this->codeset_info_.ForCharData.native_code_set == tcs)
481 return 0;
482 return this->get_translator_i (this->char_descriptor_,tcs);
485 TAO_Codeset_Translator_Base *
486 TAO_Codeset_Manager_i::get_wchar_trans (CONV_FRAME::CodeSetId tcs)
488 if (tcs == this->codeset_info_.ForWcharData.native_code_set &&
489 tcs != ACE_CODESET_ID_ISO_UTF_16)
490 return 0;
491 return this->get_translator_i (this->wchar_descriptor_,tcs);
494 TAO_Codeset_Translator_Base *
495 TAO_Codeset_Manager_i::get_translator_i (TAO_Codeset_Descriptor& cd,
496 CONV_FRAME::CodeSetId tcs)
498 for (TAO_Codeset_Descriptor::Translator_Node *tlist = cd.translators();
499 tlist; tlist = tlist->next_)
501 TAO_Codeset_Translator_Factory *fact = tlist->translator_factory_;
502 if (fact && tcs == fact->tcs ())
503 return fact;
505 return 0;
508 void
509 TAO_Codeset_Manager_i::get_ncs (CONV_FRAME::CodeSetId &ncsc,
510 CONV_FRAME::CodeSetId &ncsw)
512 ncsc = this->char_descriptor_.ncs();
513 ncsw = this->wchar_descriptor_.ncs();
516 TAO_END_VERSIONED_NAMESPACE_DECL