Add copy constructor
[platform/core/uifw/ise-engine-sunpinyin.git] / src / portability.cpp
1 /*
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3  *
4  * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved.
5  *
6  * The contents of this file are subject to the terms of either the GNU Lesser
7  * General Public License Version 2.1 only ("LGPL") or the Common Development and
8  * Distribution License ("CDDL")(collectively, the "License"). You may not use this
9  * file except in compliance with the License. You can obtain a copy of the CDDL at
10  * http://www.opensource.org/licenses/cddl1.php and a copy of the LGPLv2.1 at
11  * http://www.opensource.org/licenses/lgpl-license.php. See the License for the
12  * specific language governing permissions and limitations under the License. When
13  * distributing the software, include this License Header Notice in each file and
14  * include the full text of the License in the License file as well as the
15  * following notice:
16  *
17  * NOTICE PURSUANT TO SECTION 9 OF THE COMMON DEVELOPMENT AND DISTRIBUTION LICENSE
18  * (CDDL)
19  * For Covered Software in this distribution, this License shall be governed by the
20  * laws of the State of California (excluding conflict-of-law provisions).
21  * Any litigation relating to this License shall be subject to the jurisdiction of
22  * the Federal Courts of the Northern District of California and the state courts
23  * of the State of California, with venue lying in Santa Clara County, California.
24  *
25  * Contributor(s):
26  *
27  * If you wish your version of this file to be governed by only the CDDL or only
28  * the LGPL Version 2.1, indicate your decision by adding "[Contributor]" elects to
29  * include this software in this distribution under the [CDDL or LGPL Version 2.1]
30  * license." If you don't indicate a single choice of license, a recipient has the
31  * option to distribute your version of this file under either the CDDL or the LGPL
32  * Version 2.1, or to extend the choice of license to its licensees as provided
33  * above. However, if you add LGPL Version 2.1 code and therefore, elected the LGPL
34  * Version 2 license, then the option applies only if the new code is made subject
35  * to such option by the copyright holder.
36  */
37
38 #ifdef HAVE_CONFIG_H
39 #include "config.h"
40 #endif
41
42 #ifdef HAVE_ASSERT_H
43 #include <assert.h>
44 #endif
45
46 #include "portability.h"
47
48 #include <stdlib.h>
49
50 TLongExpFloat::TLongExpFloat(double d)
51 {
52     if (d != 0.0 && d != -0.0) {
53         TDoubleAnatomy da(d);
54         m_exp = da.getExp();
55         da.clearExp();
56         m_base = da.getValue();
57     } else {
58         m_base = d;
59         m_exp = 0;
60     }
61 }
62
63 TLongExpFloat
64 TLongExpFloat::operator*(const TLongExpFloat& b) const
65 {
66     double d = this->m_base * b.m_base;
67     TLongExpFloat reda(d);
68     reda.m_exp += this->m_exp + b.m_exp;
69     return reda;
70 }
71
72 TLongExpFloat
73 TLongExpFloat::operator/(const TLongExpFloat& b) const
74 {
75     double d = this->m_base / b.m_base;
76     TLongExpFloat reda(d);
77     reda.m_exp += (this->m_exp - b.m_exp);
78     return reda;
79 }
80
81 bool
82 TLongExpFloat::operator<(const TLongExpFloat& b) const
83 {
84     if (m_base >= 0.0 && b.m_base >= 0.0) {
85         return(m_exp < b.m_exp || (m_exp == b.m_exp && m_base < b.m_base));
86     } else if (m_base < 0.0 && b.m_base < 0.0) {
87         return(m_exp > b.m_exp || (m_exp == b.m_exp && m_base < b.m_base));
88     } else if (m_base < 0.0 && b.m_base >= 0.0)
89         return true;
90     else
91         return false;
92 }
93
94 bool
95 TLongExpFloat::operator<=(const TLongExpFloat& b) const
96 {
97     if (m_base >= 0.0 && b.m_base >= 0.0) {
98         return(m_exp < b.m_exp || (m_exp == b.m_exp && m_base <= b.m_base));
99     } else if (m_base < 0.0 && b.m_base < 0.0) {
100         return(m_exp > b.m_exp || (m_exp == b.m_exp && m_base <= b.m_base));
101     } else if (m_base < 0.0 && b.m_base >= 0.0)
102         return true;
103     else
104         return false;
105 }
106
107 bool
108 TLongExpFloat::operator==(const TLongExpFloat& b) const
109 {
110     return(m_base == b.m_base && m_exp == b.m_exp);
111 }
112
113 TLongExpFloat&
114 TLongExpFloat::operator=(const TLongExpFloat& b)
115 {
116     if (m_base == b.m_base && m_exp == b.m_exp)
117         return *this;
118
119     m_base = b.m_base;
120     m_exp = b.m_exp;
121
122     return *this;
123 }
124
125 void
126 TLongExpFloat::toString(std::string& str) const
127 {
128     char buf[256];
129     toString(buf);
130     str = buf;
131 }
132
133 #ifdef HAVE_ICONV_H
134 #include <iconv.h>
135
136 /**
137  * convert UTF-8 string pointed by s into UCS-4 Wide String at pwcs.
138  * No more than n wide char could be converted into target buffer.
139  * return -1 means error.
140  * other means the converted wide char number do not count the end 0.
141  */
142 size_t
143 MBSTOWCS(TWCHAR *pwcs, const char* s, size_t n)
144 {
145 #ifndef WORDS_BIGENDIAN
146     static iconv_t ic = iconv_open("UCS-4LE", "UTF-8");
147 #else
148     static iconv_t ic = iconv_open("UCS-4BE", "UTF-8");
149 #endif
150
151     assert(ic != (iconv_t)-1);
152
153     // To eliminate the const char* and char* diffirence in differnt system
154     TIConvSrcPtr src = (TIConvSrcPtr)s;
155     size_t srclen = std::strlen(s) + 1;
156     char* dst = (char*)pwcs;
157     size_t dstlen = n * sizeof(TWCHAR);
158
159     size_t res = iconv(ic, &src, &srclen, &dst, &dstlen);
160
161     if (res != size_t(-1) && srclen == 0) {
162         n -= dstlen / sizeof(TWCHAR);
163         return (n > 0) ? (n - 1) : 0;
164     } else {
165         return size_t(-1);
166     }
167 }
168
169 /**
170  * convert UCS-4 string pointed by pwcs into UTF-8 String at s.
171  * No more than n byte could be converted into target buffer.
172  * return -1 means error.
173  * Other means the converted byte number do not count the end 0.
174  */
175 size_t
176 WCSTOMBS(char* s, const TWCHAR* pwcs, size_t n)
177 {
178 #ifndef WORDS_BIGENDIAN
179     static iconv_t ic = iconv_open("UTF-8", "UCS-4LE");
180 #else
181     static iconv_t ic = iconv_open("UTF-8", "UCS-4BE");
182 #endif
183
184     assert(ic != (iconv_t)-1);
185
186     TIConvSrcPtr src = (TIConvSrcPtr)pwcs;
187     size_t srclen = (WCSLEN(pwcs) + 1) * sizeof(TWCHAR);
188     char* dst = (char*)s;
189     size_t dstlen = n;
190
191     size_t res = iconv(ic, &src, &srclen, &dst, &dstlen);
192
193     if (res != size_t(-1) && srclen == 0) {
194         n -= dstlen;
195         return (n > 0) ? (n - 1) : 0;
196     } else {
197         return size_t(-1);
198     }
199 }
200
201 #else // !HAVE_ICONV_H
202
203 size_t
204 MBSTOWCS(TWCHAR *pwcs, const char* s, size_t n)
205 {
206     const unsigned char *src = (const unsigned char*)s;
207     TWCHAR* dst = pwcs;
208
209     while (dst - pwcs < (ssize_t)n) {
210         if (*src < 0xc0 || *src >= 0xfe) {
211             if (*src < 0x80) *dst++ = *src;
212             if (*src++ == 0) break;
213             continue;
214         }
215
216         for (int bytes = 2; bytes <= 6; bytes++) {
217             if ((*src & ~(0xff >> (bytes + 1))) !=
218                 (((1 << bytes) - 1) << (8 - bytes))) continue;
219             if (bytes > 4) {
220                 src += bytes;
221             } else {
222                 *dst =
223                     TWCHAR(*src++ & (0xff >> (bytes + 1))) << (6 * (bytes - 1));
224                 for (; bytes-- > 1; src++) *dst |=
225                         TWCHAR(*src & 0x3f) << (6 * (bytes - 1));
226                 dst++;
227             }
228             break;
229         }
230     }
231
232     return(dst - pwcs);
233 }
234
235 size_t
236 WCSTOMBS(char* s, const TWCHAR* pwcs, size_t n)
237 {
238     char* dst = s;
239
240     while (dst - s < n) {
241         if (*pwcs < 0x80 || *pwcs > 0x10ffff) {
242             if (*pwcs < 0x80) *dst++ = *pwcs;
243             if (*pwcs++ == 0) break;
244             continue;
245         }
246
247         int bytes = *pwcs < 0x800 ? 2 : (*pwcs < 0xffff ? 3 : 4);
248         dst += bytes;
249         if (dst - s > n) return -1;
250
251         TWCHAR c = *pwcs++;
252         int nbyte = bytes;
253         char *tmp = dst - 1;
254
255         for (; nbyte > 0; c >>= 6, nbyte--)
256             *tmp-- =
257                 (nbyte ==
258                  1 ? (((1 << bytes) - 1) << (8 - bytes)) : 0x80) | (c & 0x3f);
259     }
260
261     return(dst - s);
262 }
263
264 #endif // HAVE_ICONV_H
265
266 /**
267  * return the wide string len at pwcs, not count the end 0.
268  */
269 size_t
270 WCSLEN(const TWCHAR* pwcs)
271 {
272     size_t sz = 0;
273     if (pwcs) {
274         while (*pwcs++)
275             ++sz;
276     }
277     return sz;
278 }
279
280 #if !defined (HAVE_STRNDUP)
281 extern "C" char *
282 strndup(const char *s, size_t n)
283 {
284     size_t nMost;
285     char *p = NULL;
286
287     if (!s)
288         return NULL;
289
290 #ifdef __cplusplus
291     nMost = std::min(strlen(s) + 1, n + 1);
292 #else
293     nMost = min(strlen(s) + 1, n + 1);
294 #endif
295     p = (char*)malloc(nMost);
296     memcpy(p, s, nMost);
297     p[nMost - 1] = '\0';
298
299     return p;
300 }
301 #endif //HAVE_STRNDUP
302