Update change log and spec for wrt-plugins-tizen_0.4.49
[framework/web/wrt-plugins-tizen.git] / src / Tizen / AnyFactory.cpp
1 //
2 // Tizen Web Device API
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        AnyType.cpp
20  * @author      Kisub Song (kisubs.song@samsung.com)
21  * @version     0.1
22  * @brief       Declaration of the JSFilter class
23  */
24
25 #include "AnyFactory.h"
26 #include <string.h>
27 #include <locale.h>
28 #include <Commons/Exception.h>
29 #include <PlatformException.h>
30 #include <JSUtil.h>
31 #include <sstream>
32 #include <Logger.h>
33
34 namespace DeviceAPI {
35 namespace Tizen {
36
37 using namespace DeviceAPI::Common;
38
39 class PrivateAny : public Any
40 {
41 public:
42         PrivateAny();
43         PrivateAny(JSContextRef context, const JSValueRef value, PrimitiveType type);
44         virtual ~PrivateAny();
45
46 private:
47         bool isDate(JSContextRef jsContext, JSValueRef jsValue) const;
48         std::string toJSON(JSContextRef jsContext, JSValueRef jsValue) const;
49         std::string toString(JSContextRef jsContext, JSValueRef jsValue) const;
50 };
51
52 PrivateAny::PrivateAny() : Any()
53 {
54         m_isNullOrUndefined = true;
55         m_type = PrimitiveType_Null;
56         m_json = "null";
57         m_str = "null";
58 }
59
60 PrivateAny::PrivateAny(JSContextRef context, const JSValueRef value, PrimitiveType type) : Any()
61 {
62         m_type = type;
63
64         if(type == PrimitiveType_NoType)
65                 throw UnknownException("Cannot create any with NoType");
66
67         if(JSValueIsUndefined(context, value) || JSValueIsNull(context, value))
68                 m_isNullOrUndefined = true;
69
70         try
71         {
72                 if(type == PrimitiveType_Boolean)
73                         m_value.b = JSUtil::JSValueToBoolean(context, value);
74                 else if(type == PrimitiveType_Long)
75                         m_value.l = JSUtil::JSValueToLong(context, value);
76                 else if(type == PrimitiveType_ULong)
77                         m_value.ul = JSUtil::JSValueToULong(context, value);
78                 else if(type == PrimitiveType_LongLong)
79                         m_value.ll = JSUtil::JSValueToLongLong(context, value);
80                 else if(type == PrimitiveType_ULongLong)
81                         m_value.ull = JSUtil::JSValueToULongLong(context, value);
82                 else if(type == PrimitiveType_Double)
83                         m_value.d = JSUtil::JSValueToDouble(context, value);
84                 else if(type == PrimitiveType_String)
85                 {
86                         m_value.str = new std::string();
87                         *m_value.str = JSUtil::JSValueToString(context, value);
88                 }
89                 else if(type == PrimitiveType_Time)
90                 {
91                         m_value.t = new std::tm;
92                         *m_value.t = JSUtil::JSValueToDateTm(context, value);
93                 }
94         }
95         catch(BasePlatformException &e)
96         {
97                 if(!m_isNullOrUndefined)
98                 {
99                         throw e;
100                 }
101
102                 m_type = PrimitiveType_Null;
103                 m_json = "null";
104         }
105
106         if(m_json.empty())
107                 m_json = toJSON(context, value);
108
109         m_str = toString(context, value);
110 }
111
112 PrivateAny::~PrivateAny()
113 {
114         if(m_type == PrimitiveType_String)
115         {
116                 if(m_value.str != NULL)
117                         delete m_value.str;
118         }
119         else if(m_type == PrimitiveType_Time)
120         {
121                 if(m_value.t != NULL)
122                         delete m_value.t;
123         }
124 }
125
126 bool PrivateAny::isDate(JSContextRef jsContext, JSValueRef jsValue) const
127 {
128         JSObjectRef jsObjectGlobal = JSContextGetGlobalObject(jsContext);
129         JSStringRef jsStringDate = JSStringCreateWithUTF8CString("Date");
130         JSValueRef jsValueDate = JSObjectGetProperty(jsContext, jsObjectGlobal, jsStringDate, NULL);
131         JSStringRelease(jsStringDate);
132
133         JSObjectRef jsObjectDate = JSValueToObject(jsContext, jsValueDate, NULL);
134
135         return JSValueIsInstanceOfConstructor(jsContext, jsValue, jsObjectDate, NULL);
136 }
137
138 std::string PrivateAny::toJSON(JSContextRef context, JSValueRef value) const
139 {
140         JSValueRef jsError = NULL;
141         JSStringRef jsStrJson = JSValueCreateJSONString(context, value, 0, &jsError);
142         if(jsError != NULL || jsStrJson == NULL)
143         {
144                 LoggerE("Fail to create JSON string");
145                 return std::string("");
146         }
147
148         std::string result = JSUtil::JSStringToString(context, jsStrJson);
149         JSStringRelease(jsStrJson);
150
151         return result;
152 }
153
154 std::string PrivateAny::toString(JSContextRef context, JSValueRef value) const
155 {
156         std::string result;
157
158         if(m_type == PrimitiveType_String)
159         {
160                 result = *m_value.str;
161         }
162         else if(m_type == PrimitiveType_Long ||
163                         m_type == PrimitiveType_ULong ||
164                         m_type == PrimitiveType_LongLong ||
165                         m_type == PrimitiveType_ULongLong)
166         {
167                 std::stringstream ss;
168
169                 if(m_type == PrimitiveType_Long)
170                         ss << m_value.l;
171                 else if(m_type == PrimitiveType_ULong)
172                         ss << m_value.ul;
173                 else if(m_type == PrimitiveType_LongLong)
174                         ss << m_value.ll;
175                 else if(m_type == PrimitiveType_ULongLong)
176                         ss << m_value.ull;
177
178                 result = ss.str();
179         }
180         else
181         {
182                 JSValueRef jsError = NULL;
183                 JSStringRef jsStrJson = JSValueToStringCopy(context, value, &jsError);
184                 if(jsError == NULL && jsStrJson != NULL)
185                 {
186                         result = JSUtil::JSStringToString(context, jsStrJson);
187                         JSStringRelease(jsStrJson);
188                 }
189         }
190
191         return result;
192 }
193
194 AnyPtr AnyFactory::createAny(JSContextRef context, JSValueRef value, PrimitiveType type)
195 {
196         AnyPtr any(NULL);
197
198         try
199         {
200                 any = AnyPtr(new PrivateAny(context, value, type));
201         }
202         catch(TypeMismatchException &e)
203         {
204                 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Type error occured while converting JSValueRef");
205         }
206         catch(BasePlatformException &e)
207         {
208                 ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Unknown error occured while converting JSValueRef");
209         }
210
211         return any;
212 }
213
214 AnyPtr AnyFactory::createAnyNoException(JSContextRef context, JSValueRef value, PrimitiveType type)
215 {
216         try
217         {
218                 return AnyPtr(new PrivateAny(context, value, type));
219         }
220         catch(BasePlatformException &e)
221         {
222                 LoggerE("Error while converting (" << e.getName() << ") : " << e.getMessage());
223         }
224
225         return AnyPtr(new PrivateAny());
226 }
227
228 AnyPtr AnyFactory::createAnyEmpty(JSContextRef context)
229 {
230         return AnyPtr(new PrivateAny());
231 }
232
233 } // Tizen
234 } // DeviceAPI