Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3756)

Unified Diff: chrome_frame/com_type_info_holder.h

Issue 218019: Initial import of the Chrome Frame codebase. Integration in chrome.gyp coming... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome_frame/com_message_event.cc ('k') | chrome_frame/com_type_info_holder.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome_frame/com_type_info_holder.h
===================================================================
--- chrome_frame/com_type_info_holder.h (revision 0)
+++ chrome_frame/com_type_info_holder.h (revision 0)
@@ -0,0 +1,191 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_FRAME_COM_TYPE_INFO_HOLDER_H_
+#define CHROME_FRAME_COM_TYPE_INFO_HOLDER_H_
+
+#include <map>
+#include <ocidl.h> // IProvideClassInfo2
+
+#include "base/lock.h"
+#include "base/scoped_comptr_win.h"
+
+#define NO_VTABLE __declspec(novtable)
+
+namespace com_util {
+
+// A map from a name hash (32 bit value) to a DISPID.
+// Used as a caching layer before looking the name up in a type lib.
+class NameToDispIdCache {
+ public:
+ typedef uint32 HashType;
+
+ bool Lookup(HashType hash, DISPID* dispid) const;
+ void Add(HashType hash, DISPID dispid);
+
+ // Hashes the name by calling LHashValOfName.
+ // The returned hash value is independent of the case of the characters
+ // in |name|.
+ static HashType Hash(const wchar_t* name);
+
+ protected:
+ typedef std::map<HashType, DISPID> DispidMap;
+ DispidMap map_;
+ mutable Lock lock_;
+};
+
+// Wraps an instance of ITypeInfo and builds+maintains a cache of names
+// to dispids. Also offers an Invoke method that simply forwards the call
+// to ITypeInfo::Invoke.
+class TypeInfoNameCache {
+ public:
+ // Loads the module's type library and fetches the ITypeInfo object for
+ // the specified interface ID.
+ HRESULT Initialize(const IID& iid);
+
+ // Fetches the id's of the given names. If there's a cache miss, the results
+ // are fetched from the underlying ITypeInfo and then cached.
+ HRESULT GetIDsOfNames(OLECHAR** names, uint32 count, DISPID* dispids);
+
+ // Calls ITypeInfo::Invoke.
+ HRESULT Invoke(IDispatch* p, DISPID dispid, WORD flags, DISPPARAMS* params,
+ VARIANT* result, EXCEPINFO* excepinfo, UINT* arg_err);
+
+ inline ITypeInfo* CopyTypeInfo() {
+ ITypeInfo* ti = type_info_.get();
+ if (ti)
+ ti->AddRef();
+ return ti;
+ }
+
+ protected:
+ ScopedComPtr<ITypeInfo> type_info_;
+ NameToDispIdCache cache_;
+};
+
+// The root class for type lib access.
+// This class has only one instance that should be accessed via the
+// Singleton method.
+class TypeInfoCache {
+ public:
+ TypeInfoCache() {
+ }
+
+ ~TypeInfoCache();
+
+ // Looks up a previously cached TypeInfoNameCache instance or creates and
+ // caches a new one.
+ TypeInfoNameCache* Lookup(const IID* iid);
+
+ // Call to get access to the singleton instance of TypeInfoCache.
+ static TypeInfoCache* Singleton();
+
+ protected:
+ typedef std::map<const IID*, TypeInfoNameCache*> CacheMap;
+ Lock lock_;
+ CacheMap cache_;
+};
+
+// Holds a pointer to the type info of a given COM interface.
+// The type info is loaded once on demand and after that cached.
+// NOTE: This class only supports loading the first typelib from the
+// current module.
+template <const IID& iid>
+class TypeInfoHolder {
+ public:
+ TypeInfoHolder() : type_info_(NULL) {
+ }
+
+ bool EnsureTI() {
+ if (!type_info_)
+ type_info_ = TypeInfoCache::Singleton()->Lookup(&iid);
+ return type_info_ != NULL;
+ }
+
+ HRESULT GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** info) {
+ if (EnsureTI()) {
+ *info = type_info_->CopyTypeInfo();
+ return S_OK;
+ }
+
+ return E_UNEXPECTED;
+ }
+
+ HRESULT GetIDsOfNames(REFIID riid, OLECHAR** names, UINT count, LCID lcid,
+ DISPID* dispids) {
+ if (!EnsureTI())
+ return E_UNEXPECTED;
+ return type_info_->GetIDsOfNames(names, count, dispids);
+ }
+
+ HRESULT Invoke(IDispatch* p, DISPID dispid, REFIID riid, LCID lcid,
+ WORD flags, DISPPARAMS* params, VARIANT* result,
+ EXCEPINFO* excepinfo, UINT* arg_err) {
+ if (!EnsureTI())
+ return E_UNEXPECTED;
+
+ return type_info_->Invoke(p, dispid, flags, params, result, excepinfo,
+ arg_err);
+ }
+
+ protected:
+ TypeInfoNameCache* type_info_;
+};
+
+// Implements IDispatch part of T (where T is an IDispatch derived interface).
+// The class assumes that the type info of T is available in a typelib of the
+// current module.
+template <class T, const IID& iid = __uuidof(T)>
+class NO_VTABLE IDispatchImpl : public T {
+ public:
+ STDMETHOD(GetTypeInfoCount)(UINT* count) {
+ if (count == NULL)
+ return E_POINTER;
+ *count = 1;
+ return S_OK;
+ }
+
+ STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo** pptinfo) {
+ return type_info_.GetTypeInfo(itinfo, lcid, pptinfo);
+ }
+
+ STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR* names, UINT count,
+ LCID lcid, DISPID* dispids) {
+ return type_info_.GetIDsOfNames(riid, names, count, lcid, dispids);
+ }
+ STDMETHOD(Invoke)(DISPID dispid, REFIID riid, LCID lcid, WORD flags,
+ DISPPARAMS* params, VARIANT* result, EXCEPINFO* excepinfo,
+ UINT* arg_err) {
+ return type_info_.Invoke(static_cast<IDispatch*>(this), dispid, riid, lcid,
+ flags, params, result, excepinfo, arg_err);
+ }
+
+ protected:
+ TypeInfoHolder<iid> type_info_;
+};
+
+// Simple implementation of IProvideClassInfo[2].
+template <const CLSID& class_id, const IID& source_iid>
+class NO_VTABLE IProvideClassInfo2Impl : public IProvideClassInfo2 {
+ public:
+ STDMETHOD(GetClassInfo)(ITypeInfo** pptinfo) {
+ return type_info_.GetTypeInfo(0, LANG_NEUTRAL, pptinfo);
+ }
+
+ STDMETHOD(GetGUID)(DWORD guid_kind, GUID* guid) {
+ if(guid == NULL || guid_kind != GUIDKIND_DEFAULT_SOURCE_DISP_IID)
+ return E_INVALIDARG;
+
+ *guid = source_iid;
+
+ return S_OK;
+ }
+
+ protected:
+ TypeInfoHolder<class_id> type_info_;
+};
+
+} // namespace com_util
+
+#endif // CHROME_FRAME_COM_TYPE_INFO_HOLDER_H_
« no previous file with comments | « chrome_frame/com_message_event.cc ('k') | chrome_frame/com_type_info_holder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698