tizen beta release
[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 STL string to JSValueRef.
282      * @param arg STL string to convert.
283      * @return JSValueRef object.
284      * @throw ConversionException Thrown when conversion fails.
285      */
286     JSValueRef toJSValueRef(const std::string& arg);
287
288     /**
289      * Converts char sequence to JSValueRef.
290      * @param arg char sequence to convert.
291      * @return JSValueRef object.
292      * @throw ConversionException Thrown when conversion fails.
293      */
294     JSValueRef toJSValueRef(const char* arg);
295
296     /**
297      * Converts time_t value to JSValueRef.
298      * @param arg time_t value to convert.
299      * @return JSValueRef object.
300      * @throw ConversionException Thrown when conversion fails.
301      */
302     JSValueRef toJSValueRef(const time_t arg);
303
304     /**
305      * Converts tm struct to JSValueRef.
306      * @param arg tm struct to convert.
307      * @return JSValueRef object.
308      * @throw ConversionException Thrown when conversion fails.
309      */
310     JSValueRef toJSValueRef(const tm& arg);
311
312     /**
313    * Converts STL vector of integer to JSValueRef.
314    * @param arg STL vector of integer to convert.
315    * @return JSValueRef object.
316    * @throw ConversionException Thrown when conversion fails.
317    */
318   JSValueRef toJSValueRef(const std::vector<int>& arg);
319
320    /**
321    * Converts STL vector of time_t to JSValueRef.
322    * @param arg STL vector of time_t to convert.
323    * @return JSValueRef object.
324    * @throw ConversionException Thrown when conversion fails.
325    */
326   JSValueRef toJSValueRef(const std::vector<time_t>& arg);
327
328    /**
329      * Converts STL vector of string to JSStringRef.
330      * @param arg STL string to convert.
331      * @return JSValueRef object.
332      * @throw ConversionException Thrown when conversion fails.
333      */
334     JSValueRef toJSValueRef(const std::vector<std::string>& arg);
335
336     /**
337      * Converts JSValueRef to JSValueRef
338      * @param JSValueRef js value which is returned
339      * @return JSValueRef - parameter
340      * @throw ConversionException Thrown when conversion fails.
341      */
342     JSValueRef toJSValueRef(JSValueRef arg);
343
344     /**
345      * Converts std::vector to JSValueRef
346      * @param arg vecotr of JSValueRefs
347      * @return JSValueRef - js array
348      * @throw ConversionException Thrown when conversion fails.
349      */
350     JSValueRef toJSValueRef(const std::vector<JSValueRef>& arg);
351
352     /**
353      * Template specialization to catch errors caused
354      * by wrong usage of general template or
355      * implicit conversions from SharedPtr to
356      * specialized type
357      * */
358     template<class Class>
359     JSValueRef toJSValueRef(const DPL::SharedPtr<Class>& c)
360     {
361         STATIC_ERROR(ERROR_INVALID_IMPLICIT_CONVERSION, c)
362         //above macro causes compilation error
363         return static_cast<JSValueRef>(NULL);
364     }
365
366     /**
367      * Converts STL string to JSStringRef.
368      * @param arg STL string to convert.
369      * @return JSStringRef object.
370      * @throw ConversionException Thrown when conversion fails.
371      */
372     JSStringRef toJSStringRef(const std::string& arg);
373
374   protected:
375     bool isNan(double value) const;
376
377     double toNumber_(const JSValueRef& arg);
378
379     double toNumber_(const JSStringRef& arg);
380
381     double toNumber_(const std::string& arg);
382
383     template<typename T, class Derived>
384     std::vector<T> toVectorOfT_(const JSValueRef& arg,
385             T (Derived::*f)(const JSValueRef &),
386             Derived* object)
387     {
388         if (JSValueIsNull(m_context,
389                           arg) || JSValueIsUndefined(m_context, arg)) {
390             return std::vector<T>();
391         }
392
393         if (!JSIsArrayValue(m_context, arg)) {
394             ThrowMsg(Commons::ConversionException, "Argument is not an JS array.");
395         }
396
397         std::vector<T> result;
398         JSObjectRef objArg = toJSObjectRef(arg);
399         for (std::size_t i = 0; i < JSGetArrayLength(m_context, objArg); ++i) {
400             JSValueRef element = JSGetArrayElement(m_context, objArg, i);
401             result.push_back((object->*f)(element));
402         }
403         return result;
404     }
405
406     template<typename T>
407     std::vector<T> toVectorOfT_(const JSValueRef& arg,
408             T (Converter::*f)(const JSValueRef &))
409     {
410         if (JSValueIsNull(m_context,
411                           arg) || JSValueIsUndefined(m_context, arg)) {
412             return std::vector<T>();
413         }
414
415         if (!JSIsArrayValue(m_context, arg)) {
416             ThrowMsg(Commons::ConversionException, "Argument is not an JS array.");
417         }
418
419         std::vector<T> result;
420         JSObjectRef objArg = toJSObjectRef(arg);
421         for (std::size_t i = 0; i < JSGetArrayLength(m_context, objArg); ++i) {
422             JSValueRef element = JSGetArrayElement(m_context, objArg, i);
423             result.push_back((this->*f)(element));
424         }
425         return result;
426     }
427
428     template<class T, class Derived>
429     JSValueRef toJSValueRef_(const std::vector<T>& arg,
430             JSValueRef (Derived::*f)(const T &),
431             Derived* object)
432     {
433         JSObjectRef jsResult = JSCreateArrayObject(m_context, 0, NULL);
434
435         if (NULL == jsResult) {
436             ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Could not create js array object");
437         }
438
439         for (std::size_t i = 0; i < arg.size(); ++i) {
440             JSValueRef tmpVal = (object->*f)(arg[i]);
441             if (!JSSetArrayElement(m_context, jsResult, i, tmpVal)) {
442                 ThrowMsg(WrtDeviceApis::Commons::UnknownException,
443                          "Could not insert value into js array");
444             }
445         }
446
447         return jsResult;
448     }
449
450     template<class T>
451     JSValueRef toJSValueRef_(const std::vector<T>& arg)
452     {
453         JSObjectRef jsResult = JSCreateArrayObject(m_context, 0, NULL);
454
455         if (NULL == jsResult) {
456             ThrowMsg(WrtDeviceApis::Commons::NullPointerException,
457                      "Could not create js array object");
458         }
459
460         for (std::size_t i = 0; i < arg.size(); ++i) {
461             JSValueRef tmpVal = toJSValueRef(arg[i]);
462             if (!JSSetArrayElement(m_context, jsResult, i, tmpVal)) {
463                 ThrowMsg(WrtDeviceApis::Commons::UnknownException,
464                          "Could not insert value into js array");
465             }
466         }
467
468         return jsResult;
469     }
470
471     template<class T>
472     JSValueRef toJSValueRef_(const std::list<T>& arg)
473     {
474         JSObjectRef jsResult = JSCreateArrayObject(m_context, 0, NULL);
475
476         if (NULL == jsResult) {
477             ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Could not create js array object");
478         }
479
480         typename std::list<T>::const_iterator it = arg.begin();
481         for (std::size_t i = 0; it != arg.end(); ++i, ++it) {
482             JSValueRef tmpVal = toJSValueRef(*it);
483             if (!JSSetArrayElement(m_context, jsResult, i, tmpVal)) {
484                 ThrowMsg(WrtDeviceApis::Commons::UnknownException,
485                          "Could not insert value into js array");
486             }
487         }
488
489         return jsResult;
490     }
491
492     template<class T, class Derived>
493     JSValueRef toJSValueRef_(const std::list<T>& arg,
494             JSValueRef (Derived::*f)(const T &),
495             Derived* object)
496     {
497         JSObjectRef jsResult = JSCreateArrayObject(m_context, 0, NULL);
498
499         if (NULL == jsResult) {
500             ThrowMsg(WrtDeviceApis::Commons::NullPointerException, "Could not create js array object");
501         }
502
503         typename std::list<T>::const_iterator it = arg.begin();
504         for (std::size_t i = 0; it != arg.end(); ++i, ++it) {
505             JSValueRef tmpVal = (object->*f)(*it);
506             if (!JSSetArrayElement(m_context, jsResult, i, tmpVal)) {
507                 ThrowMsg(WrtDeviceApis::Commons::UnknownException,
508                          "Could not insert value into js array");
509             }
510         }
511
512         return jsResult;
513     }
514
515     std::string toString_(const JSValueRef& arg);
516
517     template<typename T>
518     std::string toString_(const T& arg)
519     {
520         std::stringstream ss;
521         if (!(ss << arg)) {
522             ThrowMsg(WrtDeviceApis::Commons::ConversionException, "Could not convert to string.");
523         }
524         return ss.str();
525     }
526
527   protected:
528     JSContextRef m_context;
529 };
530
531 template<class C>
532 class ConverterFactory : private DPL::Noncopyable
533 {
534   public:
535     /**
536      * Converter type which deletes itself when gets out of scope.
537      */
538     typedef DPL::SharedPtr<C> ConverterType;
539
540   public:
541     /**
542      * Gets converter object.
543      * @param context JavaScript context the conversion will be performed in.
544      * @param[out] exception JavaScript value for storing exception.
545      * @return Converter object.
546      */
547     static ConverterType getConverter(JSContextRef context)
548     {
549         C* convert = new C(context);
550         return ConverterType(convert);
551     }
552
553   private:
554     ConverterFactory();
555 };
556
557 typedef ConverterFactory<Converter> BasicConverterFactory;
558
559 typedef BasicConverterFactory::ConverterType BasicConverter;
560
561 } // CommonsJavaScript
562 } // WrtDeviceApis
563
564 #endif /* WRTDEVICEAPIS_COMMONSJAVASCRIPT_CONVERTER_H_ */