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