1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 2005
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Mark Hammond <mhammond@skippinet.com.au>
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either of the GNU General Public License Version 2 or later (the "GPL"),
27 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : #ifndef nsDOMScriptObjectHolder_h__
40 : #define nsDOMScriptObjectHolder_h__
41 :
42 : #include "nsIScriptContext.h"
43 : #include "nsIDOMScriptObjectFactory.h"
44 :
45 : #include "jspubtd.h"
46 :
47 : // A thin class used to help with script object memory management. No virtual
48 : // functions and a fully inline implementation should keep the cost down.
49 : // [Note that a fully inline implementation is necessary for use by other
50 : // languages, which do not link against the layout component module]
51 : template<class T>
52 : class NS_STACK_CLASS nsScriptObjectHolder {
53 : public:
54 : // A constructor that will cause a reference to |ctx| to be stored in
55 : // the object. Only use for short-lived object holders.
56 0 : nsScriptObjectHolder<T>(nsIScriptContext *ctx, T* aObject = nsnull) :
57 0 : mObject(aObject), mContext(ctx) {
58 0 : NS_ASSERTION(ctx, "Must provide a valid context");
59 0 : }
60 :
61 : // copy constructor
62 : nsScriptObjectHolder<T>(const nsScriptObjectHolder<T>& other) :
63 : mObject(other.mObject),
64 : mContext(other.mContext)
65 : {
66 : // New hold the script object and new reference on the script context.
67 : if (mObject)
68 : mContext->HoldScriptObject(mObject);
69 : }
70 :
71 0 : ~nsScriptObjectHolder<T>() {
72 0 : if (mObject)
73 0 : mContext->DropScriptObject(mObject);
74 0 : }
75 :
76 : // misc operators
77 : nsScriptObjectHolder<T> &operator=(const nsScriptObjectHolder<T> &other) {
78 : set(other);
79 : return *this;
80 : }
81 : bool operator!() const {
82 : return !mObject;
83 : }
84 0 : operator bool() const {
85 0 : return !!mObject;
86 : }
87 0 : T* get() const {
88 0 : return mObject;
89 : }
90 :
91 : // Drop the script object - but *not* the nsIScriptContext.
92 0 : nsresult drop() {
93 0 : nsresult rv = NS_OK;
94 0 : if (mObject) {
95 0 : rv = mContext->DropScriptObject(mObject);
96 0 : mObject = nsnull;
97 : }
98 0 : return rv;
99 : }
100 :
101 0 : nsresult set(T* object) {
102 0 : NS_ASSERTION(getScriptTypeID() != nsIProgrammingLanguage::UNKNOWN,
103 : "Must know the language!");
104 0 : nsresult rv = drop();
105 0 : if (NS_FAILED(rv))
106 0 : return rv;
107 0 : if (object) {
108 0 : rv = mContext->HoldScriptObject(object);
109 : // don't store the pointer if we failed to lock it.
110 0 : if (NS_SUCCEEDED(rv)) {
111 0 : mObject = object;
112 : }
113 : }
114 0 : return rv;
115 : }
116 : nsresult set(const nsScriptObjectHolder<T> &other) {
117 : NS_ASSERTION(getScriptTypeID() == other.getScriptTypeID(),
118 : "Must have identical languages!");
119 : nsresult rv = drop();
120 : if (NS_FAILED(rv))
121 : return rv;
122 : return set(other.mObject);
123 : }
124 : // Get the language ID.
125 0 : PRUint32 getScriptTypeID() const {
126 0 : return mContext->GetScriptTypeID();
127 : }
128 : protected:
129 : T* mObject;
130 : nsCOMPtr<nsIScriptContext> mContext;
131 : };
132 :
133 : #endif // nsDOMScriptObjectHolder_h__
|