Update wrt-plugins-common_0.3.60
[platform/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 long long integer value.
97      * @param arg JSValueRef object to convert.
98      * @return Long long integer value.
99      * @throw ConversionException Thrown when conversion fails.
100      */
101     long long toLongLong(const JSValueRef& arg);
102     /**
103      * Converts JSValueRef to unsigned long value.
104      * @param arg JSValueRef object to convert.
105      * @return Unsigned long value.
106      * @throw ConversionException Thrown when conversion fails.
107      */
108     unsigned long toULong(const JSValueRef& arg);
109
110     /**
111      * Converts JSValueRef to double value.
112      * @param arg JSValueRef object to convert.
113      * @return Double value.
114      * @throw ConversionException Thrown when conversion fails.
115      */
116     double toDouble(const JSValueRef& arg);
117
118     /**
119      * Converts JSValueRef to size_t value.
120      * @param arg JSValueRef object to convert.
121      * @return Size_t value.
122      * @throw ConversionException Thrown when conversion fails.
123      */
124     std::size_t toSizeT(const JSValueRef& arg);
125
126     /**
127      * Converts JSStringRef to size_t value.
128      * @param arg JSStringRef object to convert.
129      * @return Size_t value.
130      * @throw ConversionException Thrown when conversion fails.
131      */
132     std::size_t toSizeT(const JSStringRef& arg);
133
134     /**
135      * Converts int to STL string.
136      * @param arg int to convert.
137      * @return STL string.
138      * @throw ConversionException Thrown when conversion fails.
139      */
140     std::string toString(int arg);
141
142     std::string toString(unsigned long arg);
143
144     std::string toString(long arg);
145
146     std::string toString(std::size_t arg);
147
148     /**
149      * Converts JSValueRef to STL string.
150      * @param arg JSValueRef to convert.
151      * @return STL string.
152      * @throw ConversionException Thrown when conversion fails.
153      * @remarks If one wants to convert JS Date object to a string then
154      *          toDateString() should be used.
155      */
156     std::string toString(const JSValueRef& arg);
157
158     /**
159      * Converts JSStringRef to STL string.
160      * @param arg JSStringRef to convert.
161      * @return STL string.
162      * @throw ConversionException Thrown when conversion fails.
163      */
164     std::string toString(const JSStringRef& arg);
165
166     /**
167      * Converts JSSValueRef to STL string if
168      * arg is one of: String, Number, Bool
169      * @param arg JSValueReg to convert.
170      * @return STL string.
171      * @throw ConversionException Thrown when conversion fails.
172      */
173     std::string tryString(const JSValueRef& arg);
174
175     /**
176      * Converts JS Date object to STL string.
177      * @param arg JS Date object to convert.
178      * @return STL string.
179      * @throw ConversionException Thrown when conversion fails.
180      */
181     std::string toDateString(const JSValueRef& arg);
182
183     /**
184      * Converts JSValueRef to time_t value.
185      * @param arg JSValueRef to convert.
186      * @return time_t value.
187      * @throw ConversionException Thrown when conversion fails.
188      */
189     time_t toDateTimeT(const JSValueRef& arg);
190
191     /**
192      * Converts JSValueRef to tm struct.
193      * @param arg JSValueRef to convert.
194      * @return tm struct.
195      * @throw ConversionException Thrown when conversion fails.
196      */
197     tm toDateTm(const JSValueRef& arg);
198
199     /**
200      * Converts JSValueRef to vector<unsigned char>.
201      * @param arg JSValueRef to convert.
202      * @return vector<unsigned char>.
203      * @throw ConversionException Thrown when conversion fails.
204      */
205     std::vector<unsigned char> toVectorOfUChars(const JSValueRef& arg);
206
207     /**
208      * Converts JSValueRef to vector<char>.
209      * @param arg JSValueRef to convert.
210      * @return vector<char>.
211      * @throw ConversionException Thrown when conversion fails.
212      */
213     std::vector<char> toVectorOfChars(const JSValueRef& arg);
214
215     /**
216      * Converts JSValueRef to vector<int>.
217      * @param arg JSValueRef to convert.
218      * @return vector<int>.
219      * @throw ConversionException Thrown when conversion fails.
220      */
221     std::vector<int> toVectorOfInts(const JSValueRef& arg);
222
223     /**
224      * Converts JSValueRef to vector of string.
225      * @param arg JSValueRef to convert.
226      * @return std::vector<std::string>
227      * @throw ConversionException Thrown when conversion fails.
228      */
229     std::vector<std::string> toVectorOfStrings(const JSValueRef& arg);
230
231     /**
232    * Converts JSValueRef to vector of time_t.
233    * @param arg JSValueRef to convert.
234    * @return std::vector<std::time_t>
235    * @throw ConversionException Thrown when conversion fails.
236    */
237   std::vector<std::time_t> toVectorOfTimeT(const JSValueRef& arg);
238
239   /**
240      * Converts boolean value to JSValueRef.
241      * @param arg Boolean value to convert.
242      * @return JSValueRef object.
243      * @throw ConversionException Thrown when conversion fails.
244      */
245     JSValueRef toJSValueRef(bool arg);
246
247     /**
248      * Converts integer value to JSValueRef.
249      * @param arg Integer value to convert.
250      * @return JSValueRef object.
251      * @throw ConversionException Thrown when conversion fails.
252      */
253     JSValueRef toJSValueRef(int arg);
254
255     /**
256      * Converts unsigned integer value to JSValueRef.
257      * @param arg Unsigned integer value to convert.
258      * @return JSValueRef object.
259      * @throw ConversionException Thrown when conversion fails.
260      */
261     JSValueRef toJSValueRef(unsigned int arg);
262
263     /**
264      * Converts double value to JSValueRef.
265      * @param arg Double value to convert.
266      * @return JSValueRef object.
267      * @throw ConversionException Thrown when conversion fails.
268      */
269     JSValueRef toJSValueRef(double arg);
270
271     /**
272      * Converts unsigned long value to JSValueRef.
273      * @param arg unsigned long value to convert.
274      * @return JSValueRef object.
275      * @throw ConversionException Thrown when conversion fails.
276      */
277     JSValueRef toJSValueRef(unsigned long arg);
278
279     /**
280    * Converts long value to JSValueRef.
281    * @param arg long value to convert.
282    * @return JSValueRef object.
283    * @throw ConversionException Thrown when conversion fails.
284    */
285   JSValueRef toJSValueRefLong(const long arg);
286
287     /**
288      * Converts unsigned long value to JSValueRef.
289      * @param arg long long int value to convert.
290      * @return JSValueRef object.
291      * @throw ConversionException Thrown when conversion fails.
292      */
293     JSValueRef toJSValueRef(long long int arg);
294
295   /**
296      * Converts STL string to JSValueRef.
297      * @param arg STL string to convert.
298      * @return JSValueRef object.
299      * @throw ConversionException Thrown when conversion fails.
300      */
301     JSValueRef toJSValueRef(const std::string& arg);
302
303     /**
304      * Converts char sequence to JSValueRef.
305      * @param arg char sequence to convert.
306      * @return JSValueRef object.
307      * @throw ConversionException Thrown when conversion fails.
308      */
309     JSValueRef toJSValueRef(const char* arg);
310
311     /**
312      * Converts time_t value to JSValueRef.
313      * @param arg time_t value to convert.
314      * @return JSValueRef object.
315      * @throw ConversionException Thrown when conversion fails.
316      */
317     JSValueRef toJSValueRef(const time_t arg);
318
319     /**
320      * Converts tm struct to JSValueRef.
321      * @param arg tm struct to convert.
322      * @return JSValueRef object.
323      * @throw ConversionException Thrown when conversion fails.
324      */
325     JSValueRef toJSValueRef(const tm& arg);
326
327     /**
328    * Converts STL vector of integer to JSValueRef.
329    * @param arg STL vector of integer to convert.
330    * @return JSValueRef object.
331    * @throw ConversionException Thrown when conversion fails.
332    */
333   JSValueRef toJSValueRef(const std::vector<int>& arg);
334
335    /**
336    * Converts STL vector of time_t to JSValueRef.
337    * @param arg STL vector of time_t to convert.
338    * @return JSValueRef object.
339    * @throw ConversionException Thrown when conversion fails.
340    */
341   JSValueRef toJSValueRef(const std::vector<time_t>& arg);
342
343    /**
344      * Converts STL vector of string to JSStringRef.
345      * @param arg STL string to convert.
346      * @return JSValueRef object.
347      * @throw ConversionException Thrown when conversion fails.
348      */
349     JSValueRef toJSValueRef(const std::vector<std::string>& arg);
350
351     /**
352      * Converts JSValueRef to JSValueRef
353      * @param JSValueRef js value which is returned
354      * @return JSValueRef - parameter
355      * @throw ConversionException Thrown when conversion fails.
356      */
357     JSValueRef toJSValueRef(JSValueRef arg);
358
359     /**
360      * Converts std::vector to JSValueRef
361      * @param arg vecotr of JSValueRefs
362      * @return JSValueRef - js array
363      * @throw ConversionException Thrown when conversion fails.
364      */
365     JSValueRef toJSValueRef(const std::vector<JSValueRef>& arg);
366
367     /**
368      * Template specialization to catch errors caused
369      * by wrong usage of general template or
370      * implicit conversions from SharedPtr to
371      * specialized type
372      * */
373     template<class Class>
374     JSValueRef toJSValueRef(const DPL::SharedPtr<Class>& c)
375     {
376         STATIC_ERROR(ERROR_INVALID_IMPLICIT_CONVERSION, c)
377         //above macro causes compilation error
378         return static_cast<JSValueRef>(NULL);
379     }
380
381     /**
382      * Converts STL string to JSStringRef.
383      * @param arg STL string to convert.
384      * @return JSStringRef object.
385      * @throw ConversionException Thrown when conversion fails.
386      */
387     JSStringRef toJSStringRef(const std::string& arg);
388
389   protected:
390     bool isNan(double value) const;
391
392     double toNumber_(const JSValueRef& arg);
393
394     double toNumber_(const JSStringRef& arg);
395
396     double toNumber_(const std::string& arg);
397
398     template<typename T, class Derived>
399     std::vector<T> toVectorOfT_(const JSValueRef& arg,
400             T (Derived::*f)(const JSValueRef &),
401             Derived* object)
402     {
403         if (JSValueIsNull(m_context,
404                           arg) || JSValueIsUndefined(m_context, arg)) {
405             return std::vector<T>();
406         }
407
408         if (!JSIsArrayValue(m_context, arg)) {
409             ThrowMsg(Commons::ConversionException, "Argument is not an JS array.");
410         }
411
412         std::vector<T> result;
413         JSObjectRef objArg = toJSObjectRef(arg);
414         for (std::size_t i = 0; i < JSGetArrayLength(m_context, objArg); ++i) {
415             JSValueRef element = JSGetArrayElement(m_context, objArg, i);
416             result.push_back((object->*f)(element));
417         }
418         return result;
419     }
420
421     template<typename T>
422     std::vector<T> toVectorOfT_(const JSValueRef& arg,
423             T (Converter::*f)(const JSValueRef &))
424     {
425         if (JSValueIsNull(m_context,
426                           arg) || JSValueIsUndefined(m_context, arg)) {
427             return std::vector<T>();
428         }
429
430         if (!JSIsArrayValue(m_context, arg)) {
431             ThrowMsg(Commons::ConversionException, "Argument is not an JS array.");
432         }
433
434         std::vector<T> result;
435         JSObjectRef objArg = toJSObjectRef(arg);
436         for (std::size_t i = 0; i < JSGetArrayLength(m_context, objArg); ++i) {
437             JSValueRef element = JSGetArrayElement(m_context, objArg, i);
438             result.push_back((this->*f)(element));
439         }
440         return result;
441     }
442
443     template<class T, class Derived>
444     JSValueRef toJSValueRef_(const std::vector<T>& arg,
445             JSValueRef (Derived::*f)(const T &),
446             Derived* object)
447     {
448         JSObjectRef jsResult = JSCreateArrayObject(m_context, 0, NULL);
449
450         if (NULL == jsResult) {
451             ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Could not create js array object");
452         }
453
454         for (std::size_t i = 0; i < arg.size(); ++i) {
455             JSValueRef tmpVal = (object->*f)(arg[i]);
456             if (!JSSetArrayElement(m_context, jsResult, i, tmpVal)) {
457                 ThrowMsg(WrtDeviceApis::Commons::UnknownException,
458                          "Could not insert value into js array");
459             }
460         }
461
462         return jsResult;
463     }
464
465     template<class T>
466     JSValueRef toJSValueRef_(const std::vector<T>& arg)
467     {
468         JSObjectRef jsResult = JSCreateArrayObject(m_context, 0, NULL);
469
470         if (NULL == jsResult) {
471             ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
472                      "Could not create js array object");
473         }
474
475         for (std::size_t i = 0; i < arg.size(); ++i) {
476             JSValueRef tmpVal = toJSValueRef(arg[i]);
477             if (!JSSetArrayElement(m_context, jsResult, i, tmpVal)) {
478                 ThrowMsg(WrtDeviceApis::Commons::UnknownException,
479                          "Could not insert value into js array");
480             }
481         }
482
483         return jsResult;
484     }
485
486     template<class T>
487     JSValueRef toJSValueRef_(const std::list<T>& arg)
488     {
489         JSObjectRef jsResult = JSCreateArrayObject(m_context, 0, NULL);
490
491         if (NULL == jsResult) {
492             ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Could not create js array object");
493         }
494
495         typename std::list<T>::const_iterator it = arg.begin();
496         for (std::size_t i = 0; it != arg.end(); ++i, ++it) {
497             JSValueRef tmpVal = toJSValueRef(*it);
498             if (!JSSetArrayElement(m_context, jsResult, i, tmpVal)) {
499                 ThrowMsg(WrtDeviceApis::Commons::UnknownException,
500                          "Could not insert value into js array");
501             }
502         }
503
504         return jsResult;
505     }
506
507     template<class T, class Derived>
508     JSValueRef toJSValueRef_(const std::list<T>& arg,
509             JSValueRef (Derived::*f)(const T &),
510             Derived* object)
511     {
512         JSObjectRef jsResult = JSCreateArrayObject(m_context, 0, NULL);
513
514         if (NULL == jsResult) {
515             ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Could not create js array object");
516         }
517
518         typename std::list<T>::const_iterator it = arg.begin();
519         for (std::size_t i = 0; it != arg.end(); ++i, ++it) {
520             JSValueRef tmpVal = (object->*f)(*it);
521             if (!JSSetArrayElement(m_context, jsResult, i, tmpVal)) {
522                 ThrowMsg(WrtDeviceApis::Commons::UnknownException,
523                          "Could not insert value into js array");
524             }
525         }
526
527         return jsResult;
528     }
529
530     std::string toString_(const JSValueRef& arg);
531
532     template<typename T>
533     std::string toString_(const T& arg)
534     {
535         std::stringstream ss;
536         if (!(ss << arg)) {
537             ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Could not convert to string.");
538         }
539         return ss.str();
540     }
541
542   protected:
543     JSContextRef m_context;
544 };
545
546 template<class C>
547 class ConverterFactory : private DPL::Noncopyable
548 {
549   public:
550     /**
551      * Converter type which deletes itself when gets out of scope.
552      */
553     typedef DPL::SharedPtr<C> ConverterType;
554
555   public:
556     /**
557      * Gets converter object.
558      * @param context JavaScript context the conversion will be performed in.
559      * @param[out] exception JavaScript value for storing exception.
560      * @return Converter object.
561      */
562     static ConverterType getConverter(JSContextRef context)
563     {
564         C* convert = new C(context);
565         return ConverterType(convert);
566     }
567
568   private:
569     ConverterFactory();
570 };
571
572 typedef ConverterFactory<Converter> BasicConverterFactory;
573
574 typedef BasicConverterFactory::ConverterType BasicConverter;
575
576 } // CommonsJavaScript
577 } // WrtDeviceApis
578
579 #endif /* WRTDEVICEAPIS_COMMONSJAVASCRIPT_CONVERTER_H_ */