summaryrefslogtreecommitdiff
path: root/mobile_src/Common/JSUtil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mobile_src/Common/JSUtil.cpp')
-rwxr-xr-xmobile_src/Common/JSUtil.cpp343
1 files changed, 343 insertions, 0 deletions
diff --git a/mobile_src/Common/JSUtil.cpp b/mobile_src/Common/JSUtil.cpp
new file mode 100755
index 0000000..3d0424c
--- /dev/null
+++ b/mobile_src/Common/JSUtil.cpp
@@ -0,0 +1,343 @@
+//
+// Tizen Web Device API
+// Copyright (c) 2013 Samsung Electronics Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the License);
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include "JSUtil.h"
+#include "PlatformException.h"
+#include <WKBundle.h>
+#include <cmath>
+#include <limits>
+
+
+using namespace std;
+
+namespace DeviceAPI {
+namespace Common{
+
+JSValueRef JSUtil::getProperty(JSContextRef ctx , JSObjectRef object, const char *name, JSValueRef *exception){
+ JSValueRef value;
+ JSStringRef propertyName = JSStringCreateWithUTF8CString(name);
+ JSValueRef localException = NULL;
+ value = JSObjectGetProperty(ctx, object, propertyName, &localException);
+ JSStringRelease(propertyName);
+
+ if( localException != NULL ){
+ if( exception != NULL )
+ *exception = localException;
+ else
+ throw TypeMismatchException(ctx,localException);
+ }
+ return value;
+}
+
+void JSUtil::setProperty(JSContextRef ctx , JSObjectRef object, const char *name, JSValueRef value, JSPropertyAttributes attributes, JSValueRef *exception){
+ JSStringRef propertyName = JSStringCreateWithUTF8CString(name);
+ JSValueRef localException = NULL;
+ JSObjectSetProperty(ctx, object, propertyName, value,attributes, &localException);
+ JSStringRelease(propertyName);
+ if( localException != NULL ){
+ if( exception != NULL )
+ *exception = localException;
+ else
+ throw TypeMismatchException(ctx,localException);
+ }
+}
+
+string JSUtil::JSStringToString(JSContextRef ctx, JSStringRef str){
+ std::string result;
+ size_t jsSize = JSStringGetMaximumUTF8CStringSize(str);
+ {
+ char buffer[jsSize];
+ JSStringGetUTF8CString(str, buffer, jsSize);
+ result = buffer;
+ }
+ return result;
+}
+
+string JSUtil::JSValueToString(JSContextRef ctx, JSValueRef value){
+ std::string result;
+ JSValueRef exception = NULL;
+ JSStringRef str = JSValueToStringCopy(ctx, value, &exception);
+ if (exception != NULL) {
+ throw TypeMismatchException(ctx, exception);
+ }
+ size_t jsSize = JSStringGetMaximumUTF8CStringSize(str);
+ {
+ char buffer[jsSize];
+ JSStringGetUTF8CString(str, buffer, jsSize);
+ result = buffer;
+ }
+ JSStringRelease(str);
+ return result;
+}
+
+long JSUtil::JSValueToLong(JSContextRef ctx, JSValueRef value){
+ return static_cast<long>(JSValueToLongLong(ctx,value));
+}
+
+unsigned long JSUtil::JSValueToULong(JSContextRef ctx, JSValueRef value){
+ double number = JSValueToNumber(ctx, value);
+ if( number < 0 )
+ return static_cast<unsigned long>(static_cast<long>(number));
+ return static_cast<unsigned long>(number);
+}
+
+
+long long JSUtil::JSValueToLongLong(JSContextRef ctx, JSValueRef value){
+ return static_cast<long long>(JSValueToNumber(ctx, value));
+}
+
+unsigned long long JSUtil::JSValueToULongLong(JSContextRef ctx, JSValueRef value){
+ double number = JSValueToNumber(ctx, value);
+ if( number < 0 )
+ return static_cast<unsigned long long>(static_cast<long long>(number));
+ return static_cast<unsigned long long>(number);
+}
+
+
+
+double JSUtil::JSValueToDouble(JSContextRef ctx, JSValueRef value){
+ JSValueRef exception = NULL;
+
+ double doublevalue = ::JSValueToNumber(ctx, value, &exception);
+ if(exception != NULL){
+ throw TypeMismatchException(ctx, exception);
+ }
+ if( doublevalue == std::numeric_limits<double>::infinity() )
+ throw TypeMismatchException("Value is POSITIVE_INFINITY");
+ if( doublevalue == -std::numeric_limits<double>::infinity() )
+ throw TypeMismatchException("Value is NEGATIVE_INFINITY");
+ if( std::isnan(doublevalue)){
+ throw TypeMismatchException("Value is not number");
+ }
+ return doublevalue;
+}
+
+double JSUtil::JSValueToNumber(JSContextRef ctx, JSValueRef value){
+ JSValueRef exception = NULL;
+
+ double doublevalue = ::JSValueToNumber(ctx, value, &exception);
+ if(exception != NULL){
+ throw TypeMismatchException(ctx, exception);
+ }
+ if( doublevalue == std::numeric_limits<double>::infinity() )
+ doublevalue = 0.0;
+
+ if( doublevalue == -std::numeric_limits<double>::infinity() )
+ doublevalue = 0.0;
+
+ return doublevalue;
+}
+
+signed char JSUtil::JSValueToByte(JSContextRef ctx, JSValueRef value){
+ return static_cast<signed char>(JSValueToNumber(ctx,value));
+}
+
+unsigned char JSUtil::JSValueToOctet(JSContextRef ctx, JSValueRef value){
+ return static_cast<unsigned char>(JSValueToNumber(ctx,value));
+}
+
+bool JSUtil::JSValueToBoolean(JSContextRef ctx, JSValueRef value){
+ return ::JSValueToBoolean(ctx, value);
+}
+
+time_t JSUtil::JSValueToTimeT(JSContextRef ctx, JSValueRef value){
+ if(!JSValueIsDateObject(ctx, value))
+ throw TypeMismatchException("Value is not Date Object");
+
+ JSObjectRef timeobj = NULL;
+ timeobj = JSUtil::JSValueToObject(ctx, value);
+ JSValueRef exception = NULL;
+ JSObjectRef getTime = NULL;
+ try{
+ getTime = JSUtil::JSValueToObject(ctx, getProperty(ctx, timeobj, "getTime"));
+ }catch( const TypeMismatchException& err){
+ throw TypeMismatchException("Value is not Date Object");
+ }
+
+ JSValueRef timevalue = JSObjectCallAsFunction(ctx, getTime, timeobj, 0, NULL, &exception);
+ if( exception != NULL )
+ throw TypeMismatchException("Value is not Date Object");
+
+ double millisecond = JSValueToDouble(ctx, timevalue);
+ time_t second = millisecond/1000;
+ return second;
+}
+
+tm JSUtil::JSValueToDateTm(JSContextRef ctx, JSValueRef value){
+ tm result = {0};
+
+ time_t second = JSUtil::JSValueToTimeT(ctx, value);
+
+ if(localtime_r(&second, &result) == NULL)
+ throw TypeMismatchException("Value is not Date Object");
+
+ return result;
+}
+
+tm JSUtil::JSValueToDateTmUTC(JSContextRef ctx, JSValueRef value){
+ tm result = {0};
+
+ time_t second = JSUtil::JSValueToTimeT(ctx, value);
+
+ if(gmtime_r(&second, &result) == NULL)
+ throw TypeMismatchException("Value is not Date Object");
+
+ return result;
+}
+
+JSObjectRef JSUtil::JSValueToObject(JSContextRef ctx, JSValueRef value){
+ JSValueRef exception = NULL;
+ JSObjectRef obj = ::JSValueToObject(ctx, value,&exception);
+ if( exception != NULL){
+ throw TypeMismatchException(ctx, exception);
+ }
+ return obj;
+}
+
+std::map<std::string, std::string> JSUtil::JSValueToStringMap(JSContextRef ctx, JSValueRef value){
+ std::map<std::string, std::string> result;
+ JSObjectRef obj = JSUtil::JSValueToObject(ctx, value);
+ JSPropertyNameArrayRef jsPropNames = JSObjectCopyPropertyNames(ctx, obj);
+ for (std::size_t i = 0; i < JSPropertyNameArrayGetCount(jsPropNames); ++i) {
+ std::string propName = JSUtil::JSStringToString(ctx, JSPropertyNameArrayGetNameAtIndex(jsPropNames, i));
+ std::string propValue = JSUtil::JSValueToString(ctx, JSUtil::getProperty(ctx, obj, propName.c_str(), NULL));
+ result.insert(std::make_pair(propName, propValue));
+ }
+ JSPropertyNameArrayRelease(jsPropNames);
+ return result;
+}
+
+JSObjectRef JSUtil::makeDateObject(JSContextRef ctx, const time_t value){
+ JSValueRef exception = NULL;
+ JSValueRef args[1];
+ double millisecond = value*1000.0;
+ args[0] = toJSValueRef(ctx, millisecond);
+ JSObjectRef result = JSObjectMakeDate(ctx, 1, args, &exception);
+ if( exception != NULL){
+ throw TypeMismatchException("Can't create Date object");
+ }
+ return result;
+}
+
+
+JSValueRef JSUtil::toJSValueRef(JSContextRef ctx, const string& str){
+ JSValueRef result = NULL;
+ JSStringRef jsString = JSStringCreateWithUTF8CString(str.c_str());
+ result = JSValueMakeString(ctx, jsString);
+ JSStringRelease(jsString);
+ return result;
+}
+
+JSValueRef JSUtil::toJSValueRef(JSContextRef ctx, const unsigned long value){
+ return JSValueMakeNumber(ctx, value);
+}
+
+JSValueRef JSUtil::toJSValueRef(JSContextRef ctx, const long value){
+ return JSValueMakeNumber(ctx, value);
+}
+
+JSValueRef JSUtil::toJSValueRef(JSContextRef ctx, const unsigned long long value) {
+ return JSValueMakeNumber(ctx, value);
+}
+
+JSValueRef JSUtil::toJSValueRef(JSContextRef ctx, const long long value) {
+ return JSValueMakeNumber(ctx, value);
+}
+
+JSValueRef JSUtil::toJSValueRef(JSContextRef ctx, const double value){
+ return JSValueMakeNumber(ctx, value);
+}
+
+JSValueRef JSUtil::toJSValueRef(JSContextRef ctx, const signed char value){
+ return JSValueMakeNumber(ctx, value);
+}
+
+JSValueRef JSUtil::toJSValueRef(JSContextRef ctx, const unsigned char value){
+ return JSValueMakeNumber(ctx, value);
+}
+
+
+JSValueRef JSUtil::toJSValueRef(JSContextRef ctx, const bool value){
+ return JSValueMakeBoolean(ctx, value);
+}
+
+JSValueRef JSUtil::toJSValueRef(JSContextRef ctx, const std::vector<std::string>& value){
+ return toJSValueRef_(ctx, value);
+}
+
+JSValueRef JSUtil::toJSValueRef(JSContextRef ctx, const std::vector<long>& value){
+ return toJSValueRef_(ctx, value);
+}
+
+JSValueRef JSUtil::toJSValueRef(JSContextRef ctx, const std::vector<double>& value){
+ return toJSValueRef_(ctx, value);
+}
+
+JSValueRef JSUtil::toJSValueRef(JSContextRef ctx, const std::vector<bool>& value){
+ return toJSValueRef_(ctx, value);
+}
+
+JSValueRef JSUtil::toJSValueRef(JSContextRef ctx, const std::map<std::string, std::string>& value){
+ JSObjectRef obj = JSObjectMake(ctx, NULL, NULL);
+
+ std::map<std::string, std::string>::const_iterator iter;
+ for (iter = value.begin(); iter != value.end(); ++iter) {
+ std::string propName = iter->first;
+ JSUtil::setProperty(ctx, obj, propName.c_str(), JSUtil::toJSValueRef(ctx, iter->second), kJSPropertyAttributeNone);
+ }
+
+ return obj;
+}
+
+vector<string> JSUtil::JSArrayToStringVector(JSContextRef ctx, JSValueRef value){
+ return JSArrayToType_<string>(ctx, value, JSUtil::JSValueToString);
+}
+vector<double> JSUtil::JSArrayToDoubleVector(JSContextRef ctx, JSValueRef value){
+ return JSArrayToType_<double>(ctx, value, JSUtil::JSValueToDouble);
+}
+vector<long> JSUtil::JSArrayToLongVector(JSContextRef ctx, JSValueRef value){
+ return JSArrayToType_<long>(ctx, value, JSUtil::JSValueToLong);
+}
+vector<time_t> JSUtil::JSArrayToTimeTVector(JSContextRef ctx, JSValueRef value){
+ return JSArrayToType_<time_t>(ctx, value, JSUtil::JSValueToTimeT);
+}
+vector<bool> JSUtil::JSArrayToBoolVector(JSContextRef ctx, JSValueRef value){
+ return JSArrayToType_<bool>(ctx, value, JSUtil::JSValueToBoolean);
+}
+
+bool JSUtil::JSValueIsDateObject(JSContextRef ctx, JSValueRef jsValue) {
+ JSValueRef exception = NULL;
+
+ JSObjectRef globalObj = JSContextGetGlobalObject(ctx);
+
+ JSValueRef jsDate = getProperty(ctx, globalObj, "Date", &exception);
+ if(exception)
+ return false;
+
+ JSObjectRef jsDateObj = ::JSValueToObject(ctx, jsDate, &exception);
+ if(exception)
+ return false;
+
+ bool result = JSValueIsInstanceOfConstructor(ctx, jsValue, jsDateObj, &exception);
+ if(exception)
+ return false;
+
+ return result;
+}
+
+}
+}