[N_SE-33612] In Decode(), add code to check if str[0] is '+' or '-'
[platform/framework/native/appfw.git] / src / base / FBaseInteger.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                FBaseInteger.cpp
20  * @brief               This is the implementation file for Integer class.
21  * @see                 Number
22  */
23
24 #include <wchar.h>
25 #include <limits.h>
26 #include <errno.h>
27 #include <FBaseInteger.h>
28 #include <FBaseResult.h>
29 #include <FBaseCharacter.h>
30 #include <FBaseSysLog.h>
31
32 namespace Tizen { namespace Base
33 {
34
35 Integer::Integer(int value)
36         : value(value)
37         , __pIntegerImpl(null)
38 {
39 }
40
41 Integer::Integer(const Integer& value)
42         : value(value.value)
43         , __pIntegerImpl(null)
44 {
45 }
46
47 Integer::~Integer(void)
48 {
49
50 }
51
52 Integer&
53 Integer::operator =(const Integer& rhs)
54 {
55         if (&rhs != this)
56         {
57                 value = rhs.value;
58         }
59         return *this;
60 }
61
62 int
63 Integer::Compare(int i1, int i2)
64 {
65         return(i1 < i2 ? -1 : (i1 == i2 ? 0 : 1));
66 }
67
68 int
69 Integer::CompareTo(const Integer& value) const
70 {
71         return(Integer::Compare(this->value, value.value));
72 }
73
74 bool
75 Integer::Equals(const Object& obj) const
76 {
77         const Integer* pOther = dynamic_cast <const Integer*>(&obj);
78         if (pOther == null)
79         {
80                 return false;
81         }
82
83         return value == (*pOther).value;
84 }
85
86 result
87 Integer::Decode(const String& s, int& ret)
88 {
89         SysTryReturn(NID_BASE, s.GetLength() >= 1, E_NUM_FORMAT, E_NUM_FORMAT,
90                 "[%s] The length of s MUST be greater than 0.", GetErrorMessage(E_NUM_FORMAT));
91
92         int radix = 0;
93         int startIndex = 0;
94         int minLength = 2;
95         wchar_t* pEnd = null;
96         String str(s);
97
98         if (s[0] == L'-' || s[0] == L'+')
99         {
100                 startIndex = 1;
101                 minLength = 3;
102         }
103
104         // Find radix
105         if (s[startIndex] == L'#')
106         {
107                 radix = Character::RADIX_HEXADECIMAL;
108
109                 // Remove '#'
110                 str.Remove(startIndex, 1);
111         }
112         else if (s[startIndex] == L'0' && (s.GetLength() >= minLength))
113         {
114                 if (s[startIndex + 1] == L'x' || s[startIndex + 1] == L'X')
115                 {
116                         radix = Character::RADIX_HEXADECIMAL;
117                 }
118                 else
119                 {
120                         radix = Character::RADIX_OCTAL;
121                 }
122         }
123         else
124         {
125                 radix = Character::RADIX_DECIMAL;
126         }
127
128         errno = 0;
129         ret = wcstol(str.GetPointer(), &pEnd, radix);
130         SysTryReturn(NID_BASE, (pEnd[0] == 0), E_NUM_FORMAT, E_NUM_FORMAT,
131                 "[%s] Integer decode failed. Scan stopped at (%ls).", GetErrorMessage(E_NUM_FORMAT), pEnd);
132         SysTryReturn(NID_BASE, !((ret == LONG_MAX || ret == LONG_MIN) && (errno != 0)), E_NUM_FORMAT, E_NUM_FORMAT,
133                 "[%s] Decoded value cannot fit into an Integer.", GetErrorMessage(E_NUM_FORMAT));
134
135         return E_SUCCESS;
136 }
137
138 int
139 Integer::GetHashCode(void) const
140 {
141         return value;
142 }
143
144 int
145 Integer::GetHashCode(int val)
146 {
147         return val;
148 }
149
150 result
151 Integer::Parse(const String& s, int& ret)
152 {
153         int len = s.GetLength();
154         SysTryReturn(NID_BASE, (len > 0 && len < 12), E_NUM_FORMAT, E_NUM_FORMAT,
155                 "[%s] The length of s(%ls) MUST be greater than 0 and less than 12.",
156                 GetErrorMessage(E_NUM_FORMAT), s.GetPointer());
157
158         return Parse(s, Character::RADIX_DECIMAL, ret);
159 }
160
161 result
162 Integer::Parse(const String& s, int radix, int& ret)
163 {
164         SysTryReturn(NID_BASE, ((radix == Character::RADIX_BINARY) || (radix == Character::RADIX_OCTAL) ||
165                 (radix == Character::RADIX_DECIMAL) || (radix == Character::RADIX_HEXADECIMAL)), E_OUT_OF_RANGE, E_OUT_OF_RANGE,
166                 "[%s] The radix(%d) MUST be one of 2, 8, 10 and 16.", GetErrorMessage(E_OUT_OF_RANGE), radix);
167
168         int len = s.GetLength();
169         SysTryReturn(NID_BASE, (len > 0), E_NUM_FORMAT, E_NUM_FORMAT, "[%s] The length of s MUST be greater than 0.",
170                 GetErrorMessage(E_NUM_FORMAT));
171
172         errno = 0;
173         wchar_t* pEnd = null;
174         int tmpRet = wcstol(s.GetPointer(), &pEnd, radix);
175         SysTryReturn(NID_BASE, (pEnd[0] == 0), E_NUM_FORMAT, E_NUM_FORMAT,
176                 "[%s] Integer parse failed. Scan stopped at (%ls).", GetErrorMessage(E_NUM_FORMAT), pEnd);
177         SysTryReturn(NID_BASE, !((tmpRet == LONG_MAX || tmpRet == LONG_MIN) && (errno != 0)), E_NUM_FORMAT, E_NUM_FORMAT,
178                 "[%s] Parsed value cannot fit into an Integer.", GetErrorMessage(E_NUM_FORMAT));
179
180         ret = tmpRet;
181         return E_SUCCESS;
182 }
183
184 char
185 Integer::ToChar(void) const
186 {
187         return static_cast<char> (value);
188 }
189
190 short
191 Integer::ToShort(void) const
192 {
193         return static_cast<short> (value);
194 }
195
196 int
197 Integer::ToInt(void) const
198 {
199         return value;
200 }
201
202 long
203 Integer::ToLong(void) const
204 {
205         return static_cast<long> (value);
206 }
207
208 long long
209 Integer::ToLongLong(void) const
210 {
211         return static_cast<long long> (value);
212 }
213
214 float
215 Integer::ToFloat(void) const
216 {
217         return static_cast<float> (value);
218 }
219
220 double
221 Integer::ToDouble(void) const
222 {
223         return static_cast<double> (value);
224 }
225
226 String
227 Integer::ToString(void) const
228 {
229         return(Integer::ToString(value));
230 }
231
232 String
233 Integer::ToString(int value)
234 {
235         const static unsigned int INTEGER_LENGTH_MAX = 11;
236
237         wchar_t sValue[INTEGER_LENGTH_MAX + 1] = {0, };
238         swprintf(sValue, (sizeof(sValue) / sizeof(sValue[0])), L"%d", value);
239
240         return String(sValue);
241 }
242
243 }} //Tizen::Base