Merge pull request #2309 from mitza-oci/warnings
[ACE_TAO.git] / TAO / tests / CodeSets / libs / UTF16_UCS2 / UTF16_UCS2_Translator.cpp
blob42a23179e06a222657641b4ab69246187a9b577c
1 // -*- C++ -*-
3 //=============================================================================
4 /**
5 * @file UTF16_UCS2_Translator.cpp
7 * Defines the arrays required to convert between UCS-2, a 2 byte wide char
8 * codeset, and UCS-16, aka unicode, a 2-byte codeset. As a bit-pattern
9 * these two should be identical, with the exception that UCS-2 cannot
10 * certain characters that UTF16 can, using escape codepoints.
12 * This translator can be dynamically loaded into TAO at run-time using
13 * a service configurator file with the following contents:
15 * dynamic UTF16_UCS2_Factory Service_Object * UTF16_UCS2:_make_UTF16_UCS2_Factory ()
17 * static Resource_Factory
18 * "-ORBWCharCodesetTranslator UTF16_UCS2_Factory"
20 * This code used UTF16_BOM_Translator as a starting point.
22 * @author Iliyan Jeliazkov <jeliazkov_i@ociweb.com> Byron Harris <harrisb@ociweb.com>
24 //=============================================================================
26 #include "UTF16_UCS2_Translator.h"
27 #include "tao/debug.h"
28 #include "ace/Log_Msg.h"
29 // ****************************************************************
31 typedef ACE_CDR::UShort ACE_UTF16_T;
32 static const size_t ACE_UTF16_CODEPOINT_SIZE = sizeof (ACE_UTF16_T);
34 /////////////////////////////
35 // UTF16_UCS2_Translator implementation
37 UTF16_UCS2_Translator::UTF16_UCS2_Translator (CONV_FRAME::CodeSetId tcs)
38 : tcs_ (tcs)
40 if (TAO_debug_level > 1)
41 ACE_DEBUG((LM_DEBUG, ACE_TEXT ("TAO (%P|%t) - UTF16_UCS2_Translator: tcs=0x%x\n"),
42 this->tcs_));
45 UTF16_UCS2_Translator::~UTF16_UCS2_Translator ()
49 // = Documented in $ACE_ROOT/ace/CDR_Stream.h
50 ACE_CDR::Boolean
51 UTF16_UCS2_Translator::read_wchar (ACE_InputCDR &cdr, ACE_CDR::WChar &x)
53 if (static_cast <ACE_CDR::Short> (this->major_version(cdr)) == 1 &&
54 static_cast <ACE_CDR::Short> (this->minor_version(cdr)) == 2)
56 ACE_CDR::Octet len;
57 if (! this->read_1 (cdr, &len))
58 return 0;
60 ACE_ASSERT (len == 2); // no BOM present
61 ACE_CDR::Short sx;
63 if (!this->read_array (cdr,
64 reinterpret_cast <char *> (&sx),1,1,2))
65 return 0;
67 #if defined (ACE_LITTLE_ENDIAN)
68 ACE_CDR::Short ux;
69 ACE_CDR::swap_2 (reinterpret_cast <const char*> (&sx),
70 reinterpret_cast <char *> (&ux));
71 x = static_cast <ACE_CDR::WChar> (ux);
72 #else
73 x = static_cast <ACE_CDR::WChar> (sx);
74 #endif // ACE_LITTLE_ENDIAN
75 return 1;
77 else
79 ACE_UTF16_T sx;
80 if (this->read_2 (cdr, &sx))
82 x = static_cast <ACE_CDR::WChar> (sx);
83 return 1;
86 return 0;
89 ACE_CDR::Boolean
90 UTF16_UCS2_Translator::read_wstring (ACE_InputCDR &cdr,
91 ACE_CDR::WChar *&x)
93 ACE_CDR::ULong len;
94 if (!this->read_4 (cdr, &len))
95 return 0;
97 // A check for the length being too great is done later in the
98 // call to read_char_array but we want to have it done before
99 // the memory is allocated.
100 if (len > 0 && len <= cdr.length())
102 if (static_cast <ACE_CDR::Short> (this->major_version(cdr)) == 1
103 && static_cast <ACE_CDR::Short> (this->minor_version(cdr)) == 2)
105 len /= ACE_UTF16_CODEPOINT_SIZE;
107 //allocating one extra for the null character needed by applications
108 ACE_NEW_RETURN (x,
109 ACE_CDR::WChar [len + 1],
112 x[len] = L'\x00';
113 if (this->read_wchar_array_i (cdr, x, len, 1))
115 // Since reading the array may have adjusted the length,
116 // we simply rewrite the null terminator
117 x[len] = L'\x00';
118 return 1;
121 else
123 ACE_NEW_RETURN (x,
124 ACE_CDR::WChar [len],
126 if (this->read_wchar_array (cdr, x, len))
127 return 1;
129 delete [] x;
131 else if (len == 0)
133 // Convert any null strings to empty strings since empty
134 // strings can cause crashes. (See bug 58.)
135 ACE_NEW_RETURN (x,
136 ACE_CDR::WChar[1],
138 x[0] = '\x00';
139 return 1;
141 x = 0;
142 return 0;
145 ACE_CDR::Boolean
146 UTF16_UCS2_Translator::read_wchar_array_i (ACE_InputCDR & cdr,
147 ACE_CDR::WChar *x,
148 ACE_CDR::ULong &length,
149 int)
151 int must_swap = 0;
152 char* buf;
153 static const size_t align = ACE_CDR::SHORT_ALIGN;
154 if (cdr.adjust (ACE_UTF16_CODEPOINT_SIZE * length, align, buf) == 0)
156 ACE_UTF16_T *sb = reinterpret_cast <ACE_UTF16_T *> (buf);
157 #if defined (ACE_LITTLE_ENDIAN)
158 must_swap = 1;
159 #endif // ACE_LITTLE_ENDIAN
161 for (size_t i = 0; i < length; ++i)
162 #if defined (ACE_DISABLE_SWAP_ON_READ)
163 x[i] = static_cast <ACE_CDR::WChar> (sb[i]);
164 #else
165 if (!must_swap)
167 x[i] = static_cast <ACE_CDR::WChar> (sb[i]);
169 else
171 ACE_CDR::UShort sx;
172 ACE_CDR::swap_2 (&buf[i*2], reinterpret_cast <char *> (&sx));
173 x[i] = static_cast <ACE_CDR::WChar> (sx);
175 #endif /* ACE_DISABLE_SWAP_ON_READ */
177 return 1;
179 return 0;
182 ACE_CDR::Boolean
183 UTF16_UCS2_Translator::read_wchar_array (ACE_InputCDR & cdr,
184 ACE_CDR::WChar *x,
185 ACE_CDR::ULong length)
187 if (length == 0)
188 return 1;
190 if (static_cast <ACE_CDR::Short> (this->major_version(cdr)) == 1
191 && static_cast <ACE_CDR::Short> (this->minor_version(cdr)) == 2)
193 for (size_t i = 0; i < length; ++i)
194 if (!this->read_wchar(cdr,x[i]))
195 return 0;
197 return 1;
199 else
200 return this->read_wchar_array_i (cdr, x, length);
203 ACE_CDR::Boolean
204 UTF16_UCS2_Translator::write_wchar (ACE_OutputCDR &cdr,
205 ACE_CDR::WChar x)
207 return this->write_wchar_i (cdr, x);
210 ACE_CDR::Boolean
211 UTF16_UCS2_Translator::write_wchar_i (ACE_OutputCDR &cdr, ACE_CDR::WChar x)
213 if (static_cast <ACE_CDR::Short> (this->major_version(cdr)) == 1
214 && static_cast <ACE_CDR::Short> (this->minor_version(cdr)) == 2)
216 int len = 1;
217 ACE_CDR::UShort buffer[2];
219 buffer[0] = static_cast <ACE_CDR::Short> (x);
221 unsigned char tcsize = static_cast <unsigned char>
222 (len * ACE_UTF16_CODEPOINT_SIZE);
223 if (this->write_1 (cdr, &tcsize))
224 return this->write_array(cdr, &buffer, tcsize, 1, 1);
225 else
226 return 0;
228 else if (static_cast <ACE_CDR::Short> (this->minor_version(cdr)) != 0)
230 // GIOP 1.1 simple support
231 ACE_UTF16_T sx = static_cast <ACE_UTF16_T> (x);
232 return this->write_2 (cdr, &sx);
234 else
235 { // wchar is not allowed with GIOP 1.0.
236 errno = EINVAL;
237 return 0;
241 ACE_CDR::Boolean
242 UTF16_UCS2_Translator::write_wstring (ACE_OutputCDR & cdr,
243 ACE_CDR::ULong len,
244 const ACE_CDR::WChar *x)
246 // we'll accept a null pointer but only for an empty string
247 ACE_ASSERT (x != 0 || len == 0);
248 if (static_cast <ACE_CDR::Short> (this->major_version(cdr)) == 1
249 && static_cast <ACE_CDR::Short> (this->minor_version(cdr)) == 2)
251 if (len == 0) // for zero length strings, only write a length of
252 // zero.
253 return this->write_4(cdr, &len);
255 ACE_CDR::ULong l = len * ACE_UTF16_CODEPOINT_SIZE;
256 if (this->write_4 (cdr, &l) && x != 0)
258 if (cdr.do_byte_swap())
260 return this->write_swapped_wchar_array_i (cdr, x, len);
262 else
264 return this->write_wchar_array_i (cdr, x, len);
268 else
270 // pre GIOP 1.2: include null terminator in length
271 ACE_CDR::ULong l = len + 1;
273 if (this->write_4 (cdr, &l))
275 if (x != 0)
277 return this->write_wchar_array_i (cdr, x, len + 1);
279 else
281 ACE_UTF16_T s = 0;
282 return this->write_2 (cdr, &s);
287 return 0;
290 ACE_CDR::Boolean
291 UTF16_UCS2_Translator::write_wchar_array (ACE_OutputCDR & cdr,
292 const ACE_CDR::WChar *x,
293 ACE_CDR::ULong length)
295 if (static_cast <ACE_CDR::Short> (this->major_version(cdr)) == 1
296 && static_cast <ACE_CDR::Short> (this->minor_version(cdr)) == 2)
298 for (size_t i = 0; i < length; ++i)
299 if (this->write_wchar_i (cdr, x[i]) == 0)
300 return 0;
302 return 1;
305 return this->write_wchar_array_i (cdr, x, length);
308 ACE_CDR::Boolean
309 UTF16_UCS2_Translator::write_wchar_array_i (ACE_OutputCDR & cdr,
310 const ACE_CDR::WChar *x,
311 ACE_CDR::ULong length)
313 if (length == 0)
314 return 1;
315 char* buf;
316 static const size_t align = ACE_CDR::SHORT_ALIGN;
317 if (cdr.adjust (ACE_UTF16_CODEPOINT_SIZE * length, align, buf)
318 != 0)
320 return 0;
323 ACE_UTF16_T *sb = reinterpret_cast <ACE_UTF16_T *> (buf);
325 for (size_t i = 0; i < length; ++i)
327 sb[i] = static_cast <ACE_UTF16_T> (x[i]);
329 return 1;
332 ACE_CDR::Boolean
333 UTF16_UCS2_Translator::write_swapped_wchar_array_i (ACE_OutputCDR & cdr,
334 const ACE_CDR::WChar *x,
335 ACE_CDR::ULong length)
337 if (length == 0)
338 return 1;
339 char* buf;
340 static const size_t align = ACE_CDR::SHORT_ALIGN;
341 if (cdr.adjust (ACE_UTF16_CODEPOINT_SIZE * length, align, buf)
342 != 0)
344 return 0;
347 ACE_UTF16_T *sb = reinterpret_cast <ACE_UTF16_T *> (buf);
349 for (size_t i = 0; i < length; ++i)
351 ACE_CDR::swap_2 (reinterpret_cast <const char*> (&x[i]),
352 reinterpret_cast <char *> (&sb[i]));
354 return 1;