PageRenderTime 50ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/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
  1. /**********************************************************\
  2. Original Author: Georg Fritzsche
  3. Created: Nov 6, 2010
  4. License: Dual license model; choose one of two:
  5. New BSD License
  6. http://www.opensource.org/licenses/bsd-license.php
  7. - or -
  8. GNU Lesser General Public License, version 2.1
  9. http://www.gnu.org/licenses/lgpl-2.1.html
  10. Copyright 20100 Georg Fritzsche, Firebreath development team
  11. \**********************************************************/
  12. #pragma once
  13. #ifndef FB_H_NPVARIANTUTIL
  14. #define FB_H_NPVARIANTUTIL
  15. #include <map>
  16. #include <string>
  17. #include <typeinfo>
  18. #include <boost/type_traits/is_arithmetic.hpp>
  19. #include <boost/type_traits/is_integral.hpp>
  20. #include <boost/type_traits/is_same.hpp>
  21. #include <boost/type_traits/is_floating_point.hpp>
  22. #include <boost/integer_traits.hpp>
  23. #include "NpapiTypes.h"
  24. #include "APITypes.h"
  25. #include "NpapiPluginModule.h"
  26. #include "NPJavascriptObject.h"
  27. #include "NPObjectAPI.h"
  28. #include "DOM/Document.h"
  29. #include "DOM/Window.h"
  30. #include "variant_list.h"
  31. #include "NpapiBrowserHost.h"
  32. namespace FB { namespace Npapi
  33. {
  34. struct type_info_less
  35. {
  36. bool operator() (const std::type_info* const lhs, const std::type_info* const rhs) const
  37. {
  38. return lhs->before(*rhs) ? true : false;
  39. }
  40. };
  41. typedef NPVariant (*NPVariantBuilder)(const NpapiBrowserHostPtr&, const FB::variant&);
  42. typedef std::map<std::type_info const*, NPVariantBuilder, type_info_less> NPVariantBuilderMap;
  43. template<class T>
  44. NPVariant makeNPVariant(const NpapiBrowserHostPtr& host, const FB::variant& var)
  45. {
  46. BOOST_STATIC_ASSERT((false && sizeof(T)==0));
  47. NPVariant npv;
  48. npv.type = NPVariantType_Null;
  49. return npv;
  50. }
  51. template<> inline
  52. NPVariant makeNPVariant<double>(const NpapiBrowserHostPtr& host, const FB::variant& var)
  53. {
  54. NPVariant npv;
  55. npv.type = NPVariantType_Double;
  56. npv.value.doubleValue = var.convert_cast<double>();
  57. return npv;
  58. }
  59. template<> inline
  60. NPVariant makeNPVariant<int32_t>(const NpapiBrowserHostPtr& host, const FB::variant& var)
  61. {
  62. NPVariant npv;
  63. npv.type = NPVariantType_Int32;
  64. npv.value.intValue = var.convert_cast<int32_t>();
  65. return npv;
  66. }
  67. template<> inline
  68. NPVariant makeNPVariant<bool>(const NpapiBrowserHostPtr& host, const FB::variant& var)
  69. {
  70. NPVariant npv;
  71. npv.type = NPVariantType_Bool;
  72. npv.value.boolValue = var.convert_cast<bool>();
  73. return npv;
  74. }
  75. template<> inline
  76. NPVariant makeNPVariant<std::string>(const NpapiBrowserHostPtr& host, const FB::variant& var)
  77. {
  78. NPVariant npv;
  79. std::string str = var.convert_cast<std::string>();
  80. char *outStr = (char*)host->MemAlloc(str.size() + 1);
  81. memcpy(outStr, str.c_str(), str.size() + 1);
  82. npv.type = NPVariantType_String;
  83. npv.value.stringValue.UTF8Characters = outStr;
  84. npv.value.stringValue.UTF8Length = str.size();
  85. return npv;
  86. }
  87. template<> inline
  88. NPVariant makeNPVariant<std::wstring>(const NpapiBrowserHostPtr& host, const FB::variant& var)
  89. {
  90. NPVariant npv;
  91. // This is not a typo; the std::string gets the UTF8 representation
  92. // and we pass that back to the browser
  93. std::string str = var.convert_cast<std::string>();
  94. char *outStr = (char*)host->MemAlloc(str.size() + 1);
  95. memcpy(outStr, str.c_str(), str.size() + 1);
  96. npv.type = NPVariantType_String;
  97. npv.value.stringValue.UTF8Characters = outStr;
  98. npv.value.stringValue.UTF8Length = str.size();
  99. return npv;
  100. }
  101. template<> inline
  102. NPVariant makeNPVariant<FB::FBVoid>(const NpapiBrowserHostPtr& host, const FB::variant& var)
  103. {
  104. NPVariant npv;
  105. npv.type = NPVariantType_Void;
  106. return npv;
  107. }
  108. template<> inline
  109. NPVariant makeNPVariant<FB::FBNull>(const NpapiBrowserHostPtr& host, const FB::variant& var)
  110. {
  111. NPVariant npv;
  112. npv.type = NPVariantType_Null;
  113. return npv;
  114. }
  115. template<> inline
  116. NPVariant makeNPVariant<FB::VariantList>(const NpapiBrowserHostPtr& host, const FB::variant& var)
  117. {
  118. NPVariant npv;
  119. FB::JSObjectPtr outArr = host->getDOMWindow()->createArray();
  120. FB::VariantList inArr = var.cast<FB::VariantList>();
  121. for (FB::VariantList::iterator it = inArr.begin(); it != inArr.end(); it++) {
  122. outArr->Invoke("push", FB::variant_list_of(*it));
  123. }
  124. if (NPObjectAPIPtr api = FB::ptr_cast<NPObjectAPI>(outArr)) {
  125. npv.type = NPVariantType_Object;
  126. npv.value.objectValue = api->getNPObject();
  127. host->RetainObject(npv.value.objectValue);
  128. }
  129. return npv;
  130. }
  131. template<> inline
  132. NPVariant makeNPVariant<FB::VariantMap>(const NpapiBrowserHostPtr& host, const FB::variant& var)
  133. {
  134. NPVariant npv;
  135. FB::JSObjectPtr out = host->getDOMWindow()->createMap();
  136. FB::VariantMap inMap = var.cast<FB::VariantMap>();
  137. for (FB::VariantMap::iterator it = inMap.begin(); it != inMap.end(); it++) {
  138. out->SetProperty(it->first, it->second);
  139. }
  140. if (NPObjectAPIPtr api = FB::ptr_cast<NPObjectAPI>(out)) {
  141. npv.type = NPVariantType_Object;
  142. npv.value.objectValue = api->getNPObject();
  143. host->RetainObject(npv.value.objectValue);
  144. }
  145. return npv;
  146. }
  147. // template<> inline
  148. // NPVariant makeNPVariant<FB::FBDateString>(const NpapiBrowserHostPtr& host, const FB::variant& var)
  149. // {
  150. // NPVariant npv;
  151. //
  152. // FB::FBDateString date = var.cast<FB::FBDateString>();
  153. // FB::JSObjectPtr out = host->getDOMWindow()->createDate(date.getValue());;
  154. //
  155. // if (NPObjectAPIPtr api = FB::ptr_cast<NPObjectAPI>(out)) {
  156. // npv.type = NPVariantType_Object;
  157. // npv.value.objectValue = api->getNPObject();
  158. // host->RetainObject(npv.value.objectValue);
  159. // } else {
  160. // return makeNPVariant<std::string>(host, date.getValue());
  161. // }
  162. //
  163. // return npv;
  164. // }
  165. template<> inline
  166. NPVariant makeNPVariant<FB::JSAPIPtr>(const NpapiBrowserHostPtr& host, const FB::variant& var)
  167. {
  168. NPVariant npv;
  169. if (FB::JSAPIPtr obj = var.cast<FB::JSAPIPtr>())
  170. {
  171. NPObject *outObj = NULL;
  172. if (NPObjectAPIPtr tmpObj = FB::ptr_cast<NPObjectAPI>(obj)) {
  173. outObj = tmpObj->getNPObject();
  174. host->RetainObject(outObj);
  175. } else {
  176. host->retainJSAPIPtr(obj);
  177. outObj = host->getJSAPIWrapper(var.cast<FB::JSAPIPtr>(), true);
  178. }
  179. if (outObj) {
  180. npv.type = NPVariantType_Object;
  181. npv.value.objectValue = outObj;
  182. } else {
  183. npv.type = NPVariantType_Null;
  184. }
  185. }
  186. else
  187. {
  188. npv.type = NPVariantType_Null;
  189. }
  190. return npv;
  191. }
  192. template<> inline
  193. NPVariant makeNPVariant<FB::JSAPIWeakPtr>(const NpapiBrowserHostPtr& host, const FB::variant& var)
  194. {
  195. NPVariant npv;
  196. // convert_cast will automatically make a shared_ptr out of the weak_ptr; if the weak_ptr
  197. // is expired it'll be a NULL ptr
  198. if (FB::JSAPIPtr obj = var.convert_cast<FB::JSAPIPtr>())
  199. {
  200. NPObject *outObj = NULL;
  201. if (NPObjectAPIPtr tmpObj = FB::ptr_cast<NPObjectAPI>(obj)) {
  202. outObj = tmpObj->getNPObject();
  203. host->RetainObject(outObj);
  204. } else {
  205. // The big difference between returning a weak_ptr instead of a shared_ptr is
  206. // that we don't have the browser object retain the weak_ptr
  207. outObj = host->getJSAPIWrapper(var.cast<FB::JSAPIWeakPtr>());
  208. }
  209. npv.type = NPVariantType_Object;
  210. npv.value.objectValue = outObj;
  211. }
  212. else
  213. {
  214. npv.type = NPVariantType_Null;
  215. }
  216. return npv;
  217. }
  218. template<> inline
  219. NPVariant makeNPVariant<FB::JSObjectPtr>(const NpapiBrowserHostPtr& host, const FB::variant& var)
  220. {
  221. NPVariant npv;
  222. if (FB::JSObjectPtr obj = var.cast<FB::JSObjectPtr>())
  223. {
  224. NPObject *outObj = NULL;
  225. if (NPObjectAPIPtr tmpObj = FB::ptr_cast<NPObjectAPI>(obj)) {
  226. outObj = tmpObj->getNPObject();
  227. host->RetainObject(outObj);
  228. } else {
  229. outObj = NPJavascriptObject::NewObject(host, obj);
  230. }
  231. npv.type = NPVariantType_Object;
  232. npv.value.objectValue = outObj;
  233. }
  234. else
  235. {
  236. npv.type = NPVariantType_Null;
  237. }
  238. return npv;
  239. }
  240. namespace select_npvariant_builder
  241. {
  242. template<class T>
  243. NPVariantBuilder isIntegral(const boost::true_type& /* is_integral */)
  244. {
  245. if (boost::is_same<T, bool>::value) {
  246. return &makeNPVariant<bool>;
  247. }
  248. if ((boost::is_signed<T>::value && (sizeof(T) <= sizeof(int32_t))) || (boost::is_unsigned<T>::value && (sizeof(T) <= sizeof(int32_t)/2))) {
  249. // max value of T fits into int32_t
  250. return &makeNPVariant<int32_t>;
  251. }
  252. // max value of T doesn't fit into int32_t, use string instead
  253. return &makeNPVariant<std::string>;
  254. }
  255. template<class T>
  256. NPVariantBuilder isIntegral(const boost::false_type& /* is_integral */)
  257. {
  258. BOOST_STATIC_ASSERT((boost::is_floating_point<T>::value));
  259. return &makeNPVariant<double>;
  260. }
  261. template<class T>
  262. NPVariantBuilder isArithmetic(const boost::true_type& /* is_arithmetic */)
  263. {
  264. return isIntegral<T>(boost::is_integral<T>());
  265. }
  266. template<class T>
  267. NPVariantBuilder isArithmetic(const boost::false_type& /* is_arithmetic */)
  268. {
  269. return &makeNPVariant<T>;
  270. }
  271. template<class T>
  272. NPVariantBuilder select()
  273. {
  274. return isArithmetic<T>(boost::is_arithmetic<T>());
  275. }
  276. }
  277. } }
  278. #endif