PageRenderTime 47ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/firebreath-1.5.2/src/ActiveXCore/ComVariantUtil.h

#
C Header | 331 lines | 267 code | 43 blank | 21 comment | 29 complexity | 943c97fb87d0057091619fdd8c1b9838 MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**********************************************************\
  2. Original Author: Georg Fritzsche
  3. Created: Nov 7, 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_CComVariantUTIL
  14. #define FB_H_CComVariantUTIL
  15. #include <map>
  16. #include <string>
  17. #include <typeinfo>
  18. #include <boost/assign/list_of.hpp>
  19. #include <boost/type_traits/is_arithmetic.hpp>
  20. #include <boost/type_traits/is_integral.hpp>
  21. #include <boost/type_traits/is_same.hpp>
  22. #include <boost/type_traits/is_floating_point.hpp>
  23. #include <boost/integer_traits.hpp>
  24. #include "FactoryBase.h"
  25. #include "ActiveXBrowserHost.h"
  26. #include "DOM/Document.h"
  27. #include "DOM/Window.h"
  28. #include "AXDOM/Window.h"
  29. #include "AXDOM/Document.h"
  30. #include "AXDOM/Element.h"
  31. #include "AXDOM/Node.h"
  32. #include <atlsafe.h>
  33. namespace FB { namespace ActiveX
  34. {
  35. struct type_info_less
  36. {
  37. bool operator() (const std::type_info* const lhs, const std::type_info* const rhs) const
  38. {
  39. return lhs->before(*rhs) ? true : false;
  40. }
  41. };
  42. typedef CComVariant (*ComVariantBuilder)(const ActiveXBrowserHostPtr&, const FB::variant&);
  43. typedef std::map<std::type_info const*, ComVariantBuilder, type_info_less> ComVariantBuilderMap;
  44. // GJS ---
  45. // I would probably put the ComVariantBuilderMap code into ComVariantUtil.cpp?
  46. template<class T>
  47. ComVariantBuilderMap::value_type makeBuilderEntry()
  48. {
  49. return ComVariantBuilderMap::value_type(&typeid(T), select_ccomvariant_builder::select<T>());
  50. }
  51. ComVariantBuilderMap makeComVariantBuilderMap()
  52. {
  53. ComVariantBuilderMap tdm;
  54. tdm.insert(makeBuilderEntry<bool>());
  55. tdm.insert(makeBuilderEntry<char>());
  56. tdm.insert(makeBuilderEntry<unsigned char>());
  57. tdm.insert(makeBuilderEntry<short>());
  58. tdm.insert(makeBuilderEntry<unsigned short>());
  59. tdm.insert(makeBuilderEntry<int>());
  60. tdm.insert(makeBuilderEntry<unsigned int>());
  61. tdm.insert(makeBuilderEntry<long>());
  62. tdm.insert(makeBuilderEntry<unsigned long>());
  63. #ifndef BOOST_NO_LONG_LONG
  64. tdm.insert(makeBuilderEntry<long long>());
  65. tdm.insert(makeBuilderEntry<unsigned long long>());
  66. #endif
  67. tdm.insert(makeBuilderEntry<float>());
  68. tdm.insert(makeBuilderEntry<double>());
  69. tdm.insert(makeBuilderEntry<std::string>());
  70. tdm.insert(makeBuilderEntry<std::wstring>());
  71. tdm.insert(makeBuilderEntry<FB::VariantList>());
  72. tdm.insert(makeBuilderEntry<FB::VariantMap>());
  73. tdm.insert(makeBuilderEntry<FB::JSAPIPtr>());
  74. tdm.insert(makeBuilderEntry<FB::JSAPIWeakPtr>());
  75. tdm.insert(makeBuilderEntry<FB::JSObjectPtr>());
  76. tdm.insert(makeBuilderEntry<FB::FBVoid>());
  77. tdm.insert(makeBuilderEntry<FB::FBNull>());
  78. return tdm;
  79. }
  80. const ComVariantBuilderMap& getComVariantBuilderMap()
  81. {
  82. static const ComVariantBuilderMap tdm = makeComVariantBuilderMap();
  83. return tdm;
  84. }
  85. // GJS ---
  86. template<class T>
  87. CComVariant makeArithmeticComVariant(const ActiveXBrowserHostPtr& host, const FB::variant& var)
  88. {
  89. return var.convert_cast<T>();
  90. }
  91. template<> inline
  92. CComVariant makeArithmeticComVariant<char>(const ActiveXBrowserHostPtr& host, const FB::variant& var)
  93. {
  94. return var.cast<char>();
  95. }
  96. template<> inline
  97. CComVariant makeArithmeticComVariant<unsigned char>(const ActiveXBrowserHostPtr& host, const FB::variant& var)
  98. {
  99. return var.cast<unsigned char>();
  100. }
  101. template<class T>
  102. CComVariant makeComVariant(const ActiveXBrowserHostPtr& host, const FB::variant& var)
  103. {
  104. CComVariant out;
  105. out.ChangeType(VT_NULL);
  106. return out;
  107. }
  108. template<> inline
  109. CComVariant makeComVariant<FB::FBNull>(const ActiveXBrowserHostPtr& host, const FB::variant& var)
  110. {
  111. CComVariant out;
  112. out.ChangeType(VT_NULL);
  113. return out;
  114. }
  115. template<> inline
  116. CComVariant makeComVariant<FB::FBVoid>(const ActiveXBrowserHostPtr& host, const FB::variant& var)
  117. {
  118. CComVariant out; // Just leave it at VT_EMPTY
  119. return out;
  120. }
  121. template<> inline
  122. CComVariant makeComVariant<std::string>(const ActiveXBrowserHostPtr& host, const FB::variant& var)
  123. {
  124. std::wstring wstr = var.convert_cast<std::wstring>();
  125. CComBSTR bStr(wstr.c_str());
  126. return bStr;
  127. }
  128. template<> inline
  129. CComVariant makeComVariant<std::wstring>(const ActiveXBrowserHostPtr& host, const FB::variant& var)
  130. {
  131. std::wstring wstr = var.convert_cast<std::wstring>();
  132. CComBSTR bStr(wstr.c_str());
  133. return bStr;
  134. }
  135. template<> inline
  136. CComVariant makeComVariant<FB::VariantList>(const ActiveXBrowserHostPtr& host, const FB::variant& var)
  137. {
  138. // GJS ---
  139. CComVariant outVar;
  140. FB::VariantList inArr = var.cast<FB::VariantList>();
  141. if (host->hasHTMLWindow())
  142. {
  143. FB::JSObjectPtr outArr = host->getDOMWindow()->createArray();
  144. for (FB::VariantList::iterator it = inArr.begin(); it != inArr.end(); it++) {
  145. FB::VariantList vl = boost::assign::list_of(*it);
  146. outArr->Invoke("push", vl);
  147. }
  148. IDispatchAPIPtr api = ptr_cast<IDispatchAPI>(outArr);
  149. if (api) {
  150. return api->getIDispatch();
  151. }
  152. }
  153. else
  154. {
  155. CComSafeArray<VARIANT> sa;
  156. const ComVariantBuilderMap& builderMap = getComVariantBuilderMap();
  157. for (FB::VariantList::iterator itr = inArr.begin(); itr != inArr.end(); itr++) {
  158. const std::type_info& type = itr->get_type();
  159. ComVariantBuilderMap::const_iterator found = builderMap.find(&type);
  160. if (found == builderMap.end())
  161. continue;
  162. CComVariant var = (found->second)(host, *itr);
  163. sa.Add(var);
  164. }
  165. outVar = sa.Detach();
  166. }
  167. return outVar;
  168. // GJS ---
  169. }
  170. template<> inline
  171. CComVariant makeComVariant<FB::VariantMap>(const ActiveXBrowserHostPtr& host, const FB::variant& var)
  172. {
  173. // GJS ---
  174. CComVariant outVar;
  175. FB::VariantMap inMap = var.cast<FB::VariantMap>();
  176. if (host->hasHTMLWindow())
  177. {
  178. FB::JSObjectPtr out = host->getDOMWindow()->createMap();
  179. for (FB::VariantMap::iterator it = inMap.begin(); it != inMap.end(); it++) {
  180. out->SetProperty(it->first, it->second);
  181. }
  182. IDispatchAPIPtr api = ptr_cast<IDispatchAPI>(out);
  183. if (api) {
  184. outVar = api->getIDispatch();
  185. }
  186. }
  187. else
  188. {
  189. CComSafeArray<VARIANT> sa;
  190. const ComVariantBuilderMap& builderMap = getComVariantBuilderMap();
  191. for (FB::VariantMap::iterator itr = inMap.begin(); itr != inMap.end(); itr++) {
  192. const std::type_info& valType = itr->second.get_type();
  193. ComVariantBuilderMap::const_iterator valTypeFound = builderMap.find(&valType);
  194. if (valTypeFound == builderMap.end())
  195. continue;
  196. CComSafeArray<VARIANT> sa2;
  197. CComVariant key = makeComVariant<std::string>(host, itr->first);
  198. CComVariant val = (valTypeFound->second)(host, itr->second);
  199. sa2.Add(key);
  200. sa2.Add(val);
  201. sa.Add(sa2.Detach());
  202. }
  203. if (sa.GetCount() > 0)
  204. outVar = sa.Detach();
  205. }
  206. return outVar;
  207. // GJS ---
  208. }
  209. template<> inline
  210. CComVariant makeComVariant<FB::JSAPIPtr>(const ActiveXBrowserHostPtr& host, const FB::variant& var)
  211. {
  212. CComVariant outVar;
  213. FB::JSAPIPtr obj(var.cast<FB::JSAPIPtr>());
  214. IDispatchAPIPtr api = ptr_cast<IDispatchAPI>(obj);
  215. if (api) {
  216. outVar = api->getIDispatch();
  217. } else {
  218. if (obj) {
  219. // Add obj to the list of shared_ptrs that browserhost keeps
  220. host->retainJSAPIPtr(obj);
  221. outVar = host->getJSAPIWrapper(obj, true);
  222. outVar.pdispVal->Release();
  223. } else {
  224. outVar.ChangeType(VT_NULL);
  225. }
  226. }
  227. return outVar;
  228. }
  229. template<> inline
  230. CComVariant makeComVariant<FB::JSAPIWeakPtr>(const ActiveXBrowserHostPtr& host, const FB::variant& var)
  231. {
  232. CComVariant outVar;
  233. FB::JSAPIPtr obj(var.convert_cast<FB::JSAPIPtr>());
  234. IDispatchAPIPtr api = ptr_cast<IDispatchAPI>(obj);
  235. if (api) {
  236. outVar = api->getIDispatch();
  237. } else {
  238. if (obj) {
  239. outVar = host->getJSAPIWrapper(obj);
  240. outVar.pdispVal->Release();
  241. } else {
  242. outVar.ChangeType(VT_NULL);
  243. }
  244. }
  245. return outVar;
  246. }
  247. template<> inline
  248. CComVariant makeComVariant<FB::JSObjectPtr>(const ActiveXBrowserHostPtr& host, const FB::variant& var)
  249. {
  250. CComVariant outVar;
  251. FB::JSObjectPtr obj(var.cast<FB::JSObjectPtr>());
  252. IDispatchAPIPtr api = ptr_cast<IDispatchAPI>(obj);
  253. if (api) {
  254. outVar = api->getIDispatch();
  255. } else {
  256. if (obj) {
  257. FB::JSAPIPtr ptr(var.convert_cast<FB::JSAPIPtr>());
  258. host->retainJSAPIPtr(ptr);
  259. outVar = getFactoryInstance()->createCOMJSObject(host, ptr);
  260. outVar.pdispVal->Release();
  261. } else {
  262. outVar.ChangeType(VT_NULL);
  263. }
  264. }
  265. return outVar;
  266. }
  267. namespace select_ccomvariant_builder
  268. {
  269. template<class T>
  270. ComVariantBuilder isArithmetic(const boost::true_type& /* is_arithmetic */)
  271. {
  272. return &makeArithmeticComVariant<T>;
  273. }
  274. template<class T>
  275. ComVariantBuilder isArithmetic(const boost::false_type& /* is_arithmetic */)
  276. {
  277. return &makeComVariant<T>;
  278. }
  279. template<class T>
  280. ComVariantBuilder select()
  281. {
  282. return isArithmetic<T>(boost::is_arithmetic<T>());
  283. }
  284. }
  285. } }
  286. #endif