summaryrefslogtreecommitdiffstats
path: root/chrome_frame/scoped_ns_ptr_win.h
diff options
context:
space:
mode:
authorslightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-24 05:11:58 +0000
committerslightlyoff@chromium.org <slightlyoff@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-24 05:11:58 +0000
commitf781782dd67077478e117c61dca4ea5eefce3544 (patch)
tree4801f724123cfdcbb69c4e7fe40a565b331723ae /chrome_frame/scoped_ns_ptr_win.h
parent63cf4759efa2373e33436fb5df6849f930081226 (diff)
downloadchromium_src-f781782dd67077478e117c61dca4ea5eefce3544.zip
chromium_src-f781782dd67077478e117c61dca4ea5eefce3544.tar.gz
chromium_src-f781782dd67077478e117c61dca4ea5eefce3544.tar.bz2
Initial import of the Chrome Frame codebase. Integration in chrome.gyp coming in a separate CL.
BUG=None TEST=None Review URL: http://codereview.chromium.org/218019 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27042 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/scoped_ns_ptr_win.h')
-rw-r--r--chrome_frame/scoped_ns_ptr_win.h149
1 files changed, 149 insertions, 0 deletions
diff --git a/chrome_frame/scoped_ns_ptr_win.h b/chrome_frame/scoped_ns_ptr_win.h
new file mode 100644
index 0000000..91780fd
--- /dev/null
+++ b/chrome_frame/scoped_ns_ptr_win.h
@@ -0,0 +1,149 @@
+// 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_SCOPED_NS_PTR_WIN_H_
+#define CHROME_FRAME_SCOPED_NS_PTR_WIN_H_
+
+#include "base/logging.h"
+#include "base/ref_counted.h"
+
+#include "third_party/xulrunner-sdk/win/include/xpcom/nsISupports.h"
+
+
+// Utility template to prevent users of ScopedNsPtr from calling AddRef and/or
+// Release() without going through the ScopedNsPtr class.
+template <class nsInterface>
+class BlocknsISupportsMethods : public nsInterface {
+ private:
+ NS_IMETHOD QueryInterface(REFNSIID iid, void** object) = 0;
+ NS_IMETHOD_(nsrefcnt) AddRef() = 0;
+ NS_IMETHOD_(nsrefcnt) Release() = 0;
+};
+
+// A smart pointer class for nsISupports.
+// Based on ScopedComPtr.
+// We have our own class instead of nsCOMPtr. nsCOMPtr has parts of its
+// implementation in the xpcomglue lib which we can't use since that lib
+// is built with incompatible build flags to ours.
+template <class nsInterface,
+ const nsIID* interface_id =
+ reinterpret_cast<const nsIID*>(&__uuidof(nsInterface))>
+class ScopedNsPtr : public scoped_refptr<nsInterface> {
+ public:
+ typedef scoped_refptr<nsInterface> ParentClass;
+
+ ScopedNsPtr() {
+ }
+
+ explicit ScopedNsPtr(nsInterface* p) : ParentClass(p) {
+ }
+
+ explicit ScopedNsPtr(const ScopedNsPtr<nsInterface, interface_id>& p)
+ : ParentClass(p) {
+ }
+
+ ~ScopedNsPtr() {
+ // We don't want the smart pointer class to be bigger than the pointer
+ // it wraps.
+ COMPILE_ASSERT(sizeof(ScopedNsPtr<nsInterface, interface_id>) ==
+ sizeof(nsInterface*), ScopedNsPtrSize);
+ }
+
+ // Explicit Release() of the held object. Useful for reuse of the
+ // ScopedNsPtr instance.
+ // Note that this function equates to nsISupports::Release and should not
+ // be confused with e.g. scoped_ptr::release().
+ void Release() {
+ if (ptr_ != NULL) {
+ ptr_->Release();
+ ptr_ = NULL;
+ }
+ }
+
+ // Sets the internal pointer to NULL and returns the held object without
+ // releasing the reference.
+ nsInterface* Detach() {
+ nsInterface* p = ptr_;
+ ptr_ = NULL;
+ return p;
+ }
+
+ // Accepts an interface pointer that has already been addref-ed.
+ void Attach(nsInterface* p) {
+ DCHECK(ptr_ == NULL);
+ ptr_ = p;
+ }
+
+ // Retrieves the pointer address.
+ // Used to receive object pointers as out arguments (and take ownership).
+ // The function DCHECKs on the current value being NULL.
+ // Usage: Foo(p.Receive());
+ nsInterface** Receive() {
+ DCHECK(ptr_ == NULL) << "Object leak. Pointer must be NULL";
+ return &ptr_;
+ }
+
+ template <class Query>
+ nsresult QueryInterface(Query** p) {
+ DCHECK(p != NULL);
+ DCHECK(ptr_ != NULL);
+ return ptr_->QueryInterface(Query::GetIID(), reinterpret_cast<void**>(p));
+ }
+
+ template <class Query>
+ nsresult QueryInterface(const nsIID& iid, Query** p) {
+ DCHECK(p != NULL);
+ DCHECK(ptr_ != NULL);
+ return ptr_->QueryInterface(iid, reinterpret_cast<void**>(p));
+ }
+
+ // Queries |other| for the interface this object wraps and returns the
+ // error code from the other->QueryInterface operation.
+ nsresult QueryFrom(nsISupports* other) {
+ DCHECK(other != NULL);
+ return other->QueryInterface(iid(), reinterpret_cast<void**>(Receive()));
+ }
+
+ // Checks if the identity of |other| and this object is the same.
+ bool IsSameObject(nsISupports* other) {
+ if (!other && !ptr_)
+ return true;
+
+ if (!other || !ptr_)
+ return false;
+
+ nsIID iid = NS_ISUPPORTS_IID;
+ ScopedNsPtr<nsISupports, iid> my_identity;
+ QueryInterface(my_identity.Receive());
+
+ ScopedNsPtr<nsISupports, iid> other_identity;
+ other->QueryInterface(other_identity.Receive());
+
+ return static_cast<nsISupports*>(my_identity) ==
+ static_cast<nsISupports*>(other_identity);
+ }
+
+ // Provides direct access to the interface.
+ // Here we use a well known trick to make sure we block access to
+ // IUknown methods so that something bad like this doesn't happen:
+ // ScopedNsPtr<nsISupports> p(Foo());
+ // p->Release();
+ // ... later the destructor runs, which will Release() again.
+ // and to get the benefit of the DCHECKs we add to QueryInterface.
+ // There's still a way to call these methods if you absolutely must
+ // by statically casting the ScopedNsPtr instance to the wrapped interface
+ // and then making the call... but generally that shouldn't be necessary.
+ BlocknsISupportsMethods<nsInterface>* operator->() const {
+ DCHECK(ptr_ != NULL);
+ return reinterpret_cast<BlocknsISupportsMethods<nsInterface>*>(ptr_);
+ }
+
+ // static methods
+
+ static const nsIID& iid() {
+ return *interface_id;
+ }
+};
+
+#endif // CHROME_FRAME_SCOPED_NS_PTR_WIN_H_