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

Side by Side Diff: base/scoped_comptr_win.h

Issue 3781009: Move the windows-specific scoped_* stuff from base to base/win and in the bas... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 2 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef BASE_SCOPED_COMPTR_WIN_H_ 5 // TODO(brettw) remove this file when all callers are converted to using the
6 #define BASE_SCOPED_COMPTR_WIN_H_ 6 // new location/namespace
7 #pragma once 7 #include "base/win/scoped_comptr.h"
8 8
9 #include <unknwn.h> 9 using base::win::ScopedComPtr;
10
11 #include "base/logging.h"
12 #include "base/ref_counted.h"
13
14 // Utility template to prevent users of ScopedComPtr from calling AddRef and/or
15 // Release() without going through the ScopedComPtr class.
16 template <class Interface>
17 class BlockIUnknownMethods : public Interface {
18 private:
19 STDMETHOD(QueryInterface)(REFIID iid, void** object) = 0;
20 STDMETHOD_(ULONG, AddRef)() = 0;
21 STDMETHOD_(ULONG, Release)() = 0;
22 };
23
24 // A fairly minimalistic smart class for COM interface pointers.
25 // Uses scoped_refptr for the basic smart pointer functionality
26 // and adds a few IUnknown specific services.
27 template <class Interface, const IID* interface_id = &__uuidof(Interface)>
28 class ScopedComPtr : public scoped_refptr<Interface> {
29 public:
30 typedef scoped_refptr<Interface> ParentClass;
31
32 ScopedComPtr() {
33 }
34
35 explicit ScopedComPtr(Interface* p) : ParentClass(p) {
36 }
37
38 ScopedComPtr(const ScopedComPtr<Interface, interface_id>& p)
39 : ParentClass(p) {
40 }
41
42 ~ScopedComPtr() {
43 // We don't want the smart pointer class to be bigger than the pointer
44 // it wraps.
45 COMPILE_ASSERT(sizeof(ScopedComPtr<Interface, interface_id>) ==
46 sizeof(Interface*), ScopedComPtrSize);
47 }
48
49 // Explicit Release() of the held object. Useful for reuse of the
50 // ScopedComPtr instance.
51 // Note that this function equates to IUnknown::Release and should not
52 // be confused with e.g. scoped_ptr::release().
53 void Release() {
54 if (ptr_ != NULL) {
55 ptr_->Release();
56 ptr_ = NULL;
57 }
58 }
59
60 // Sets the internal pointer to NULL and returns the held object without
61 // releasing the reference.
62 Interface* Detach() {
63 Interface* p = ptr_;
64 ptr_ = NULL;
65 return p;
66 }
67
68 // Accepts an interface pointer that has already been addref-ed.
69 void Attach(Interface* p) {
70 DCHECK(ptr_ == NULL);
71 ptr_ = p;
72 }
73
74 // Retrieves the pointer address.
75 // Used to receive object pointers as out arguments (and take ownership).
76 // The function DCHECKs on the current value being NULL.
77 // Usage: Foo(p.Receive());
78 Interface** Receive() {
79 DCHECK(ptr_ == NULL) << "Object leak. Pointer must be NULL";
80 return &ptr_;
81 }
82
83 template <class Query>
84 HRESULT QueryInterface(Query** p) {
85 DCHECK(p != NULL);
86 DCHECK(ptr_ != NULL);
87 // IUnknown already has a template version of QueryInterface
88 // so the iid parameter is implicit here. The only thing this
89 // function adds are the DCHECKs.
90 return ptr_->QueryInterface(p);
91 }
92
93 // QI for times when the IID is not associated with the type.
94 HRESULT QueryInterface(const IID& iid, void** obj) {
95 DCHECK(obj != NULL);
96 DCHECK(ptr_ != NULL);
97 return ptr_->QueryInterface(iid, obj);
98 }
99
100 // Queries |other| for the interface this object wraps and returns the
101 // error code from the other->QueryInterface operation.
102 HRESULT QueryFrom(IUnknown* object) {
103 DCHECK(object != NULL);
104 return object->QueryInterface(Receive());
105 }
106
107 // Convenience wrapper around CoCreateInstance
108 HRESULT CreateInstance(const CLSID& clsid, IUnknown* outer = NULL,
109 DWORD context = CLSCTX_ALL) {
110 DCHECK(ptr_ == NULL);
111 HRESULT hr = ::CoCreateInstance(clsid, outer, context, *interface_id,
112 reinterpret_cast<void**>(&ptr_));
113 return hr;
114 }
115
116 // Checks if the identity of |other| and this object is the same.
117 bool IsSameObject(IUnknown* other) {
118 if (!other && !ptr_)
119 return true;
120
121 if (!other || !ptr_)
122 return false;
123
124 ScopedComPtr<IUnknown> my_identity;
125 QueryInterface(my_identity.Receive());
126
127 ScopedComPtr<IUnknown> other_identity;
128 other->QueryInterface(other_identity.Receive());
129
130 return static_cast<IUnknown*>(my_identity) ==
131 static_cast<IUnknown*>(other_identity);
132 }
133
134 // Provides direct access to the interface.
135 // Here we use a well known trick to make sure we block access to
136 // IUknown methods so that something bad like this doesn't happen:
137 // ScopedComPtr<IUnknown> p(Foo());
138 // p->Release();
139 // ... later the destructor runs, which will Release() again.
140 // and to get the benefit of the DCHECKs we add to QueryInterface.
141 // There's still a way to call these methods if you absolutely must
142 // by statically casting the ScopedComPtr instance to the wrapped interface
143 // and then making the call... but generally that shouldn't be necessary.
144 BlockIUnknownMethods<Interface>* operator->() const {
145 DCHECK(ptr_ != NULL);
146 return reinterpret_cast<BlockIUnknownMethods<Interface>*>(ptr_);
147 }
148
149 // Pull in operator=() from the parent class.
150 using scoped_refptr<Interface>::operator=;
151
152 // static methods
153
154 static const IID& iid() {
155 return *interface_id;
156 }
157 };
158
159 #endif // BASE_SCOPED_COMPTR_WIN_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698