OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #ifndef WEBKIT_GLUE_PLUGINS_PEPPER_VAR_H_ | |
6 #define WEBKIT_GLUE_PLUGINS_PEPPER_VAR_H_ | |
7 | |
8 #include <string> | |
9 | |
10 #include "webkit/glue/plugins/pepper_resource.h" | |
11 | |
12 struct PP_Var; | |
13 struct PPB_Var; | |
14 struct PPB_Var_Deprecated; | |
15 typedef struct NPObject NPObject; | |
16 typedef struct _NPVariant NPVariant; | |
17 typedef void* NPIdentifier; | |
18 | |
19 namespace pepper { | |
20 | |
21 // Var ------------------------------------------------------------------------- | |
22 | |
23 // Represents a non-POD var. This is derived from a resource even though it | |
24 // isn't a resource from the plugin's perspective. This allows us to re-use | |
25 // the refcounting and the association with the module from the resource code. | |
26 class Var : public Resource { | |
27 public: | |
28 virtual ~Var(); | |
29 | |
30 // Resource overrides. | |
31 virtual Var* AsVar(); | |
32 | |
33 // Returns a PP_Var that corresponds to the given NPVariant. The contents of | |
34 // the NPVariant will be copied unless the NPVariant corresponds to an | |
35 // object. This will handle all Variant types including POD, strings, and | |
36 // objects. | |
37 // | |
38 // The returned PP_Var will have a refcount of 1, this passing ownership of | |
39 // the reference to the caller. This is suitable for returning to a plugin. | |
40 static PP_Var NPVariantToPPVar(PluginModule* module, | |
41 const NPVariant* variant); | |
42 | |
43 // Returns a NPIdentifier that corresponds to the given PP_Var. The contents | |
44 // of the PP_Var will be copied. Returns 0 if the given PP_Var is not a a | |
45 // string or integer type. | |
46 static NPIdentifier PPVarToNPIdentifier(PP_Var var); | |
47 | |
48 // Returns a PP_Var corresponding to the given identifier. In the case of | |
49 // a string identifier, the string will be allocated associated with the | |
50 // given module. A returned string will have a reference count of 1. | |
51 static PP_Var NPIdentifierToPPVar(PluginModule* module, NPIdentifier id); | |
52 | |
53 // Provides access to the manual refcounting of a PP_Var from the plugin's | |
54 // perspective. This is different than the AddRef/Release on this scoped | |
55 // object. This uses the ResourceTracker, which keeps a separate "plugin | |
56 // refcount" that prevents the plugin from messing up our refcounting or | |
57 // freeing something out from under us. | |
58 // | |
59 // You should not generally need to use these functions. However, if you | |
60 // call a plugin function that returns a var, it will transfer a ref to us | |
61 // (the caller) which in the case of a string or object var will need to | |
62 // be released. | |
63 // | |
64 // Example, assuming we're expecting the plugin to return a string: | |
65 // PP_Var rv = some_ppp_interface->DoSomething(a, b, c); | |
66 // | |
67 // // Get the string value. This will take a reference to the object which | |
68 // // will prevent it from being deleted out from under us when we call | |
69 // // PluginReleasePPVar(). | |
70 // scoped_refptr<StringVar> string(StringVar::FromPPVar(rv)); | |
71 // | |
72 // // Release the reference the plugin gave us when returning the value. | |
73 // // This is legal to do for all types of vars. | |
74 // Var::PluginReleasePPVar(rv); | |
75 // | |
76 // // Use the string. | |
77 // if (!string) | |
78 // return false; // It didn't return a proper string. | |
79 // UseTheString(string->value()); | |
80 static void PluginAddRefPPVar(PP_Var var); | |
81 static void PluginReleasePPVar(PP_Var var); | |
82 | |
83 // Returns the PPB_Var_Deprecated interface for the plugin to use. | |
84 static const PPB_Var_Deprecated* GetDeprecatedInterface(); | |
85 | |
86 // Returns the PPB_Var interface for the plugin to use. | |
87 static const PPB_Var* GetInterface(); | |
88 | |
89 protected: | |
90 // This can only be constructed as a StringVar or an ObjectVar. | |
91 explicit Var(PluginModule* module); | |
92 | |
93 private: | |
94 DISALLOW_COPY_AND_ASSIGN(Var); | |
95 }; | |
96 | |
97 // StringVar ------------------------------------------------------------------- | |
98 | |
99 // Represents a string-based Var. | |
100 // | |
101 // Returning a given string as a PP_Var: | |
102 // return StringVar::StringToPPVar(module, my_string); | |
103 // | |
104 // Converting a PP_Var to a string: | |
105 // scoped_refptr<StringVar> string(StringVar::FromPPVar(var)); | |
106 // if (!string) | |
107 // return false; // Not a string or an invalid var. | |
108 // DoSomethingWithTheString(string->value()); | |
109 class StringVar : public Var { | |
110 public: | |
111 StringVar(PluginModule* module, const char* str, uint32 len); | |
112 virtual ~StringVar(); | |
113 | |
114 const std::string& value() const { return value_; } | |
115 | |
116 // Resource overrides. | |
117 virtual StringVar* AsStringVar(); | |
118 | |
119 // Helper function to create a PP_Var of type string that contains a copy of | |
120 // the given string. The input data must be valid UTF-8 encoded text, if it | |
121 // is not valid UTF-8, a NULL var will be returned. | |
122 // | |
123 // The return value will have a reference count of 1. Internally, this will | |
124 // create a StringVar, associate it with a module, and return the reference | |
125 // to it in the var. | |
126 static PP_Var StringToPPVar(PluginModule* module, const std::string& str); | |
127 static PP_Var StringToPPVar(PluginModule* module, | |
128 const char* str, uint32 len); | |
129 | |
130 // Helper function that converts a PP_Var to a string. This will return NULL | |
131 // if the PP_Var is not of string type or the string is invalid. | |
132 static scoped_refptr<StringVar> FromPPVar(PP_Var var); | |
133 | |
134 private: | |
135 std::string value_; | |
136 | |
137 DISALLOW_COPY_AND_ASSIGN(StringVar); | |
138 }; | |
139 | |
140 // ObjectVar ------------------------------------------------------------------- | |
141 | |
142 // Represents a JavaScript object Var. By itself, this represents random | |
143 // NPObjects that a given plugin (identified by the resource's module) wants to | |
144 // reference. If two different modules reference the same NPObject (like the | |
145 // "window" object), then there will be different ObjectVar's (and hence PP_Var | |
146 // IDs) for each module. This allows us to track all references owned by a | |
147 // given module and free them when the plugin exits independently of other | |
148 // plugins that may be running at the same time. | |
149 // | |
150 // See StringVar for examples, except obviously using NPObjects instead of | |
151 // strings. | |
152 class ObjectVar : public Var { | |
153 public: | |
154 virtual ~ObjectVar(); | |
155 | |
156 // Resource overrides. | |
157 virtual ObjectVar* AsObjectVar(); | |
158 | |
159 // Returns the underlying NPObject corresponding to this ObjectVar. | |
160 // Guaranteed non-NULL. | |
161 NPObject* np_object() const { return np_object_; } | |
162 | |
163 // Helper function to create a PP_Var of type object that contains the given | |
164 // NPObject for use byt he given module. Calling this function multiple times | |
165 // given the same module + NPObject results in the same PP_Var, assuming that | |
166 // there is still a PP_Var with a reference open to it from the previous | |
167 // call. | |
168 // | |
169 // The module is necessary because we can have different modules pointing to | |
170 // the same NPObject, and we want to keep their refs separate. | |
171 // | |
172 // If no ObjectVar currently exists corresponding to the NPObject, one is | |
173 // created associated with the given module. | |
174 static PP_Var NPObjectToPPVar(PluginModule* module, NPObject* object); | |
175 | |
176 // Helper function that converts a PP_Var to an object. This will return NULL | |
177 // if the PP_Var is not of object type or the object is invalid. | |
178 static scoped_refptr<ObjectVar> FromPPVar(PP_Var var); | |
179 | |
180 protected: | |
181 // You should always use FromNPObject to create an ObjectVar. This function | |
182 // guarantees that we maintain the 1:1 mapping between NPObject and | |
183 // ObjectVar. | |
184 ObjectVar(PluginModule* module, NPObject* np_object); | |
185 | |
186 private: | |
187 // Guaranteed non-NULL, this is the underlying object used by WebKit. We | |
188 // hold a reference to this object. | |
189 NPObject* np_object_; | |
190 | |
191 DISALLOW_COPY_AND_ASSIGN(ObjectVar); | |
192 }; | |
193 | |
194 // TryCatch -------------------------------------------------------------------- | |
195 | |
196 // Instantiate this object on the stack to catch V8 exceptions and pass them | |
197 // to an optional out parameter supplied by the plugin. | |
198 class TryCatch { | |
199 public: | |
200 // The given exception may be NULL if the consumer isn't interested in | |
201 // catching exceptions. If non-NULL, the given var will be updated if any | |
202 // exception is thrown (so it must outlive the TryCatch object). | |
203 // | |
204 // The module associated with the exception is passed so we know which module | |
205 // to associate any exception string with. It may be NULL if you don't know | |
206 // the module at construction time, in which case you should set it later | |
207 // by calling set_module(). | |
208 // | |
209 // If an exception is thrown when the module is NULL, setting *any* exception | |
210 // will result in using the InvalidObjectException. | |
211 TryCatch(PluginModule* module, PP_Var* exception); | |
212 ~TryCatch(); | |
213 | |
214 // Get and set the module. This may be NULL (see the constructor). | |
215 PluginModule* module() { return module_; } | |
216 void set_module(PluginModule* module) { module_ = module; } | |
217 | |
218 // Returns true is an exception has been thrown. This can be true immediately | |
219 // after construction if the var passed to the constructor is non-void. | |
220 bool has_exception() const { return has_exception_; } | |
221 | |
222 // Sets the given exception. If no module has been set yet, the message will | |
223 // be ignored (since we have no module to associate the string with) and the | |
224 // SetInvalidObjectException() will be used instead. | |
225 // | |
226 // If an exception has been previously set, this function will do nothing | |
227 // (normally you want only the first exception). | |
228 void SetException(const char* message); | |
229 | |
230 // Sets the exception to be a generic message contained in a magic string | |
231 // not associated with any module. | |
232 void SetInvalidObjectException(); | |
233 | |
234 private: | |
235 static void Catch(void* self, const char* message); | |
236 | |
237 PluginModule* module_; | |
238 | |
239 // True if an exception has been thrown. Since the exception itself may be | |
240 // NULL if the plugin isn't interested in getting the exception, this will | |
241 // always indicate if SetException has been called, regardless of whether | |
242 // the exception itself has been stored. | |
243 bool has_exception_; | |
244 | |
245 // May be null if the consumer isn't interesting in catching exceptions. | |
246 PP_Var* exception_; | |
247 }; | |
248 | |
249 } // namespace pepper | |
250 | |
251 #endif // WEBKIT_GLUE_PLUGINS_PEPPER_VAR_H_ | |
OLD | NEW |