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"
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
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
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
58 TAO_Codeset_Manager_i::default_wchar_codeset
= TAO_DEFAULT_WCHAR_CODESET_ID
;
60 TAO_Codeset_Manager_i::TAO_Codeset_Manager_i ()
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_
;
85 TAO_Codeset_Manager_i::set_codeset (TAO_Tagged_Components
& tc
) const
87 tc
.set_code_sets (this->codeset_info_
);
91 TAO_Codeset_Manager_i::set_tcs (TAO_Profile
&theProfile
,
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")));
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
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
));
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"),
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"),
150 trans
.wchar_translator(this->get_wchar_trans (tcs
));
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
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
));
186 if (request
.transport()->is_tcs_set())
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
));
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
;
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 ();
267 if (id
== cs_comp
.conversion_code_sets
[i
])
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();
283 if (this->isElementOf(cs_comp1
.conversion_code_sets
[index
], cs_comp2
))
285 return cs_comp1
.conversion_code_sets
[index
];
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
;
330 throw ::CORBA::CODESET_INCOMPATIBLE ();
338 TAO_Codeset_Manager_i::open(TAO_ORB_Core
& core
)
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");
346 ACE_Service_Config::process_directive
347 (ACE_DYNAMIC_VERSIONED_SERVICE_DIRECTIVE ("UTF8_Latin1_Factory",
350 "_make_TAO_UTF8_Latin1_Factory",
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");
364 ACE_Service_Config::process_directive
365 (ACE_DYNAMIC_VERSIONED_SERVICE_DIRECTIVE ("UTF16_BOM_Factory",
368 "_make_TAO_UTF16_BOM_Factory",
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")
380 TAO_Codeset_Service_Context_Handler
* h
= 0;
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)
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)
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()));
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
430 if (tlist
->translator_factory_
== 0)
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"),
441 if (tlist
->translator_factory_
->ncs() != cs_comp
.native_code_set
)
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"),
449 tlist
->translator_factory_
->ncs()));
450 tlist
->translator_factory_
= 0;
454 // this is a special case for the utf16 bom translator.
455 if (tlist
->translator_factory_
->tcs() == cs_comp
.native_code_set
)
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"),
467 tlist
->translator_factory_
->ncs(),
468 tlist
->translator_factory_
->tcs()
473 cs_comp
.conversion_code_sets
.length(index
);
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
)
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
)
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 ())
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