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