summaryrefslogtreecommitdiff
path: root/src/CommonsJavaScript/Converter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/CommonsJavaScript/Converter.cpp')
-rw-r--r--src/CommonsJavaScript/Converter.cpp389
1 files changed, 389 insertions, 0 deletions
diff --git a/src/CommonsJavaScript/Converter.cpp b/src/CommonsJavaScript/Converter.cpp
new file mode 100644
index 0000000..e68c16b
--- /dev/null
+++ b/src/CommonsJavaScript/Converter.cpp
@@ -0,0 +1,389 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 <sstream>
+#include <limits>
+#include <dpl/scoped_free.h>
+#include "ScopedJSStringRef.h"
+#include "Converter.h"
+
+using namespace WrtDeviceApis::Commons;
+
+namespace WrtDeviceApis {
+namespace CommonsJavaScript {
+Converter::Converter(JSContextRef context) : m_context(context)
+{}
+
+Converter::~Converter()
+{}
+
+JSObjectRef Converter::toJSObjectRef(const JSValueRef& arg)
+{
+ if (!arg) {
+ Throw(NullPointerException);
+ }
+ JSValueRef exception = NULL;
+ JSObjectRef result = JSValueToObject(m_context, arg, &exception);
+ if ((NULL == result) || (NULL != exception)) {
+ ThrowMsg(ConversionException, "Couldn't convert to a JS Object.");
+ }
+ return result;
+}
+
+bool Converter::toBool(const JSValueRef& arg)
+{
+ return JSValueToBoolean(m_context, arg);
+}
+
+unsigned char Converter::toUChar(const JSValueRef& arg)
+{
+ return static_cast<unsigned char>(toChar(arg));
+}
+
+char Converter::toChar(const JSValueRef& arg)
+{
+ double tmp = toNumber_(arg);
+ return (isNan(tmp) ? 0 : static_cast<char>(tmp));
+}
+
+int Converter::toInt(const JSValueRef& arg)
+{
+ double tmp = toNumber_(arg);
+ return (isNan(tmp) ? 0 : static_cast<int>(tmp));
+}
+
+int Converter::toInt(const std::string &arg)
+{
+ return static_cast<int>(toNumber_(arg));
+}
+
+long Converter::toLong(const JSValueRef& arg)
+{
+ double tmp = toNumber_(arg);
+ return (isNan(tmp) ? 0 : static_cast<long>(tmp));
+}
+
+long long Converter::toLongLong(const JSValueRef& arg)
+{
+ double tmp = toNumber_(arg);
+ return (isNan(tmp) ? 0 : static_cast<long long>(tmp));
+}
+
+unsigned long Converter::toULong(const JSValueRef& arg)
+{
+ double tmp = toNumber_(arg);
+ return (isNan(tmp) ? 0 : static_cast<unsigned long>(tmp));
+}
+
+std::size_t Converter::toSizeT(const JSValueRef& arg)
+{
+ double tmp = toNumber_(arg);
+ return (isNan(tmp) ? 0 : static_cast<std::size_t>(tmp));
+}
+
+std::size_t Converter::toSizeT(const JSStringRef& arg)
+{
+ return static_cast<std::size_t>(toNumber_(arg));
+}
+
+double Converter::toDouble(const JSValueRef& arg)
+{
+ return toNumber_(arg);
+}
+
+std::string Converter::toString(int arg)
+{
+ return toString_(arg);
+}
+
+std::string Converter::toString(unsigned long arg)
+{
+ return toString_(arg);
+}
+
+std::string Converter::toString(long arg)
+{
+ return toString_(arg);
+}
+
+std::string Converter::toString(std::size_t arg)
+{
+ return toString_(arg);
+}
+
+std::string Converter::toString(const JSValueRef& arg)
+{
+ return toString_(arg);
+}
+
+std::string Converter::tryString(const JSValueRef& arg)
+{
+ if (!JSValueIsString(m_context, arg) &&
+ !JSValueIsNumber(m_context, arg) &&
+ !JSValueIsBoolean(m_context, arg))
+ {
+ ThrowMsg(ConversionException,
+ "Argument is not convertable to JS String.");
+ }
+
+ return toString_(arg);
+}
+
+std::string Converter::toDateString(const JSValueRef& arg)
+{
+ if (!JSValueIsObject(m_context, arg)) {
+ ThrowMsg(ConversionException, "Argument is not JS Date.");
+ }
+
+ return toString_(arg);
+}
+
+std::string Converter::toString(const JSStringRef& arg)
+{
+ std::string result;
+ size_t jsSize = JSStringGetMaximumUTF8CStringSize(arg);
+ if (jsSize > 0) {
+ jsSize = jsSize + 1;
+ std::unique_ptr<char[]> buffer(new char[jsSize]);
+ size_t written = JSStringGetUTF8CString(arg, buffer.get(), jsSize);
+ if (written > jsSize) {
+ ThrowMsg(ConversionException,
+ "Conversion could not be fully performed.");
+ }
+ result = buffer.get();
+ }
+
+ return result;
+}
+
+time_t Converter::toDateTimeT(const JSValueRef& arg)
+{
+ struct tm tm = toDateTm(arg);
+ return mktime(&tm);
+}
+
+tm Converter::toDateTm(const JSValueRef& arg)
+{
+ using namespace std::placeholders;
+
+ std::string stringDate = toDateString(arg);
+ struct tm result;
+ char* currentLocale = setlocale(LC_TIME, NULL);
+ if (currentLocale == NULL) {
+ ThrowMsg(ConversionException, "Couldn't get current locale.");
+ }
+ std::unique_ptr<char, void(*)(void*)> currentLocaleCopy(strdup(currentLocale), &free);
+ if (setlocale(LC_TIME, "C") == NULL) {
+ ThrowMsg(ConversionException, "Couldn't set POSIX locale.");
+ }
+ if (strptime(stringDate.c_str(), "%a %b %d %Y %T", &result) == NULL) {
+ ThrowMsg(ConversionException, "Couldn't convert supplied date.");
+ }
+ if (setlocale(LC_TIME, currentLocaleCopy.get()) == NULL) {
+ ThrowMsg(ConversionException, "Couldn't set previous locale back.");
+ }
+ //strptime function doesn't affect tm_isdst flag.
+ //It may cause -1hr conversion error. Setting it to -1 informs that
+ //there is no information about daylight saving time.
+ result.tm_isdst = -1;
+ return result;
+}
+
+std::vector<unsigned char> Converter::toVectorOfUChars(const JSValueRef& arg)
+{
+ return toVectorOfT_(arg, &Converter::toUChar);
+}
+
+std::vector<char> Converter::toVectorOfChars(const JSValueRef& arg)
+{
+ return toVectorOfT_(arg, &Converter::toChar);
+}
+
+std::vector<int> Converter::toVectorOfInts(const JSValueRef& arg)
+{
+ return toVectorOfT_(arg, &Converter::toInt);
+}
+
+std::vector<std::string> Converter::toVectorOfStrings(const JSValueRef& arg)
+{
+ return toVectorOfT_(arg, &Converter::toString);
+}
+
+std::vector<time_t> Converter::toVectorOfTimeT(const JSValueRef& arg)
+{
+ return toVectorOfT_(arg, &Converter::toDateTimeT);
+}
+
+JSValueRef Converter::toJSValueRef(bool arg)
+{
+ return JSValueMakeBoolean(m_context, arg);
+}
+
+JSValueRef Converter::toJSValueRef(int arg)
+{
+ return JSValueMakeNumber(m_context, arg);
+}
+
+JSValueRef Converter::toJSValueRef(unsigned int arg)
+{
+ return JSValueMakeNumber(m_context, arg);
+}
+
+JSValueRef Converter::toJSValueRef(unsigned long arg)
+{
+ return JSValueMakeNumber(m_context, arg);
+}
+
+JSValueRef Converter::toJSValueRefLong(const long arg)
+{
+ return JSValueMakeNumber(m_context, arg);
+}
+
+JSValueRef Converter::toJSValueRef(long long int arg)
+{
+ return JSValueMakeNumber(m_context, arg);
+}
+
+JSValueRef Converter::toJSValueRef(double arg)
+{
+ return JSValueMakeNumber(m_context, arg);
+}
+
+JSValueRef Converter::toJSValueRef(const std::string& arg)
+{
+ JSValueRef result = NULL;
+ JSStringRef jsString = JSStringCreateWithUTF8CString(arg.c_str());
+ result = JSValueMakeString(m_context, jsString);
+ JSStringRelease(jsString);
+ return result;
+}
+
+JSValueRef Converter::toJSValueRef(const tm& arg)
+{
+ JSValueRef args[6];
+ args[0] = JSValueMakeNumber(m_context, arg.tm_year + 1900);
+ args[1] = JSValueMakeNumber(m_context, arg.tm_mon);
+ args[2] = JSValueMakeNumber(m_context, arg.tm_mday);
+ args[3] = JSValueMakeNumber(m_context, arg.tm_hour);
+ args[4] = JSValueMakeNumber(m_context, arg.tm_min);
+ args[5] = JSValueMakeNumber(m_context, arg.tm_sec);
+
+ JSValueRef exception = NULL;
+ JSObjectRef result = JSObjectMakeDate(m_context, 6, args, &exception);
+ if (NULL != exception) {
+ ThrowMsg(ConversionException, "Couldn't convert to a JS Date.");
+ }
+
+ return result;
+}
+
+JSValueRef Converter::toJSValueRef(const time_t arg)
+{
+ struct tm tminfo;
+ memset(&tminfo,0,sizeof(tminfo));
+ localtime_r(&arg, &tminfo);
+ return toJSValueRef(tminfo);
+}
+
+JSValueRef Converter::toJSValueRef(const std::vector<std::string>& arg)
+{
+ return toJSValueRef_(arg);
+}
+
+JSValueRef Converter::toJSValueRef(const char* arg)
+{
+ return toJSValueRef(std::string(arg));
+}
+
+JSValueRef Converter::toJSValueRef(const std::vector<int>& arg)
+{
+ return toJSValueRef_(arg);
+}
+
+JSValueRef Converter::toJSValueRef(const std::vector<time_t>& arg)
+{
+ return toJSValueRef_(arg);
+}
+
+JSValueRef Converter::toJSValueRef(JSValueRef arg)
+{
+ return arg;
+}
+
+JSValueRef Converter::toJSValueRef(const std::vector<JSValueRef>& arg)
+{
+ return toJSValueRef_(arg);
+}
+
+JSStringRef Converter::toJSStringRef(const std::string& arg)
+{
+ return JSStringCreateWithUTF8CString(arg.c_str());
+}
+
+double Converter::toNumber_(const JSStringRef& arg)
+{
+ return toNumber_(toString(arg));
+}
+
+double Converter::toNumber_(const std::string& arg)
+{
+ double result;
+ std::stringstream ss(arg);
+ if (!(ss >> result)) {
+ Throw(ConversionException);
+ }
+ return result;
+}
+
+double Converter::toNumber_(const JSValueRef& arg)
+{
+ JSValueRef exception = NULL;
+ double result = JSValueToNumber(m_context, arg, &exception);
+ if (NULL != exception) {
+ ThrowMsg(ConversionException, "Couldn't convert to a number.");
+ }
+ return result;
+}
+
+std::string Converter::toString_(const JSValueRef& arg)
+{
+ std::string result;
+
+ JSValueRef exception = NULL;
+ JSStringRef str = JSValueToStringCopy(m_context, arg, &exception);
+ if (NULL == str) {
+ ThrowMsg(ConversionException, "Couldn't cast to a string.");
+ }
+
+ size_t jsSize = JSStringGetMaximumUTF8CStringSize(str);
+ if (jsSize > 0) {
+ std::unique_ptr<char[]> buffer(new char[jsSize]);
+ JSStringGetUTF8CString(str, buffer.get(), jsSize);
+ result = buffer.get();
+ }
+ JSStringRelease(str);
+ return result;
+}
+
+bool Converter::isNan(double value) const
+{
+ // This should work unless -ffast-math (GCC) option is used.
+ STATIC_CHECK(std::numeric_limits<double>::is_iec559,
+ NOT_IEEE754_REPRESENTATION);
+ return (value != value);
+}
+} // CommonsJavaScript
+} // WrtDeviceApis
+