1f23103980e6383008db244196f2226791a384dc
[framework/web/wrt-plugins-tizen.git] / src / Common / ArgumentValidationChecker.cpp
1 //
2 // Tizen Web Device API
3 // Copyright (c) 2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 #include "ArgumentValidationChecker.h"
19 #include "JSTizenException.h"
20
21
22 #include <dlog.h>
23 #include <stdarg.h>
24
25 #undef LOG_TAG
26 #define LOG_TAG "TIZEN_DEVICEAPI"
27
28 using namespace std;
29
30 namespace DeviceAPI {
31 namespace Common {
32
33
34 void ArgumentValidationChecker::check(JSContextRef ctx, int argumentCount, const JSValueRef arguments [ ], int convertedArgumentCount, JSValueRef convertedArguments [ ], Option option, ...){
35     va_list var_args;
36     va_start (var_args, option);
37     Option opt = option;
38     int index = 0;
39     while( opt != END){
40         Type type = static_cast<Type>(va_arg(var_args, int));
41         JSObjectRef testObject = NULL;
42         bool nullable = ((opt & NULLABLE) == NULLABLE );
43         JSValueRef jsException = NULL;
44
45         if( index >= convertedArgumentCount ){
46             LOGE("invalid argument check code");
47             va_end (var_args);
48             return;
49         }
50         
51         if( argumentCount <= index ){
52             if( !nullable ) 
53                 convertedArguments[index] = JSValueMakeUndefined(ctx);
54             else
55                 convertedArguments[index] = JSValueMakeNull(ctx);
56             testObject = NULL;
57         }else{
58             convertedArguments[index] = arguments[index];
59             if( JSValueIsObject(ctx, arguments[index]) )
60                 testObject = JSValueToObject(ctx, arguments[index], NULL);
61             else
62                 testObject = NULL;
63         }
64
65         if( JSValueIsNull(ctx, convertedArguments[index]) && nullable){
66             if( type == ArgumentValidationChecker::UserDefine)
67                 va_arg(var_args, JSClassRef);
68             if( type == ArgumentValidationChecker::SelfCheck)
69                 va_arg(var_args, SelfChecker);
70
71             opt = static_cast<Option>(va_arg (var_args, int));
72             index++;
73             continue;
74         }
75
76
77         switch( type ){
78             case ArgumentValidationChecker::Float:
79             case ArgumentValidationChecker::Long:
80             {
81                 double testValue = JSValueToNumber(ctx, convertedArguments[index], &jsException );
82                 if( jsException != NULL )
83                     throw ArgumentValidationException(JSTizenException::TYPE_MISMATCH_ERROR, "Could not converting to number", index);
84                 if( ArgumentValidationChecker::Float == type && testValue != testValue )
85                     throw ArgumentValidationException(JSTizenException::TYPE_MISMATCH_ERROR, "Converted value is nan", index);
86                 break;
87             }
88             case ArgumentValidationChecker::String:
89             {
90                 JSStringRef convertedstr = JSValueToStringCopy(ctx, convertedArguments[index], &jsException);
91                 if( jsException != NULL){
92                     throw ArgumentValidationException(JSTizenException::TYPE_MISMATCH_ERROR, "Could not converting to string", index);
93                 }
94                 JSStringRelease(convertedstr);
95                 break;
96             }
97             case ArgumentValidationChecker::Boolean:
98                 //Boolean can convert from any types.
99                 break;
100             case ArgumentValidationChecker::Function:
101                 if( testObject == NULL || !JSObjectIsFunction(ctx, testObject) )
102                     throw ArgumentValidationException(JSTizenException::TYPE_MISMATCH_ERROR, "argument is not function", index);
103                 break;
104             case ArgumentValidationChecker::Object:
105                 if( testObject == NULL )
106                     throw ArgumentValidationException(JSTizenException::TYPE_MISMATCH_ERROR, "argument is not object", index);
107                 break;
108             case ArgumentValidationChecker::Array:
109                 if( !JSIsArrayValue(ctx, convertedArguments[index])){
110                     JSObjectRef jsArray = JSCreateArrayObject(ctx, 0, NULL);
111                     JSSetArrayElement(ctx, jsArray, 0, convertedArguments[index]);
112                     convertedArguments[index] = jsArray;
113                  }
114                 break;
115             case ArgumentValidationChecker::UserDefine:
116             {
117                 JSClassRef classType = va_arg(var_args, JSClassRef);
118                 if( !JSValueIsObjectOfClass(ctx, convertedArguments[index],classType) )
119                     throw ArgumentValidationException(JSTizenException::TYPE_MISMATCH_ERROR, "argument is not wanted object", index);
120                 break;
121             }
122             case ArgumentValidationChecker::SelfCheck:
123             {
124                 SelfChecker checker = va_arg(var_args, SelfChecker);
125                 if( !checker(convertedArguments[index]) )
126                     throw ArgumentValidationException(JSTizenException::TYPE_MISMATCH_ERROR, "argument is not wanted object", index);
127                 break;
128             }
129         }
130         
131         opt = static_cast<Option>(va_arg (var_args, int));
132         index++;
133     }    
134     va_end (var_args);
135 }
136
137
138 }
139 }