Parse() remains original value when the function returns errror
[platform/framework/native/appfw.git] / src / base / FBaseFloat.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file                FBaseFloat.cpp
20  * @brief               This is the implementation file for Float class.
21  * @see                 Number class
22  */
23
24 // Includes
25 #include <cfloat>
26 #include <math.h>
27 #include <stdio.h>
28 #include <wchar.h>
29 #include <errno.h>
30 #include <limits.h>
31 #include <FBaseFloat.h>
32 #include <FBaseResult.h>
33 #include <FBaseSysLog.h>
34
35 namespace Tizen { namespace Base
36 {
37
38 union FloatBitRep
39 {
40         explicit
41         FloatBitRep(float f = 0.0)
42                 : value(f)
43         {
44         };
45
46         FloatBitRep(unsigned int i)
47                 : rep(i)
48         {
49         };
50
51         float value;
52         unsigned int rep;
53 };
54
55 Float::Float(float value)
56         : value(value)
57         , __pFloatImpl(null)
58 {
59 }
60
61 Float::Float(const Float& value)
62         : value(value.value)
63         , __pFloatImpl(null)
64 {
65 }
66
67 Float::~Float(void)
68 {
69 }
70
71 Float&
72 Float::operator =(const Float& rhs)
73 {
74         if (&rhs != this)
75         {
76                 value = rhs.value;
77         }
78         return *this;
79 }
80
81 int
82 Float::Compare(float f1, float f2)
83 {
84         int ret = 0;
85
86         if (f1 > f2)
87         {
88                 ret = 1;
89         }
90         else if (f1 < f2)
91         {
92                 ret = -1;
93         }
94         else
95         {
96                 ret = 0;
97         }
98
99         return ret;
100 }
101
102 int
103 Float::CompareTo(const Float& value) const
104 {
105         return(Float::Compare(this->value, value.value));
106 }
107
108 bool
109 Float::Equals(const Object& obj) const
110 {
111         const Float* pOther = dynamic_cast <const Float*>(&obj);
112
113         if (pOther == null)
114         {
115                 return false;
116         }
117
118         if (Float::Compare(this->value, (*pOther).value) == 0)
119         {
120                 return true;
121         }
122         else
123         {
124                 return false;
125         }
126 }
127
128 int
129 Float::GetHashCode(void) const
130 {
131         float* pTemp = const_cast<float*> (&value);
132         int* pValue = reinterpret_cast<int*> (pTemp);
133         return *pValue;
134 }
135
136 int
137 Float::GetHashCode(float val)
138 {
139         int* pValue = reinterpret_cast<int*> (&val);
140         return *pValue;
141 }
142
143 result
144 Float::Parse(const String& s, float& ret)
145 {
146         SysTryReturn(NID_BASE, s.GetLength() >= 1, E_NUM_FORMAT, E_NUM_FORMAT,
147                 "[%s] The length of s MUST be greater than 0.", GetErrorMessage(E_NUM_FORMAT));
148
149         errno = 0;
150         wchar_t* pEnd = null;
151         float tmpRet = wcstof(s.GetPointer(), &pEnd);
152         SysTryReturn(NID_BASE, (!Float::Compare(pEnd[0], 0)), E_NUM_FORMAT, E_NUM_FORMAT,
153                 "[%s] Float parse failed. Scan stopped at (%ls).", GetErrorMessage(E_NUM_FORMAT), pEnd);
154         SysTryReturn(NID_BASE, !((!Float::Compare(tmpRet, HUGE_VAL) || !Float::Compare(tmpRet, -HUGE_VAL)) && (errno != 0)),
155                 E_NUM_FORMAT, E_NUM_FORMAT, "[%s] Parsed value cannot fit into a Float.", GetErrorMessage(E_NUM_FORMAT));
156
157         ret = tmpRet;
158         return E_SUCCESS;
159 }
160
161 char
162 Float::ToChar(void) const
163 {
164         return static_cast<char> (value);
165 }
166
167 short
168 Float::ToShort(void) const
169 {
170         return  static_cast<short> (value);
171 }
172
173 int
174 Float::ToInt(void) const
175 {
176         return static_cast<int> (value);
177 }
178
179 long
180 Float::ToLong(void) const
181 {
182         return static_cast<long> (value);
183 }
184
185 long long
186 Float::ToLongLong(void) const
187 {
188         return static_cast<long long> (value);
189 }
190
191 float
192 Float::ToFloat(void) const
193 {
194         return value;
195 }
196
197 double
198 Float::ToDouble(void) const
199 {
200         return static_cast<double> (value);
201 }
202
203 String
204 Float::ToString(void) const
205 {
206         return(Float::ToString(value));
207 }
208
209 String
210 Float::ToString(float value)
211 {
212         const static unsigned int MAX_DIG = 7 + 3;
213         const static unsigned int FLOAT_LENGTH_MAX = __DBL_MAX_10_EXP + MAX_DIG;
214
215         if (Float::IsNaN(value))
216         {
217                 return String(L"NaN");
218         }
219         else if (Float::IsInfinity(value))
220         {
221                 return String(L"Infinity");
222         }
223         else
224         {
225                 wchar_t sValue[FLOAT_LENGTH_MAX + 1] = {0, };
226                 swprintf(sValue, (sizeof(sValue) / sizeof(sValue[0])), L"%g", value);
227
228                 return String(sValue);
229         }
230 }
231
232 int
233 Float::ToBits(float value)
234 {
235         FloatBitRep bitRep;
236         bitRep.value = value;
237         return bitRep.rep;
238 }
239
240 float
241 Float::ToFloatFromBits(int value)
242 {
243         FloatBitRep bitRep;
244         bitRep.rep = value;
245         return bitRep.value;
246 }
247
248 bool
249 Float::IsFinite(float value)
250 {
251         return((isfinite(value) != 0) ? true : false);
252 }
253
254 bool
255 Float::IsInfinity(void) const
256 {
257         return(Float::IsInfinity(value));
258 }
259
260 bool
261 Float::IsInfinity(float value)
262 {
263         return(!Float::IsFinite(value));
264 }
265
266 bool
267 Float::IsNaN(void) const
268 {
269         return(Float::IsNaN(value));
270 }
271
272 bool
273 Float::IsNaN(float value)
274 {
275         return((isnan(value) != 0) ? true : false);
276 }
277
278 float
279 Float::GetMaxValue(void)
280 {
281         return FLT_MAX;
282 }
283
284 float
285 Float::GetMinValue(void)
286 {
287         return FLT_MIN;
288 }
289
290 }} // Tizen::Base