/firebreath-1.5.2/src/NpapiCore/NPVariantUtil.h
C Header | 332 lines | 241 code | 52 blank | 39 comment | 23 complexity | 8f6095ab09507e860aeaa26a828be352 MD5 | raw file
Possible License(s): LGPL-2.1
- /**********************************************************\
- Original Author: Georg Fritzsche
-
- Created: Nov 6, 2010
- License: Dual license model; choose one of two:
- New BSD License
- http://www.opensource.org/licenses/bsd-license.php
- - or -
- GNU Lesser General Public License, version 2.1
- http://www.gnu.org/licenses/lgpl-2.1.html
-
- Copyright 20100 Georg Fritzsche, Firebreath development team
- \**********************************************************/
- #pragma once
- #ifndef FB_H_NPVARIANTUTIL
- #define FB_H_NPVARIANTUTIL
- #include <map>
- #include <string>
- #include <typeinfo>
- #include <boost/type_traits/is_arithmetic.hpp>
- #include <boost/type_traits/is_integral.hpp>
- #include <boost/type_traits/is_same.hpp>
- #include <boost/type_traits/is_floating_point.hpp>
- #include <boost/integer_traits.hpp>
- #include "NpapiTypes.h"
- #include "APITypes.h"
- #include "NpapiPluginModule.h"
- #include "NPJavascriptObject.h"
- #include "NPObjectAPI.h"
- #include "DOM/Document.h"
- #include "DOM/Window.h"
- #include "variant_list.h"
- #include "NpapiBrowserHost.h"
- namespace FB { namespace Npapi
- {
- struct type_info_less
- {
- bool operator() (const std::type_info* const lhs, const std::type_info* const rhs) const
- {
- return lhs->before(*rhs) ? true : false;
- }
- };
-
- typedef NPVariant (*NPVariantBuilder)(const NpapiBrowserHostPtr&, const FB::variant&);
- typedef std::map<std::type_info const*, NPVariantBuilder, type_info_less> NPVariantBuilderMap;
-
- template<class T>
- NPVariant makeNPVariant(const NpapiBrowserHostPtr& host, const FB::variant& var)
- {
- BOOST_STATIC_ASSERT((false && sizeof(T)==0));
- NPVariant npv;
- npv.type = NPVariantType_Null;
- return npv;
- }
-
- template<> inline
- NPVariant makeNPVariant<double>(const NpapiBrowserHostPtr& host, const FB::variant& var)
- {
- NPVariant npv;
- npv.type = NPVariantType_Double;
- npv.value.doubleValue = var.convert_cast<double>();
- return npv;
- }
-
- template<> inline
- NPVariant makeNPVariant<int32_t>(const NpapiBrowserHostPtr& host, const FB::variant& var)
- {
- NPVariant npv;
- npv.type = NPVariantType_Int32;
- npv.value.intValue = var.convert_cast<int32_t>();
- return npv;
- }
-
- template<> inline
- NPVariant makeNPVariant<bool>(const NpapiBrowserHostPtr& host, const FB::variant& var)
- {
- NPVariant npv;
- npv.type = NPVariantType_Bool;
- npv.value.boolValue = var.convert_cast<bool>();
- return npv;
- }
-
- template<> inline
- NPVariant makeNPVariant<std::string>(const NpapiBrowserHostPtr& host, const FB::variant& var)
- {
- NPVariant npv;
-
- std::string str = var.convert_cast<std::string>();
- char *outStr = (char*)host->MemAlloc(str.size() + 1);
- memcpy(outStr, str.c_str(), str.size() + 1);
- npv.type = NPVariantType_String;
- npv.value.stringValue.UTF8Characters = outStr;
- npv.value.stringValue.UTF8Length = str.size();
-
- return npv;
- }
-
- template<> inline
- NPVariant makeNPVariant<std::wstring>(const NpapiBrowserHostPtr& host, const FB::variant& var)
- {
- NPVariant npv;
-
- // This is not a typo; the std::string gets the UTF8 representation
- // and we pass that back to the browser
- std::string str = var.convert_cast<std::string>();
- char *outStr = (char*)host->MemAlloc(str.size() + 1);
- memcpy(outStr, str.c_str(), str.size() + 1);
- npv.type = NPVariantType_String;
- npv.value.stringValue.UTF8Characters = outStr;
- npv.value.stringValue.UTF8Length = str.size();
-
- return npv;
- }
-
- template<> inline
- NPVariant makeNPVariant<FB::FBVoid>(const NpapiBrowserHostPtr& host, const FB::variant& var)
- {
- NPVariant npv;
- npv.type = NPVariantType_Void;
- return npv;
- }
- template<> inline
- NPVariant makeNPVariant<FB::FBNull>(const NpapiBrowserHostPtr& host, const FB::variant& var)
- {
- NPVariant npv;
- npv.type = NPVariantType_Null;
- return npv;
- }
-
- template<> inline
- NPVariant makeNPVariant<FB::VariantList>(const NpapiBrowserHostPtr& host, const FB::variant& var)
- {
- NPVariant npv;
-
- FB::JSObjectPtr outArr = host->getDOMWindow()->createArray();
- FB::VariantList inArr = var.cast<FB::VariantList>();
-
- for (FB::VariantList::iterator it = inArr.begin(); it != inArr.end(); it++) {
- outArr->Invoke("push", FB::variant_list_of(*it));
- }
-
- if (NPObjectAPIPtr api = FB::ptr_cast<NPObjectAPI>(outArr)) {
- npv.type = NPVariantType_Object;
- npv.value.objectValue = api->getNPObject();
- host->RetainObject(npv.value.objectValue);
- }
-
- return npv;
- }
-
- template<> inline
- NPVariant makeNPVariant<FB::VariantMap>(const NpapiBrowserHostPtr& host, const FB::variant& var)
- {
- NPVariant npv;
-
- FB::JSObjectPtr out = host->getDOMWindow()->createMap();
- FB::VariantMap inMap = var.cast<FB::VariantMap>();
-
- for (FB::VariantMap::iterator it = inMap.begin(); it != inMap.end(); it++) {
- out->SetProperty(it->first, it->second);
- }
-
- if (NPObjectAPIPtr api = FB::ptr_cast<NPObjectAPI>(out)) {
- npv.type = NPVariantType_Object;
- npv.value.objectValue = api->getNPObject();
- host->RetainObject(npv.value.objectValue);
- }
-
- return npv;
- }
-
- // template<> inline
- // NPVariant makeNPVariant<FB::FBDateString>(const NpapiBrowserHostPtr& host, const FB::variant& var)
- // {
- // NPVariant npv;
- //
- // FB::FBDateString date = var.cast<FB::FBDateString>();
- // FB::JSObjectPtr out = host->getDOMWindow()->createDate(date.getValue());;
- //
- // if (NPObjectAPIPtr api = FB::ptr_cast<NPObjectAPI>(out)) {
- // npv.type = NPVariantType_Object;
- // npv.value.objectValue = api->getNPObject();
- // host->RetainObject(npv.value.objectValue);
- // } else {
- // return makeNPVariant<std::string>(host, date.getValue());
- // }
- //
- // return npv;
- // }
-
- template<> inline
- NPVariant makeNPVariant<FB::JSAPIPtr>(const NpapiBrowserHostPtr& host, const FB::variant& var)
- {
- NPVariant npv;
-
- if (FB::JSAPIPtr obj = var.cast<FB::JSAPIPtr>())
- {
- NPObject *outObj = NULL;
-
- if (NPObjectAPIPtr tmpObj = FB::ptr_cast<NPObjectAPI>(obj)) {
- outObj = tmpObj->getNPObject();
- host->RetainObject(outObj);
- } else {
- host->retainJSAPIPtr(obj);
- outObj = host->getJSAPIWrapper(var.cast<FB::JSAPIPtr>(), true);
- }
- if (outObj) {
- npv.type = NPVariantType_Object;
- npv.value.objectValue = outObj;
- } else {
- npv.type = NPVariantType_Null;
- }
- }
- else
- {
- npv.type = NPVariantType_Null;
- }
-
- return npv;
- }
- template<> inline
- NPVariant makeNPVariant<FB::JSAPIWeakPtr>(const NpapiBrowserHostPtr& host, const FB::variant& var)
- {
- NPVariant npv;
- // convert_cast will automatically make a shared_ptr out of the weak_ptr; if the weak_ptr
- // is expired it'll be a NULL ptr
- if (FB::JSAPIPtr obj = var.convert_cast<FB::JSAPIPtr>())
- {
- NPObject *outObj = NULL;
-
- if (NPObjectAPIPtr tmpObj = FB::ptr_cast<NPObjectAPI>(obj)) {
- outObj = tmpObj->getNPObject();
- host->RetainObject(outObj);
- } else {
- // The big difference between returning a weak_ptr instead of a shared_ptr is
- // that we don't have the browser object retain the weak_ptr
- outObj = host->getJSAPIWrapper(var.cast<FB::JSAPIWeakPtr>());
- }
-
- npv.type = NPVariantType_Object;
- npv.value.objectValue = outObj;
- }
- else
- {
- npv.type = NPVariantType_Null;
- }
-
- return npv;
- }
-
- template<> inline
- NPVariant makeNPVariant<FB::JSObjectPtr>(const NpapiBrowserHostPtr& host, const FB::variant& var)
- {
- NPVariant npv;
-
- if (FB::JSObjectPtr obj = var.cast<FB::JSObjectPtr>())
- {
- NPObject *outObj = NULL;
-
- if (NPObjectAPIPtr tmpObj = FB::ptr_cast<NPObjectAPI>(obj)) {
- outObj = tmpObj->getNPObject();
- host->RetainObject(outObj);
- } else {
- outObj = NPJavascriptObject::NewObject(host, obj);
- }
-
- npv.type = NPVariantType_Object;
- npv.value.objectValue = outObj;
- }
- else
- {
- npv.type = NPVariantType_Null;
- }
-
- return npv;
- }
-
- namespace select_npvariant_builder
- {
- template<class T>
- NPVariantBuilder isIntegral(const boost::true_type& /* is_integral */)
- {
- if (boost::is_same<T, bool>::value) {
- return &makeNPVariant<bool>;
- }
-
- if ((boost::is_signed<T>::value && (sizeof(T) <= sizeof(int32_t))) || (boost::is_unsigned<T>::value && (sizeof(T) <= sizeof(int32_t)/2))) {
- // max value of T fits into int32_t
- return &makeNPVariant<int32_t>;
- }
-
- // max value of T doesn't fit into int32_t, use string instead
- return &makeNPVariant<std::string>;
- }
-
- template<class T>
- NPVariantBuilder isIntegral(const boost::false_type& /* is_integral */)
- {
- BOOST_STATIC_ASSERT((boost::is_floating_point<T>::value));
- return &makeNPVariant<double>;
- }
-
- template<class T>
- NPVariantBuilder isArithmetic(const boost::true_type& /* is_arithmetic */)
- {
- return isIntegral<T>(boost::is_integral<T>());
- }
-
- template<class T>
- NPVariantBuilder isArithmetic(const boost::false_type& /* is_arithmetic */)
- {
- return &makeNPVariant<T>;
- }
-
- template<class T>
- NPVariantBuilder select()
- {
- return isArithmetic<T>(boost::is_arithmetic<T>());
- }
- }
- } }
- #endif