Index: ppapi/proxy/plugin_var_tracker.cc |
=================================================================== |
--- ppapi/proxy/plugin_var_tracker.cc (revision 0) |
+++ ppapi/proxy/plugin_var_tracker.cc (revision 0) |
@@ -0,0 +1,134 @@ |
+// Copyright (c) 2010 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. |
+ |
+#include "ppapi/proxy/plugin_var_tracker.h" |
+ |
+#include "base/ref_counted.h" |
+#include "ppapi/c/ppb_var.h" |
+#include "ppapi/proxy/plugin_dispatcher.h" |
+#include "ppapi/proxy/ppapi_messages.h" |
+ |
+namespace pp { |
+namespace proxy { |
+ |
+namespace { |
+ |
+class RefCountedString : public base::RefCounted<RefCountedString> { |
+ public: |
+ RefCountedString() { |
+ } |
+ RefCountedString(const std::string& str) : value_(str) { |
+ } |
+ RefCountedString(const char* data, size_t len) |
+ : value_(data, len) { |
+ } |
+ |
+ const std::string& value() const { return value_; } |
+ |
+ private: |
+ std::string value_; |
+}; |
+ |
+// When running in the plugin, this will convert the string ID to the object |
+// using casting. No validity checking is done. |
+RefCountedString* PluginStringFromID(int64 id) { |
+ return reinterpret_cast<RefCountedString*>(static_cast<intptr_t>(id)); |
+} |
+ |
+} // namespace |
+ |
+PluginVarTracker::PluginVarTracker(PluginDispatcher* dispatcher) |
+ : dispatcher_(dispatcher), |
+ browser_var_interface_(NULL) { |
+} |
+ |
+void PluginVarTracker::Init() { |
+ browser_var_interface_ = reinterpret_cast<const PPB_Var*>( |
+ dispatcher_->GetLocalInterface(PPB_VAR_INTERFACE)); |
+} |
+ |
+int64 PluginVarTracker::MakeString(const std::string& str) { |
+ RefCountedString* out = new RefCountedString(str); |
+ out->AddRef(); |
+ return static_cast<int64>(reinterpret_cast<intptr_t>(out)); |
+} |
+ |
+std::string PluginVarTracker::GetString(const PP_Var& var) const { |
+ return PluginStringFromID(var.value.as_id)->value(); |
+} |
+ |
+const std::string* PluginVarTracker::GetExistingString( |
+ const PP_Var& var) const { |
+ if (var.type != PP_VARTYPE_STRING) |
+ return NULL; |
+ RefCountedString* str = PluginStringFromID(var.value.as_id); |
+ return &str->value(); |
+} |
+ |
+void PluginVarTracker::AddRef(const PP_Var& var) { |
+ if (var.type == PP_VARTYPE_STRING) { |
+ PluginStringFromID(var.value.as_id)->AddRef(); |
+ } else if (var.type == PP_VARTYPE_OBJECT && var.value.as_id != 0) { |
+ int& ref_count = object_ref_count_[var.value.as_id]; |
+ ref_count++; |
+ if (ref_count == 1) { |
+ // We must handle the case where we got requested to AddRef an object |
+ // that we've never seen before. This should tell the browser we've |
+ // taken a ref. This comes up when the browser passes an object as an |
+ // input param and holds a ref for us. We may not have seen that object |
+ // and the plugin handler may want to AddRef and release it internally. |
+ SendAddRefObjectMsg(var.value.as_id); |
+ } |
+ } |
+} |
+ |
+void PluginVarTracker::Release(const PP_Var& var) { |
+ if (var.type == PP_VARTYPE_STRING) { |
+ PluginStringFromID(var.value.as_id)->Release(); |
+ } else if (var.type == PP_VARTYPE_OBJECT) { |
+ ObjectRefCount::iterator found = object_ref_count_.find(var.value.as_id); |
+ if (found == object_ref_count_.end()) |
+ return; // Invalid object. |
+ found->second--; |
+ |
+ if (found->second == 0) { |
+ // Plugin has released all of its refs, tell the browser. |
+ object_ref_count_.erase(found); |
+ SendReleaseObjectMsg(var.value.as_id); |
+ } |
+ } |
+} |
+ |
+void PluginVarTracker::ReceiveObjectPassRef(const PP_Var& var) { |
+ // We're the plugin and the renderer just sent us a ref. The renderer has |
+ // addrefed the var in its tracker for us since it's returning it. |
+ // |
+ // - If We don't have a reference to this already, then we just add it to |
+ // our tracker and use that one ref. |
+ // |
+ // - If we do already have a reference to it, that means the renderer now |
+ // has two references on our behalf. We want to transfer that extra |
+ // reference to our list. This means we addref in the plugin, and release |
+ // the extra one in the renderer. |
+ ObjectRefCount::iterator found = object_ref_count_.find(var.value.as_id); |
+ if (found == object_ref_count_.end()) { |
+ object_ref_count_[var.value.as_id] = 1; |
+ } else { |
+ SendReleaseObjectMsg(var.value.as_id); |
+ found->second++; |
+ } |
+} |
+ |
+void PluginVarTracker::SendAddRefObjectMsg(int64_t id) { |
+ dispatcher_->Send(new PpapiHostMsg_PPBVar_AddRefObject( |
+ INTERFACE_ID_PPB_VAR_DEPRECATED, id)); |
jam
2010/11/03 17:21:22
nit: here and below, 2 extra spaces
|
+} |
+ |
+void PluginVarTracker::SendReleaseObjectMsg(int64_t id) { |
+ dispatcher_->Send(new PpapiHostMsg_PPBVar_ReleaseObject( |
+ INTERFACE_ID_PPB_VAR_DEPRECATED, id)); |
+} |
+ |
+} // namesace proxy |
+} // namespace pp |
Property changes on: ppapi/proxy/plugin_var_tracker.cc |
___________________________________________________________________ |
Added: svn:eol-style |
+ LF |