diff options
Diffstat (limited to 'wearable_src/Common')
45 files changed, 6200 insertions, 0 deletions
diff --git a/wearable_src/Common/ArgumentValidator.cpp b/wearable_src/Common/ArgumentValidator.cpp new file mode 100755 index 0000000..62c5e20 --- /dev/null +++ b/wearable_src/Common/ArgumentValidator.cpp @@ -0,0 +1,317 @@ +// +// 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 "ArgumentValidator.h" +#include "PlatformException.h" +#include "JSUtil.h" +#include <CommonsJavaScript/Converter.h> + +#include <limits> +#include <dlog.h> +#include <math.h> +#include <stdarg.h> + +using namespace std; +using namespace WrtDeviceApis::CommonsJavaScript; +using namespace WrtDeviceApis::Commons; + + +namespace DeviceAPI { +namespace Common{ + +ArgumentValidator::ArgumentValidator(JSContextRef ctx, int argc, const JSValueRef* argv):mContext(ctx),mArgc(argc), mArgv(argv){ +} + +ArgumentValidator::~ArgumentValidator(){ +} + +JSValueRef ArgumentValidator::getArgument(int index, bool nullable) const{ + if( index < mArgc ){ + return mArgv[index]; + } + + JSValueRef value = NULL; + if( nullable ) + value = JSValueMakeNull(mContext); + else + value = JSValueMakeUndefined(mContext); + return value; +} + +bool ArgumentValidator::isOmitted(int index){ + if( index < mArgc) + return false; + return true; +} +bool ArgumentValidator::isNull(int index){ + if( !isOmitted(index) && JSValueIsNull(mContext, mArgv[index]) ){ + return true; + } + return false; +} +bool ArgumentValidator::isUndefined(int index){ + if( !isOmitted(index) && JSValueIsUndefined(mContext, mArgv[index]) ){ + return true; + } + return false; +} + +double ArgumentValidator::toNumber(int index, bool nullable, double defaultvalue) const{ + JSValueRef value = getArgument(index, nullable); + if( JSValueIsNull(mContext, value) && nullable){ + return defaultvalue; + } + return JSUtil::JSValueToNumber(mContext, value); +} + +short ArgumentValidator::toShort(int index, bool nullable, short defaultvalue) const{ + return static_cast<short>(toLong(index,nullable,defaultvalue)); +} + +long ArgumentValidator::toLong(int index, bool nullable, long defaultvalue) const{ + return static_cast<long>(toLongLong(index,nullable,defaultvalue)); +} + +signed char ArgumentValidator::toByte(int index, bool nullable, signed char defaultvalue) const{ + return static_cast<signed char>(toLong(index,nullable,defaultvalue)); +} + +unsigned char ArgumentValidator::toOctet(int index, bool nullable, unsigned char defaultvalue) const{ + return static_cast<unsigned char>(toULong(index,nullable,defaultvalue)); +} + +unsigned short ArgumentValidator::toUShort(int index, bool nullable, unsigned short defaultvalue) const{ + return static_cast<unsigned short>(toULong(index,nullable,defaultvalue)); +} + +unsigned long ArgumentValidator::toULong(int index, bool nullable, unsigned long defaultvalue) const{ + return static_cast<unsigned long>(toLongLong(index,nullable,defaultvalue)); +} + +long long ArgumentValidator::toLongLong(int index, bool nullable, long long defaultvalue) const{ + return static_cast<long long>(toNumber(index,nullable,defaultvalue)); +} + +unsigned long long ArgumentValidator::toULongLong(int index, bool nullable, unsigned long long defaultvalue) const{ + return static_cast<unsigned long long>(toLongLong(index,nullable,defaultvalue)); +} + +double ArgumentValidator::toDouble(int index, bool nullable, double defaultvalue) const{ + JSValueRef value = getArgument(index, nullable); + if( JSValueIsNull(mContext, value) && nullable){ + return defaultvalue; + } + return JSUtil::JSValueToDouble(mContext, value); +} + +std::string ArgumentValidator::toString(int index, bool nullable, const string & defaultvalue) const{ + JSValueRef value = getArgument(index, nullable); + if( JSValueIsNull(mContext, value) && nullable){ + return defaultvalue; + } + + std::string result; + + JSValueRef exception = NULL; + JSStringRef str = JSValueToStringCopy(mContext, value, &exception); + if (exception != NULL) { + throw TypeMismatchException(mContext, exception); + } + size_t jsSize = JSStringGetMaximumUTF8CStringSize(str); + { + char buffer[jsSize]; + JSStringGetUTF8CString(str, buffer, jsSize); + result = buffer; + } + JSStringRelease(str); + return result; +} + +bool ArgumentValidator::toBool(int index, bool nullable, bool defaultvalue) const{ + JSValueRef value = getArgument(index, nullable); + if( JSValueIsNull(mContext, value) && nullable){ + return defaultvalue; + } + bool boolvalue = JSValueToBoolean(mContext, value); + return boolvalue; +} + +time_t ArgumentValidator::toTimeT(int index, bool nullable, time_t defaultvalue) const{ + JSValueRef value = getArgument(index, nullable); + if( JSValueIsNull(mContext, value) && nullable){ + return defaultvalue; + } + return JSUtil::JSValueToTimeT(mContext, value); +} + +JSObjectRef ArgumentValidator::toObject(int index, bool nullable) const{ + JSValueRef value = getArgument(index, nullable); + if( JSValueIsNull(mContext, value) && nullable){ + return NULL; + } + if( !JSValueIsObject(mContext, value) ){ + throw TypeMismatchException("Value is not Object"); + } + + JSValueRef exception = NULL; + JSObjectRef object = JSValueToObject(mContext, value, &exception); + if( exception ){ + throw TypeMismatchException(mContext, exception); + } + return object; +} + +JSObjectRef ArgumentValidator::toObject(int index, JSClassRef info, bool nullable) const{ + JSObjectRef obj = toObject(index, nullable); + if( obj == NULL ) + return NULL; + if( !JSValueIsObjectOfClass( mContext, obj, info) ){ + throw TypeMismatchException("Value is not correct type"); + } + return obj; +} + +JSValueRef ArgumentValidator::toJSValueRef(int index, bool nullable) const{ + return getArgument(index, nullable); +} + +JSObjectRef ArgumentValidator::toFunction(int index, bool nullable) const{ + JSObjectRef obj = toObject(index, nullable); + if( obj == NULL && nullable){ + return NULL; + } + if( !JSObjectIsFunction( mContext, obj )){ + throw TypeMismatchException("Value is not function"); + } + return obj; +} + +JSObjectRef ArgumentValidator::toArrayObject(int index, bool nullable) const{ + JSValueRef value = getArgument(index, nullable); + if( JSValueIsNull(mContext, value) && nullable){ + return NULL; + } + + if( !JSIsArrayValue(mContext, value)){ + throw TypeMismatchException("Type is not Array"); + } + + JSValueRef exception = NULL; + JSObjectRef obj = JSValueToObject(mContext, value, &exception); + if( exception != NULL ) + throw TypeMismatchException(mContext, exception); + return obj; +} + + +std::vector<std::string> ArgumentValidator::toStringVector(int index, bool nullable) const{ + JSObjectRef value = toArrayObject(index, nullable); + if( value == NULL || JSValueIsNull(mContext, value) ){ + return std::vector<std::string>(); + } + return JSUtil::JSArrayToStringVector(mContext, value); +} + +std::vector<long> ArgumentValidator::toLongVector(int index, bool nullable) const{ + JSObjectRef value = toArrayObject(index, nullable); + if( value == NULL || JSValueIsNull(mContext, value) ){ + return std::vector<long>(); + } + return JSUtil::JSArrayToLongVector(mContext, value); +} + + +std::vector<double> ArgumentValidator::toDoubleVector(int index, bool nullable) const{ + JSObjectRef value = toArrayObject(index, nullable); + if( value == NULL || JSValueIsNull(mContext, value) ){ + return std::vector<double>(); + } + return JSUtil::JSArrayToDoubleVector(mContext, value); +} + +std::vector<time_t> ArgumentValidator::toTimeTVector(int index, bool nullable) const{ + JSObjectRef value = toArrayObject(index, nullable); + if( value == NULL || JSValueIsNull(mContext, value) ){ + return std::vector<time_t>(); + } + return JSUtil::JSArrayToTimeTVector(mContext, value); +} + +std::vector<bool> ArgumentValidator::toBoolVector(int index, bool nullable) const{ + JSObjectRef value = toArrayObject(index, nullable); + if( value == NULL || JSValueIsNull(mContext, value) ){ + return std::vector<bool>(); + } + return JSUtil::JSArrayToBoolVector(mContext, value); +} + +std::vector<JSValueRef> ArgumentValidator::toJSValueRefVector(int index, bool nullable) const{ + JSObjectRef value = toArrayObject(index, nullable); + if( value == NULL || JSValueIsNull(mContext, value) ){ + return std::vector<JSValueRef>(); + } + + std::vector<JSValueRef> result; + for (std::size_t i = 0; i < JSGetArrayLength(mContext, value); ++i) { + JSValueRef element = JSGetArrayElement(mContext, value, i); + result.push_back(element); + } + return result; +} + +std::map<std::string, std::string> ArgumentValidator::toStringMap(int index, bool nullable) const{ + JSObjectRef value = toObject(index, nullable); + if( value == NULL || JSValueIsNull(mContext, value) ){ + return std::map<std::string, std::string>(); + } + + return JSUtil::JSValueToStringMap(mContext, value); +} + +JSObjectRef ArgumentValidator::toCallbackObject(int index, bool nullable, const char *callback, ...) const{ + JSObjectRef obj = toObject(index, nullable); + if( obj == NULL ){ + if( nullable ){ + return NULL; + } + throw TypeMismatchException("Value is not Object"); + } + va_list var_args; + va_start (var_args, callback); + const char * check = callback; + while( check != NULL ){ + JSStringRef propertyName = JSStringCreateWithUTF8CString(check); + bool has = JSObjectHasProperty(mContext, obj, propertyName); + JSStringRelease(propertyName); + if( has ){ + JSObjectRef o = JSUtil::JSValueToObject(mContext, JSUtil::getProperty(mContext, obj, check)); + if( !JSObjectIsFunction(mContext, o) ){ + va_end(var_args); + throw TypeMismatchException("Property is not function object"); + } + } + check = static_cast<const char *>(va_arg(var_args, const char *)); + } + va_end(var_args); + return obj; +} + + + +} +} diff --git a/wearable_src/Common/ArgumentValidator.h b/wearable_src/Common/ArgumentValidator.h new file mode 100755 index 0000000..33ed114 --- /dev/null +++ b/wearable_src/Common/ArgumentValidator.h @@ -0,0 +1,82 @@ +// +// 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. +// + +#ifndef _ARGUMENT_VALIDATOR_H_ +#define _ARGUMENT_VALIDATOR_H_ + +#include <string> +#include <vector> +#include <map> +#include <JavaScriptCore/JavaScript.h> +#include <ctime> + +namespace DeviceAPI { +namespace Common{ + +class ArgumentValidator{ +public: + ArgumentValidator(JSContextRef ctx, int argc, const JSValueRef* argv); + ~ArgumentValidator(); + + double toNumber(int index, bool nullable = false, double defaultvalue = 0.0) const; + short toShort(int index, bool nullable = false, short defaultvalue = 0) const; + unsigned short toUShort(int index, bool nullable = false, unsigned short defaultvalue = 0) const; + long toLong(int index, bool nullable = false, long defaultvalue = 0) const; + unsigned long toULong(int index, bool nullable = false, unsigned long defaultvalue = 0) const; + long long toLongLong(int index, bool nullable = false, long long defaultvalue = 0) const; + unsigned long long toULongLong(int index, bool nullable = false, unsigned long long defaultvalue = 0) const; + double toDouble(int index, bool nullable = false, double defaultvalue = 0.0) const; + signed char toByte(int index, bool nullable = false, signed char defaultvalue = 0) const; + unsigned char toOctet(int index, bool nullable = false, unsigned char defaultvalue = 0) const; + std::string toString(int index, bool nullable = false, const std::string& defaultvalue = "") const; + bool toBool(int index, bool nullable = false, bool defaultvalue = false) const; + time_t toTimeT(int index, bool nullable = false, time_t defaultvalue = 0) const; + JSObjectRef toObject(int index, bool nullable = false) const; + JSObjectRef toObject(int index, JSClassRef info, bool nullable = false) const; + JSObjectRef toFunction(int index, bool nullable = false) const; + JSObjectRef toArrayObject(int index, bool nullable = false) const; + JSValueRef toJSValueRef(int index, bool nullable = false) const; + + bool isOmitted(int index); + bool isNull(int index); + bool isUndefined(int index); + + JSObjectRef toCallbackObject(int index, bool nullable, const char *callback, ...) const; + + std::vector<std::string> toStringVector(int index, bool nullable = false) const; + std::vector<long> toLongVector(int index, bool nullable = false) const; + std::vector<double> toDoubleVector(int index, bool nullable = false) const; + std::vector<time_t> toTimeTVector(int index, bool nullable = false) const; + std::vector<bool> toBoolVector(int index, bool nullable = false) const; + std::vector<JSValueRef> toJSValueRefVector(int index, bool nullable= false) const; + + std::map<std::string, std::string> toStringMap(int index, bool nullable = false) const; + +private: + JSValueRef getArgument(int index, bool nullable) const; + JSContextRef mContext; + int mArgc; + const JSValueRef* mArgv; + +}; + +} +} + +#endif //_ARGUMENT_VALIDATOR_H_ + + diff --git a/wearable_src/Common/AsyncCallbackManager.h b/wearable_src/Common/AsyncCallbackManager.h new file mode 100644 index 0000000..e2427f5 --- /dev/null +++ b/wearable_src/Common/AsyncCallbackManager.h @@ -0,0 +1,98 @@ +// +// Tizen Web Device API +// Copyright (c) 2012 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. +// + +/** + * @file AsyncCallbackManager.h + * @author Kisub Song (kisubs.song@samsung.com) + * @version 0.1 + * @brief + */ + +#ifndef _TIZEN_COMMONS_ASYNC_CALLBACK_MANAGER_H_ +#define _TIZEN_COMMONS_ASYNC_CALLBACK_MANAGER_H_ + +#include <dpl/shared_ptr.h> +#include <dpl/type_list.h> +#include <CommonsJavaScript/JSCallbackManager.h> +#include "Singleton.h" +#include "Export.h" +#include "Logger.h" + +namespace DeviceAPI { +namespace Common { + +class AsyncCallbackManager +{ +public: + typedef std::map<WrtDeviceApis::CommonsJavaScript::JSCallbackManagerPtr, JSContextRef> JSCallbackManagerMap; + typedef typename JSCallbackManagerMap::iterator JSCallbackManagerMapIter; + typedef std::pair<WrtDeviceApis::CommonsJavaScript::JSCallbackManagerPtr,JSContextRef> JSCallbackManagerPair; + + AsyncCallbackManager() + { + }; + + virtual ~AsyncCallbackManager() + { + m_map.clear(); + }; + + virtual void registerCallbackManager(WrtDeviceApis::CommonsJavaScript::JSCallbackManagerPtr &cbm, const JSContextRef context) + { + LoggerD("Registering an callback manager on context:" << context); + m_map.insert(JSCallbackManagerPair(cbm, context)); + } + + virtual void unregisterContext(const JSContextRef context) + { + LoggerD("Unregistering all callback managers on context:" << context); + for(JSCallbackManagerMapIter i=m_map.begin(); i!=m_map.end(); i++) + { + if(i->second == context) + { + LoggerD("unregister a callback manager"); + i->first->setOnSuccess(NULL); + i->first->setOnError(NULL); + // This function does not remove cbm from multimap. + // It only prohibit plugin invoke javascript callback. + } + } + } + + virtual void unregisterCallbackManager(const WrtDeviceApis::CommonsJavaScript::JSCallbackManagerPtr &cbm) + { + LoggerD("Unregistering an callback manager"); + JSCallbackManagerMapIter i = m_map.find(cbm); + + if(i == m_map.end()) + { + LoggerW("nothing to unregister"); + // Something wrong + return; + } + + m_map.erase(i); + } + +private: + JSCallbackManagerMap m_map; +}; + +} // Common +} // DeviceAPI + +#endif // _TIZEN_COMMONS_ASYNC_CALLBACK_MANAGER_H_ diff --git a/wearable_src/Common/CMakeLists.txt b/wearable_src/Common/CMakeLists.txt new file mode 100755 index 0000000..e0d7704 --- /dev/null +++ b/wearable_src/Common/CMakeLists.txt @@ -0,0 +1,29 @@ +SET(SRCS + CallbackUserData.cpp + GlobalContextManager.cpp + ArgumentValidator.cpp + JSUtil.cpp + PlatformException.cpp + MultiCallbackUserData.cpp + JSFunctionWrapper.cpp + JSObjectRefWrapper.cpp + JSStringRefWrapper.cpp + JSWebAPIErrorFactory.cpp + JSWebAPIError.cpp + JSWebAPIException.cpp + WebAPIError.cpp + PropertyBag.cpp + JSArray.cpp +) + +ADD_LIBRARY(${COMMON_TARGET_NAME} SHARED ${SRCS}) + +TARGET_LINK_LIBRARIES(${COMMON_TARGET_NAME} + ${LIBS_COMMON} +) + +INSTALL(TARGETS ${COMMON_TARGET_NAME} LIBRARY DESTINATION ${DESTINATION_LIB_PREFIX}/${COMMON_DESTINATION_NAME}) +INSTALL( + DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ DESTINATION ${DESTINATION_HEADER_PREFIX}/common + FILES_MATCHING PATTERN "*.h" PATTERN "CMakeFiles" EXCLUDE +) diff --git a/wearable_src/Common/CallbackUserData.cpp b/wearable_src/Common/CallbackUserData.cpp new file mode 100755 index 0000000..7fc818f --- /dev/null +++ b/wearable_src/Common/CallbackUserData.cpp @@ -0,0 +1,96 @@ +// +// 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 "CallbackUserData.h" +#include "MultiCallbackUserData.h" +#include <stdarg.h> + +using namespace std; + +namespace DeviceAPI { +namespace Common { + +CallbackUserData::CallbackUserData(JSContextRef globalCtx): mContext(globalCtx), mImpl(NULL){ + mImpl = new MultiCallbackUserData(globalCtx); +} + +CallbackUserData::~CallbackUserData(){ + MultiCallbackUserData * impl = static_cast<MultiCallbackUserData*>(mImpl); + if( impl ) + delete impl; + mImpl = NULL; +} + +void CallbackUserData::setSuccessCallback(JSValueRef onSuccess){ + MultiCallbackUserData * impl = static_cast<MultiCallbackUserData*>(mImpl); + + if( onSuccess && JSValueIsObject(mContext, onSuccess) ){ + JSObjectRef success = JSValueToObject(mContext, onSuccess, NULL); + impl->setCallback("success", success); + } +} + +void CallbackUserData::setErrorCallback(JSValueRef onError){ + MultiCallbackUserData * impl = static_cast<MultiCallbackUserData*>(mImpl); + + if( onError && JSValueIsObject(mContext, onError) ){ + JSObjectRef error = JSValueToObject(mContext, onError, NULL); + impl->setCallback("error", error); + } +} + +void CallbackUserData::callSuccessCallback(int count, JSValueRef obj [ ]){ + MultiCallbackUserData * impl = static_cast<MultiCallbackUserData*>(mImpl); + impl->invokeCallback("success", count, obj); +} + +void CallbackUserData::callSuccessCallback(JSValueRef obj){ + JSValueRef args[1] = {obj}; + callSuccessCallback(1, args); +} + +void CallbackUserData::callSuccessCallback(){ + callSuccessCallback(0, NULL); +} + +void CallbackUserData::callErrorCallback(int count, JSValueRef obj [ ]){ + MultiCallbackUserData * impl = static_cast<MultiCallbackUserData*>(mImpl); + impl->invokeCallback("error", count, obj); +} + +void CallbackUserData::callErrorCallback(JSValueRef obj){ + JSValueRef args[1] = {obj}; + callErrorCallback(1, args); +} + +void CallbackUserData::callErrorCallback(){ + callErrorCallback(0, NULL); +} + +void CallbackUserData::cleanContext(){ + MultiCallbackUserData * impl = static_cast<MultiCallbackUserData*>(mImpl); + mContext = NULL; + impl->cleanContext(); +} + + +JSContextRef CallbackUserData::getContext(){ + return mContext; +} + +} +} diff --git a/wearable_src/Common/CallbackUserData.h b/wearable_src/Common/CallbackUserData.h new file mode 100755 index 0000000..8d73e47 --- /dev/null +++ b/wearable_src/Common/CallbackUserData.h @@ -0,0 +1,55 @@ +// +// 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. +// + +#ifndef _WRTPLUGINS_TIZEN_CALLBACKUSERDATA_ +#define _WRTPLUGINS_TIZEN_CALLBACKUSERDATA_ + +#include <JavaScriptCore/JavaScript.h> + +namespace DeviceAPI { +namespace Common{ + +class CallbackUserData{ + public: + CallbackUserData(JSContextRef globalCtx); + virtual ~CallbackUserData(); + JSContextRef getContext(); + void setSuccessCallback(JSValueRef onSuccess); + void setErrorCallback(JSValueRef onError); + + void callSuccessCallback(); + void callSuccessCallback(JSValueRef obj); + void callSuccessCallback(int count, JSValueRef obj[]); + + void callErrorCallback(); + void callErrorCallback(JSValueRef obj); + void callErrorCallback(int count, JSValueRef obj[]); + + void cleanContext(); + + private: + JSContextRef mContext; + void *mImpl; + +}; + + +} +} + +#endif //_TIZEN_COMMON_CALLBACKUSERDATA_ + diff --git a/wearable_src/Common/Export.h b/wearable_src/Common/Export.h new file mode 100644 index 0000000..44afafc --- /dev/null +++ b/wearable_src/Common/Export.h @@ -0,0 +1,29 @@ +// +// 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. +// + +#ifndef __TIZEN_EXPORT_H__ +#define __TIZEN_EXPORT_H__ + +#if defined(__GNUC__) && __GNUC__ >= 4 + #define DLL_EXPORT __attribute__((visibility("default"))) + #define DLL_LOCAL __attribute__((visibility("hidden"))) +#else + #define DLL_EXPORT + #define DLL_LOCAL +#endif + +#endif // __TIZEN_EXPORT_H__ diff --git a/wearable_src/Common/GlobalContextManager.cpp b/wearable_src/Common/GlobalContextManager.cpp new file mode 100644 index 0000000..e949d14 --- /dev/null +++ b/wearable_src/Common/GlobalContextManager.cpp @@ -0,0 +1,88 @@ +// +// 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 "GlobalContextManager.h" +#include "Logger.h" + +using namespace std; + +namespace DeviceAPI { +namespace Common{ + +GlobalContextManager::GlobalContextManager(){ +} + +GlobalContextManager* GlobalContextManager::getInstance(){ + static GlobalContextManager instance; + return &instance; +} + +JSContextRef GlobalContextManager::getGlobalContext(JSContextRef ctx){ + if( ctx == NULL ){ + LoggerE("local context is NULL"); + return NULL; + } + JSObjectRef global = JSContextGetGlobalObject(ctx); + ContextMapT::iterator itr; + itr = mContexts.find(global); + if( itr == mContexts.end() ){ + LoggerE("Can not found global Context"); + return NULL; + } + return itr->second; +} + +bool GlobalContextManager::isAliveGlobalContext(JSContextRef ctx){ + if( ctx == NULL ) + return false; + + JSContextRef context = getGlobalContext(ctx); + + if( context == ctx ) + return true; + else + return false; +} + +void GlobalContextManager::addGlobalContext(JSContextRef ctx){ + ContextMapT::iterator itr; + JSObjectRef global = JSContextGetGlobalObject(ctx); + itr = mContexts.find(global); + if( itr != mContexts.end() ){ + LoggerD("already added global context"); + return; + } + mContexts[global] = ctx; +} + +void GlobalContextManager::removeGlobalContext(JSContextRef ctx){ + ContextMapT::iterator itr; + JSObjectRef global = JSContextGetGlobalObject(ctx); + itr = mContexts.find(global); + if( itr == mContexts.end() ){ + LoggerD("does not exist context"); + return; + } + if( itr->second == ctx ) + mContexts.erase(itr); + else + LoggerE("passed context is not global context"); +} + +} +} + diff --git a/wearable_src/Common/GlobalContextManager.h b/wearable_src/Common/GlobalContextManager.h new file mode 100644 index 0000000..40f8f8e --- /dev/null +++ b/wearable_src/Common/GlobalContextManager.h @@ -0,0 +1,78 @@ +// +// 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. +// + +#ifndef _TIZEN_COMMON_GLOBALCONTEXTMANAGER_ +#define _TIZEN_COMMON_GLOBALCONTEXTMANAGER_ + +#include <JavaScriptCore/JavaScript.h> +#include <map> + +namespace DeviceAPI { +namespace Common{ + + +/** + * @brief Manage and tracking global context handle + */ +class GlobalContextManager{ + public : + /** + * @breif Gets global context from local context + * + * @param ctx local context + * @return The global context reference or NULL if function has failed + */ + JSContextRef getGlobalContext(JSContextRef ctx); + + /** + * @breif Add global context in manager + * + * @param ctx The global context to add + */ + void addGlobalContext(JSContextRef ctx); + + /** + * @breif Remove global context in manager + * + * @param ctx The global context to remove + */ + void removeGlobalContext(JSContextRef ctx); + + /** + * @breif Check the validation of global context + * + * @param ctx The global context to check + * @return true : the global context is alive, false : the global context was released + */ + bool isAliveGlobalContext(JSContextRef ctx); + + /** + * @breif Gets singletone handle + * + * @return GlobalContextManager handle + */ + static GlobalContextManager* getInstance(); + + private: + GlobalContextManager(); + typedef std::map<JSObjectRef, JSContextRef> ContextMapT; + std::map<JSObjectRef, JSContextRef> mContexts; +}; + +} +} +#endif //_TIZEN_COMMON_GLOBALCONTEXTMANAGER_ diff --git a/wearable_src/Common/IListenerManager.h b/wearable_src/Common/IListenerManager.h new file mode 100644 index 0000000..bf8aad6 --- /dev/null +++ b/wearable_src/Common/IListenerManager.h @@ -0,0 +1,157 @@ +// +// Tizen Web Device API +// Copyright (c) 2012 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. +// + +/** + * @file IListenerManager.h + * @author Kisub Song (kisubs.song@samsung.com) + * @version 0.1 + * @brief + */ + +#ifndef _TIZEN_COMMONS_ILISTENER_MANAGER_H_ +#define _TIZEN_COMMONS_ILISTENER_MANAGER_H_ + +#include <map> +#include <JavaScriptCore/JavaScript.h> +#include <dpl/shared_ptr.h> +#include "Singleton.h" +#include "Export.h" +#include "Logger.h" + +namespace DeviceAPI { +namespace Common { + +class IListenerItem; +typedef DPL::SharedPtr<IListenerItem> IListenerItemPtr; + +class IListenerItem +{ +public: + IListenerItem(JSContextRef context, JSObjectRef object, long watchId) : + m_context(context), + m_object(object), + m_watchId(watchId) + { + } + + virtual ~IListenerItem() + { + } + + virtual void protectObject() + { + LoggerD("Protect object:" << m_object); + + JSValueProtect(m_context, m_object); + } + + virtual void unprotectObject() + { + LoggerD("Unprotect object:" << m_object); + + JSValueUnprotect(m_context, m_object); + } + + virtual void cancelListener() + { + LoggerW("IListenerItem MUST be used as an inherited shape."); + LoggerW("If this log has been printed, it must be used with wrong usage."); + } + + virtual bool equal(const DeviceAPI::Common::IListenerItemPtr &other) const + { + if(!other) + return false; + + if(m_object == other->m_object && m_watchId == other->m_watchId) + return true; + + return false; + } + +protected: + JSContextRef m_context; + JSObjectRef m_object; + long m_watchId; +}; + +class IListenerController +{ +public: + typedef std::multimap<JSContextRef, IListenerItemPtr> ListenerMap; + typedef typename ListenerMap::iterator ListenerMapIter; + typedef std::pair<JSContextRef, IListenerItemPtr> ListenerPair; + typedef std::pair<ListenerMapIter, ListenerMapIter> ListenerMapIterPair; + + IListenerController() + { + } + + virtual ~IListenerController() + { + } + + virtual void registerListener(IListenerItemPtr &canceller, const JSContextRef context) + { + LoggerD("Registering a listener on context:" << context); + + canceller->protectObject(); + m_map.insert(ListenerPair(context, canceller)); + } + + virtual void unregisterContext(const JSContextRef context) + { + LoggerD("Unregistering all listeners on context:" << context); + + ListenerMapIterPair iterPair = m_map.equal_range(context); + + for(ListenerMapIter i=iterPair.first; i!=iterPair.second; i++) + { + LoggerD("Unregistering a listener"); + i->second->cancelListener(); + i->second->unprotectObject(); + } + + m_map.erase(context); + } + + virtual void unregisterListener(const IListenerItemPtr &canceller) + { + LoggerD("Unregistering a listener"); + + for(ListenerMapIter i=m_map.begin(); i!=m_map.end(); i++) + { + if(i->second->equal(canceller)) + { + LoggerD("Found object"); + i->second->unprotectObject(); + + m_map.erase(i); + + break; + } + } + } + +private: + ListenerMap m_map; +}; + +} // Common +} // DeviceAPI + +#endif // _TIZEN_COMMONS_ILISTENER_MANAGER_H_ diff --git a/wearable_src/Common/JSArray.cpp b/wearable_src/Common/JSArray.cpp new file mode 100755 index 0000000..cd386da --- /dev/null +++ b/wearable_src/Common/JSArray.cpp @@ -0,0 +1,48 @@ +#include "JSArray.h" +#include "PlatformException.h" + +namespace DeviceAPI { +namespace Common { + +JSArrayBase::JSArrayBase( JSContextRef context, JSObjectRef array ):mContext(context), mArray(array){ + if(!JSIsArrayValue(context, array)){ + throw TypeMismatchException("The type is not array"); + } + JSValueProtect(context, array); +} + +JSArrayBase::JSArrayBase( JSContextRef context):mContext(context){ + JSValueRef exception = NULL; + mArray = JSObjectMakeArray( context, 0, NULL, &exception); + if(exception != NULL){ + throw UnknownException(context, exception); + } +} + +JSArrayBase::~JSArrayBase(){ + JSValueUnprotect(mContext, mArray); +} + +size_t JSArrayBase::size() const { + return JSGetArrayLength(mContext, mArray); +} + +void JSArrayBase::resize(size_t size){ + JSUtil::setProperty(mContext, mArray, "length", JSUtil::toJSValueRef(mContext, static_cast<double>(size)), kJSPropertyAttributeNone, NULL); +} + +JSValueRef JSArrayBase::get(int index) const{ + return JSGetArrayElement(mContext, mArray, index); +} + +bool JSArrayBase::set( int index, JSValueRef value){ + bool t = JSSetArrayElement(mContext, mArray, index, value); + return t; +} + +bool JSArrayBase::append( JSValueRef value ){ + return set( size(), value); +} + +}//Common +}//DeviceAPI diff --git a/wearable_src/Common/JSArray.h b/wearable_src/Common/JSArray.h new file mode 100755 index 0000000..c27ca21 --- /dev/null +++ b/wearable_src/Common/JSArray.h @@ -0,0 +1,171 @@ +// +// 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. +// + +#ifndef __TIZEN_COMMON_JSARRAY_H__ +#define __TIZEN_COMMON_JSARRAY_H__ +#include <JavaScriptCore/JavaScript.h> +#include <vector> +#include "JSUtil.h" + +namespace DeviceAPI { +namespace Common { + +class JSArrayBase{ +public: + JSArrayBase( JSContextRef context, JSObjectRef array ); + JSArrayBase( JSContextRef context ); + + virtual ~JSArrayBase(); + size_t size() const; + void resize(size_t size); + JSValueRef get(int index) const; + bool set(int index, JSValueRef value); + bool append(JSValueRef value); + +protected: + JSContextRef mContext; + JSObjectRef mArray; +}; + + +template <typename T> +class JSArray : protected JSArrayBase{ + friend class ItemProxy; +public: + typedef JSValueRef (*ToJSFunction)(JSContextRef, T); + typedef T (*ToNativeFunction)(JSContextRef, JSValueRef ); + + + JSArray( JSContextRef context, JSObjectRef array, ToNativeFunction nativefun, ToJSFunction jsfun) + :JSArrayBase(context,array),mToNative(nativefun), mToJs(jsfun) { + } + JSArray( JSContextRef context, ToNativeFunction nativefun, ToJSFunction jsfun) + :JSArrayBase(context),mToNative(nativefun), mToJs(jsfun) { + } + + ~JSArray(){ + } + + class ItemProxy { + JSArray<T> *mArray; + int mIndex; + public: + ItemProxy(JSArray<T>* array, int index):mArray(array), mIndex(index){ + } + operator T(){ + return mArray->mToNative(mArray->mContext, mArray->get(mIndex)); + } + ItemProxy& operator=( const T native){ + JSValueRef v = mArray->mToJs(mArray->mContext, native); + mArray->set(mIndex, v); + return *this; + } + ItemProxy& operator=( const ItemProxy& other){ + JSValueRef v = other.mArray->get(other.mIndex); + mArray->set(mIndex, v); + return *this; + } + + }; + size_t size() const{ + return JSArrayBase::size(); + } + + void resize(size_t size){ + JSArrayBase::resize(size); + } + + bool append( T v){ + return JSArrayBase::set( size(), mToJs(mContext, v)); + } + + ItemProxy operator[]( int index ){ + return ItemProxy(this, index); + } + + operator JSObjectRef(){ + return mArray; + } + + operator std::vector<T>(){ + std::vector<T> v; + size_t length = size(); + for( unsigned int i = 0 ; i < length ; i++){ + JSValueRef t = get(i); + T tmp = mToNative(mContext, t); + v.push_back(tmp); + } + return v; + } + + void operator=( const std::vector<T>& list ){ + overwrite(list); + } + + void operator=( const JSArray<T>& rhs){ + resize(rhs.size()); + for(unsigned int i = 0 ; i < rhs.size(); i++){ + set(i, rhs.get(i)); + } + } + +protected: + void overwrite( const std::vector<T>& list ){ + unsigned int i; + unsigned int listSize = list.size(); + resize(listSize); + for( i = 0 ; i < listSize ; i++){ + JSValueRef v = mToJs(mContext, list[i]); + set(i, v); + } + } + + + + +private: + ToNativeFunction mToNative; + ToJSFunction mToJs; +}; + + +class JSStringArray : public JSArray<std::string>{ + static JSValueRef makeJSValue(JSContextRef ctx, std::string v){ + return JSUtil::toJSValueRef(ctx, v); + } + public: + JSStringArray(JSContextRef ctx, JSObjectRef array): JSArray<std::string>(ctx, array, JSUtil::JSValueToString, makeJSValue){} + JSStringArray(JSContextRef ctx): JSArray<std::string>(ctx, JSUtil::JSValueToString, makeJSValue){} + void operator=( const std::vector<std::string>& list ){overwrite(list);} +}; + + +class JSLongArray : public JSArray<long>{ + static JSValueRef makeJSValue(JSContextRef ctx, long v){ + return JSUtil::toJSValueRef(ctx, v); + } + public: + JSLongArray(JSContextRef ctx, JSObjectRef array): JSArray<long>(ctx, array, JSUtil::JSValueToLong, makeJSValue){} + JSLongArray(JSContextRef ctx): JSArray<long>(ctx, JSUtil::JSValueToLong, makeJSValue){} + void operator=( const std::vector<long>& list ){overwrite(list);} + +}; + + + + +} +} +#endif //__TIZEN_COMMON_JSARRAY_H__ + diff --git a/wearable_src/Common/JSFunctionWrapper.cpp b/wearable_src/Common/JSFunctionWrapper.cpp new file mode 100644 index 0000000..7c68bcd --- /dev/null +++ b/wearable_src/Common/JSFunctionWrapper.cpp @@ -0,0 +1,136 @@ +// +// Tizen Web Device API +// Copyright (c) 2012 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 "JSFunctionWrapper.h" + +#include "Logger.h" + +namespace DeviceAPI { +namespace Common { + +JSFunctionWrapper::JSFunctionWrapper(JSContextRef context, JSValueRef function, JSObjectRef thisObject) : + m_context(context), + m_function(function), + m_thisObject(thisObject) +{ + if(m_function) + JSValueProtect(m_context, m_function); +} + +JSFunctionWrapper::~JSFunctionWrapper() +{ + if(m_function) + JSValueUnprotect(m_context, m_function); +} + +void JSFunctionWrapper::setFunction(const JSValueRef value) +{ + if(m_function) + JSValueUnprotect(m_context, m_function); + + m_function = value; + + if(m_function) + JSValueProtect(m_context, m_function); +} + +JSValueRef JSFunctionWrapper::getFunction() const +{ + return m_function; +} + +void JSFunctionWrapper::setThisObject(const JSObjectRef thisObject) +{ + m_thisObject = thisObject; +} + +JSObjectRef JSFunctionWrapper::getThisObject() const +{ + return m_thisObject; +} + +bool JSFunctionWrapper::invokable() const +{ + if(m_function == NULL) + return false; + + JSValueRef exception = NULL; + + JSObjectRef function = JSValueToObject(m_context, m_function, &exception); + if(exception != NULL) + return false; + + if(!JSObjectIsFunction(m_context, function)) + return false; + + return true; +} + +JSValueRef JSFunctionWrapper::invoke(JSValueRef argv[], unsigned argc) +{ + if(!invokable()) + return NULL; + + JSObjectRef function = JSValueToObject(m_context, m_function, NULL); + + JSValueRef exception = NULL; + + JSValueRef result = JSObjectCallAsFunction(m_context, function, m_thisObject, argc, argv, &exception); + + if(exception != NULL) + return NULL; + + return result; +} + +JSValueRef JSFunctionWrapper::invoke(JSValueRef arg) +{ + if(!invokable()) + return NULL; + + JSObjectRef function = JSValueToObject(m_context, m_function, NULL); + + JSValueRef exception = NULL; + + JSValueRef argv[1] = { arg }; + JSValueRef result = JSObjectCallAsFunction(m_context, function, m_thisObject, 1, argv, &exception); + + if(exception != NULL) + return NULL; + + return result; +} + +JSValueRef JSFunctionWrapper::invoke() +{ + if(!invokable()) + return NULL; + + JSObjectRef function = JSValueToObject(m_context, m_function, NULL); + + JSValueRef exception = NULL; + + JSValueRef result = JSObjectCallAsFunction(m_context, function, m_thisObject, 0, NULL, &exception); + + if(exception != NULL) + return NULL; + + return result; +} + +} // Common +} // DeviceAPI diff --git a/wearable_src/Common/JSFunctionWrapper.h b/wearable_src/Common/JSFunctionWrapper.h new file mode 100644 index 0000000..e60f4bf --- /dev/null +++ b/wearable_src/Common/JSFunctionWrapper.h @@ -0,0 +1,62 @@ +// +// Tizen Web Device API +// Copyright (c) 2012 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. +// + +/** + * @file JSFunctionWrapper.h + * @version 0.1 + * @brief + */ + +#ifndef _JS_FUNCTION_WRAPPER_H_ +#define _JS_FUNCTION_WRAPPER_H_ + +#include <JavaScriptCore/JavaScript.h> + +#include <boost/shared_ptr.hpp> + +namespace DeviceAPI { +namespace Common { + +class JSFunctionWrapper +{ +public: + JSFunctionWrapper(JSContextRef context, JSValueRef function, JSObjectRef thisObject); + virtual ~JSFunctionWrapper(); + + void setFunction(const JSValueRef function); + JSValueRef getFunction() const; + + void setThisObject(const JSObjectRef thisObject); + JSObjectRef getThisObject() const; + + bool invokable() const; + + JSValueRef invoke(JSValueRef argv[], unsigned argc); + JSValueRef invoke(JSValueRef arg); + JSValueRef invoke(); + +private: + JSContextRef m_context; + JSValueRef m_function; + JSObjectRef m_thisObject; // it does not protect thisObject +}; +typedef boost::shared_ptr<JSFunctionWrapper> JSFunctionWrapperPtr; + +} // Common +} // DeviceAPI + +#endif // _JS_FUNCTION_WRAPPER_H_ diff --git a/wearable_src/Common/JSObjectRefWrapper.cpp b/wearable_src/Common/JSObjectRefWrapper.cpp new file mode 100644 index 0000000..705090e --- /dev/null +++ b/wearable_src/Common/JSObjectRefWrapper.cpp @@ -0,0 +1,131 @@ +// +// Tizen Web Device API +// Copyright (c) 2012 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 "JSObjectRefWrapper.h" + +#include <string> +#include <algorithm> + +#include "Logger.h" +#include "PlatformException.h" +#include "JSStringRefWrapper.h" + +namespace DeviceAPI { +namespace Common { + +JSObjectRefWrapper::JSObjectRefWrapper(JSContextRef context, JSObjectRef object) : + m_context(context), + m_object(object), + m_protectCount(0) +{ +} + +JSObjectRefWrapper::~JSObjectRefWrapper() +{ + while(m_protectCount) + unprotect(); +} + +void JSObjectRefWrapper::protect() +{ + JSValueRef jsValue = static_cast<JSValueRef>(m_object); + JSValueProtect(m_context, jsValue); + m_protectCount++; +} + +void JSObjectRefWrapper::unprotect() +{ + if(m_protectCount) + { + JSValueRef jsValue = static_cast<JSValueRef>(m_object); + JSValueUnprotect(m_context, jsValue); + m_protectCount--; + } +} + +JSContextRef JSObjectRefWrapper::getContext() const +{ + return m_context; +} + +JSObjectRef JSObjectRefWrapper::getObject() const +{ + return m_object; +} + +JSValueRef JSObjectRefWrapper::getProperty(const std::string propertyName) const +{ + JSValueRef exception = NULL; + + JSStringRefWrapper jsStrWrapName(propertyName); + JSValueRef jsValueProp = JSObjectGetProperty(m_context, m_object, jsStrWrapName.get(), &exception); + if(exception != NULL) + { + LoggerD("Error occured while getting property '" << propertyName << "' from object."); + throw TypeMismatchException(m_context, exception); + } + + return jsValueProp; +} + +JSObjectRef JSObjectRefWrapper::getPropertyObject(const std::string propertyName) const +{ + JSValueRef exception = NULL; + + JSValueRef jsValueProp = getProperty(propertyName); + + JSObjectRef result = JSValueToObject(m_context, jsValueProp, &exception); + if(exception != NULL) + { + LoggerD("Error occured while converting property '" << propertyName << "' to object."); + throw TypeMismatchException(m_context, exception); + } + + return result; +} + +std::string JSObjectRefWrapper::getPropertyString(const std::string propertyName) const +{ + JSValueRef exception = NULL; + + JSValueRef jsValueProp = getProperty(propertyName); + + JSStringRef jsStrProp = JSValueToStringCopy(m_context, jsValueProp, &exception); + if(exception != NULL) + { + LoggerD("Error occured while converting property '" << propertyName << "' to string."); + throw TypeMismatchException(m_context, exception); + } + + size_t jsStrLenPropId = JSStringGetLength(jsStrProp); + + size_t bufferSize = jsStrLenPropId * 4 + 1; + char * buffer = new char[bufferSize]; + + std::fill(buffer, buffer+bufferSize, 0); + + JSStringGetUTF8CString(jsStrProp, buffer, bufferSize); + + std::string result(buffer); + + delete []buffer; + + return result; +} + +} // Common +} // DeviceAPI diff --git a/wearable_src/Common/JSObjectRefWrapper.h b/wearable_src/Common/JSObjectRefWrapper.h new file mode 100644 index 0000000..d06cb09 --- /dev/null +++ b/wearable_src/Common/JSObjectRefWrapper.h @@ -0,0 +1,64 @@ +// +// Tizen Web Device API +// Copyright (c) 2012 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. +// + +/** + * @file JSObjectRefWrapper.h + * @version 0.1 + * @brief + */ + +#ifndef _JS_OBJECT_REF_WRAPPER_H_ +#define _JS_OBJECT_REF_WRAPPER_H_ + +#include <JavaScriptCore/JavaScript.h> + +#include <string> + +namespace DeviceAPI { +namespace Common { + +class JSObjectRefWrapper +{ +public: + JSObjectRefWrapper(JSContextRef context, JSObjectRef object); + virtual ~JSObjectRefWrapper(); + + JSContextRef getContext() const; + JSObjectRef getObject() const; + +protected: + void protect(); + void unprotect(); + + JSValueRef getProperty(const std::string propertyName) const; + + JSObjectRef getPropertyObject(const std::string propertyName) const; + + std::string getPropertyString(const std::string propertyName) const; + +protected: + JSContextRef m_context; + JSObjectRef m_object; + +private: + int m_protectCount; +}; + +} // Common +} // DeviceAPI + +#endif // _JS_OBJECT_REF_WRAPPER_H_ diff --git a/wearable_src/Common/JSStringRefWrapper.cpp b/wearable_src/Common/JSStringRefWrapper.cpp new file mode 100644 index 0000000..b0aa69c --- /dev/null +++ b/wearable_src/Common/JSStringRefWrapper.cpp @@ -0,0 +1,83 @@ +// +// Tizen Web Device API +// Copyright (c) 2012 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 "JSStringRefWrapper.h" + +namespace DeviceAPI { +namespace Common { + +JSStringRefWrapper::JSStringRefWrapper(JSStringRefWrapper &obj) : m_ref(NULL) +{ + JSStringRef ref = obj.m_ref; + if(ref) + { + const JSChar* chars = JSStringGetCharactersPtr(ref); + size_t numChars = JSStringGetLength(ref); + + m_ref = JSStringCreateWithCharacters(chars, numChars); + } +} + +JSStringRefWrapper::JSStringRefWrapper(JSStringRef ref) : m_ref(ref) +{ +} + +JSStringRefWrapper::JSStringRefWrapper(const std::string str) +{ + m_ref = JSStringCreateWithUTF8CString(str.c_str()); +} + +JSStringRefWrapper::JSStringRefWrapper(const char * str) +{ + m_ref = JSStringCreateWithUTF8CString(str); +} + +JSStringRefWrapper::~JSStringRefWrapper() +{ + if (m_ref != NULL) + JSStringRelease(m_ref); +} + +JSStringRefWrapper & JSStringRefWrapper::operator=(const JSStringRefWrapper &obj) +{ + JSStringRef ref = obj.m_ref; + + if (m_ref != NULL) + JSStringRelease(m_ref); + + if(ref) + { + const JSChar* chars = JSStringGetCharactersPtr(ref); + size_t numChars = JSStringGetLength(ref); + + m_ref = JSStringCreateWithCharacters(chars, numChars); + } + else + { + m_ref = NULL; + } + + return *this; +} + +JSStringRef JSStringRefWrapper::get() const +{ + return m_ref; +} + +} // Common +} // DeviceAPI diff --git a/wearable_src/Common/JSStringRefWrapper.h b/wearable_src/Common/JSStringRefWrapper.h new file mode 100644 index 0000000..f9e9dd5 --- /dev/null +++ b/wearable_src/Common/JSStringRefWrapper.h @@ -0,0 +1,47 @@ +// +// Tizen Web Device API +// Copyright (c) 2012 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. +// + +#ifndef _JS_STRING_REF_WRAPPER_H_ +#define _JS_STRING_REF_WRAPPER_H_ + +#include <string> +#include <JavaScriptCore/JavaScript.h> + +namespace DeviceAPI { +namespace Common { + +class JSStringRefWrapper +{ +public: + JSStringRefWrapper(JSStringRefWrapper &obj); + JSStringRefWrapper(JSStringRef ref); + JSStringRefWrapper(const std::string str); + JSStringRefWrapper(const char * str); + virtual ~JSStringRefWrapper(); + + JSStringRefWrapper & operator=(const JSStringRefWrapper &obj); + + JSStringRef get() const; + +private: + JSStringRef m_ref; +}; + +} // Common +} // DeviceAPI + +#endif // _JS_STRING_REF_WRAPPER_H_ diff --git a/wearable_src/Common/JSUtil.cpp b/wearable_src/Common/JSUtil.cpp new file mode 100755 index 0000000..1404b7c --- /dev/null +++ b/wearable_src/Common/JSUtil.cpp @@ -0,0 +1,349 @@ +// +// 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 <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){ + return static_cast<unsigned long>(JSValueToLongLong(ctx,value)); +} + +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){ + return static_cast<unsigned long long>(JSValueToLongLong(ctx,value)); +} + +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 short value){ + return JSValueMakeNumber(ctx, value); +} + +JSValueRef JSUtil::toJSValueRef(JSContextRef ctx, const short value){ + return JSValueMakeNumber(ctx, value); +} + +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<unsigned short>& value){ + return toJSValueRef_(ctx, value); +} + +JSValueRef JSUtil::toJSValueRef(JSContextRef ctx, const std::vector<short>& 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; +} + +} +} diff --git a/wearable_src/Common/JSUtil.h b/wearable_src/Common/JSUtil.h new file mode 100755 index 0000000..733761e --- /dev/null +++ b/wearable_src/Common/JSUtil.h @@ -0,0 +1,621 @@ +// +// 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. +// + +#ifndef _JSUTIL_H_ +#define _JSUTIL_H_ +#include <JavaScriptCore/JavaScript.h> +#include <string> +#include <map> +#include <vector> +#include "PlatformException.h" +#include <ctime> + + +namespace DeviceAPI { +namespace Common{ + +class JSUtil{ +public: + /** + * @brief Gets a property from an object. + * + * @remarks + * if pass NULL in exception, when occurred error, it throw C++ exception(TypeMismatchException). + * + * @param[in] ctx The execution context to use. + * @param[in] object The JSObject whose property you want to get. + * @param[in] name The name of property + * @param[out] exception A pointer to a JSValueRef in which to store an exception, if any. + * + * @exception TypeMismatchException + */ + static JSValueRef getProperty(JSContextRef ctx , JSObjectRef object, const char *name, JSValueRef *exception=NULL); + + /** + * @brief Sets a property on an object. + * + * @remarks + * if pass NULL in exception, when occurred error, it throw C++ exception(TypeMismatchException). + * + * @param[in] ctx The execution context to use. + * @param[in] object The JSObject whose property you want to set. + * @param[in] name The name of property + * @param[in] attributes A logically ORed set of JSPropertyAttributes to give to the property. + * @param[out] exception A pointer to a JSValueRef in which to store an exception, if any. + * + * @exception TypeMismatchException + */ + static void setProperty(JSContextRef ctx , JSObjectRef object, const char *name, JSValueRef value, JSPropertyAttributes attributes, JSValueRef *exception=NULL); + + /** + * @brief Converts a JavaScript string to STL string + * + * @param[in] ctx The execution context to use. + * @param[in] value The JSString to convert. + * + * @return A STL string with the result of conversion + */ + static std::string JSStringToString(JSContextRef ctx, JSStringRef str); + + /** + * @brief Converts a JavaScript value to STL string + * + * @param[in] ctx The execution context to use. + * @param[in] value The JSValue to convert. + * + * @return A STL string with the result of conversion + * + * @exception TypeMismatchException + */ + static std::string JSValueToString(JSContextRef ctx, JSValueRef value); + + /** + * @brief Converts a JavaScript value to long number and returns the resulting long number. + * + * @param[in] ctx The execution context to use. + * @param[in] value The JSValue to convert. + * + * @return The result of conversion + * + * @exception TypeMismatchException + */ + static long JSValueToLong(JSContextRef ctx, JSValueRef value); + + /** + * @brief Converts a JavaScript value to unsigned long number and returns the resulting unsigned long number. + * + * @param[in] ctx The execution context to use. + * @param[in] value The JSValue to convert. + * + * @return The result of conversion + * + * @exception TypeMismatchException + */ + static unsigned long JSValueToULong(JSContextRef ctx, JSValueRef value); + + + /** + * @brief Converts a JavaScript value to long long number and returns the resulting long long number. + * + * @param[in] ctx The execution context to use. + * @param[in] value The JSValue to convert. + * + * @return The result of conversion + * + * @exception TypeMismatchException + */ + static long long JSValueToLongLong(JSContextRef ctx, JSValueRef value); + + /** + * @brief Converts a JavaScript value to unsigned long long number and returns the resulting unsigned long long number. + * + * @param[in] ctx The execution context to use. + * @param[in] value The JSValue to convert. + * + * @return The result of conversion + * + * @exception TypeMismatchException + */ + static unsigned long long JSValueToULongLong(JSContextRef ctx, JSValueRef value); + + + /** + * @brief Converts a JavaScript value to double number and returns the resulting double number. + * + * @remarks TypeMismatchException is thrown when the result of conversion was NaN(Not a Number). + * + * @param[in] ctx The execution context to use. + * @param[in] value The JSValue to convert. + * + * @return The result of conversion + * + * @exception TypeMismatchException + */ + static double JSValueToDouble(JSContextRef ctx, JSValueRef value); + + /** + * @brief Converts a JavaScript value to number and returns the resulting number. + * + * @param[in] ctx The execution context to use. + * @param[in] value The JSValue to convert. + * + * @return The result of conversion + * + * @exception TypeMismatchException + */ + static double JSValueToNumber(JSContextRef ctx, JSValueRef value); + + + /** + * @brief Converts a JavaScript value to byte(signed) number and returns the resulting byte(signed) number. + * + * @param[in] ctx The execution context to use. + * @param[in] value The JSValue to convert. + * + * @return The result of conversion + * + * @exception TypeMismatchException + */ + static signed char JSValueToByte(JSContextRef ctx, JSValueRef value); + + /** + * @brief Converts a JavaScript value to Octet(unsigned) number and returns the resulting Octet(unsigned) number. + * + * @param[in] ctx The execution context to use. + * @param[in] value The JSValue to convert. + * + * @return The result of conversion + * + * @exception TypeMismatchException + */ + static unsigned char JSValueToOctet(JSContextRef ctx, JSValueRef value); + + + /** + * @brief Converts a JavaScript value to boolean and returns the resulting bollean + * + * + * @param[in] ctx The execution context to use. + * @param[in] value The JSValue to convert. + * + * @return The result of conversion + */ + static bool JSValueToBoolean(JSContextRef ctx, JSValueRef value); + + /** + * @brief Converts a JavaScript value to time_t and returns the resulting time_t. + * + * @remarks TypeMismatchException is thrown when the value was not Date type. + * + * @param[in] ctx The execution context to use. + * @param[in] value The JSValue to convert. + * + * @return The result of conversion + * + * @exception TypeMismatchException + */ + static time_t JSValueToTimeT(JSContextRef ctx, JSValueRef value); + + /** + * @brief Converts a JavaScript value to tm and returns the resulting tm. + * + * @remarks TypeMismatchException is thrown when the value was not Date type. + * + * @param[in] ctx The execution context to use. + * @param[in] value The JSValue to convert. + * + * @return The result of conversion + * + * @exception TypeMismatchException + */ + static std::tm JSValueToDateTm(JSContextRef ctx, JSValueRef value); + + /** + * @brief Converts a JavaScript value to tm as UTC time and returns the resulting tm. + * + * @remarks TypeMismatchException is thrown when the value was not Date type. + * + * @param[in] ctx The execution context to use. + * @param[in] value The JSValue to convert. + * + * @return The result of conversion + * + * @exception TypeMismatchException + */ + static std::tm JSValueToDateTmUTC(JSContextRef ctx, JSValueRef value); + + /** + * @brief Converts a JavaScript value to object and returns the resulting object. + * + * @remarks TypeMismatchException is thrown when the value was not Object type. + * + * @param[in] ctx The execution context to use. + * @param[in] value The JSValue to convert. + * + * @return The JSObject result of conversion + * + * @exception TypeMismatchException + */ + static JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value); + + /** + * @brief Converts a JavaScript value to STL string vector and returns the resulting STL string vector + * + * @remarks TypeMismatchException is thrown when the array element could not converts to string.\n + * If the value is not Array object, Will return empty vector + * + * + * @param[in] ctx The execution context to use. + * @param[in] value The JSValue to convert. + * + * @return A STL string vector + * + * @exception TypeMismatchException + */ + static std::vector<std::string> JSArrayToStringVector(JSContextRef ctx, JSValueRef value); + + /** + * @brief Converts a JavaScript value to double number vector and returns the resulting double number vector + * + * @remarks TypeMismatchException is thrown when the array element could not converts to double.\n + * If the value is not Array object, Will return empty vector + * + * + * @param[in] ctx The execution context to use. + * @param[in] value The JSValue to convert. + * + * @return A double number vector + * + * @exception TypeMismatchException + */ + static std::vector<double> JSArrayToDoubleVector(JSContextRef ctx, JSValueRef value); + + /** + * @brief Converts a JavaScript value to long number vector and returns the resulting long number vector + * + * @remarks TypeMismatchException is thrown when the array element could not converts to long.\n + * If the value is not Array object, Will return empty vector + * + * + * @param[in] ctx The execution context to use. + * @param[in] value The JSValue to convert. + * + * @return A long number vector + * + * @exception TypeMismatchException + */ + static std::vector<long> JSArrayToLongVector(JSContextRef ctx, JSValueRef value); + + /** + * @brief Converts a JavaScript value to time_t vector and returns the resulting time_t vector + * + * @remarks TypeMismatchException is thrown when the array element could not converts to time_t.\n + * If the value is not Array object, Will return empty vector + * + * + * @param[in] ctx The execution context to use. + * @param[in] value The JSValue to convert. + * + * @return A time_t vector + * + * @exception TypeMismatchException + */ + static std::vector<time_t> JSArrayToTimeTVector(JSContextRef ctx, JSValueRef value); + + /** + * @brief Converts a JavaScript value to boolean vector and returns the resulting boolean vector + * + * @remarks If the value is not Array object, Will return empty vector + * + * + * @param[in] ctx The execution context to use. + * @param[in] value The JSValue to convert. + * + * @return A boolean vector + */ + static std::vector<bool> JSArrayToBoolVector(JSContextRef ctx, JSValueRef value); + + /** + * @brief Converts a JavaScript value to map<string,string> and returns the resulting object. + * + * @remarks TypeMismatchException is thrown when the value was not Object type. + * + * @param[in] ctx The execution context to use. + * @param[in] value The JSValue to convert. + * + * @return The JSObject result of conversion + * + * @exception TypeMismatchException + */ + static std::map<std::string, std::string> JSValueToStringMap(JSContextRef ctx, JSValueRef value); + + /** + * @brief Creates a JavaScript value of the string type. + * + * @param[in] ctx The execution context to use. + * @param[in] str The STL string to assign to the newly created JSValue. The newly created JSValue retains string, and releases it upon garbage collection. + * + * @return A JSValue of the string type, representing the value of string. + */ + static JSValueRef toJSValueRef(JSContextRef ctx, const std::string& str); + + /** + * @brief Creates a JavaScript value of the number type. + * + * @param[in] ctx The execution context to use. + * @param[in] value The short to assign to the newly created JSValue. + * + * @return A JSValue of the number type, representing the value of number. + */ + static JSValueRef toJSValueRef(JSContextRef ctx, const short value); + + /** + * @brief Creates a JavaScript value of the number type. + * + * @param[in] ctx The execution context to use. + * @param[in] value The unsigned short to assign to the newly created JSValue. + * + * @return A JSValue of the number type, representing the value of number. + */ + static JSValueRef toJSValueRef(JSContextRef ctx, const unsigned short value); + + /** + * @brief Creates a JavaScript value of the number type. + * + * @param[in] ctx The execution context to use. + * @param[in] value The long to assign to the newly created JSValue. + * + * @return A JSValue of the number type, representing the value of number. + */ + static JSValueRef toJSValueRef(JSContextRef ctx, const long value); + + /** + * @brief Creates a JavaScript value of the number type. + * + * @param[in] ctx The execution context to use. + * @param[in] value The unsigned long to assign to the newly created JSValue. + * + * @return A JSValue of the number type, representing the value of number. + */ + static JSValueRef toJSValueRef(JSContextRef ctx, const unsigned long value); + + /** + * @brief Creates a JavaScript value of the number type. + * + * @param[in] ctx The execution context to use. + * @param[in] value The long long to assign to the newly created JSValue. + * + * @return A JSValue of the number type, representing the value of number. + */ + static JSValueRef toJSValueRef(JSContextRef ctx, const long long value); + + /** + * @brief Creates a JavaScript value of the number type. + * + * @param[in] ctx The execution context to use. + * @param[in] value The unsigned long long to assign to the newly created JSValue. + * + * @return A JSValue of the number type, representing the value of number. + */ + static JSValueRef toJSValueRef(JSContextRef ctx, const unsigned long long value); + /** + * @brief Creates a JavaScript value of the number type. + * + * @param[in] ctx The execution context to use. + * @param[in] value The double to assign to the newly created JSValue. + * + * @return A JSValue of the number type, representing the value of number. + */ + static JSValueRef toJSValueRef(JSContextRef ctx, const double value); + + /** + * @brief Creates a JavaScript value of the boolean type. + * + * @param[in] ctx The execution context to use. + * @param[in] value The bool to assign to the newly created JSValue. + * + * @return A JSValue of the boolean type, representing the value of boolean. + */ + static JSValueRef toJSValueRef(JSContextRef ctx, const bool value); + + /** + * @brief Creates a JavaScript value of the number type. + * + * @param[in] ctx The execution context to use. + * @param[in] value The signed char to assign to the newly created JSValue. + * + * @return A JSValue of the number type, representing the value of number. + */ + static JSValueRef toJSValueRef(JSContextRef ctx, const signed char value); + + /** + * @brief Creates a JavaScript value of the number type. + * + * @param[in] ctx The execution context to use. + * @param[in] value The signed char to assign to the newly created JSValue. + * + * @return A JSValue of the number type, representing the value of number. + */ + static JSValueRef toJSValueRef(JSContextRef ctx, const unsigned char value); + + + + /** + * @brief Creates a JavaScript value of the string Array type. + * + * @remarks UnknownException is thrown when could not create Array object.\n + * + * @param[in] ctx The execution context to use. + * @param[in] value The STL string vector to assign to the newly created JSArray + * + * @return A JSArray of the string type + * + * @exception UnknownException + */ + static JSValueRef toJSValueRef(JSContextRef ctx, const std::vector<std::string>& value); + + + /** + * @brief Creates a JavaScript value of the number Array type. + * + * @remarks UnknownException is thrown when could not create Array object.\n + * + * @param[in] ctx The execution context to use. + * @param[in] value The unsigned short vector to assign to the newly created JSArray + * + * @return A JSArray of the number type + * + * @exception UnknownException + */ + static JSValueRef toJSValueRef(JSContextRef ctx, const std::vector<unsigned short>& value); + + + /** + * @brief Creates a JavaScript value of the number Array type. + * + * @remarks UnknownException is thrown when could not create Array object.\n + * + * @param[in] ctx The execution context to use. + * @param[in] value The long vector to assign to the newly created JSArray + * + * @return A JSArray of the number type + * + * @exception UnknownException + */ + static JSValueRef toJSValueRef(JSContextRef ctx, const std::vector<short>& value); + + + /** + * @brief Creates a JavaScript value of the number Array type. + * + * @remarks UnknownException is thrown when could not create Array object.\n + * + * @param[in] ctx The execution context to use. + * @param[in] value The long vector to assign to the newly created JSArray + * + * @return A JSArray of the number type + * + * @exception UnknownException + */ + static JSValueRef toJSValueRef(JSContextRef ctx, const std::vector<long>& value); + + /** + * @brief Creates a JavaScript value of the number Array type. + * + * @remarks UnknownException is thrown when could not create Array object.\n + * + * @param[in] ctx The execution context to use. + * @param[in] value The double vector to assign to the newly created JSArray + * + * @return A JSArray of the number type + * + * @exception UnknownException + */ + static JSValueRef toJSValueRef(JSContextRef ctx, const std::vector<double>& value); + + + /** + * @brief Creates a JavaScript value of the boolean Array type. + * + * @remarks UnknownException is thrown when could not create Array object.\n + * + * @param[in] ctx The execution context to use. + * @param[in] value The boolean vector to assign to the newly created JSArray + * + * @return A JSArray of the boolean type + * + * @exception UnknownException + */ + static JSValueRef toJSValueRef(JSContextRef ctx, const std::vector<bool>& value); + + /** + * @brief Creates a JavaScript value of the string map type. + * + * @remarks UnknownException is thrown when could not create Array object.\n + * + * @param[in] ctx The execution context to use. + * @param[in] value The string map to assign to the newly created JSValue + * + * @return A JSValue of the string map type + * + * @exception UnknownException + */ + static JSValueRef toJSValueRef(JSContextRef ctx, const std::map<std::string, std::string>& value); + + /** + * @brief Creates a JavaScript Date object with time_t value + * + * @remarks TypeMismatchException is thrown when could not create Date object.\n + * + * @param[in] ctx The execution context to use. + * @param[in] value The time_t value to create + * + * @return A JSObject that is a Date. + * + * @exception TypeMismatchException + */ + static JSObjectRef makeDateObject(JSContextRef ctx, const time_t value); + + + template<class T> + static std::vector<T> JSArrayToType_(JSContextRef ctx, JSValueRef value, T (*convert)(JSContextRef, JSValueRef)){ + std::vector<T> result; + if( !JSIsArrayValue(ctx, value)){ + return result; + } + JSObjectRef arrayobj = JSUtil::JSValueToObject(ctx, value); + + for (std::size_t i = 0; i < JSGetArrayLength(ctx, arrayobj); ++i) { + JSValueRef element = JSGetArrayElement(ctx, arrayobj, i); + T v = convert(ctx, element); + result.push_back(v); + } + return result; + } + + template<class T> + static JSValueRef toJSValueRef_(JSContextRef ctx, const std::vector<T>& value){ + JSValueRef *valueArray = new JSValueRef[value.size()]; + for( unsigned int i = 0 ; i < value.size(); i++){ + valueArray[i] = toJSValueRef(ctx,value[i]); + if(valueArray[i] == NULL){ + if(valueArray != NULL) + delete [] valueArray; + throw UnknownException("Element of array is invalid"); + } + } + JSValueRef exception = NULL; + JSObjectRef jsResult = JSObjectMakeArray(ctx, value.size(), valueArray, &exception); + if (exception != NULL) { + if(valueArray != NULL) + delete [] valueArray; + throw UnknownException(ctx, exception); + } + if(valueArray != NULL) + delete [] valueArray; + return jsResult; + }; + +private: + static bool JSValueIsDateObject(JSContextRef ctx, JSValueRef jsValue); +}; + +}} + +#endif //_JSUTIL_H_ + + diff --git a/wearable_src/Common/JSWebAPIError.cpp b/wearable_src/Common/JSWebAPIError.cpp new file mode 100644 index 0000000..6380462 --- /dev/null +++ b/wearable_src/Common/JSWebAPIError.cpp @@ -0,0 +1,197 @@ +// +// Tizen Web Device API +// Copyright (c) 2012 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 "JSWebAPIError.h" + +#include <string> +#include <map> +#include "JSUtil.h" +#include "Logger.h" + +namespace DeviceAPI { +namespace Common { + +#define CLASS_NAME "WebAPIError" +#define PROPERTY_CODE "code" +#define PROPERTY_NAME "name" +#define PROPERTY_TYPE "type" +#define PROPERTY_MESSAGE "message" + +JSClassRef JSWebAPIError::m_classRef = NULL; + +JSClassDefinition JSWebAPIError::m_classInfo = +{ + 0, + kJSClassAttributeNone, + CLASS_NAME, + 0, + m_properties, + m_function, + initialize, + finalize, + NULL, // hasProperty, + NULL, // getProperty, + NULL, // setProperty, + NULL, // deleteProperty, + NULL, // getPropertyNames, + NULL, // callAsFunction, + NULL, // callAsConstructor, + NULL, // hasInstance, + NULL, // convertToType, +}; + +JSStaticFunction JSWebAPIError::m_function[] = +{ + { "toString", toString, kJSPropertyAttributeNone }, + { 0, 0, 0 } +}; + +JSStaticValue JSWebAPIError::m_properties[] = { + { PROPERTY_CODE, getProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_NAME, getProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_TYPE, getProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_MESSAGE, getProperty, NULL, kJSPropertyAttributeReadOnly }, + { 0, 0, 0, 0 } +}; + +const JSClassDefinition* JSWebAPIError::getClassInfo() +{ + return &m_classInfo; +} + +JSClassRef JSWebAPIError::getClassRef() +{ + if (!m_classRef) + { + m_classRef = JSClassCreate(&m_classInfo); + } + return m_classRef; +} + +bool JSWebAPIError::isObjectOfClass(JSContextRef context, JSValueRef value) +{ + return JSValueIsObjectOfClass(context, value, getClassRef()); +} + +JSObjectRef JSWebAPIError::createJSObject(JSContextRef context, WebAPIError* webapiError) +{ + JSObjectRef jsObjectRef = JSObjectMake(context, getClassRef(), static_cast<void*>(webapiError)); + if (NULL == jsObjectRef) { + LoggerE("object creation error"); + return NULL; + } + return jsObjectRef; +} + +WebAPIError* JSWebAPIError::getPriv(JSContextRef context, JSObjectRef object) +{ + if(!JSValueIsObjectOfClass(context, object, getClassRef())) + return NULL; + + return static_cast<WebAPIError*>(JSObjectGetPrivate(object)); +} + +JSObjectRef JSWebAPIError::constructor(JSContextRef context, + JSObjectRef constructor, + size_t argumentCount, + const JSValueRef arguments[], + JSValueRef* exception) +{ + return JSWebAPIErrorFactory::postException(context, exception, + JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, + "Illegal constructor"); +} + +void JSWebAPIError::initialize(JSContextRef /*context*/, JSObjectRef /*object*/) +{ +} + +void JSWebAPIError::finalize(JSObjectRef object) +{ + WebAPIError* webapiErrObj = static_cast<WebAPIError*>(JSObjectGetPrivate(object)); + if(webapiErrObj) + { + JSObjectSetPrivate(object, NULL); + delete webapiErrObj; + } +} + +JSValueRef JSWebAPIError::getProperty(JSContextRef context, + JSObjectRef object, + JSStringRef propertyName, + JSValueRef* /*exception*/) +{ + WebAPIError* webapiErrObj = getPriv(context, object); + if(!webapiErrObj) + { + LoggerE("Private object is not set."); + return JSValueMakeUndefined(context); + } + + try + { + std::string propertyNameStr = JSUtil::JSStringToString(context, propertyName); + + if (propertyNameStr == PROPERTY_CODE) + { + return JSUtil::toJSValueRef(context, static_cast<long>(webapiErrObj->getCode())); + } + else if (propertyNameStr == PROPERTY_NAME) + { + return JSUtil::toJSValueRef(context, webapiErrObj->getName()); + } + else if (propertyNameStr == PROPERTY_TYPE) + { + return JSUtil::toJSValueRef(context, webapiErrObj->getName()); + } + else if (propertyNameStr == PROPERTY_MESSAGE) + { + return JSUtil::toJSValueRef(context, webapiErrObj->getMessage()); + } + } + catch(const BasePlatformException & err) + { + LoggerE("Exception: " << err.getMessage()); + } + + return JSValueMakeUndefined(context); +} + +JSValueRef JSWebAPIError::toString(JSContextRef context, + JSObjectRef object, + JSObjectRef thisObject, + size_t argumentCount, + const JSValueRef arguments[], + JSValueRef* exception) +{ + WebAPIError* webapiErrObj = getPriv(context, thisObject); + if(!webapiErrObj) + { + LoggerE("Private object is not set."); + return NULL; + } + + std::string name = webapiErrObj->getName(); + std::string message = webapiErrObj->getMessage(); + + std::string result = name + ": " + message; + + return JSUtil::toJSValueRef(context, result); +} + +} // Common +} // DeviceAPI diff --git a/wearable_src/Common/JSWebAPIError.h b/wearable_src/Common/JSWebAPIError.h new file mode 100644 index 0000000..3596a9d --- /dev/null +++ b/wearable_src/Common/JSWebAPIError.h @@ -0,0 +1,81 @@ +// +// Tizen Web Device API +// Copyright (c) 2012 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. +// + +#ifndef _JS_WEBAPI_ERROR_H_ +#define _JS_WEBAPI_ERROR_H_ + +#include <JavaScriptCore/JavaScript.h> +#include "JSWebAPIErrorFactory.h" + +#include "WebAPIError.h" + +namespace DeviceAPI { +namespace Common { + +class JSWebAPIErrorFactory; + +class JSWebAPIError +{ +public: + static JSClassRef getClassRef(); + + static const JSClassDefinition* getClassInfo(); + + static bool isObjectOfClass(JSContextRef context, JSValueRef value); + + static JSObjectRef constructor(JSContextRef context, + JSObjectRef constructor, + size_t argumentCount, + const JSValueRef arguments[], + JSValueRef* exception); + +private: + static JSObjectRef createJSObject(JSContextRef context, WebAPIError* webapiError); + + static WebAPIError* getPriv(JSContextRef context, JSObjectRef object); + + static void initialize(JSContextRef context, JSObjectRef object); + + static void finalize(JSObjectRef object); + + static JSValueRef getProperty(JSContextRef context, + JSObjectRef object, + JSStringRef propertyName, + JSValueRef* exception); + + static JSValueRef toString(JSContextRef context, + JSObjectRef object, + JSObjectRef thisObject, + size_t argumentCount, + const JSValueRef arguments[], + JSValueRef* exception); + + static JSClassDefinition m_classInfo; + + static JSStaticValue m_properties[]; + + static JSClassRef m_classRef; + + static JSStaticFunction m_function[]; + + friend class JSWebAPIErrorFactory; +}; + +} // Common +} // DeviceAPI + +#endif // _JS_WEBAPI_ERROR_H_ diff --git a/wearable_src/Common/JSWebAPIErrorFactory.cpp b/wearable_src/Common/JSWebAPIErrorFactory.cpp new file mode 100644 index 0000000..e6d0270 --- /dev/null +++ b/wearable_src/Common/JSWebAPIErrorFactory.cpp @@ -0,0 +1,264 @@ +// +// Tizen Web Device API +// Copyright (c) 2012 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 "JSWebAPIErrorFactory.h" + +#include <map> + +#include "JSStringRefWrapper.h" +#include "JSWebAPIException.h" +#include "JSWebAPIError.h" +#include "Logger.h" + +#define INDEX_SIZE_ERROR_NAME_STR "IndexSizeError" +#define DOMSTRING_SIZE_ERROR_NAME_STR "DOMStringSizeError" +#define HIERARCHY_REQUEST_ERROR_NAME_STR "HierarchyRequestError" +#define WRONG_DOCUMENT_ERROR_NAME_STR "WrongDocumentError" +#define INVALID_CHARACTER_ERROR_NAME_STR "InvalidCharacterError" +#define NO_DATA_ALLOWED_ERROR_NAME_STR "NoDataAllowedError" +#define NO_MODIFICATION_ALLOWED_ERROR_NAME_STR "NoModificationAllowedError" +#define NOT_FOUND_ERROR_NAME_STR "NotFoundError" +#define NOT_SUPPORTED_ERROR_NAME_STR "NotSupportedError" +#define INUSE_ATTRIBUTE_ERROR_NAME_STR "InuseAttributeError" +#define INVALID_STATE_ERROR_NAME_STR "InvalidStateError" +#define SYNTAX_ERROR_NAME_STR "SyntaxError" +#define INVALID_MODIFICATION_ERROR_NAME_STR "InvalidModificationError" +#define NAMESPACE_ERROR_NAME_STR "NamespaceError" +#define INVALID_ACCESS_ERROR_NAME_STR "InvalidAccessError" +#define VALIDATION_ERROR_NAME_STR "ValidationError" +#define TYPE_MISMATCH_ERROR_NAME_STR "TypeMismatchError" +#define SECURITY_ERROR_NAME_STR "SecurityError" +#define NETWORK_ERROR_NAME_STR "NetworkError" +#define ABORT_ERROR_NAME_STR "AbortError" +#define URL_MISMATCH_ERROR_NAME_STR "URLMismatchError" +#define QUOTA_EXCEEDED_ERROR_NAME_STR "QuotaExceededError" +#define TIMEOUT_ERROR_NAME_STR "TimeoutError" +#define INVALID_NODE_TYPE_ERROR_NAME_STR "InvalidNodeTypeError" +#define DATA_CLONE_ERROR_NAME_STR "DataCloneError" +#define ENCODING_ERROR_NAME_STR "EncodingError" + +#define UNKNOWN_ERROR_NAME_STR "UnknownError" +#define INVALID_VALUES_ERROR_NAME_STR "InvalidValuesError" +#define IO_ERROR_NAME_STR "IOError" +#define PERMISSION_DENIED_ERROR_NAME_STR "PermissionDeniedError" +#define SERVICE_NOT_AVAILABLE_ERROR_NAME_STR "ServiceNotAvailableError" + +#define ECMA_ERROR_NAME_STR "Error" +#define ECMA_EVAL_ERROR_NAME_STR "EvalError" +#define ECMA_RANGE_ERROR_NAME_STR "RangeError" +#define ECMA_REFERENCE_ERROR_NAME_STR "ReferenceError" +#define ECMA_SYNTAX_ERROR_NAME_STR "SyntaxError" +#define ECMA_TYPE_ERROR_NAME_STR "TypeError" +#define ECMA_URI_ERROR_NAME_STR "URIError" + +#define CUSTOM_ERROR_NAME_STR "CustomError" + +namespace DeviceAPI { +namespace Common { + +enum ErrorClass +{ + ERROR_TYPE_DOM, + ERROR_TYPE_TIZEN, + ERROR_TYPE_ECMA, + ERROR_TYPE_CUSTOM +}; + +struct DeviceAPIErrorProperties +{ + const ErrorClass type; + const unsigned int code; + const char* name; +}; +typedef std::map<std::string, DeviceAPIErrorProperties> DeviceAPIErrorPropertiesMap; + +static DeviceAPIErrorPropertiesMap s_errorProperties = { + { INDEX_SIZE_ERROR_NAME_STR, { ERROR_TYPE_DOM, 1, INDEX_SIZE_ERROR_NAME_STR } }, + { DOMSTRING_SIZE_ERROR_NAME_STR, { ERROR_TYPE_DOM, 2, DOMSTRING_SIZE_ERROR_NAME_STR } }, + { HIERARCHY_REQUEST_ERROR_NAME_STR, { ERROR_TYPE_DOM, 3, HIERARCHY_REQUEST_ERROR_NAME_STR } }, + { WRONG_DOCUMENT_ERROR_NAME_STR, { ERROR_TYPE_DOM, 4, WRONG_DOCUMENT_ERROR_NAME_STR } }, + { INVALID_CHARACTER_ERROR_NAME_STR, { ERROR_TYPE_DOM, 5, INVALID_CHARACTER_ERROR_NAME_STR } }, + { NO_DATA_ALLOWED_ERROR_NAME_STR, { ERROR_TYPE_DOM, 6, NO_DATA_ALLOWED_ERROR_NAME_STR } }, + { NO_MODIFICATION_ALLOWED_ERROR_NAME_STR, { ERROR_TYPE_DOM, 7, NO_MODIFICATION_ALLOWED_ERROR_NAME_STR } }, + { NOT_FOUND_ERROR_NAME_STR, { ERROR_TYPE_DOM, 8, NOT_FOUND_ERROR_NAME_STR } }, + { NOT_SUPPORTED_ERROR_NAME_STR, { ERROR_TYPE_DOM, 9, NOT_SUPPORTED_ERROR_NAME_STR } }, + { INUSE_ATTRIBUTE_ERROR_NAME_STR, { ERROR_TYPE_DOM, 10, INUSE_ATTRIBUTE_ERROR_NAME_STR } }, + { INVALID_STATE_ERROR_NAME_STR, { ERROR_TYPE_DOM, 11, INVALID_STATE_ERROR_NAME_STR } }, + { SYNTAX_ERROR_NAME_STR, { ERROR_TYPE_DOM, 12, SYNTAX_ERROR_NAME_STR } }, + { INVALID_MODIFICATION_ERROR_NAME_STR, { ERROR_TYPE_DOM, 13, INVALID_MODIFICATION_ERROR_NAME_STR } }, + { NAMESPACE_ERROR_NAME_STR, { ERROR_TYPE_DOM, 14, NAMESPACE_ERROR_NAME_STR } }, + { INVALID_ACCESS_ERROR_NAME_STR, { ERROR_TYPE_DOM, 15, INVALID_ACCESS_ERROR_NAME_STR } }, + { VALIDATION_ERROR_NAME_STR, { ERROR_TYPE_DOM, 16, VALIDATION_ERROR_NAME_STR } }, + { TYPE_MISMATCH_ERROR_NAME_STR, { ERROR_TYPE_DOM, 17, TYPE_MISMATCH_ERROR_NAME_STR } }, + { SECURITY_ERROR_NAME_STR, { ERROR_TYPE_DOM, 18, SECURITY_ERROR_NAME_STR } }, + { NETWORK_ERROR_NAME_STR, { ERROR_TYPE_DOM, 19, NETWORK_ERROR_NAME_STR } }, + { ABORT_ERROR_NAME_STR, { ERROR_TYPE_DOM, 20, ABORT_ERROR_NAME_STR } }, + { URL_MISMATCH_ERROR_NAME_STR, { ERROR_TYPE_DOM, 21, URL_MISMATCH_ERROR_NAME_STR } }, + { QUOTA_EXCEEDED_ERROR_NAME_STR, { ERROR_TYPE_DOM, 22, QUOTA_EXCEEDED_ERROR_NAME_STR } }, + { TIMEOUT_ERROR_NAME_STR, { ERROR_TYPE_DOM, 23, TIMEOUT_ERROR_NAME_STR } }, + { INVALID_NODE_TYPE_ERROR_NAME_STR, { ERROR_TYPE_DOM, 24, INVALID_NODE_TYPE_ERROR_NAME_STR } }, + { DATA_CLONE_ERROR_NAME_STR, { ERROR_TYPE_DOM, 25, DATA_CLONE_ERROR_NAME_STR } }, + { ENCODING_ERROR_NAME_STR, { ERROR_TYPE_DOM, 0, ENCODING_ERROR_NAME_STR } }, + { UNKNOWN_ERROR_NAME_STR, { ERROR_TYPE_TIZEN, 0, UNKNOWN_ERROR_NAME_STR } }, + { INVALID_VALUES_ERROR_NAME_STR, { ERROR_TYPE_TIZEN, 0, INVALID_VALUES_ERROR_NAME_STR } }, + { IO_ERROR_NAME_STR, { ERROR_TYPE_TIZEN, 0, IO_ERROR_NAME_STR } }, + { PERMISSION_DENIED_ERROR_NAME_STR, { ERROR_TYPE_TIZEN, 0, PERMISSION_DENIED_ERROR_NAME_STR } }, + { SERVICE_NOT_AVAILABLE_ERROR_NAME_STR, { ERROR_TYPE_TIZEN, 0, SERVICE_NOT_AVAILABLE_ERROR_NAME_STR } }, +}; + +static DeviceAPIErrorProperties s_customErrorProperties = { ERROR_TYPE_CUSTOM, 0, CUSTOM_ERROR_NAME_STR }; + +const std::string JSWebAPIErrorFactory::INDEX_SIZE_ERROR = INDEX_SIZE_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::DOMSTRING_SIZE_ERROR = DOMSTRING_SIZE_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::HIERARCHY_REQUEST_ERROR = HIERARCHY_REQUEST_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::WRONG_DOCUMENT_ERROR = WRONG_DOCUMENT_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::INVALID_CHARACTER_ERROR = INVALID_CHARACTER_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::NO_DATA_ALLOWED_ERROR = NO_DATA_ALLOWED_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::NO_MODIFICATION_ALLOWED_ERROR = NO_MODIFICATION_ALLOWED_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::NOT_FOUND_ERROR = NOT_FOUND_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::NOT_SUPPORTED_ERROR = NOT_SUPPORTED_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::INUSE_ATTRIBUTE_ERROR = INUSE_ATTRIBUTE_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::INVALID_STATE_ERROR = INVALID_STATE_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::SYNTAX_ERROR = SYNTAX_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::INVALID_MODIFICATION_ERROR = INVALID_MODIFICATION_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::NAMESPACE_ERROR = NAMESPACE_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::INVALID_ACCESS_ERROR = INVALID_ACCESS_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::VALIDATION_ERROR = VALIDATION_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR = TYPE_MISMATCH_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::SECURITY_ERROR = SECURITY_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::NETWORK_ERROR = NETWORK_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::ABORT_ERROR = ABORT_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::URL_MISMATCH_ERROR = URL_MISMATCH_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::QUOTA_EXCEEDED_ERROR = QUOTA_EXCEEDED_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::TIMEOUT_ERROR = TIMEOUT_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::INVALID_NODE_TYPE_ERROR = INVALID_NODE_TYPE_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::DATA_CLONE_ERROR = DATA_CLONE_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::ENCODING_ERROR = ENCODING_ERROR_NAME_STR; + +const std::string JSWebAPIErrorFactory::UNKNOWN_ERROR = UNKNOWN_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::INVALID_VALUES_ERROR = INVALID_VALUES_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::IO_ERROR = IO_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::PERMISSION_DENIED_ERROR = PERMISSION_DENIED_ERROR_NAME_STR; +const std::string JSWebAPIErrorFactory::SERVICE_NOT_AVAILABLE_ERROR = SERVICE_NOT_AVAILABLE_ERROR_NAME_STR; + +JSWebAPIErrorFactory::JSWebAPIErrorFactory() +{ +} + +JSWebAPIErrorFactory::~JSWebAPIErrorFactory() +{ +} + +JSObjectRef JSWebAPIErrorFactory::makeErrorObject(JSContextRef context, + const std::string& name, + const std::string& message) +{ + return createErrorObject(context, name, message, false); +} + +JSObjectRef JSWebAPIErrorFactory::makeErrorObject(JSContextRef context, + const BasePlatformException& error) +{ + return createErrorObject(context, error.getName(), error.getMessage(), false); +} + +JSObjectRef JSWebAPIErrorFactory::postException(JSContextRef context, + JSValueRef* exception, + const std::string& name, + const std::string& message) +{ + if(exception == NULL) + { + LoggerE("exception ptr is NULL."); + return NULL; + } + + JSObjectRef exceptionObj = createErrorObject(context, name, message, true); + + *exception = exceptionObj; + + return exceptionObj; +} + +JSObjectRef JSWebAPIErrorFactory::postException(JSContextRef context, + JSValueRef* exception, + const BasePlatformException& error) +{ + return postException(context, exception, error.getName(), error.getMessage()); +} + +JSObjectRef JSWebAPIErrorFactory::createErrorObject(JSContextRef context, + const std::string& name, + const std::string& message, + const bool isException) +{ + JSObjectRef jsErrorObject = NULL; + + DeviceAPIErrorProperties *properties; + + DeviceAPIErrorPropertiesMap::iterator iter = s_errorProperties.find(name); + if(iter != s_errorProperties.end()) + properties = &(iter->second); + else + properties = &s_customErrorProperties; + + if(properties->type == ERROR_TYPE_ECMA) + return createECMAErrorObject(context, properties->name, message); + + WebAPIError *errorObject = NULL; + switch(properties->type) + { + case ERROR_TYPE_DOM: + case ERROR_TYPE_TIZEN: + errorObject = new WebAPIError(properties->code, properties->name, message); + break; + case ERROR_TYPE_CUSTOM: + errorObject = new WebAPIError(0, name, message); + break; + case ERROR_TYPE_ECMA: // Cannot happen + default: + errorObject = new WebAPIError(0, "Error", message); + break; + } + + if(isException) + jsErrorObject = JSWebAPIException::createJSObject(context, errorObject); + else + jsErrorObject = JSWebAPIError::createJSObject(context, errorObject); + + return jsErrorObject; +} + +JSObjectRef JSWebAPIErrorFactory::createECMAErrorObject(JSContextRef context, + const std::string& name, + const std::string& message) +{ + std::string jsCodeStr; + jsCodeStr = "new " + name + "("; + if(!message.empty()) + jsCodeStr += "\"" + message + "\""; + jsCodeStr += ");"; + + JSStringRefWrapper jsCode(jsCodeStr); + + JSValueRef errValue = JSEvaluateScript(context, jsCode.get(), NULL, NULL, 0, NULL); + + return JSValueToObject(context, errValue, NULL); +} + +} // Common +} // DeviceAPI diff --git a/wearable_src/Common/JSWebAPIErrorFactory.h b/wearable_src/Common/JSWebAPIErrorFactory.h new file mode 100644 index 0000000..6dfc55b --- /dev/null +++ b/wearable_src/Common/JSWebAPIErrorFactory.h @@ -0,0 +1,97 @@ +// +// Tizen Web Device API +// Copyright (c) 2012 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. +// + +#ifndef _JS_WEBAPI_ERROR_FACTORY_H_ +#define _JS_WEBAPI_ERROR_FACTORY_H_ + +#include <string> +#include <JavaScriptCore/JavaScript.h> +#include "PlatformException.h" + +namespace DeviceAPI { +namespace Common { + +class JSWebAPIErrorFactory +{ +public: + JSWebAPIErrorFactory(); + virtual ~JSWebAPIErrorFactory(); + + static JSObjectRef makeErrorObject(JSContextRef context, + const std::string& name, + const std::string& message = std::string()); + + static JSObjectRef makeErrorObject(JSContextRef context, + const BasePlatformException& error); + + static JSObjectRef postException(JSContextRef context, + JSValueRef* exception, + const std::string& name, + const std::string& message = std::string()); + + static JSObjectRef postException(JSContextRef context, + JSValueRef* exception, + const BasePlatformException& error); + + static const std::string INDEX_SIZE_ERROR; + static const std::string DOMSTRING_SIZE_ERROR; + static const std::string HIERARCHY_REQUEST_ERROR; + static const std::string WRONG_DOCUMENT_ERROR; + static const std::string INVALID_CHARACTER_ERROR; + static const std::string NO_DATA_ALLOWED_ERROR; + static const std::string NO_MODIFICATION_ALLOWED_ERROR; + static const std::string NOT_FOUND_ERROR; + static const std::string NOT_SUPPORTED_ERROR; + static const std::string INUSE_ATTRIBUTE_ERROR; + static const std::string INVALID_STATE_ERROR; + static const std::string SYNTAX_ERROR; + static const std::string INVALID_MODIFICATION_ERROR; + static const std::string NAMESPACE_ERROR; + static const std::string INVALID_ACCESS_ERROR; + static const std::string VALIDATION_ERROR; + static const std::string TYPE_MISMATCH_ERROR; + static const std::string SECURITY_ERROR; + static const std::string NETWORK_ERROR; + static const std::string ABORT_ERROR; + static const std::string URL_MISMATCH_ERROR; + static const std::string QUOTA_EXCEEDED_ERROR; + static const std::string TIMEOUT_ERROR; + static const std::string INVALID_NODE_TYPE_ERROR; + static const std::string DATA_CLONE_ERROR; + static const std::string ENCODING_ERROR; + + static const std::string UNKNOWN_ERROR; + static const std::string INVALID_VALUES_ERROR; + static const std::string IO_ERROR; + static const std::string PERMISSION_DENIED_ERROR; + static const std::string SERVICE_NOT_AVAILABLE_ERROR; + +private: + static JSObjectRef createErrorObject(JSContextRef context, + const std::string& name, + const std::string& message, + const bool isException); + + static JSObjectRef createECMAErrorObject(JSContextRef context, + const std::string& name, + const std::string& message); +}; + +} // Common +} // DeviceAPI + +#endif // _JS_WEBAPI_ERROR_FACTORY_H_ diff --git a/wearable_src/Common/JSWebAPIException.cpp b/wearable_src/Common/JSWebAPIException.cpp new file mode 100644 index 0000000..0aac394 --- /dev/null +++ b/wearable_src/Common/JSWebAPIException.cpp @@ -0,0 +1,304 @@ +// +// Tizen Web Device API +// Copyright (c) 2012 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 "JSWebAPIException.h" +#include <string> +#include <map> +#include "JSUtil.h" +#include "JSStringRefWrapper.h" +#include "Logger.h" + +namespace DeviceAPI { +namespace Common { + +#define CLASS_NAME "WebAPIException" + +#define PROPERTY_CODE "code" +#define PROPERTY_NAME "name" +#define PROPERTY_TYPE "type" +#define PROPERTY_MESSAGE "message" + +#define PROPERTY_INDEX_SIZE_ERR "INDEX_SIZE_ERR" +#define PROPERTY_DOMSTRING_SIZE_ERR "DOMSTRING_SIZE_ERR" +#define PROPERTY_HIERARCHY_REQUEST_ERR "HIERARCHY_REQUEST_ERR" +#define PROPERTY_WRONG_DOCUMENT_ERR "WRONG_DOCUMENT_ERR" +#define PROPERTY_INVALID_CHARACTER_ERR "INVALID_CHARACTER_ERR" +#define PROPERTY_NO_DATA_ALLOWED_ERR "NO_DATA_ALLOWED_ERR" +#define PROPERTY_NO_MODIFICATION_ALLOWED_ERR "NO_MODIFICATION_ALLOWED_ERR" +#define PROPERTY_NOT_FOUND_ERR "NOT_FOUND_ERR" +#define PROPERTY_NOT_SUPPORTED_ERR "NOT_SUPPORTED_ERR" +#define PROPERTY_INUSE_ATTRIBUTE_ERR "INUSE_ATTRIBUTE_ERR" +#define PROPERTY_INVALID_STATE_ERR "INVALID_STATE_ERR" +#define PROPERTY_SYNTAX_ERR "SYNTAX_ERR" +#define PROPERTY_INVALID_MODIFICATION_ERR "INVALID_MODIFICATION_ERR" +#define PROPERTY_NAMESPACE_ERR "NAMESPACE_ERR" +#define PROPERTY_INVALID_ACCESS_ERR "INVALID_ACCESS_ERR" +#define PROPERTY_VALIDATION_ERR "VALIDATION_ERR" +#define PROPERTY_TYPE_MISMATCH_ERR "TYPE_MISMATCH_ERR" +#define PROPERTY_SECURITY_ERR "SECURITY_ERR" +#define PROPERTY_NETWORK_ERR "NETWORK_ERR" +#define PROPERTY_ABORT_ERR "ABORT_ERR" +#define PROPERTY_URL_MISMATCH_ERR "URL_MISMATCH_ERR" +#define PROPERTY_QUOTA_EXCEEDED_ERR "QUOTA_EXCEEDED_ERR" +#define PROPERTY_TIMEOUT_ERR "TIMEOUT_ERR" +#define PROPERTY_INVALID_NODE_TYPE_ERR "INVALID_NODE_TYPE_ERR" +#define PROPERTY_DATA_CLONE_ERR "DATA_CLONE_ERR" + +typedef std::map<std::string, int> DeviceAPIErrorCodeMap; + +static DeviceAPIErrorCodeMap errorCodes = { + { PROPERTY_INDEX_SIZE_ERR, 1 }, + { PROPERTY_DOMSTRING_SIZE_ERR, 2 }, + { PROPERTY_HIERARCHY_REQUEST_ERR, 3 }, + { PROPERTY_WRONG_DOCUMENT_ERR, 4 }, + { PROPERTY_INVALID_CHARACTER_ERR, 5 }, + { PROPERTY_NO_DATA_ALLOWED_ERR, 6 }, + { PROPERTY_NO_MODIFICATION_ALLOWED_ERR, 7 }, + { PROPERTY_NOT_FOUND_ERR, 8 }, + { PROPERTY_NOT_SUPPORTED_ERR, 9 }, + { PROPERTY_INUSE_ATTRIBUTE_ERR, 10 }, + { PROPERTY_INVALID_STATE_ERR, 11 }, + { PROPERTY_SYNTAX_ERR, 12 }, + { PROPERTY_INVALID_MODIFICATION_ERR, 13 }, + { PROPERTY_NAMESPACE_ERR, 14 }, + { PROPERTY_INVALID_ACCESS_ERR, 15 }, + { PROPERTY_VALIDATION_ERR, 16 }, + { PROPERTY_TYPE_MISMATCH_ERR, 17 }, + { PROPERTY_SECURITY_ERR, 18 }, + { PROPERTY_NETWORK_ERR, 19 }, + { PROPERTY_ABORT_ERR, 20 }, + { PROPERTY_URL_MISMATCH_ERR, 21 }, + { PROPERTY_QUOTA_EXCEEDED_ERR, 22 }, + { PROPERTY_TIMEOUT_ERR, 23 }, + { PROPERTY_INVALID_NODE_TYPE_ERR, 24 }, + { PROPERTY_DATA_CLONE_ERR, 25 } +}; + +JSClassRef JSWebAPIException::m_classRef = NULL; + +JSClassDefinition JSWebAPIException::m_classInfo = +{ + 0, + kJSClassAttributeNone, + CLASS_NAME, + 0, + m_properties, + m_function, + initialize, + finalize, + NULL, // hasProperty, + NULL, // getProperty, + NULL, // setProperty, + NULL, // deleteProperty, + NULL, // getPropertyNames, + NULL, // callAsFunction, + NULL, // callAsConstructor, + NULL, // hasInstance, + NULL, // convertToType, +}; + +JSStaticFunction JSWebAPIException::m_function[] = +{ + { "toString", toString, kJSPropertyAttributeNone }, + { 0, 0, 0 } +}; + +JSStaticValue JSWebAPIException::m_properties[] = { + { PROPERTY_CODE, getProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_NAME, getProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_TYPE, getProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_MESSAGE, getProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_INDEX_SIZE_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_DOMSTRING_SIZE_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_HIERARCHY_REQUEST_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_WRONG_DOCUMENT_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_INVALID_CHARACTER_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_NO_DATA_ALLOWED_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_NO_MODIFICATION_ALLOWED_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_NOT_FOUND_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_NOT_SUPPORTED_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_INUSE_ATTRIBUTE_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_INVALID_STATE_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_SYNTAX_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_INVALID_MODIFICATION_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_NAMESPACE_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_INVALID_ACCESS_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_VALIDATION_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_TYPE_MISMATCH_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_SECURITY_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_NETWORK_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_ABORT_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_URL_MISMATCH_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_QUOTA_EXCEEDED_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_TIMEOUT_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_INVALID_NODE_TYPE_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { PROPERTY_DATA_CLONE_ERR, getStaticProperty, NULL, kJSPropertyAttributeReadOnly }, + { 0, 0, 0, 0 } +}; + +const JSClassDefinition* JSWebAPIException::getClassInfo() +{ + return &m_classInfo; +} + +JSClassRef JSWebAPIException::getClassRef() +{ + if (!m_classRef) + { + m_classRef = JSClassCreate(&m_classInfo); + } + return m_classRef; +} + +bool JSWebAPIException::isObjectOfClass(JSContextRef context, JSValueRef value) +{ + return JSValueIsObjectOfClass(context, value, getClassRef()); +} + +JSObjectRef JSWebAPIException::createJSObject(JSContextRef context, WebAPIError* webapiError) +{ + JSObjectRef jsObjectRef = JSObjectMake(context, getClassRef(), static_cast<void*>(webapiError)); + if (NULL == jsObjectRef) { + LoggerE("object creation error"); + return NULL; + } + return jsObjectRef; +} + +WebAPIError* JSWebAPIException::getPriv(JSContextRef context, JSObjectRef object) +{ + if(!JSValueIsObjectOfClass(context, object, getClassRef())) + return NULL; + + return static_cast<WebAPIError*>(JSObjectGetPrivate(object)); +} + +JSObjectRef JSWebAPIException::constructor(JSContextRef context, + JSObjectRef constructor, + size_t argumentCount, + const JSValueRef arguments[], + JSValueRef* exception) +{ + return JSWebAPIErrorFactory::postException(context, exception, + JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, + "Illegal constructor"); +} + +void JSWebAPIException::initializeConstructor(JSContextRef context, JSObjectRef constructor) +{ + for(DeviceAPIErrorCodeMap::iterator iter = errorCodes.begin(); iter != errorCodes.end(); iter++) + { + JSStringRefWrapper name(iter->first); + JSValueRef value = JSValueMakeNumber(context, static_cast<double>(iter->second)); + JSObjectSetProperty(context, constructor, name.get(), value, kJSPropertyAttributeReadOnly, NULL); + } +} + +void JSWebAPIException::initialize(JSContextRef /*context*/, JSObjectRef /*object*/) +{ +} + +void JSWebAPIException::finalize(JSObjectRef /*object*/) +{ +} + +JSValueRef JSWebAPIException::getProperty(JSContextRef context, + JSObjectRef object, + JSStringRef propertyName, + JSValueRef* /*exception*/) +{ + WebAPIError* webapiErrObj = getPriv(context, object); + if(!webapiErrObj) + { + LoggerE("Private object is not set."); + return JSValueMakeUndefined(context); + } + + try + { + std::string propertyNameStr = JSUtil::JSStringToString(context, propertyName); + + if (propertyNameStr == PROPERTY_CODE) + { + return JSUtil::toJSValueRef(context, static_cast<long>(webapiErrObj->getCode())); + } + else if (propertyNameStr == PROPERTY_NAME) + { + return JSUtil::toJSValueRef(context, webapiErrObj->getName()); + } + else if (propertyNameStr == PROPERTY_TYPE) + { + return JSUtil::toJSValueRef(context, webapiErrObj->getName()); + } + else if (propertyNameStr == PROPERTY_MESSAGE) + { + return JSUtil::toJSValueRef(context, webapiErrObj->getMessage()); + } + } + catch(const BasePlatformException & err) + { + LoggerE("Exception: " << err.getMessage()); + } + + return JSValueMakeUndefined(context); +} + +JSValueRef JSWebAPIException::getStaticProperty(JSContextRef context, + JSObjectRef object, + JSStringRef propertyName, + JSValueRef* /*exception*/) +{ + try + { + std::string propertyNameStr = JSUtil::JSStringToString(context, propertyName); + + DeviceAPIErrorCodeMap::iterator iter = errorCodes.find(propertyNameStr); + if(iter != errorCodes.end()) + return JSUtil::toJSValueRef(context, static_cast<long>(iter->second)); + } + catch(const BasePlatformException & err) + { + LoggerE("Exception: " << err.getMessage()); + } + + return JSValueMakeUndefined(context); +} + +JSValueRef JSWebAPIException::toString(JSContextRef context, + JSObjectRef object, + JSObjectRef thisObject, + size_t argumentCount, + const JSValueRef arguments[], + JSValueRef* exception) +{ + WebAPIError* webapiErrObj = getPriv(context, thisObject); + if(!webapiErrObj) + { + LoggerE("Private object is not set."); + return NULL; + } + + std::string name = webapiErrObj->getName(); + std::string message = webapiErrObj->getMessage(); + + std::string result = name + ": " + message; + + return JSUtil::toJSValueRef(context, result); +} + +} // Common +} // DeviceAPI diff --git a/wearable_src/Common/JSWebAPIException.h b/wearable_src/Common/JSWebAPIException.h new file mode 100644 index 0000000..cc726e5 --- /dev/null +++ b/wearable_src/Common/JSWebAPIException.h @@ -0,0 +1,88 @@ +// +// Tizen Web Device API +// Copyright (c) 2012 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. +// + +#ifndef _JS_WEBAPI_EXCEPTION_H_ +#define _JS_WEBAPI_EXCEPTION_H_ + +#include <JavaScriptCore/JavaScript.h> +#include "JSWebAPIErrorFactory.h" + +#include "WebAPIError.h" + +namespace DeviceAPI { +namespace Common { + +class JSWebAPIErrorFactory; + +class JSWebAPIException +{ +public: + static JSClassRef getClassRef(); + + static const JSClassDefinition* getClassInfo(); + + static bool isObjectOfClass(JSContextRef context, JSValueRef value); + + static JSObjectRef constructor(JSContextRef context, + JSObjectRef constructor, + size_t argumentCount, + const JSValueRef arguments[], + JSValueRef* exception); + + static void initializeConstructor(JSContextRef context, JSObjectRef constructor); + +private: + static JSObjectRef createJSObject(JSContextRef context, WebAPIError* webapiError); + + static WebAPIError* getPriv(JSContextRef context, JSObjectRef object); + + static void initialize(JSContextRef context, JSObjectRef object); + + static void finalize(JSObjectRef object); + + static JSValueRef getProperty(JSContextRef context, + JSObjectRef object, + JSStringRef propertyName, + JSValueRef* exception); + + static JSValueRef getStaticProperty(JSContextRef context, + JSObjectRef object, + JSStringRef propertyName, + JSValueRef* exception); + + static JSValueRef toString(JSContextRef context, + JSObjectRef object, + JSObjectRef thisObject, + size_t argumentCount, + const JSValueRef arguments[], + JSValueRef* exception); + + static JSClassDefinition m_classInfo; + + static JSStaticValue m_properties[]; + + static JSClassRef m_classRef; + + static JSStaticFunction m_function[]; + + friend class JSWebAPIErrorFactory; +}; + +} // Common +} // DeviceAPI + +#endif // _JS_WEBAPI_EXCEPTION_H_ diff --git a/wearable_src/Common/Logger.h b/wearable_src/Common/Logger.h new file mode 100644 index 0000000..5b3aba5 --- /dev/null +++ b/wearable_src/Common/Logger.h @@ -0,0 +1,63 @@ +// +// 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. +// + +#ifndef __TIZEN_COMMON_LOGGER_H__ +#define __TIZEN_COMMON_LOGGER_H__ + +#include <dlog.h> +#include <sstream> + +#undef LOG_TAG +#define LOG_TAG "WRT_PLUGINS/TIZEN" + +#define _LOGGER(prio, fmt, args...) \ + do { \ + std::ostringstream platformLog; \ + platformLog << "%s: %s(%d) > "; \ + platformLog << fmt; \ + print_log(prio, LOG_TAG, platformLog.str().c_str(), __MODULE__, __func__, __LINE__, ##args); \ + } while(0) + +#ifdef TIZEN_ENGINEER_MODE + #define LoggerD(fmt, args...) _LOGGER(DLOG_DEBUG, fmt, ##args) +#else + #define LoggerD(fmt, args...) do { } while(0) +#endif + +#define LoggerI(fmt, args...) _LOGGER(DLOG_INFO, fmt, ##args) +#define LoggerW(fmt, args...) _LOGGER(DLOG_WARN, fmt, ##args) +#define LoggerE(fmt, args...) _LOGGER(DLOG_ERROR, fmt, ##args) + + +#ifdef TIZEN_ENGINEER_MODE +#define _SLOGGER(prio, fmt, args...) \ + do { \ + std::ostringstream platformLog; \ + platformLog << "%s: %s(%d) > [SECURE_LOG] "; \ + platformLog << fmt; \ + print_log(prio, LOG_TAG, platformLog.str().c_str(), __MODULE__, __func__, __LINE__, ##args); \ + } while(0) +#else +#define _SLOGGER(prio,fmt,args...) do { } while(0) +#endif + +#define SLoggerD(fmt, args...) _SLOGGER(DLOG_DEBUG, fmt, ##args) +#define SLoggerI(fmt, args...) _SLOGGER(DLOG_INFO, fmt, ##args) +#define SLoggerW(fmt, args...) _SLOGGER(DLOG_WARN, fmt, ##args) +#define SLoggerE(fmt, args...) _SLOGGER(DLOG_ERROR, fmt, ##args) + +#endif // __TIZEN_COMMON_LOGGER_H__ diff --git a/wearable_src/Common/MultiCallbackUserData.cpp b/wearable_src/Common/MultiCallbackUserData.cpp new file mode 100755 index 0000000..449a61a --- /dev/null +++ b/wearable_src/Common/MultiCallbackUserData.cpp @@ -0,0 +1,151 @@ +// +// 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 "MultiCallbackUserData.h" +#include "GlobalContextManager.h" +#include "PlatformException.h" +#include "JSUtil.h" +#include "Logger.h" + +using namespace std; + +namespace DeviceAPI { +namespace Common { + +MultiCallbackUserData::MultiCallbackUserData(JSContextRef globalCtx): mContext(globalCtx), mObject(NULL){ +} + +MultiCallbackUserData::MultiCallbackUserData(JSContextRef globalCtx, JSObjectRef object): mContext(globalCtx), mObject(object){ + if( mObject ) + JSValueProtect(mContext, mObject); +} + +MultiCallbackUserData::~MultiCallbackUserData(){ + if( !GlobalContextManager::getInstance()->isAliveGlobalContext(mContext)){ + //Remove Callback functions in Native Map + CallbackMapT::iterator itr; + for( itr = mCallbacks.begin() ; itr != mCallbacks.end() ; ++itr){ + JSObjectRef t = itr->second; + if( t != NULL ) + JSValueUnprotect(mContext, t); + } + + //Remove Callback Object + if( mObject ){ + JSValueUnprotect(mContext, mObject); + mObject = NULL; + } + } +} + +void MultiCallbackUserData::setCallback(const string &key, JSObjectRef callback){ + + // Callback Object Case + if( mObject ){ + JSUtil::setProperty(mContext, mObject, key.c_str(), callback, kJSPropertyAttributeNone); + return; + } + + // Callback function Case + CallbackMapT::iterator itr; + itr = mCallbacks.find(key); + if( itr != mCallbacks.end() && itr->second != NULL){ + JSValueUnprotect(mContext, itr->second); + } + + if( callback != NULL ){ + JSValueProtect(mContext, callback); + } + + mCallbacks[key] = callback; +} + + +void MultiCallbackUserData::invokeCallback(const std::string &key, int count, JSValueRef obj [ ]){ + if( !GlobalContextManager::getInstance()->isAliveGlobalContext(mContext)){ + LOGE("context was closed"); + return; + } + + // Callback Object case + if( mObject ){ + try{ + // Getting callback value + JSValueRef callbackValue = JSUtil::getProperty(mContext, mObject, key.c_str()); + + // Testing existing + if( JSValueIsUndefined(mContext, callbackValue) ){ + LOGE("There is no such callback[%s]", key.c_str()); + return; + } + + JSObjectRef callbackObject = JSUtil::JSValueToObject(mContext, callbackValue); + + // Testing type validation + if( !JSObjectIsFunction( mContext, callbackObject) ){ + LOGE("%s is not function", key.c_str()); + return; + } + + JSValueRef exception = NULL; + JSObjectCallAsFunction(mContext, callbackObject, NULL, count, obj, &exception); + + // check Exception in function call + if( exception != NULL ){ + throw UnknownException(mContext, exception); + } + }catch( const BasePlatformException& err){ + LOGE("Error in Callback invoke - %s:%s", err.getName().c_str(), err.getMessage().c_str()); + } + return; + } + + // Callback function case + CallbackMapT::iterator itr; + itr = mCallbacks.find(key); + if( itr == mCallbacks.end()){ + LOGE("There is no such callback[%s]", key.c_str()); + return; + } + + if( itr->second ){ + JSObjectCallAsFunction(mContext, itr->second , NULL, count, obj, NULL); + }else{ + LOGE("The callback[%s] is NULL", key.c_str()); + } +} + +void MultiCallbackUserData::invokeCallback(const std::string &key, JSValueRef obj){ + JSValueRef args[1] = {obj}; + invokeCallback(key, 1, args); +} + +void MultiCallbackUserData::invokeCallback(const std::string &key){ + invokeCallback(key, 0, NULL); +} + +JSContextRef MultiCallbackUserData::getContext(){ + return mContext; +} + +void MultiCallbackUserData::cleanContext(){ + mContext = NULL; +} + +} +} + diff --git a/wearable_src/Common/MultiCallbackUserData.h b/wearable_src/Common/MultiCallbackUserData.h new file mode 100755 index 0000000..29ba5b0 --- /dev/null +++ b/wearable_src/Common/MultiCallbackUserData.h @@ -0,0 +1,58 @@ +// +// 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. +// + +#ifndef _TIZEN_COMMON_MULTICALLBACKUSERDATA_ +#define _TIZEN_COMMON_MULTICALLBACKUSERDATA_ + +#include <JavaScriptCore/JavaScript.h> +#include <string> +#include <map> +#include <boost/shared_ptr.hpp> + +namespace DeviceAPI { +namespace Common{ + +class MultiCallbackUserData{ + public: + MultiCallbackUserData(JSContextRef globalCtx); + MultiCallbackUserData(JSContextRef globalCtx, JSObjectRef object); + virtual ~MultiCallbackUserData(); + JSContextRef getContext(); + void setCallback(const std::string &key, JSObjectRef callback); + + void invokeCallback(const std::string &key); + void invokeCallback(const std::string &key, JSValueRef obj); + void invokeCallback(const std::string &key, int count, JSValueRef obj[]); + + void cleanContext(); + + private: + JSContextRef mContext; + JSObjectRef mObject; + typedef std::map<const std::string, JSObjectRef> CallbackMapT; + std::map<const std::string, JSObjectRef> mCallbacks; +}; + +typedef boost::shared_ptr<MultiCallbackUserData> MultiCallbackUserDataPtr; + + +} +} + +#endif //_TIZEN_COMMON_MULTICALLBACKUSERDATA_ + + diff --git a/wearable_src/Common/PlatformException.cpp b/wearable_src/Common/PlatformException.cpp new file mode 100644 index 0000000..168664d --- /dev/null +++ b/wearable_src/Common/PlatformException.cpp @@ -0,0 +1,130 @@ +// +// 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 "PlatformException.h" +#include "JSUtil.h" +#include "JSWebAPIErrorFactory.h" +#include <CommonsJavaScript/Converter.h> + +using namespace WrtDeviceApis::CommonsJavaScript; +using namespace WrtDeviceApis::Commons; + + + +namespace DeviceAPI { +namespace Common{ + +BasePlatformException::BasePlatformException(const char* name, const char* message):mName(name),mMessage(message){ +} + +BasePlatformException::BasePlatformException(JSContextRef context, JSValueRef value){ + JSObjectRef object = JSValueToObject(context, value, NULL); + if( object == NULL ) + return; + + JSValueRef message = JSUtil::getProperty(context, object, "message"); + JSValueRef name = JSUtil::getProperty(context, object, "name"); + + try{ + Converter convert(context); + if( !JSValueIsUndefined(context, message )) + mMessage = convert.toString(message); + if( !JSValueIsUndefined(context, name )) + mName = convert.toString(name); + }catch( const ConversionException& err){ + } +} + +BasePlatformException::~BasePlatformException() { +} + +std::string BasePlatformException::getName() const{ + return mName; +} + +std::string BasePlatformException::getMessage() const{ + return mMessage; +} + + +TypeMismatchException::TypeMismatchException(const char* message):BasePlatformException("TypeMismatchError", message){ +} +TypeMismatchException::TypeMismatchException(JSContextRef ctx, JSValueRef exception):BasePlatformException(ctx,exception){ + mName = "TypeMismatchError"; +} + +InvalidValuesException::InvalidValuesException(const char* message):BasePlatformException("InvalidValuesError", message){ +} +InvalidValuesException::InvalidValuesException(JSContextRef ctx, JSValueRef exception):BasePlatformException(ctx,exception){ + mName = "InvalidValuesError"; +} + +IOException::IOException(const char* message):BasePlatformException("IOError", message){ +} +IOException::IOException(JSContextRef ctx, JSValueRef exception):BasePlatformException(ctx,exception){ + mName = "IOError"; +} + + +UnknownException::UnknownException(const char* message):BasePlatformException("UnknownError", message){ +} +UnknownException::UnknownException(JSContextRef ctx, JSValueRef exception):BasePlatformException(ctx,exception){ + mName = "UnknownError"; +} + +ServiceNotAvailableException::ServiceNotAvailableException(const char* message):BasePlatformException("ServiceNotAvailableError", message){ +} +ServiceNotAvailableException::ServiceNotAvailableException(JSContextRef ctx, JSValueRef exception):BasePlatformException(ctx,exception){ + mName = "ServiceNotAvailableError"; +} + +SecurityException::SecurityException(const char* message):BasePlatformException("SecurityError", message){ +} +SecurityException::SecurityException(JSContextRef ctx, JSValueRef exception):BasePlatformException(ctx,exception){ + mName = "SecurityError"; +} + +NotSupportedException::NotSupportedException(const char* message):BasePlatformException("NotSupportedError", message){ +} +NotSupportedException::NotSupportedException(JSContextRef ctx, JSValueRef exception):BasePlatformException(ctx,exception){ + mName = "NotSupportedError"; +} + +NotFoundException::NotFoundException(const char* message):BasePlatformException("NotFoundError", message){ +} +NotFoundException::NotFoundException(JSContextRef ctx, JSValueRef exception):BasePlatformException(ctx,exception){ + mName = "NotFoundError"; +} + +InvalidAccessException::InvalidAccessException(const char* message):BasePlatformException("InvalidAccessError", message){ +} +InvalidAccessException::InvalidAccessException(JSContextRef ctx, JSValueRef exception):BasePlatformException(ctx,exception){ + mName = "InvalidAccessError"; +} + +QuotaExceededException::QuotaExceededException(const char* message):BasePlatformException("QuotaExceededError", message){ +} +QuotaExceededException::QuotaExceededException(JSContextRef ctx, JSValueRef exception):BasePlatformException(ctx,exception){ + mName = "QuotaExceededError"; +} + + + + +} +} diff --git a/wearable_src/Common/PlatformException.h b/wearable_src/Common/PlatformException.h new file mode 100644 index 0000000..cc73da9 --- /dev/null +++ b/wearable_src/Common/PlatformException.h @@ -0,0 +1,113 @@ +// +// 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. +// + + +#ifndef _PLATFORM_EXCEPTION_H_ +#define _PLATFORM_EXCEPTION_H_ + +#include <string> +#include <JavaScriptCore/JavaScript.h> + + +namespace DeviceAPI { +namespace Common{ + +class BasePlatformException{ +public: + BasePlatformException(const char* name, const char* message); + BasePlatformException(JSContextRef ctx, JSValueRef exception); + virtual ~BasePlatformException(); + + virtual std::string getName() const; + virtual std::string getMessage() const; + +protected: + std::string mName; + std::string mMessage; +}; + +class TypeMismatchException : public BasePlatformException{ +public: + TypeMismatchException(const char* message); + TypeMismatchException(JSContextRef ctx, JSValueRef exception); +}; + + +class InvalidValuesException : public BasePlatformException{ +public: + InvalidValuesException(const char* message); + InvalidValuesException(JSContextRef ctx, JSValueRef exception); +}; + + +class IOException : public BasePlatformException{ +public: + IOException(const char* message); + IOException(JSContextRef ctx, JSValueRef exception); +}; + + +class UnknownException : public BasePlatformException{ +public: + UnknownException(const char* message); + UnknownException(JSContextRef ctx, JSValueRef exception); +}; + +class ServiceNotAvailableException : public BasePlatformException{ +public: + ServiceNotAvailableException(const char* message); + ServiceNotAvailableException(JSContextRef ctx, JSValueRef exception); +}; + +class SecurityException : public BasePlatformException{ +public: + SecurityException(const char* message); + SecurityException(JSContextRef ctx, JSValueRef exception); +}; + +class NotSupportedException : public BasePlatformException{ +public: + NotSupportedException(const char* message); + NotSupportedException(JSContextRef ctx, JSValueRef exception); +}; + +class NotFoundException : public BasePlatformException{ +public: + NotFoundException(const char* message); + NotFoundException(JSContextRef ctx, JSValueRef exception); +}; + +class InvalidAccessException : public BasePlatformException{ +public: + InvalidAccessException(const char* message); + InvalidAccessException(JSContextRef ctx, JSValueRef exception); +}; + +class QuotaExceededException : public BasePlatformException{ +public: + QuotaExceededException(const char* message); + QuotaExceededException(JSContextRef ctx, JSValueRef exception); +}; + + + + +}} + + +#endif //_PLATFORM_EXCEPTION_H_ + diff --git a/wearable_src/Common/PropertyBag.cpp b/wearable_src/Common/PropertyBag.cpp new file mode 100755 index 0000000..2572745 --- /dev/null +++ b/wearable_src/Common/PropertyBag.cpp @@ -0,0 +1,261 @@ +// +// 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 "PropertyBag.h" +#include "Logger.h" +#include "JSUtil.h" +#include "GlobalContextManager.h" +#include "PlatformException.h" +#include <cmath> + +using namespace std; + +namespace DeviceAPI { +namespace Common { + +PropertyBag::PropertyBag(){ +} + +PropertyBag::~PropertyBag(){ + contextMapT::iterator contextItr; + for( contextItr = mContextMap.begin() ; contextItr != mContextMap.end() ; ++contextItr){ + propertyBagT::iterator propertyItr; + propertyBagT * bag = contextItr->second; + for( propertyItr = bag->begin(); propertyItr != bag->end(); ++propertyItr){ + JSValueRef v = propertyItr->second; + if( v != NULL ) + JSValueUnprotect(contextItr->first, v); + } + delete bag; + } +} + +std::map<const std::string, JSValueRef> * PropertyBag::getBag(JSContextRef globalCtx){ + //find property bag for the context + contextMapT::iterator itr; + itr = mContextMap.find(globalCtx); + propertyBagT *bag = NULL; + + if( itr == mContextMap.end() ){ + bag = new propertyBagT(); + mContextMap[globalCtx] = bag; + }else{ + bag = mContextMap[globalCtx]; + } + return bag; +} + +void PropertyBag::removeItem(JSContextRef globalCtx, propertyBagT *bag, const std::string& propertyName){ + if( bag == NULL ) + return; + propertyBagT::iterator item = bag->find(propertyName); + if( item != bag->end() && item->second != NULL){ + JSValueUnprotect(globalCtx, item->second); + bag->erase(item); + } +} + +void PropertyBag::deleteProperty(JSContextRef ctx, const std::string& propertyName){ + JSContextRef globalCtx = GlobalContextManager::getInstance()->getGlobalContext(ctx); + if( globalCtx == NULL ){ + LOGE("Cannot found global context!"); + return; + } + propertyBagT *bag = getBag(globalCtx); + removeItem(globalCtx, bag, propertyName); +} +void PropertyBag::deleteProperty(JSContextRef ctx, JSStringRef propertyName){ + deleteProperty(ctx, JSUtil::JSStringToString(ctx, propertyName)); +} + + +bool PropertyBag::setProperty(JSContextRef ctx, const std::string& propertyName, JSValueRef value){ + JSContextRef globalCtx = GlobalContextManager::getInstance()->getGlobalContext(ctx); + if( globalCtx == NULL ){ + LOGE("Cannot found global context!"); + return false; + } + propertyBagT *bag = getBag(globalCtx); + if( bag == NULL) + return false; + removeItem(globalCtx, bag, propertyName); + if( value != NULL ) + JSValueProtect(globalCtx, value); + (*bag)[propertyName] = value; + return true; +} + +bool PropertyBag::setProperty(JSContextRef ctx, const std::string& propertyName, double number){ + JSValueRef value = JSUtil::toJSValueRef(ctx, number); + return setProperty(ctx, propertyName, value); +} + +bool PropertyBag::setProperty(JSContextRef ctx, const std::string& propertyName, std::string& str){ + JSValueRef value = JSUtil::toJSValueRef(ctx, str); + return setProperty(ctx, propertyName, value); +} + +bool PropertyBag::setProperty(JSContextRef ctx, const std::string& propertyName, const char *str){ + string strvalue = string(str); + JSValueRef value = JSUtil::toJSValueRef(ctx, strvalue); + return setProperty(ctx, propertyName, value); +} + +bool PropertyBag::setProperty(JSContextRef ctx, const std::string& propertyName, bool boolean){ + JSValueRef value = JSUtil::toJSValueRef(ctx, boolean); + return setProperty(ctx, propertyName, value); +} + + +bool PropertyBag::setProperty(JSContextRef ctx, const std::string& propertyName, JSValueRef value, JSClassRef classRef){ + if( !JSValueIsObjectOfClass( ctx, value, classRef) ){ + LOGE("The value is incorrect type"); + return true; //ignore set property + } + return setProperty(ctx, propertyName, value); +} + + +bool PropertyBag::setFunctionProperty(JSContextRef ctx, const std::string& propertyName, JSValueRef function){ + JSObjectRef obj = JSUtil::JSValueToObject(ctx, function); + if( !JSObjectIsFunction( ctx, obj) ){ + LOGE("The value is incorrect type"); + return true; //ignore set property + } + return setProperty(ctx, propertyName, function); +} + +bool PropertyBag::setArrayProperty(JSContextRef ctx, const std::string& propertyName, JSValueRef array){ + if( !JSIsArrayValue(ctx, array)){ + LOGE("The value is not Array type"); + return true; //ignore set property + } + return setProperty(ctx, propertyName, array); +} + + +bool PropertyBag::setProperty(JSContextRef ctx, JSStringRef propertyName, JSValueRef value){ + return setProperty(ctx, JSUtil::JSStringToString(ctx, propertyName), value); +} +bool PropertyBag::setProperty(JSContextRef ctx, JSStringRef propertyName, double number){ + return setProperty(ctx, JSUtil::JSStringToString(ctx, propertyName), number); +} +bool PropertyBag::setProperty(JSContextRef ctx, JSStringRef propertyName, std::string& str){ + return setProperty(ctx, JSUtil::JSStringToString(ctx, propertyName), str); +} +bool PropertyBag::setProperty(JSContextRef ctx, JSStringRef propertyName, const char * str){ + return setProperty(ctx, JSUtil::JSStringToString(ctx, propertyName), str); +} +bool PropertyBag::setProperty(JSContextRef ctx, JSStringRef propertyName, bool boolean){ + return setProperty(ctx, JSUtil::JSStringToString(ctx, propertyName), boolean); +} +bool PropertyBag::setProperty(JSContextRef ctx, JSStringRef propertyName, JSValueRef value, JSClassRef classRef){ + return setProperty(ctx, JSUtil::JSStringToString(ctx, propertyName),value, classRef); +} +bool PropertyBag::setFunctionProperty(JSContextRef ctx, JSStringRef propertyName, JSValueRef function){ + return setFunctionProperty(ctx, JSUtil::JSStringToString(ctx, propertyName),function); +} +bool PropertyBag::setArrayProperty(JSContextRef ctx, JSStringRef propertyName, JSValueRef array){ + return setArrayProperty(ctx, JSUtil::JSStringToString(ctx, propertyName),array); +} + + + +JSValueRef PropertyBag::getProperty(JSContextRef ctx, const std::string& propertyName){ + JSContextRef globalCtx = GlobalContextManager::getInstance()->getGlobalContext(ctx); + if( globalCtx == NULL ){ + LOGE("Cannot found global context!"); + return NULL; + } + + propertyBagT *bag = getBag(globalCtx); + if( bag == NULL) + return NULL; + + propertyBagT::iterator item = bag->find(propertyName); + if( item == bag->end()){ + LOGE("Cannot found item"); + return NULL; + } + return item->second; +} + +double PropertyBag::getNumberProperty(JSContextRef ctx, const std::string& propertyName){ + JSValueRef value = getProperty(ctx, propertyName); + if( value == NULL ) + return 0.0; + try{ + return JSUtil::JSValueToDouble(ctx, value); + }catch(const BasePlatformException& err){ + LOGE("Cannot convert to number"); + } + return std::nan("not number"); +} + +double PropertyBag::getDoubleProperty(JSContextRef ctx, const std::string& propertyName){ + JSValueRef value = getProperty(ctx, propertyName); + if( value == NULL ) + return 0; + return JSUtil::JSValueToDouble(ctx, value); +} + +bool PropertyBag::getBooleanProperty(JSContextRef ctx, const std::string& propertyName){ + JSValueRef value = getProperty(ctx, propertyName); + if( value == NULL ) + return false; + return JSUtil::JSValueToBoolean(ctx, value); +} + +std::string PropertyBag::getStringProperty(JSContextRef ctx, const std::string& propertyName){ + JSValueRef value = getProperty(ctx, propertyName); + if( value == NULL ) + return "undefined"; + return JSUtil::JSValueToString(ctx, value); +} + +JSObjectRef PropertyBag::getObjectProperty(JSContextRef ctx, const std::string& propertyName){ + JSValueRef value = getProperty(ctx, propertyName); + if( value == NULL ) + return NULL; + if( !JSValueIsObject(ctx, value) ) + return NULL; + return JSUtil::JSValueToObject(ctx, value); +} + +double PropertyBag::getNumberProperty(JSContextRef ctx, JSStringRef propertyName){ + return getNumberProperty(ctx, JSUtil::JSStringToString(ctx, propertyName)); +} +double PropertyBag::getDoubleProperty(JSContextRef ctx, JSStringRef propertyName){ + return getDoubleProperty(ctx, JSUtil::JSStringToString(ctx, propertyName)); +} +bool PropertyBag::getBooleanProperty(JSContextRef ctx, JSStringRef propertyName){ + return getBooleanProperty(ctx, JSUtil::JSStringToString(ctx, propertyName)); +} +std::string PropertyBag::getStringProperty(JSContextRef ctx, JSStringRef propertyName){ + return getStringProperty(ctx, JSUtil::JSStringToString(ctx, propertyName)); +} +JSObjectRef PropertyBag::getObjectProperty(JSContextRef ctx, JSStringRef propertyName){ + return getObjectProperty(ctx, JSUtil::JSStringToString(ctx, propertyName)); +} +JSValueRef PropertyBag::getProperty(JSContextRef ctx, JSStringRef propertyName){ + return getProperty(ctx, JSUtil::JSStringToString(ctx,propertyName)); +} + + + +} //Common +} //DeviceAPI diff --git a/wearable_src/Common/PropertyBag.h b/wearable_src/Common/PropertyBag.h new file mode 100755 index 0000000..71709da --- /dev/null +++ b/wearable_src/Common/PropertyBag.h @@ -0,0 +1,94 @@ +// +// 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. +// + +#ifndef __TIZEN_COMMON_PROPERTY_BAG_H__ +#define __TIZEN_COMMON_PROPERTY_BAG_H__ + +#include <JavaScriptCore/JavaScript.h> +#include <string> +#include <map> + +namespace DeviceAPI { +namespace Common{ + +class PropertyBag{ +public: + PropertyBag(); + virtual ~PropertyBag(); + + void deleteProperty(JSContextRef ctx, const std::string& propertyName); + void deleteProperty(JSContextRef ctx, JSStringRef propertyName); + + + bool setProperty(JSContextRef ctx, const std::string& propertyName, JSValueRef value); + bool setProperty(JSContextRef ctx, JSStringRef propertyName, JSValueRef value); + + bool setProperty(JSContextRef ctx, const std::string& propertyName, double number); + bool setProperty(JSContextRef ctx, JSStringRef propertyName, double number); + + bool setProperty(JSContextRef ctx, const std::string& propertyName, std::string& str); + bool setProperty(JSContextRef ctx, JSStringRef propertyName, std::string& str); + + bool setProperty(JSContextRef ctx, const std::string& propertyName, const char *str); + bool setProperty(JSContextRef ctx, JSStringRef propertyName, const char * str); + + bool setProperty(JSContextRef ctx, const std::string& propertyName, bool boolean); + bool setProperty(JSContextRef ctx, JSStringRef propertyName, bool boolean); + + bool setProperty(JSContextRef ctx, const std::string& propertyName, JSValueRef value, JSClassRef classRef); + bool setProperty(JSContextRef ctx, JSStringRef propertyName, JSValueRef value, JSClassRef classRef); + + bool setFunctionProperty(JSContextRef ctx, const std::string& propertyName, JSValueRef function); + bool setFunctionProperty(JSContextRef ctx, JSStringRef propertyName, JSValueRef function); + + bool setArrayProperty(JSContextRef ctx, const std::string& propertyName, JSValueRef array); + bool setArrayProperty(JSContextRef ctx, JSStringRef propertyName, JSValueRef array); + + JSValueRef getProperty(JSContextRef ctx, const std::string& propertyName); + JSValueRef getProperty(JSContextRef ctx, JSStringRef propertyName); + + double getNumberProperty(JSContextRef ctx, const std::string& propertyName); + double getNumberProperty(JSContextRef ctx, JSStringRef propertyName); + + double getDoubleProperty(JSContextRef ctx, const std::string& propertyName); + double getDoubleProperty(JSContextRef ctx, JSStringRef propertyName); + + bool getBooleanProperty(JSContextRef ctx, const std::string& propertyName); + bool getBooleanProperty(JSContextRef ctx, JSStringRef propertyName); + + std::string getStringProperty(JSContextRef ctx, const std::string& propertyName); + std::string getStringProperty(JSContextRef ctx, JSStringRef propertyName); + + JSObjectRef getObjectProperty(JSContextRef ctx, const std::string& propertyName); + JSObjectRef getObjectProperty(JSContextRef ctx, JSStringRef propertyName); + +private: + typedef std::map<const std::string, JSValueRef> propertyBagT; + typedef std::map<JSContextRef, propertyBagT*> contextMapT; + std::map<JSContextRef, propertyBagT*> mContextMap; + + std::map<const std::string, JSValueRef> * getBag(JSContextRef globalCtx); + void removeItem(JSContextRef globalCtx, propertyBagT *bag, const std::string& propertyName); + +}; + + +} //Common +} //DeviceAPI + + +#endif //__TIZEN_COMMON_PROPERTY_BAG_H__ diff --git a/wearable_src/Common/SecurityExceptions.h b/wearable_src/Common/SecurityExceptions.h new file mode 100644 index 0000000..7ce0402 --- /dev/null +++ b/wearable_src/Common/SecurityExceptions.h @@ -0,0 +1,78 @@ +// +// Tizen Web Device API +// Copyright (c) 2012 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. +// + +#ifndef TIZENAPIS_COMMONS_JS_SECURITYEXCEPTIONS_H_ +#define TIZENAPIS_COMMONS_JS_SECURITYEXCEPTIONS_H_ + +#include <JavaScriptCore/JavaScript.h> +#include "JSWebAPIErrorFactory.h" + +namespace DeviceAPI { +namespace Common { + +/** + * synchronously checks access status and throws JS Security exception if + * necessary + */ + #define TIZEN_SYNC_ACCESS_HANDLER(status, context, exception) \ + do { \ + switch (status) { \ + case AceSecurityStatus::InternalError: \ + return JSWebAPIErrorFactory::postException(context, exception, \ + JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error"); \ + break; \ + case AceSecurityStatus::PrivacyDenied: \ + return JSWebAPIErrorFactory::postException(context, exception, \ + JSWebAPIErrorFactory::SECURITY_ERROR, "The user blocks an application from calling this method."); \ + break; \ + case AceSecurityStatus::AccessDenied: \ + return JSWebAPIErrorFactory::postException(context, exception, \ + JSWebAPIErrorFactory::SECURITY_ERROR, "The application does not have the privilege to call this method."); \ + break; \ + default: \ + break; \ + } \ + } while (0) + +/** + * checks access status and returns an error through JSCallbackManager if + * necessary + */ +#define TIZEN_ASYNC_CBM_ACCESS_HANDLER(status, context, cbm) \ + do { \ + switch (status) { \ + case AceSecurityStatus::InternalError: \ + cbm->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, \ + JSWebAPIErrorFactory::UNKNOWN_ERROR, "Internal error")); \ + return JSValueMakeNull(context); \ + case AceSecurityStatus::PrivacyDenied: \ + cbm->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, \ + JSWebAPIErrorFactory::SECURITY_ERROR, "The user blocks an application from calling this method.")); \ + return JSValueMakeNull(context); \ + case AceSecurityStatus::AccessDenied: \ + cbm->callOnError(JSWebAPIErrorFactory::makeErrorObject(context, \ + JSWebAPIErrorFactory::SECURITY_ERROR, "The application does not have the privilege to call this method.")); \ + return JSValueMakeNull(context); \ + default: \ + break; \ + } \ + } while (0) + +}// Common +}// DeviceAPI +#endif /*TIZENAPIS_COMMONS_JS_SECURITYEXCEPTIONS_H_ */ + diff --git a/wearable_src/Common/Singleton.h b/wearable_src/Common/Singleton.h new file mode 100644 index 0000000..89d65b4 --- /dev/null +++ b/wearable_src/Common/Singleton.h @@ -0,0 +1,50 @@ +// +// Tizen Web Device API +// Copyright (c) 2012 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. +// + +/** + * @file Singleton.h + * @author Kisub Song (kisubs.song@samsung.com) + * @version 0.1 + * @brief + */ + +#include <Export.h> + +#ifndef _TIZEN_COMMONS_SINGLETON_H_ +#define _TIZEN_COMMONS_SINGLETON_H_ + +#define SINGLETON_DEFINITION(CLASSNAME) \ + class DLL_EXPORT CLASSNAME##Singleton : private CLASSNAME { \ + private: \ + CLASSNAME##Singleton() {} \ + static CLASSNAME##Singleton &InternalInstance(); \ + public: \ + virtual ~CLASSNAME##Singleton() {} \ + static CLASSNAME &Instance(); \ + }; + +#define SINGLETON_IMPLEMENTATION(CLASSNAME) \ + CLASSNAME##Singleton& CLASSNAME##Singleton::InternalInstance() { \ + static CLASSNAME##Singleton instance; \ + return instance; \ + } \ + CLASSNAME& CLASSNAME##Singleton::Instance() { \ + CLASSNAME##Singleton& instance = CLASSNAME##Singleton::InternalInstance(); \ + return instance; \ + } + +#endif // _TIZEN_COMMONS_SINGLETON_H_ diff --git a/wearable_src/Common/StandaloneConsole/CMakeLists.txt b/wearable_src/Common/StandaloneConsole/CMakeLists.txt new file mode 100644 index 0000000..a539bb5 --- /dev/null +++ b/wearable_src/Common/StandaloneConsole/CMakeLists.txt @@ -0,0 +1,24 @@ +SET(TARGET "standaloneconsole")
+
+SET(SRCS
+ JSConsole.cpp
+ StandaloneConsole.cpp
+)
+
+INCLUDE_DIRECTORIES( + ${TOP}/Common
+) +
+ +ADD_LIBRARY(${TARGET} SHARED ${SRCS})
+ +TARGET_LINK_LIBRARIES(${TARGET}
+ ${LIBS_COMMON}
+) + +INSTALL(TARGETS ${TARGET} LIBRARY DESTINATION ${DESTINATION_LIB_PREFIX}/${COMMON_DESTINATION_NAME})
+INSTALL( + DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ DESTINATION ${DESTINATION_HEADER_PREFIX}/common + FILES_MATCHING PATTERN "*.h" PATTERN "CMakeFiles" EXCLUDE +) +
diff --git a/wearable_src/Common/StandaloneConsole/JSConsole.cpp b/wearable_src/Common/StandaloneConsole/JSConsole.cpp new file mode 100755 index 0000000..42fe5ad --- /dev/null +++ b/wearable_src/Common/StandaloneConsole/JSConsole.cpp @@ -0,0 +1,134 @@ +// +// 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 "JSConsole.h" +#include <CommonsJavaScript/Converter.h> +#include <stdio.h> +#include <dlog.h> +#include <sys/time.h> +#include <ctime> +#include <sys/time.h> + + +#undef LOG_TAG +#define LOG_TAG "TIZEN_DEVICEAPI" + +using namespace std; +using namespace WrtDeviceApis::CommonsJavaScript; +using namespace WrtDeviceApis::Commons; + + +namespace DeviceAPI { +namespace Test { + +JSClassRef JSConsole::m_jsClassRef = NULL; + +JSClassDefinition JSConsole::m_jsClassInfo = { + 0, // current (and only) version is 0 + kJSClassAttributeNone, //attributes + "console", //class name + NULL, // parent class + NULL, //static values + JSConsole::m_function, // static functions + JSConsole::initialize, // initialize + JSConsole::finalize, //finalize + NULL, //hasProperty + NULL, //getProperty + NULL, //setProperty + NULL, //deleteProperty + NULL, //getPropertyNames + NULL, // callAsConstructor + NULL, // constructor + JSConsole::hasInstance, + NULL // convertToType +}; + + +JSStaticFunction JSConsole::m_function[] = { + { "log", JSConsole::log, kJSPropertyAttributeNone }, + { "debug", JSConsole::log, kJSPropertyAttributeNone }, + { 0, 0, 0 } +}; + +const JSClassRef JSConsole::getClassRef() +{ + if (!m_jsClassRef) { + m_jsClassRef = JSClassCreate(&m_jsClassInfo); + } + return m_jsClassRef; +} + +const JSClassDefinition* JSConsole::getClassInfo() +{ + return &m_jsClassInfo; +} + + +JSObjectRef JSConsole::createJSObject( JSContextRef ctx ){ + return JSObjectMake(ctx, getClassRef(), NULL); +} + + +void JSConsole::initialize(JSContextRef ctx, JSObjectRef object) +{ +} + +void JSConsole::finalize(JSObjectRef object) +{ +} + +bool JSConsole::hasInstance(JSContextRef context, JSObjectRef constructor, JSValueRef possibleInstance, JSValueRef* exception) { + return JSValueIsObjectOfClass(context, possibleInstance, getClassRef()); +} + +#define timersub(a, b, result) \ +do { \ + (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ + (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ + if ((result)->tv_usec < 0) { \ + --(result)->tv_sec; \ + (result)->tv_usec += 1000000; \ + } \ +} while (0) + +JSValueRef JSConsole::log(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){ + static struct timeval prev = {0}; + struct timeval current = {0}; + struct timeval diff = {0}; + gettimeofday(¤t, NULL); + if( prev.tv_sec == 0 && prev.tv_usec == 0) + prev = current; + + timersub(¤t, &prev, &diff); + prev = current; + + Converter convert(ctx); + if( argumentCount == 0 ) + return JSValueMakeUndefined(ctx); + + try{ + string result = convert.toString(arguments[0]); + printf("<log[%d.%06d]>%s\n",(int)diff.tv_sec,(int)diff.tv_usec,result.c_str()); + LOGD("%s", result.c_str()); + }catch(const ConversionException& err){ + } + return JSValueMakeUndefined(ctx); +} + +} // Filesystem +} // TizenApis + diff --git a/wearable_src/Common/StandaloneConsole/JSConsole.h b/wearable_src/Common/StandaloneConsole/JSConsole.h new file mode 100644 index 0000000..5c6d08b --- /dev/null +++ b/wearable_src/Common/StandaloneConsole/JSConsole.h @@ -0,0 +1,53 @@ +// +// 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. +// + +#ifndef _TIZEN_COMMON_JS_CONSOLE_ +#define _TIZEN_COMMON_JS_CONSOLE_ + +#include <JavaScriptCore/JavaScript.h> + +namespace DeviceAPI { +namespace Test{ + +class JSConsole{ +public: + static const JSClassDefinition* getClassInfo(); + static const JSClassRef getClassRef(); + + static JSObjectRef createJSObject(JSContextRef context); + +protected: + static void initialize(JSContextRef context, JSObjectRef object); + static void finalize(JSObjectRef object); + static bool hasInstance(JSContextRef context, JSObjectRef constructor, JSValueRef possibleInstance, JSValueRef* exception); + + static JSValueRef log(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception); + static JSValueRef assert(JSContextRef context, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception); + +private: + static JSClassDefinition m_jsClassInfo; + static JSClassRef m_jsClassRef; + static JSStaticFunction m_function[]; + +}; + +} // Test +} // TizenApis + +#endif //_TIZEN_COMMON_JS_CONSOLE_ + + diff --git a/wearable_src/Common/StandaloneConsole/StandaloneConsole.cpp b/wearable_src/Common/StandaloneConsole/StandaloneConsole.cpp new file mode 100755 index 0000000..3aba307 --- /dev/null +++ b/wearable_src/Common/StandaloneConsole/StandaloneConsole.cpp @@ -0,0 +1,582 @@ +// +// 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 <stdio.h> +#include <dlog.h> +#include <JavaScriptCore/JavaScript.h> +#include "StandaloneConsole.h" +#include "JSConsole.h" +#include <Ecore.h> +#include <GlobalContextManager.h> +#include <string> +#include <vector> +#include <iostream> +#include <termios.h> +#include <JSUtil.h> + +#undef LOG_TAG +#define LOG_TAG "TIZEN_DEVICEAPI" + +using namespace std; +using namespace DeviceAPI::Common; + +namespace DeviceAPI { +namespace Test { + +struct _Command{ + char * mLine; + StandaloneConsole *mConsole; + pthread_mutex_t *mLock; + _Command(const char * cmd, StandaloneConsole *console, pthread_mutex_t* lock){ + mLine = strdup(cmd); + mConsole = console; + mLock = lock; + } + ~_Command(){ + free(mLine); + } + void run(){ + mConsole->RunLine(mLine); + pthread_mutex_unlock(mLock); + } +}; + +struct CallbackData{ + JSObjectRef callback; + int id; + StandaloneConsole *console; +}; + +static Eina_Bool tick(void *data){ + return true; +} + +static Eina_Bool commandDispath(void *data){ + _Command *cmd = (_Command*)data; + cmd->run(); + delete cmd; + return false; +} + +Eina_Bool StandaloneConsole::timerCb(void *data){ + CallbackData *callback = (CallbackData*)data; + StandaloneConsole *console = callback->console; + map<int,int>::iterator itr; + itr = console->mTimerMap.find(callback->id); + if( itr == console->mTimerMap.end() ){ + JSValueUnprotect(console->getGlobalContext(), callback->callback); + delete callback; + return false; + } + if( itr->second == 0){ + console->mTimerMap.erase(itr); + JSValueUnprotect(console->getGlobalContext(), callback->callback); + delete callback; + return false; + } + if( callback->callback != NULL){ + JSObjectCallAsFunction(console->getGlobalContext(), callback->callback, NULL, 0, 0, NULL); + } + + if( itr->second == 2 ){ + console->mTimerMap.erase(itr); + JSValueUnprotect(console->getGlobalContext(), callback->callback); + delete callback; + return false; + } + + return true; +} + + +JSValueRef StandaloneConsole::alert(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){ + if( argumentCount < 1 ) + return JSValueMakeUndefined(ctx); + + + //JSContextRef globalCtx = GlobalContextManager::getInstance()->getGlobalContext(ctx); + //printf(" local : %p, global : %p \n", ctx, globalCtx); + + JSStringRef str = JSValueToStringCopy(ctx, arguments[0], NULL); + if(str == NULL){ + return JSValueMakeUndefined(ctx); + } + int n = JSStringGetLength(str); + { + char cstr[n+1]; + JSStringGetUTF8CString(str, cstr,n+1); + printf("<alert>%s\n", cstr); + } + return JSValueMakeUndefined(ctx); +} + +JSValueRef StandaloneConsole::setInterval(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){ + static int id = 0; + StandaloneConsole *console = static_cast<StandaloneConsole*>(JSObjectGetPrivate(thisObject)); + if( argumentCount < 2 ){ + if( exception != NULL){ + + } + return JSValueMakeUndefined(ctx); + } + int handleid = id++; + double interval = JSValueToNumber(ctx, arguments[1], NULL); + interval = interval/1000; + + console->mTimerMap.insert(pair<int,int>(handleid, 1)); + CallbackData *data = new CallbackData(); + JSValueProtect(console->getGlobalContext(), arguments[0]); + data->callback = JSValueToObject(ctx, arguments[0], NULL); + data->id = handleid; + data->console = console; + + ecore_timer_add( interval, StandaloneConsole::timerCb , data); + return JSValueMakeNumber(ctx, handleid); + +} + +JSValueRef StandaloneConsole::setTimeout(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){ + static int id = 0; + StandaloneConsole *console = static_cast<StandaloneConsole*>(JSObjectGetPrivate(thisObject)); + + if( argumentCount < 2 ){ + if( exception != NULL){ + + } + return JSValueMakeUndefined(ctx); + } + int handleid = id++; + double interval = JSValueToNumber(ctx, arguments[1], NULL); + interval = interval/1000; + + console->mTimerMap.insert(pair<int,int>(handleid, 2)); + CallbackData *data = new CallbackData(); + JSValueProtect(console->getGlobalContext(), arguments[0]); + data->callback = JSValueToObject(ctx, arguments[0], NULL); + data->id = handleid; + data->console = console; + + ecore_timer_add( interval, StandaloneConsole::timerCb , data); + return JSValueMakeNumber(ctx, handleid); + +} + + +JSValueRef StandaloneConsole::clearInterval(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){ + StandaloneConsole *console = static_cast<StandaloneConsole*>(JSObjectGetPrivate(thisObject)); + if(console == NULL) return JSValueMakeUndefined(ctx); + if( argumentCount < 1 ){ + printf("error clearInterval\n"); + if( exception != NULL){ + + } + return JSValueMakeUndefined(ctx); + } + + int handleid = JSValueToNumber(ctx, arguments[0], NULL); + map<int,int>::iterator it; + it = console->mTimerMap.find(handleid); + if( it != console->mTimerMap.end()) + console->mTimerMap[handleid] = 0; + return JSValueMakeUndefined(ctx); +} + + +static JSValueRef test(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){ + return JSValueMakeUndefined(ctx); +} + + +static void setProperty(JSContextRef ctx , JSObjectRef object, const char *name, JSValueRef value, JSPropertyAttributes attributes) +{ + JSStringRef propertyName = JSStringCreateWithUTF8CString(name); + JSObjectSetProperty(ctx, object, propertyName, value,attributes, NULL ); + JSStringRelease(propertyName); +} + +static JSValueRef getProperty(JSContextRef ctx , JSObjectRef object, const char *name){ + JSValueRef value; + JSStringRef propertyName = JSStringCreateWithUTF8CString(name); + value = JSObjectGetProperty(ctx, object, propertyName, NULL); + JSStringRelease(propertyName); + return value; +} + +static char * toString(JSContextRef ctx , JSValueRef jsV){ + JSValueRef exception = NULL; + JSStringRef jsStr = JSValueToStringCopy(ctx, jsV, &exception); + if( exception != NULL ) + return NULL; + int n = JSStringGetMaximumUTF8CStringSize(jsStr); + char *buf = new char[n+1]; + JSStringGetUTF8CString(jsStr, buf, n+1); + JSStringRelease(jsStr); + return buf; +} + +StandaloneConsole::StandaloneConsole():mGlobalContext(NULL),mGlobalObject(NULL){ +} + +StandaloneConsole::~StandaloneConsole(){ +} + +void StandaloneConsole::initialize(){ + // Function table + JSStaticFunction functions[] = { + { "alert", StandaloneConsole::alert , kJSPropertyAttributeNone }, + { "setInterval", StandaloneConsole::setInterval , kJSPropertyAttributeNone }, + { "setTimeout", StandaloneConsole::setTimeout , kJSPropertyAttributeNone }, + { "clearInterval", StandaloneConsole::clearInterval , kJSPropertyAttributeNone }, + { "clearTimeout", StandaloneConsole::clearInterval , kJSPropertyAttributeNone }, + { "test", test, kJSPropertyAttributeNone }, + { 0, 0, 0 } + }; + + // Global class + JSClassDefinition def = { + 0, // current (and only) version is 0 + kJSClassAttributeNone, //attributes + "global", //class name + NULL, // parent class + NULL, //static values + functions, // static functions + NULL, // initialize + NULL, //finalize + NULL, //hasProperty + NULL, //getProperty + NULL, //setProperty + NULL, //deleteProperty + NULL, //getPropertyNames + NULL, // callAsConstructor + NULL, // constructor + NULL, + NULL // convertToType + }; + + JSClassRef globalClass = JSClassCreate(&def); + + mGlobalContext = JSGlobalContextCreate(globalClass); + mGlobalObject = JSContextGetGlobalObject(mGlobalContext); + JSObjectSetPrivate(mGlobalObject, this); + JSObjectRef console = JSConsole::createJSObject(mGlobalContext); + setProperty(mGlobalContext, mGlobalObject, "console", console, kJSPropertyAttributeReadOnly); + + + //is it ecore bug? event was not invoke, it was added in another thread + ecore_timer_add(0.001, tick, NULL); +} + + +JSObjectRef StandaloneConsole::getGlobalObject(){ + return mGlobalObject; +} + +JSContextRef StandaloneConsole::getGlobalContext(){ + return mGlobalContext; +} + + +JSValueRef StandaloneConsole::RunLineEx(const char* line, JSValueRef *exception){ + JSStringRef jsScript = JSStringCreateWithUTF8CString(line); + int size = strlen(line); + if( size != static_cast <int>(JSStringGetLength(jsScript))){ + cout <<"error - fail to converting JSStringRef"<<endl; + } + JSValueRef ret = JSEvaluateScript(mGlobalContext, jsScript, NULL, NULL, 0, exception); + JSStringRelease(jsScript); + return ret; +} + +JSValueRef StandaloneConsole::RunScriptEx(const char* path, JSValueRef *exception){ + + FILE* f = fopen(path, "r"); + if( f == NULL ){ + return NULL; + } + + fseek(f, 0, SEEK_END); + int length = ftell(f); + fseek(f, 0, SEEK_SET); + + if( length > 0 ) + { + char buff[length+1]; + memset(buff, 0, length+1); + int r = fread(buff, 1, length, f); + fclose(f); + + if( r != length ){ + printf("error read\n"); + return JSValueMakeUndefined(mGlobalContext); + } + return RunLineEx(buff, exception); + } + fclose(f); + return JSValueMakeUndefined(mGlobalContext); +} + +void StandaloneConsole::RunLine(const char * line){ + JSValueRef exception = NULL; + JSValueRef v = RunLineEx(line, &exception); + reportingResult(v,exception); +} + +void StandaloneConsole::RunScript(const char * path){ + JSValueRef exception = NULL; + JSValueRef v = RunScriptEx(path, &exception); + reportingResult(v,exception); +} + +void StandaloneConsole::GarbageCollect(){ + printf("GarbageCollect\n"); + JSGarbageCollect(mGlobalContext); +} +void StandaloneConsole::reportingResult(JSValueRef v, JSValueRef exception){ + if( exception != NULL ){ + char *errStr = toString(mGlobalContext, exception); + if( errStr != NULL ){ + printf("< error - %s\n", errStr); + delete[] errStr; + } + JSObjectRef errObj = JSValueToObject(mGlobalContext, exception, NULL); + if( errObj != NULL ){ + JSValueRef stack = getProperty(mGlobalContext, errObj, "stack"); + char *stackStr = NULL; + if( !JSValueIsUndefined(mGlobalContext, stack) && (stackStr = toString(mGlobalContext, stack )) != NULL){ + printf("stack:%s\n", stackStr); + delete[] stackStr; + } + } + }else{ + char *resultStr = toString(mGlobalContext, v); + if( resultStr != NULL ){ + printf("< %s\n", resultStr); + delete[] resultStr; + } + } +} + +JSObjectRef StandaloneConsole::registModule(const char * name, JSClassRef module, void * priv){ + JSObjectRef obj = JSObjectMake(mGlobalContext, module, priv); + setProperty(mGlobalContext, mGlobalObject, name, obj, kJSPropertyAttributeReadOnly); + return obj; +} + +void StandaloneConsole::appendModule(const char * name, JSObjectRef module){ + setProperty(mGlobalContext, mGlobalObject, name, module, kJSPropertyAttributeReadOnly); +} + + +int getch(void) +{ + int ch; + struct termios buf; + struct termios save; + + tcgetattr(0, &save); + buf = save; + buf.c_lflag &= ~(ICANON|ECHO); + buf.c_cc[VMIN] = 1; + buf.c_cc[VTIME] = 0; + tcsetattr(0, TCSAFLUSH, &buf); + ch = getchar(); + tcsetattr(0, TCSAFLUSH, &save); + return ch; +} + +struct termios gSave; + +void onExit(void) +{ + tcsetattr(0, TCSAFLUSH, &gSave); +} + +class LineBuffer{ + vector<string> mHistory; + string mLine; + int mHistoryIndex; + unsigned int mCurrentPos; + unsigned int mCurrentPosTmp; + int mLineLength; +public: + LineBuffer():mHistoryIndex(0), mCurrentPos(0){ + tcgetattr(0, &gSave); + atexit(onExit); + } + ~LineBuffer(){ + tcsetattr(0, TCSAFLUSH, &gSave); + } + + void backSpace( int length ){ + for( int i =0 ; i < length ; i++){ + putchar('\b'); + putchar(' '); + putchar('\b'); + } + } + + void cleanLine(){ + int diff = mLineLength - mCurrentPosTmp; + while( diff-- > 0 ){ + moveCursor(false); + } + backSpace(mLineLength); + } + + void applyHistory( unsigned int index ){ + if( mHistory.size() > index ){ + mLine = mHistory[index]; + mCurrentPos = mLine.size(); + } + } + + void moveCursor( bool Left ){ + putchar(27);putchar(91); + if( Left ) + putchar(68); + else + putchar(67); + } + + void moveCurrentCursorPosition(){ + int diff = mLine.size() - mCurrentPos; + + while( diff-- > 0 ){ + moveCursor(true); + } + } + + bool checkSpecialKeys(int a){ + if( a == 8 ){ + if( mLine.size() != 0 && mCurrentPos != 0){ + mCurrentPos--; + mLine.erase(mCurrentPos,1); + } + return true; + } + if( a == 27 ){ + a = getch(); // 91 + a = getch(); + switch( a ){ + case 65: + //UP + if( mHistoryIndex > 0 ){ + applyHistory(--mHistoryIndex); + } + break; + case 66: + //DOWN + if( (unsigned)mHistoryIndex < mHistory.size() ){ + applyHistory(++mHistoryIndex); + } + break; + case 67: + //RIGHT + if( mCurrentPos < mLine.size()) + mCurrentPos++; + break; + case 68: + //LEFT + if( mCurrentPos > 0 ) + mCurrentPos--; + break; + case 51: + //delete + getch(); + if( mCurrentPos < mLine.size()) + mLine.erase(mCurrentPos,1); + break; + case 52: + //end + getch(); + mCurrentPos = mLine.size(); + break; + case 49: + //home + mCurrentPos = 0; + a = getch(); + break; + default: + a = getch(); + } + + return true; + } + return false; + } + + string Prompt(const char * prompt){ + printf("%s", prompt); + mCurrentPos = 0; + mLine.clear(); + mLineLength = mLine.size(); + mCurrentPosTmp = mCurrentPos; + while(1){ + int a = getch(); + cleanLine(); + if( a == 10 ) + break; + + if(!checkSpecialKeys(a)){ + mLine.insert(mCurrentPos,1, a); + mCurrentPos++; + } + cout << mLine; + moveCurrentCursorPosition(); + mLineLength = mLine.size(); + mCurrentPosTmp = mCurrentPos; + } + cout << mLine; + if( mLine.size() > 0 ){ + mHistory.push_back(mLine); + mHistoryIndex = mHistory.size(); + } + return mLine; + } + +}; + + + +void StandaloneConsole::commandline(StandaloneConsole* console){ + pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_lock(&lock); + printf("command line mode ( \"quit\" for exit )\n"); + LineBuffer linebuff; + while(1){ + string line = linebuff.Prompt(">"); + printf("\n"); + + if( line == "quit" ) + break; + if( line == "gc" ){ + console->GarbageCollect(); + continue; + } + if( line.size() == 0 ) + continue; + _Command *cmd = new _Command(line.c_str(), console, &lock); + // for thread safety + ecore_idler_add(commandDispath, cmd); + pthread_mutex_lock(&lock); + } +} + + +} +} + diff --git a/wearable_src/Common/StandaloneConsole/StandaloneConsole.h b/wearable_src/Common/StandaloneConsole/StandaloneConsole.h new file mode 100644 index 0000000..b125f8e --- /dev/null +++ b/wearable_src/Common/StandaloneConsole/StandaloneConsole.h @@ -0,0 +1,68 @@ +// +// 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. +// + +#ifndef _TIZEN_COMMON_STANDALONECONSOLE_ +#define _TIZEN_COMMON_STANDALONECONSOLE_ + +#include <Ecore.h> +#include <map> +#include <JavaScriptCore/JavaScript.h> + +namespace DeviceAPI { +namespace Test{ + +class StandaloneConsole{ + public : + StandaloneConsole(); + virtual ~StandaloneConsole(); + void initialize(); + JSObjectRef getGlobalObject(); + JSContextRef getGlobalContext(); + + void RunLine(const char *line); + void RunScript(const char * path); + + void GarbageCollect(); + + + JSValueRef RunLineEx( const char *line , JSValueRef *exception); + JSValueRef RunScriptEx( const char *path , JSValueRef *exception); + + JSObjectRef registModule( const char *name, JSClassRef module, void *priv); + void appendModule( const char* name, JSObjectRef module ); + + static JSValueRef alert(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception); + static JSValueRef setInterval(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception); + static JSValueRef clearInterval(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception); + + static JSValueRef setTimeout(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception); + + static void commandline(StandaloneConsole *console); + + private: + static Eina_Bool timerCb(void *data); + void reportingResult(JSValueRef v, JSValueRef exception); + + JSContextRef mGlobalContext; + JSObjectRef mGlobalObject; + std::map<int,int> mTimerMap; +}; + +} +} + +#endif //_TIZEN_COMMON_STANDALONECONSOLE_ diff --git a/wearable_src/Common/TimeTracer/CMakeLists.txt b/wearable_src/Common/TimeTracer/CMakeLists.txt new file mode 100644 index 0000000..3dddade --- /dev/null +++ b/wearable_src/Common/TimeTracer/CMakeLists.txt @@ -0,0 +1,24 @@ +SET(TARGET "timetracer") + +SET(SRCS + TimeTracer.c +) + +INCLUDE_DIRECTORIES( + ${TOP}/Common +) + +ADD_DEFINITIONS("-DTIME_TRACER_UNIT_MSEC") + +ADD_LIBRARY(${TARGET} SHARED ${SRCS}) + +TARGET_LINK_LIBRARIES(${TARGET} + ${LIBS_COMMON} +) + +INSTALL(TARGETS ${TARGET} LIBRARY DESTINATION ${DESTINATION_LIB_PREFIX}/${COMMON_DESTINATION_NAME}) +INSTALL( + DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ DESTINATION ${DESTINATION_HEADER_PREFIX}/common + FILES_MATCHING PATTERN "*.h" PATTERN "CMakeFiles" EXCLUDE +) + diff --git a/wearable_src/Common/TimeTracer/TimeTracer.c b/wearable_src/Common/TimeTracer/TimeTracer.c new file mode 100644 index 0000000..62432d7 --- /dev/null +++ b/wearable_src/Common/TimeTracer/TimeTracer.c @@ -0,0 +1,374 @@ +// +// 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. +// + +#undef LOG_TAG +#define LOG_TAG "TIME_TRACER" + +#include <stdio.h> +#include <dlog.h> +#include <stdio.h> +#include <malloc.h> +#include <string.h> +#include <assert.h> +#include <sys/time.h> +#include <sys/utsname.h> +#include <sys/resource.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> +#include <stdarg.h> +#include <stdlib.h> +#include <time.h> +#include "TimeTracer.h" + +/* +* Global Variables +*/ +#define TIME_TRACER_ITEM_MAX 500 +#define OUTPUT_DIR "/tmp/wrt-plugins-tizen-time-trace-result" + +time_tracer_item ** g_items = NULL; //Time tracer item list +static int g_index = 0; +static int g_max_item_name_length = 0; +static unsigned long g_first_time = 0xFFFFFFFF; + +/* +* Internal Implementation +*/ +static void __time_tracer_item_free(void) +{ + int i = 0; + if (!g_items) + return; + + for(i=0;i<g_index;i++) + { + if(g_items[i]) + { + if (g_items[i]->name) + free(g_items[i]->name); + free(g_items[i]); + g_items[i] = NULL; + } + } + + g_index = 0; + g_max_item_name_length = 0; + g_first_time = 0xFFFFFFFF; + free(g_items); + g_items = NULL; +} + +static int __get_time_tracer_item_index(char* name) +{ + int i; + assert(name); + if(!g_items) + return -1; + + for ( i = 0; i < g_index; i++ ) + { + if(!g_items[i]) + return -1; + if (strcmp(name, g_items[i]->name)==0) + return i; + } + return -1; +} + + +/* +* Implementation +*/ +int time_tracer_init(void) +{ + if (g_items) { + LOGW("[%s] Ignored. Already Initialized.", __FUNCTION__); + return 0; + } + g_items = (time_tracer_item **) malloc(TIME_TRACER_ITEM_MAX * sizeof(time_tracer_item *)); + if(!g_items) + { + LOGE("[%s] Failed to create global tracer item",__FUNCTION__); + return -1; + } + g_first_time = 0xFFFFFFFF; + LOGE("TIME TRACER INITIALIZED"); + return 0; +} + +int time_tracer_release(void) +{ + if (!g_items) + return 0; + LOGE("TIME TRACER DESTROYED"); + __time_tracer_item_free(); + return 0; +} + +int time_tracer_item_begin(const char* name, int show, const char* filename, int line) +{ + time_tracer_item *item = NULL; + int index = 0; + int name_len = 0; + struct timeval t; + + if (!g_items) + return 0; + + if (g_index == TIME_TRACER_ITEM_MAX) + { + LOGE("[%s] Do not exceed tracer item max value (max : %d, index : %d)",__FUNCTION__,TIME_TRACER_ITEM_MAX, g_index); + return -1; + } + + if (!name) + { + LOGE("[%s] Item name is NULL.",__FUNCTION__); + return -1; + } + + name_len = strlen(name); + if(name_len==0) + { + LOGE("[%s] Item name is Empty.",__FUNCTION__); + return -1; + } + + //1. Creates of gets the item + //1-1. Creates new item if 'name' is not exists. + if ((index = __get_time_tracer_item_index(name)) == -1) + { + item = (time_tracer_item *)malloc(sizeof(time_tracer_item)); + if ( !item ) + { + LOGE("[%s] Failed to create tracer item", __FUNCTION__); + return -1; + } + + //Clean-up + memset( item, 0, sizeof (time_tracer_item) ); + item->min_elapsed_time = 0xFFFFFFFF; + + item->name = strdup(name); + if (!item->name) + { + LOGE("[%s] Failed to strdup", __FUNCTION__); + free(item); + return -1; + } + + //Add to the global item array + g_items[g_index] = item; + g_index++; + + if ( g_max_item_name_length < name_len ) + g_max_item_name_length = name_len; + } + else // 1-2. Returns existing item + { + item = g_items[index]; + } + + + // 2. Gets the timestamp + gettimeofday( &t, NULL ); + item->timestamp = t.tv_sec*1000000L + t.tv_usec; +#ifdef TIME_TRACER_UNIT_MSEC + item->timestamp = ( item->timestamp >= 1000) ? item->timestamp/1000 : 0; +#endif + + + if (item->first_timestamp == 0) // in case of first + { + //set first timestamp + item->first_timestamp = item->timestamp; + if (g_first_time > item->first_timestamp) + g_first_time = item->first_timestamp; + } + + // 3. Verify pairs of begin, end + if (item->on_tracing) + { + LOGE("[%s] (Name : %s) is not 'end'ed!",__FUNCTION__, item->name); + item->mismatch_count ++; + return -1; + } + + //set tracing on + item->on_tracing = 1; + + if (show) + { + LOGE("[%s][BEGIN] %s (at %s:%d)", __FUNCTION__,name, filename, line ); + printf("[%s][BEGIN] %s (at %s:%d)\n", LOG_TAG,name, filename, line ); + } + //Add invoke count for given item + item->invoke_count++; + return 0; +} + +int time_tracer_item_end(const char* name, int show, const char* filename, int line) +{ + time_tracer_item * item = NULL; + unsigned int tval = 0; + int index = 0; + struct timeval t; + + if (!g_items) + return 0; + + // 1. Gets current timestamp first for more accuracy. + gettimeofday( &t, NULL ); + + if (g_index == TIME_TRACER_ITEM_MAX) + { + LOGE("[%s] Do not exceed tracer item max value (max : %d, index : %d)",__FUNCTION__,TIME_TRACER_ITEM_MAX, g_index); + return -1; + } + + if (!name) + { + LOGE("[%s] Item name is NULL.",__FUNCTION__); + return -1; + } + + if(strlen(name)==0) + { + LOGE("[%s] Item name is Empty.",__FUNCTION__); + return -1; + } + + //2. Gets the item + if ((index = __get_time_tracer_item_index(name)) == -1) + { + LOGE("[%s] (Name : %s) is not exist.",__FUNCTION__, name); + return -1; + } + item = g_items[index]; + + // 3. Verify pairs of begin, end + if (!item->on_tracing) + { + LOGE("[%s] (Name : %s) is not 'begin' yet",__FUNCTION__, item->name); + item->mismatch_count ++; + return -1; + } + + tval = t.tv_sec*1000000L + t.tv_usec; +#ifdef TIME_TRACER_UNIT_MSEC + tval = (tval>=1000) ? tval/1000 : 0; +#endif + + //set last timestamp as current time + item->last_timestamp = tval; + + //calculates the time gap(elapsed time) between current timestamp and item's timestamp. + tval = tval - item->timestamp; + + //set max_elapsed_time if current elapsed time is larger than item's max elasped time. + item->max_elapsed_time = tval > item->max_elapsed_time ? tval : item->max_elapsed_time; + //set min_elapsed_time if current elapsed time is less than item's min elasped time. + item->min_elapsed_time = tval < item->min_elapsed_time ? tval : item->min_elapsed_time; + + //Accumulates the item's total elapse time + item->total_elapsed_time += tval; + //set tracing off + item->on_tracing = 0; + + if (show) + { + LOGE("[%s][END] %s - total elapsed time(acc): %ld, current elased time : %d (at %s:%d)",__FUNCTION__, name, item->total_elapsed_time, tval, filename, line ); + printf("[%s][END] %s - total elapsed time(acc): %ld, current elased time : %d (at %s:%d)\n",LOG_TAG,name, item->total_elapsed_time, tval, filename, line ); + } + return 0; +} + +void time_tracer_export_report(int direction, char* name) +{ + int i = 0; + char format[256]; + FILE* fp = stderr; + + if (!g_items) + return; + + switch (direction) + { + case TIME_TRACER_EXPORT_STDOUT: + fp = stdout; + break; + case TIME_TRACER_EXPORT_STDERR: + fp = stderr; + break; + case TIME_TRACER_EXPORT_FILE: + if(mkdir(OUTPUT_DIR,0755)!=0) + { + LOGE("[%s] Failed to mkdir()",__FUNCTION__); + } + char f_name[256]; + if(name==NULL || strlen(name)==0) + sprintf(f_name,"%s/%s",OUTPUT_DIR,"default.log"); + else + sprintf(f_name,"%s/%s.%s",OUTPUT_DIR,name,"log"); + fp = fopen(f_name, "wt"); + if (!fp) + { + LOGE("[%s] Failed to fopen().",__FUNCTION__); + return; + } + break; + default: + LOGE("[%s] Invalid output direction.",__FUNCTION__); + return; + } + +#ifdef TIME_TRACER_UNIT_MSEC + sprintf(format, "[%%3d] %%-%ds|\tTotal:%%4ld,\tCnt:%%3ld,\tAvg:%%4ld,\tMin:%%4ld,\tMax:%%4ld,\tStart:%%4lu,\tEnd:%%4lu,\tMismatch:%%3ld\n", g_max_item_name_length); + fprintf(fp, "TIME TRACER REPORT [BEGIN]=========================== [# of Item:%d, unit(msec)]\n", g_index); + LOGE("TIME TRACER REPORT [BEGIN]=========================== [# of Item:%d, unit(msec)]", g_index); +#else + snprintf(format, sizeof(format)-1, "[%%3d] %%-%ds |\tTotal:%%ld,\tCnt:%%ld,\tAvg:%%ld,\tMin:%%ld,\tMax:%%ld,\tStart:%%lu,\tEnd:%%lu,\tMismatch:%%ld\n", g_max_item_name_length); + fprintf(fp, "TIME TRACER REPORT [BEGIN]=========================== [# of Item:%d, unit(usec)]\n", g_index); + LOGE("TIME TRACER REPORT [BEGIN]=========================== [# of Item:%d, unit(usec)]", g_index); +#endif + + for ( i = 0; i < g_index; i++ ) + { + if (g_items[i]->invoke_count == 0) + g_items[i]->invoke_count = 1; + + fprintf(fp,format,i, + g_items[i]->name, // item name + g_items[i]->total_elapsed_time, // total elasped time + g_items[i]->invoke_count, // # of call + (g_items[i]->total_elapsed_time == 0)?0:(int)(g_items[i]->total_elapsed_time / g_items[i]->invoke_count), // calculates the average elapsed time + g_items[i]->min_elapsed_time, // mininum elpased time + g_items[i]->max_elapsed_time,// maximum elpased time + g_items[i]->first_timestamp - g_first_time, //begin timestamp + g_items[i]->last_timestamp - g_first_time, //end timestamp + g_items[i]->mismatch_count ); // # of mismatch (begin - end mismatch) + + print_log(DLOG_ERROR, LOG_TAG, format,i,g_items[i]->name, g_items[i]->total_elapsed_time, g_items[i]->invoke_count, (g_items[i]->total_elapsed_time == 0)?0:(int)(g_items[i]->total_elapsed_time / g_items[i]->invoke_count), g_items[i]->min_elapsed_time, g_items[i]->max_elapsed_time, g_items[i]->first_timestamp - g_first_time, g_items[i]->last_timestamp - g_first_time, g_items[i]->mismatch_count ); + + } + fprintf(fp, "TIME TRACER REPORT [END] ============================\n"); + LOGE("TIME TRACER REPORT [END] ============================"); + + if ( direction == TIME_TRACER_EXPORT_FILE ) + fclose(fp); +} diff --git a/wearable_src/Common/TimeTracer/TimeTracer.h b/wearable_src/Common/TimeTracer/TimeTracer.h new file mode 100644 index 0000000..f203c91 --- /dev/null +++ b/wearable_src/Common/TimeTracer/TimeTracer.h @@ -0,0 +1,76 @@ +// +// 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. +// + +#ifndef __TIZEN_COMMON_TIME_TRACER__ +#define __TIZEN_COMMON_TIME_TRACER__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _time_tracer_item +{ + char* name; + unsigned long total_elapsed_time; + unsigned long min_elapsed_time; + unsigned long max_elapsed_time; + unsigned long first_timestamp; + unsigned long last_timestamp; + unsigned long timestamp; + int on_tracing; + int invoke_count; + int mismatch_count; +} time_tracer_item; + +/* COMMON */ +int time_tracer_init(void); +int time_tracer_release(void); +void time_tracer_export_report(int direction, char* name); +int time_tracer_item_begin(const char* name, int show,const char* filename, int line); +int time_tracer_item_end(const char* name, int show, const char* filename, int line); + +#define TIME_TRACER_EXPORT_STDOUT 0 +#define TIME_TRACER_EXPORT_STDERR 1 +#define TIME_TRACER_EXPORT_FILE 2 + +#ifdef ENABLE_TIME_TRACER +//Initialize the time tracer +#define TIME_TRACER_INIT() (time_tracer_init()) +//Release the time tracer +#define TIME_TRACER_RELEASE() (time_tracer_release()) +//Export tracing report to stdout +#define TIME_TRACER_EXPORT_REPORT() (time_tracer_export_report(TIME_TRACER_EXPORT_STDOUT,NULL)) +//Export tracing report to user specific direction (stdout, stderr, file) +#define TIME_TRACER_EXPORT_REPORT_TO(x,y) (time_tracer_export_report(x,y)) +//Set tracing point to begin +#define TIME_TRACER_ITEM_BEGIN(name,show) (time_tracer_item_begin(name,show,__FILE__,__LINE__)) +//Set tracing point to end +#define TIME_TRACER_ITEM_END(name,show) (time_tracer_item_end(name,show,__FILE__,__LINE__) ) +#else +#define TIME_TRACER_INIT() +#define TIME_TRACER_RELEASE() +#define TIME_TRACER_EXPORT_REPORT() +#define TIME_TRACER_EXPORT_REPORT_TO(x,y) +#define TIME_TRACER_ITEM_BEGIN(name,show) +#define TIME_TRACER_ITEM_END(name,show) +#endif + +#ifdef __cplusplus +} +#endif + +#endif //__TIZEN_COMMON_TIME_TRACER__ diff --git a/wearable_src/Common/WebAPIError.cpp b/wearable_src/Common/WebAPIError.cpp new file mode 100644 index 0000000..e8e1909 --- /dev/null +++ b/wearable_src/Common/WebAPIError.cpp @@ -0,0 +1,49 @@ +// +// Tizen Web Device API +// Copyright (c) 2012 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 "WebAPIError.h" + +namespace DeviceAPI { +namespace Common { + +WebAPIError::WebAPIError(const int code, const std::string& name, const std::string& message) : + m_code(code), + m_name(name), + m_message(message) +{ +} + +WebAPIError::~WebAPIError() +{ +} + +int WebAPIError::getCode() const +{ + return m_code; +} + +std::string WebAPIError::getName() const +{ + return m_name; +} + +std::string WebAPIError::getMessage() const +{ + return m_message; +} + +} // Common +} // DeviceAPI diff --git a/wearable_src/Common/WebAPIError.h b/wearable_src/Common/WebAPIError.h new file mode 100644 index 0000000..323fb81 --- /dev/null +++ b/wearable_src/Common/WebAPIError.h @@ -0,0 +1,46 @@ +// +// Tizen Web Device API +// Copyright (c) 2012 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. +// + +#ifndef _WEBAPI_ERROR_H_ +#define _WEBAPI_ERROR_H_ + +#include <string> +#include <dpl/shared_ptr.h> + +namespace DeviceAPI { +namespace Common { + +class WebAPIError +{ +public: + WebAPIError(const int code, const std::string& name, const std::string& message = std::string()); + virtual ~WebAPIError(); + + int getCode() const; + std::string getName() const; + std::string getMessage() const; + +private: + int m_code; + std::string m_name; + std::string m_message; +}; + +} // Common +} // DeviceAPI + +#endif // _WEBAPI_ERROR_H_ |