Update change log and spec for wrt-plugins-tizen_0.4.59
[framework/web/wrt-plugins-tizen.git] / src / MessagePort / MessagePortJSUtil.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2013 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 #include "MessagePortJSUtil.h"
19
20 #include <CommonsJavaScript/ScopedJSStringRef.h>
21
22 #include <set>
23 #include <string>
24 #include <sstream>
25 #include "JSLocalMessagePort.h"
26 #include "JSRemoteMessagePort.h"
27 #include <Logger.h>
28
29 #define MESSAGE_PORT_ATTRIBUTE_KEY "key"
30 #define MESSAGE_PORT_ATTRIBUTE_VALUE "value"
31
32 namespace DeviceAPI {
33 namespace MessagePort {
34
35 using namespace std;
36 using namespace DeviceAPI::Common;
37
38 JSValueRef MessagePortJSUtil::toJSValueRef(JSContextRef context, const MessagePortDataItemMapPtr &arg)
39 {
40         JSObjectRef resultObject = JSCreateArrayObject(context, 0, NULL);
41         if (!resultObject)
42                 throw TypeMismatchException("Can not create array object");
43
44         int i = 0;
45         MessagePortDataItemMap::iterator iter;
46         for(iter = arg->begin(); iter != arg->end(); iter++, i++)
47         {
48                 const WrtDeviceApis::CommonsJavaScript::ScopedJSStringRef keyStr(
49                                 JSStringCreateWithUTF8CString(MESSAGE_PORT_ATTRIBUTE_KEY));
50                 const WrtDeviceApis::CommonsJavaScript::ScopedJSStringRef valueStr(
51                                 JSStringCreateWithUTF8CString(MESSAGE_PORT_ATTRIBUTE_VALUE));
52
53                 JSValueRef key = JSUtil::toJSValueRef(context, iter->first);
54                 JSValueRef value = JSUtil::toJSValueRef(context, iter->second);
55
56                 JSObjectRef jsobject = JSObjectMake(context, NULL, NULL);
57                 JSObjectSetProperty(context, jsobject, keyStr.get(), key, kJSPropertyAttributeNone, NULL);
58                 JSObjectSetProperty(context, jsobject, valueStr.get(), value, kJSPropertyAttributeNone, NULL);
59
60                 JSValueRef jsvalue = jsobject;
61
62                 if (!JSSetArrayElement(context, resultObject, i, jsvalue))
63                         throw TypeMismatchException("Can not fill contact array");
64         }
65
66         return static_cast<JSValueRef>(resultObject);
67 }
68
69 JSValueRef MessagePortJSUtil::toJSValueRef(JSContextRef context, const LocalMessagePortPtr &arg)
70 {
71         LocalMessagePortController *priv = new LocalMessagePortController(context, arg);
72         JSObjectRef object = JSObjectMake(context, JSLocalMessagePort::getClassRef(), priv);
73         if (!object)
74                 throw TypeMismatchException("Could not create JS object.");
75
76         return object;
77 }
78
79 JSValueRef MessagePortJSUtil::toJSValueRef(JSContextRef context, const RemoteMessagePortPtr &arg)
80 {
81         JSRemoteMessagePortPriv* priv = new JSRemoteMessagePortPriv(context, arg);
82         JSObjectRef object = JSObjectMake(context, JSRemoteMessagePort::getClassRef(), priv);
83         if (!object)
84                 throw TypeMismatchException("Could not create JS object.");
85
86         return object;
87 }
88
89 MessagePortDataItemMapPtr MessagePortJSUtil::JSValueToMessagePortDataItemMap(JSContextRef context, JSValueRef jsValue)
90 {
91         if(!JSIsArrayValue(context, jsValue))
92                 throw TypeMismatchException("MessagePortArray is not array.");
93
94         MessagePortDataItemMapPtr result = MessagePortDataItemMapPtr(new MessagePortDataItemMap());
95
96         const WrtDeviceApis::CommonsJavaScript::ScopedJSStringRef keyStr(
97                         JSStringCreateWithUTF8CString(MESSAGE_PORT_ATTRIBUTE_KEY));
98         const WrtDeviceApis::CommonsJavaScript::ScopedJSStringRef valueStr(
99                         JSStringCreateWithUTF8CString(MESSAGE_PORT_ATTRIBUTE_VALUE));
100
101         set<string> keyDupChecker;
102         JSObjectRef jsObject = JSValueToObject(context, jsValue);
103         unsigned int length = JSGetArrayLength(context, jsObject);
104         for (std::size_t i = 0; i < length; i++)
105         {
106                 JSValueRef element = JSGetArrayElement(context, jsObject, i);
107
108                 if(!JSValueIsObject(context, element))
109                 {
110                         stringstream ss;
111                         ss << "data[" << i << "] is not object type";
112                         throw TypeMismatchException(ss.str().c_str());
113                 }
114
115                 JSObjectRef jsObject = JSValueToObject(context, element);
116
117                 std::string key;
118                 std::string value;
119
120                 JSValueRef keyData = JSObjectGetProperty(context, jsObject, keyStr.get(), NULL);
121                 try
122                 {
123                         key = JSUtil::JSValueToString(context, keyData);
124                 }
125                 catch(BasePlatformException &e)
126                 {
127                         stringstream ss;
128                         ss << "data[" << i << "].key is not string type";
129                         throw TypeMismatchException(ss.str().c_str());
130                 }
131
132                 if(key.empty())
133                 {
134                         stringstream ss;
135                         ss << "data[" << i << "].key is empty";
136                         throw InvalidValuesException(ss.str().c_str());
137                 }
138
139                 if(keyDupChecker.find(key) != keyDupChecker.end())
140                 {
141                         stringstream ss;
142                         ss << "data[" << i << "].key \"" << key << "\" is duplicated";
143                         throw InvalidValuesException(ss.str().c_str());
144                 }
145
146                 keyDupChecker.insert(key);
147
148                 JSValueRef valueData = JSObjectGetProperty(context, jsObject, valueStr.get(), NULL);
149                 try
150                 {
151                         value = JSUtil::JSValueToString(context, valueData);
152                 }
153                 catch(BasePlatformException &e)
154                 {
155                         stringstream ss;
156                         ss << "data[" << i << "].value is not string type";
157                         throw TypeMismatchException(ss.str().c_str());
158                 }
159
160                 MessagePortDataItemPair pair(key, value);
161                 result->insert(pair);
162         }
163
164         return result;
165 }
166
167 LocalMessagePortPtr MessagePortJSUtil::JSValueToLocalMessagePort(JSContextRef context, JSValueRef jsValue)
168 {
169         if(!JSLocalMessagePort::isObjectOfClass(context, jsValue))
170         {
171                 LoggerE("Not a LocalMessagePort object");
172                 throw TypeMismatchException("value is not a LocalMessagePort object");
173         }
174
175         return JSLocalMessagePort::getLocalMessagePort(context, jsValue);
176 }
177
178 RemoteMessagePortPtr MessagePortJSUtil::JSValueToRemoteMessagePort(JSContextRef context, JSValueRef jsValue)
179 {
180         if(!JSRemoteMessagePort::isObjectOfClass(context, jsValue))
181         {
182                 LoggerE("Not a RemoteMessagePort object");
183                 throw TypeMismatchException("value is not a RemoteMessagePort object");
184         }
185
186         return JSRemoteMessagePort::getRemoteMessagePort(context, jsValue);
187 }
188
189 } // MessagePort
190 } // DeviceAPI