Update wrt-plugins-common_0.3.53
[framework/web/wrt-plugins-common.git] / src / CommonsJavaScript / Converter.h
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 #ifndef WRTDEVICEAPIS_COMMONSJAVASCRIPT_CONVERTER_H_
17 #define WRTDEVICEAPIS_COMMONSJAVASCRIPT_CONVERTER_H_
18
19 #include <ctime>
20 #include <cstddef>
21 #include <string>
22 #include <vector>
23 #include <list>
24 #include <JavaScriptCore/JavaScript.h>
25 #include <dpl/noncopyable.h>
26 #include <dpl/shared_ptr.h>
27 #include <Commons/Exception.h>
28 #include <Commons/StaticAssert.h>
29
30 namespace WrtDeviceApis {
31 namespace CommonsJavaScript {
32
33 class Converter : private DPL::Noncopyable
34 {
35   public:
36     explicit Converter(JSContextRef context);
37     virtual ~Converter();
38
39     /**
40      * Converts JSValueRef to JSObjectRef.
41      * @param arg JSValueRef object to convert.
42      * @return JSObjectRef object.
43      * @throw ConversionException Thrown when conversion fails.
44      */
45     JSObjectRef toJSObjectRef(const JSValueRef& arg);
46
47     /**
48      * Converts JSValueRef object to boolean value.
49      * @param arg JSValueRef object to convert.
50      * @return Boolean value.
51      * @throw ConversionException Thrown when conversion fails.
52      */
53     bool toBool(const JSValueRef& arg);
54
55     /**
56      * Converts JSValueRef object to unsigned char value.
57      * @param arg JSValueRef object to convert.
58      * @return Unsigned char value.
59      * @throw ConversionException Thrown when conversion fails.
60      */
61     unsigned char toUChar(const JSValueRef& arg);
62
63     /**
64      * Converts JSValueRef object to char value.
65      * @param arg JSValueRef object to convert.
66      * @return Char value.
67      * @throw ConversionException Thrown when conversion fails.
68      */
69     char toChar(const JSValueRef& arg);
70
71     /**
72      * Converts JSValueRef to integer value.
73      * @param arg JSValueRef object to convert.
74      * @return Integer value.
75      * @throw ConversionException Thrown when conversion fails.
76      */
77     int toInt(const JSValueRef& arg);
78
79     /**
80      * Converts string to integer value.
81      * @param arg string to convert.
82      * @return Integer value.
83      * @throw ConversionException Thrown when conversion fails.
84      */
85     int toInt(const std::string& arg);
86
87     /**
88      * Converts JSvalueRef to long integer value.
89      * @param arg JSValueRef object to convert.
90      * @return Long integer value.
91      * @throw ConversionException Thrown when conversion fails.
92      */
93     long toLong(const JSValueRef& arg);
94
95     /**
96      * Converts JSValueRef to unsigned long value.
97      * @param arg JSValueRef object to convert.
98      * @return Unsigned long value.
99      * @throw ConversionException Thrown when conversion fails.
100      */
101     unsigned long toULong(const JSValueRef& arg);
102
103     /**
104      * Converts JSValueRef to double value.
105      * @param arg JSValueRef object to convert.
106      * @return Double value.
107      * @throw ConversionException Thrown when conversion fails.
108      */
109     double toDouble(const JSValueRef& arg);
110
111     /**
112      * Converts JSValueRef to size_t value.
113      * @param arg JSValueRef object to convert.
114      * @return Size_t value.
115      * @throw ConversionException Thrown when conversion fails.
116      */
117     std::size_t toSizeT(const JSValueRef& arg);
118
119     /**
120      * Converts JSStringRef to size_t value.
121      * @param arg JSStringRef object to convert.
122      * @return Size_t value.
123      * @throw ConversionException Thrown when conversion fails.
124      */
125     std::size_t toSizeT(const JSStringRef& arg);
126
127     /**
128      * Converts int to STL string.
129      * @param arg int to convert.
130      * @return STL string.
131      * @throw ConversionException Thrown when conversion fails.
132      */
133     std::string toString(int arg);
134
135     std::string toString(unsigned long arg);
136
137     std::string toString(long arg);
138
139     std::string toString(std::size_t arg);
140
141     /**
142      * Converts JSValueRef to STL string.
143      * @param arg JSValueRef to convert.
144      * @return STL string.
145      * @throw ConversionException Thrown when conversion fails.
146      * @remarks If one wants to convert JS Date object to a string then
147      *          toDateString() should be used.
148      */
149     std::string toString(const JSValueRef& arg);
150
151     /**
152      * Converts JSStringRef to STL string.
153      * @param arg JSStringRef to convert.
154      * @return STL string.
155      * @throw ConversionException Thrown when conversion fails.
156      */
157     std::string toString(const JSStringRef& arg);
158
159     /**
160      * Converts JSSValueRef to STL string if
161      * arg is one of: String, Number, Bool
162      * @param arg JSValueReg to convert.
163      * @return STL string.
164      * @throw ConversionException Thrown when conversion fails.
165      */
166     std::string tryString(const JSValueRef& arg);
167
168     /**
169      * Converts JS Date object to STL string.
170      * @param arg JS Date object to convert.
171      * @return STL string.
172      * @throw ConversionException Thrown when conversion fails.
173      */
174     std::string toDateString(const JSValueRef& arg);
175
176     /**
177      * Converts JSValueRef to time_t value.
178      * @param arg JSValueRef to convert.
179      * @return time_t value.
180      * @throw ConversionException Thrown when conversion fails.
181      */
182     time_t toDateTimeT(const JSValueRef& arg);
183
184     /**
185      * Converts JSValueRef to tm struct.
186      * @param arg JSValueRef to convert.
187      * @return tm struct.
188      * @throw ConversionException Thrown when conversion fails.
189      */
190     tm toDateTm(const JSValueRef& arg);
191
192     /**
193      * Converts JSValueRef to vector<unsigned char>.
194      * @param arg JSValueRef to convert.
195      * @return vector<unsigned char>.
196      * @throw ConversionException Thrown when conversion fails.
197      */
198     std::vector<unsigned char> toVectorOfUChars(const JSValueRef& arg);
199
200     /**
201      * Converts JSValueRef to vector<char>.
202      * @param arg JSValueRef to convert.
203      * @return vector<char>.
204      * @throw ConversionException Thrown when conversion fails.
205      */
206     std::vector<char> toVectorOfChars(const JSValueRef& arg);
207
208     /**
209      * Converts JSValueRef to vector<int>.
210      * @param arg JSValueRef to convert.
211      * @return vector<int>.
212      * @throw ConversionException Thrown when conversion fails.
213      */
214     std::vector<int> toVectorOfInts(const JSValueRef& arg);
215
216     /**
217      * Converts JSValueRef to vector of string.
218      * @param arg JSValueRef to convert.
219      * @return std::vector<std::string>
220      * @throw ConversionException Thrown when conversion fails.
221      */
222     std::vector<std::string> toVectorOfStrings(const JSValueRef& arg);
223
224     /**
225    * Converts JSValueRef to vector of time_t.
226    * @param arg JSValueRef to convert.
227    * @return std::vector<std::time_t>
228    * @throw ConversionException Thrown when conversion fails.
229    */
230   std::vector<std::time_t> toVectorOfTimeT(const JSValueRef& arg);
231
232   /**
233      * Converts boolean value to JSValueRef.
234      * @param arg Boolean value to convert.
235      * @return JSValueRef object.
236      * @throw ConversionException Thrown when conversion fails.
237      */
238     JSValueRef toJSValueRef(bool arg);
239
240     /**
241      * Converts integer value to JSValueRef.
242      * @param arg Integer value to convert.
243      * @return JSValueRef object.
244      * @throw ConversionException Thrown when conversion fails.
245      */
246     JSValueRef toJSValueRef(int arg);
247
248     /**
249      * Converts unsigned integer value to JSValueRef.
250      * @param arg Unsigned integer value to convert.
251      * @return JSValueRef object.
252      * @throw ConversionException Thrown when conversion fails.
253      */
254     JSValueRef toJSValueRef(unsigned int arg);
255
256     /**
257      * Converts double value to JSValueRef.
258      * @param arg Double value to convert.
259      * @return JSValueRef object.
260      * @throw ConversionException Thrown when conversion fails.
261      */
262     JSValueRef toJSValueRef(double arg);
263
264     /**
265      * Converts unsigned long value to JSValueRef.
266      * @param arg unsigned long value to convert.
267      * @return JSValueRef object.
268      * @throw ConversionException Thrown when conversion fails.
269      */
270     JSValueRef toJSValueRef(unsigned long arg);
271
272     /**
273    * Converts long value to JSValueRef.
274    * @param arg long value to convert.
275    * @return JSValueRef object.
276    * @throw ConversionException Thrown when conversion fails.
277    */
278   JSValueRef toJSValueRefLong(const long arg);
279
280     /**
281      * Converts unsigned long value to JSValueRef.
282      * @param arg long long int value to convert.
283      * @return JSValueRef object.
284      * @throw ConversionException Thrown when conversion fails.
285      */
286     JSValueRef toJSValueRef(long long int arg);
287
288   /**
289      * Converts STL string to JSValueRef.
290      * @param arg STL string to convert.
291      * @return JSValueRef object.
292      * @throw ConversionException Thrown when conversion fails.
293      */
294     JSValueRef toJSValueRef(const std::string& arg);
295
296     /**
297      * Converts char sequence to JSValueRef.
298      * @param arg char sequence to convert.
299      * @return JSValueRef object.
300      * @throw ConversionException Thrown when conversion fails.
301      */
302     JSValueRef toJSValueRef(const char* arg);
303
304     /**
305      * Converts time_t value to JSValueRef.
306      * @param arg time_t value to convert.
307      * @return JSValueRef object.
308      * @throw ConversionException Thrown when conversion fails.
309      */
310     JSValueRef toJSValueRef(const time_t arg);
311
312     /**
313      * Converts tm struct to JSValueRef.
314      * @param arg tm struct to convert.
315      * @return JSValueRef object.
316      * @throw ConversionException Thrown when conversion fails.
317      */
318     JSValueRef toJSValueRef(const tm& arg);
319
320     /**
321    * Converts STL vector of integer to JSValueRef.
322    * @param arg STL vector of integer to convert.
323    * @return JSValueRef object.
324    * @throw ConversionException Thrown when conversion fails.
325    */
326   JSValueRef toJSValueRef(const std::vector<int>& arg);
327
328    /**
329    * Converts STL vector of time_t to JSValueRef.
330    * @param arg STL vector of time_t to convert.
331    * @return JSValueRef object.
332    * @throw ConversionException Thrown when conversion fails.
333    */
334   JSValueRef toJSValueRef(const std::vector<time_t>& arg);
335
336    /**
337      * Converts STL vector of string to JSStringRef.
338      * @param arg STL string to convert.
339      * @return JSValueRef object.
340      * @throw ConversionException Thrown when conversion fails.
341      */
342     JSValueRef toJSValueRef(const std::vector<std::string>& arg);
343
344     /**
345      * Converts JSValueRef to JSValueRef
346      * @param JSValueRef js value which is returned
347      * @return JSValueRef - parameter
348      * @throw ConversionException Thrown when conversion fails.
349      */
350     JSValueRef toJSValueRef(JSValueRef arg);
351
352     /**
353      * Converts std::vector to JSValueRef
354      * @param arg vecotr of JSValueRefs
355      * @return JSValueRef - js array
356      * @throw ConversionException Thrown when conversion fails.
357      */
358     JSValueRef toJSValueRef(const std::vector<JSValueRef>& arg);
359
360     /**
361      * Template specialization to catch errors caused
362      * by wrong usage of general template or
363      * implicit conversions from SharedPtr to
364      * specialized type
365      * */
366     template<class Class>
367     JSValueRef toJSValueRef(const DPL::SharedPtr<Class>& c)
368     {
369         STATIC_ERROR(ERROR_INVALID_IMPLICIT_CONVERSION, c)
370         //above macro causes compilation error
371         return static_cast<JSValueRef>(NULL);
372     }
373
374     /**
375      * Converts STL string to JSStringRef.
376      * @param arg STL string to convert.
377      * @return JSStringRef object.
378      * @throw ConversionException Thrown when conversion fails.
379      */
380     JSStringRef toJSStringRef(const std::string& arg);
381
382   protected:
383     bool isNan(double value) const;
384
385     double toNumber_(const JSValueRef& arg);
386
387     double toNumber_(const JSStringRef& arg);
388
389     double toNumber_(const std::string& arg);
390
391     template<typename T, class Derived>
392     std::vector<T> toVectorOfT_(const JSValueRef& arg,
393             T (Derived::*f)(const JSValueRef &),
394             Derived* object)
395     {
396         if (JSValueIsNull(m_context,
397                           arg) || JSValueIsUndefined(m_context, arg)) {
398             return std::vector<T>();
399         }
400
401         if (!JSIsArrayValue(m_context, arg)) {
402             ThrowMsg(Commons::ConversionException, "Argument is not an JS array.");
403         }
404
405         std::vector<T> result;
406         JSObjectRef objArg = toJSObjectRef(arg);
407         for (std::size_t i = 0; i < JSGetArrayLength(m_context, objArg); ++i) {
408             JSValueRef element = JSGetArrayElement(m_context, objArg, i);
409             result.push_back((object->*f)(element));
410         }
411         return result;
412     }
413
414     template<typename T>
415     std::vector<T> toVectorOfT_(const JSValueRef& arg,
416             T (Converter::*f)(const JSValueRef &))
417     {
418         if (JSValueIsNull(m_context,
419                           arg) || JSValueIsUndefined(m_context, arg)) {
420             return std::vector<T>();
421         }
422
423         if (!JSIsArrayValue(m_context, arg)) {
424             ThrowMsg(Commons::ConversionException, "Argument is not an JS array.");
425         }
426
427         std::vector<T> result;
428         JSObjectRef objArg = toJSObjectRef(arg);
429         for (std::size_t i = 0; i < JSGetArrayLength(m_context, objArg); ++i) {
430             JSValueRef element = JSGetArrayElement(m_context, objArg, i);
431             result.push_back((this->*f)(element));
432         }
433         return result;
434     }
435
436     template<class T, class Derived>
437     JSValueRef toJSValueRef_(const std::vector<T>& arg,
438             JSValueRef (Derived::*f)(const T &),
439             Derived* object)
440     {
441         JSObjectRef jsResult = JSCreateArrayObject(m_context, 0, NULL);
442
443         if (NULL == jsResult) {
444             ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Could not create js array object");
445         }
446
447         for (std::size_t i = 0; i < arg.size(); ++i) {
448             JSValueRef tmpVal = (object->*f)(arg[i]);
449             if (!JSSetArrayElement(m_context, jsResult, i, tmpVal)) {
450                 ThrowMsg(WrtDeviceApis::Commons::UnknownException,
451                          "Could not insert value into js array");
452             }
453         }
454
455         return jsResult;
456     }
457
458     template<class T>
459     JSValueRef toJSValueRef_(const std::vector<T>& arg)
460     {
461         JSObjectRef jsResult = JSCreateArrayObject(m_context, 0, NULL);
462
463         if (NULL == jsResult) {
464             ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
465                      "Could not create js array object");
466         }
467
468         for (std::size_t i = 0; i < arg.size(); ++i) {
469             JSValueRef tmpVal = toJSValueRef(arg[i]);
470             if (!JSSetArrayElement(m_context, jsResult, i, tmpVal)) {
471                 ThrowMsg(WrtDeviceApis::Commons::UnknownException,
472                          "Could not insert value into js array");
473             }
474         }
475
476         return jsResult;
477     }
478
479     template<class T>
480     JSValueRef toJSValueRef_(const std::list<T>& arg)
481     {
482         JSObjectRef jsResult = JSCreateArrayObject(m_context, 0, NULL);
483
484         if (NULL == jsResult) {
485             ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Could not create js array object");
486         }
487
488         typename std::list<T>::const_iterator it = arg.begin();
489         for (std::size_t i = 0; it != arg.end(); ++i, ++it) {
490             JSValueRef tmpVal = toJSValueRef(*it);
491             if (!JSSetArrayElement(m_context, jsResult, i, tmpVal)) {
492                 ThrowMsg(WrtDeviceApis::Commons::UnknownException,
493                          "Could not insert value into js array");
494             }
495         }
496
497         return jsResult;
498     }
499
500     template<class T, class Derived>
501     JSValueRef toJSValueRef_(const std::list<T>& arg,
502             JSValueRef (Derived::*f)(const T &),
503             Derived* object)
504     {
505         JSObjectRef jsResult = JSCreateArrayObject(m_context, 0, NULL);
506
507         if (NULL == jsResult) {
508             ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Could not create js array object");
509         }
510
511         typename std::list<T>::const_iterator it = arg.begin();
512         for (std::size_t i = 0; it != arg.end(); ++i, ++it) {
513             JSValueRef tmpVal = (object->*f)(*it);
514             if (!JSSetArrayElement(m_context, jsResult, i, tmpVal)) {
515                 ThrowMsg(WrtDeviceApis::Commons::UnknownException,
516                          "Could not insert value into js array");
517             }
518         }
519
520         return jsResult;
521     }
522
523     std::string toString_(const JSValueRef& arg);
524
525     template<typename T>
526     std::string toString_(const T& arg)
527     {
528         std::stringstream ss;
529         if (!(ss << arg)) {
530             ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Could not convert to string.");
531         }
532         return ss.str();
533     }
534
535   protected:
536     JSContextRef m_context;
537 };
538
539 template<class C>
540 class ConverterFactory : private DPL::Noncopyable
541 {
542   public:
543     /**
544      * Converter type which deletes itself when gets out of scope.
545      */
546     typedef DPL::SharedPtr<C> ConverterType;
547
548   public:
549     /**
550      * Gets converter object.
551      * @param context JavaScript context the conversion will be performed in.
552      * @param[out] exception JavaScript value for storing exception.
553      * @return Converter object.
554      */
555     static ConverterType getConverter(JSContextRef context)
556     {
557         C* convert = new C(context);
558         return ConverterType(convert);
559     }
560
561   private:
562     ConverterFactory();
563 };
564
565 typedef ConverterFactory<Converter> BasicConverterFactory;
566
567 typedef BasicConverterFactory::ConverterType BasicConverter;
568
569 } // CommonsJavaScript
570 } // WrtDeviceApis
571
572 #endif /* WRTDEVICEAPIS_COMMONSJAVASCRIPT_CONVERTER_H_ */