[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

tkent at chromium.org tkent at chromium.org
Thu Apr 8 02:10:42 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 46f8f9e532deb43490113660aba37f3838f561f9
Author: tkent at chromium.org <tkent at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Mar 5 00:50:17 2010 +0000

    2010-03-04  Kent Tamura  <tkent at chromium.org>
    
            Reviewed by Dimitri Glazkov.
    
            [DRT/Chromium] Add CppVariant and CppBoundClass
            https://bugs.webkit.org/show_bug.cgi?id=35634
    
            Add CppVariant and CppBoundClass classes, which are going to be
            used by DumpRenderTree Chromium port. These files are based on:
            - src/webkit/glue/cpp_variant.{cc,h} and
            - src/webkit/glue/cpp_bound_class.{cc,h}
            of Chromium rev.40492.
    
            * DumpRenderTree/chromium/CppBoundClass.cpp: Added.
            * DumpRenderTree/chromium/CppBoundClass.h: Added.
            * DumpRenderTree/chromium/CppVariant.cpp: Added.
            * DumpRenderTree/chromium/CppVariant.h: Added.
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@55563 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog
index e9b854e..c23faea 100644
--- a/WebKitTools/ChangeLog
+++ b/WebKitTools/ChangeLog
@@ -1,3 +1,21 @@
+2010-03-04  Kent Tamura  <tkent at chromium.org>
+
+        Reviewed by Dimitri Glazkov.
+
+        [DRT/Chromium] Add CppVariant and CppBoundClass
+        https://bugs.webkit.org/show_bug.cgi?id=35634
+
+        Add CppVariant and CppBoundClass classes, which are going to be
+        used by DumpRenderTree Chromium port. These files are based on:
+        - src/webkit/glue/cpp_variant.{cc,h} and
+        - src/webkit/glue/cpp_bound_class.{cc,h}
+        of Chromium rev.40492.
+
+        * DumpRenderTree/chromium/CppBoundClass.cpp: Added.
+        * DumpRenderTree/chromium/CppBoundClass.h: Added.
+        * DumpRenderTree/chromium/CppVariant.cpp: Added.
+        * DumpRenderTree/chromium/CppVariant.h: Added.
+
 2010-03-04  Mark Rowe  <mrowe at apple.com>
 
         Build fix for older versions of Ruby.
diff --git a/WebKitTools/DumpRenderTree/chromium/CppBoundClass.cpp b/WebKitTools/DumpRenderTree/chromium/CppBoundClass.cpp
new file mode 100644
index 0000000..839787a
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/chromium/CppBoundClass.cpp
@@ -0,0 +1,350 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2009 Pawel Hajdan (phajdan.jr at chromium.org)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// This file contains definitions for CppBoundClass
+
+// Here's the control flow of a JS method getting forwarded to a class.
+// - Something calls our NPObject with a function like "Invoke".
+// - CppNPObject's static invoke() function forwards it to its attached
+//   CppBoundClass's invoke() method.
+// - CppBoundClass has then overridden invoke() to look up the function
+//   name in its internal map of methods, and then calls the appropriate
+//   method.
+
+#include "config.h"
+#include "CppBoundClass.h"
+
+#include "public/WebBindings.h"
+#include "public/WebFrame.h"
+#include "public/WebString.h"
+#include <wtf/Assertions.h>
+#include <wtf/OwnPtr.h>
+
+using namespace WebKit;
+using namespace std;
+
+class CppVariantPropertyCallback : public CppBoundClass::PropertyCallback {
+public:
+    CppVariantPropertyCallback(CppVariant* value) : m_value(value) { }
+
+    virtual bool getValue(CppVariant* value)
+    {
+        value->set(*m_value);
+        return true;
+    }
+
+    virtual bool setValue(const CppVariant& value)
+    {
+        m_value->set(value);
+        return true;
+    }
+
+private:
+    CppVariant* m_value;
+};
+
+class GetterPropertyCallback : public CppBoundClass::PropertyCallback {
+public:
+    GetterPropertyCallback(CppBoundClass::GetterCallback* callback)
+        : m_callback(callback) { }
+
+    virtual bool getValue(CppVariant* value)
+    {
+        m_callback->run(value);
+        return true;
+    }
+
+    virtual bool setValue(const CppVariant& value) { return false; }
+
+private:
+    OwnPtr<CppBoundClass::GetterCallback> m_callback;
+};
+
+// Our special NPObject type.  We extend an NPObject with a pointer to a
+// CppBoundClass, which is just a C++ interface that we forward all NPObject
+// callbacks to.
+struct CppNPObject {
+    NPObject parent; // This must be the first field in the struct.
+    CppBoundClass* boundClass;
+
+    //
+    // All following objects and functions are static, and just used to interface
+    // with NPObject/NPClass.
+    //
+
+    // An NPClass associates static functions of CppNPObject with the
+    // function pointers used by the JS runtime.
+    static NPClass npClass;
+
+    // Allocate a new NPObject with the specified class.
+    static NPObject* allocate(NPP, NPClass*);
+
+    // Free an object.
+    static void deallocate(NPObject*);
+
+    // Returns true if the C++ class associated with this NPObject exposes the
+    // given property.  Called by the JS runtime.
+    static bool hasProperty(NPObject*, NPIdentifier);
+
+    // Returns true if the C++ class associated with this NPObject exposes the
+    // given method.  Called by the JS runtime.
+    static bool hasMethod(NPObject*, NPIdentifier);
+
+    // If the given method is exposed by the C++ class associated with this
+    // NPObject, invokes it with the given arguments and returns a result.  Otherwise,
+    // returns "undefined" (in the JavaScript sense).  Called by the JS runtime.
+    static bool invoke(NPObject*, NPIdentifier,
+                       const NPVariant* arguments, uint32_t argumentCount,
+                       NPVariant* result);
+
+    // If the given property is exposed by the C++ class associated with this
+    // NPObject, returns its value.  Otherwise, returns "undefined" (in the
+    // JavaScript sense).  Called by the JS runtime.
+    static bool getProperty(NPObject*, NPIdentifier, NPVariant* result);
+
+    // If the given property is exposed by the C++ class associated with this
+    // NPObject, sets its value.  Otherwise, does nothing. Called by the JS
+    // runtime.
+    static bool setProperty(NPObject*, NPIdentifier, const NPVariant* value);
+};
+
+// Build CppNPObject's static function pointers into an NPClass, for use
+// in constructing NPObjects for the C++ classes.
+NPClass CppNPObject::npClass = {
+    NP_CLASS_STRUCT_VERSION,
+    CppNPObject::allocate,
+    CppNPObject::deallocate,
+    /* NPInvalidateFunctionPtr */ 0,
+    CppNPObject::hasMethod,
+    CppNPObject::invoke,
+    /* NPInvokeDefaultFunctionPtr */ 0,
+    CppNPObject::hasProperty,
+    CppNPObject::getProperty,
+    CppNPObject::setProperty,
+    /* NPRemovePropertyFunctionPtr */ 0
+};
+
+NPObject* CppNPObject::allocate(NPP npp, NPClass* aClass)
+{
+    CppNPObject* obj = new CppNPObject;
+    // obj->parent will be initialized by the NPObject code calling this.
+    obj->boundClass = 0;
+    return &obj->parent;
+}
+
+void CppNPObject::deallocate(NPObject* npObj)
+{
+    CppNPObject* obj = reinterpret_cast<CppNPObject*>(npObj);
+    delete obj;
+}
+
+bool CppNPObject::hasMethod(NPObject* npObj, NPIdentifier ident)
+{
+    CppNPObject* obj = reinterpret_cast<CppNPObject*>(npObj);
+    return obj->boundClass->hasMethod(ident);
+}
+
+bool CppNPObject::hasProperty(NPObject* npObj, NPIdentifier ident)
+{
+    CppNPObject* obj = reinterpret_cast<CppNPObject*>(npObj);
+    return obj->boundClass->hasProperty(ident);
+}
+
+bool CppNPObject::invoke(NPObject* npObj, NPIdentifier ident,
+                         const NPVariant* arguments, uint32_t argumentCount,
+                         NPVariant* result)
+{
+    CppNPObject* obj = reinterpret_cast<CppNPObject*>(npObj);
+    return obj->boundClass->invoke(ident, arguments, argumentCount, result);
+}
+
+bool CppNPObject::getProperty(NPObject* npObj, NPIdentifier ident, NPVariant* result)
+{
+    CppNPObject* obj = reinterpret_cast<CppNPObject*>(npObj);
+    return obj->boundClass->getProperty(ident, result);
+}
+
+bool CppNPObject::setProperty(NPObject* npObj, NPIdentifier ident, const NPVariant* value)
+{
+    CppNPObject* obj = reinterpret_cast<CppNPObject*>(npObj);
+    return obj->boundClass->setProperty(ident, value);
+}
+
+CppBoundClass::~CppBoundClass()
+{
+    for (MethodList::iterator i = m_methods.begin(); i != m_methods.end(); ++i)
+        delete i->second;
+
+    for (PropertyList::iterator i = m_properties.begin(); i != m_properties.end(); ++i)
+        delete i->second;
+
+    // Unregister ourselves if we were bound to a frame.
+    if (m_boundToFrame)
+        WebBindings::unregisterObject(NPVARIANT_TO_OBJECT(m_selfVariant));
+}
+
+bool CppBoundClass::hasMethod(NPIdentifier ident) const
+{
+    return m_methods.find(ident) != m_methods.end();
+}
+
+bool CppBoundClass::hasProperty(NPIdentifier ident) const
+{
+    return m_properties.find(ident) != m_properties.end();
+}
+
+bool CppBoundClass::invoke(NPIdentifier ident,
+                           const NPVariant* arguments,
+                           size_t argumentCount,
+                           NPVariant* result) {
+    MethodList::const_iterator end = m_methods.end();
+    MethodList::const_iterator method = m_methods.find(ident);
+    Callback* callback;
+    if (method == end) {
+        if (!m_fallbackCallback.get()) {
+            VOID_TO_NPVARIANT(*result);
+            return false;
+        }
+        callback = m_fallbackCallback.get();
+    } else
+        callback = (*method).second;
+
+    // Build a CppArgumentList argument vector from the NPVariants coming in.
+    CppArgumentList cppArguments(argumentCount);
+    for (size_t i = 0; i < argumentCount; i++)
+        cppArguments[i].set(arguments[i]);
+
+    CppVariant cppResult;
+    callback->run(cppArguments, &cppResult);
+
+    cppResult.copyToNPVariant(result);
+    return true;
+}
+
+bool CppBoundClass::getProperty(NPIdentifier ident, NPVariant* result) const
+{
+    PropertyList::const_iterator callback = m_properties.find(ident);
+    if (callback == m_properties.end()) {
+        VOID_TO_NPVARIANT(*result);
+        return false;
+    }
+
+    CppVariant cppValue;
+    if (!callback->second->getValue(&cppValue))
+        return false;
+    cppValue.copyToNPVariant(result);
+    return true;
+}
+
+bool CppBoundClass::setProperty(NPIdentifier ident, const NPVariant* value)
+{
+    PropertyList::iterator callback = m_properties.find(ident);
+    if (callback == m_properties.end())
+        return false;
+
+    CppVariant cppValue;
+    cppValue.set(*value);
+    return (*callback).second->setValue(cppValue);
+}
+
+void CppBoundClass::bindCallback(const string& name, Callback* callback)
+{
+    NPIdentifier ident = WebBindings::getStringIdentifier(name.c_str());
+    MethodList::iterator oldCallback = m_methods.find(ident);
+    if (oldCallback != m_methods.end()) {
+        delete oldCallback->second;
+        if (!callback) {
+            m_methods.remove(oldCallback);
+            return;
+        }
+    }
+
+    m_methods.set(ident, callback);
+}
+
+void CppBoundClass::bindGetterCallback(const string& name, GetterCallback* callback)
+{
+    PropertyCallback* propertyCallback = callback ? new GetterPropertyCallback(callback) : 0;
+    bindProperty(name, propertyCallback);
+}
+
+void CppBoundClass::bindProperty(const string& name, CppVariant* prop)
+{
+    PropertyCallback* propertyCallback = prop ? new CppVariantPropertyCallback(prop) : 0;
+    bindProperty(name, propertyCallback);
+}
+
+void CppBoundClass::bindProperty(const string& name, PropertyCallback* callback)
+{
+    NPIdentifier ident = WebBindings::getStringIdentifier(name.c_str());
+    PropertyList::iterator oldCallback = m_properties.find(ident);
+    if (oldCallback != m_properties.end()) {
+        delete oldCallback->second;
+        if (!callback) {
+            m_properties.remove(oldCallback);
+            return;
+        }
+    }
+
+    m_properties.set(ident, callback);
+}
+
+bool CppBoundClass::isMethodRegistered(const string& name) const
+{
+    NPIdentifier ident = WebBindings::getStringIdentifier(name.c_str());
+    MethodList::const_iterator callback = m_methods.find(ident);
+    return callback != m_methods.end();
+}
+
+CppVariant* CppBoundClass::getAsCppVariant()
+{
+    if (!m_selfVariant.isObject()) {
+        // Create an NPObject using our static NPClass.  The first argument (a
+        // plugin's instance handle) is passed through to the allocate function
+        // directly, and we don't use it, so it's ok to be 0.
+        NPObject* npObj = WebBindings::createObject(0, &CppNPObject::npClass);
+        CppNPObject* obj = reinterpret_cast<CppNPObject*>(npObj);
+        obj->boundClass = this;
+        m_selfVariant.set(npObj);
+        WebBindings::releaseObject(npObj); // CppVariant takes the reference.
+    }
+    ASSERT(m_selfVariant.isObject());
+    return &m_selfVariant;
+}
+
+void CppBoundClass::bindToJavascript(WebFrame* frame, const WebString& classname)
+{
+    // BindToWindowObject will take its own reference to the NPObject, and clean
+    // up after itself.  It will also (indirectly) register the object with V8,
+    // so we must remember this so we can unregister it when we're destroyed.
+    frame->bindToWindowObject(classname, NPVARIANT_TO_OBJECT(*getAsCppVariant()));
+    m_boundToFrame = true;
+}
diff --git a/WebKitTools/DumpRenderTree/chromium/CppBoundClass.h b/WebKitTools/DumpRenderTree/chromium/CppBoundClass.h
new file mode 100644
index 0000000..6cb638e
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/chromium/CppBoundClass.h
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2009 Pawel Hajdan (phajdan.jr at chromium.org)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+  CppBoundClass class:
+  This base class serves as a parent for C++ classes designed to be bound to
+  JavaScript objects.
+
+  Subclasses should define the constructor to build the property and method
+  lists needed to bind this class to a JS object.  They should also declare
+  and define member variables and methods to be exposed to JS through
+  that object.
+*/
+
+#ifndef CppBoundClass_h
+#define CppBoundClass_h
+
+#include "CppVariant.h"
+#include <wtf/HashMap.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebKit {
+class WebFrame;
+class WebString;
+}
+
+typedef Vector<CppVariant> CppArgumentList;
+
+// CppBoundClass lets you map Javascript method calls and property accesses
+// directly to C++ method calls and CppVariant* variable access.
+class CppBoundClass : public Noncopyable {
+public:
+    class PropertyCallback {
+    public:
+        virtual ~PropertyCallback() { }
+
+        // Sets |value| to the value of the property. Returns false in case of
+        // failure. |value| is always non-0.
+        virtual bool getValue(CppVariant* result) = 0;
+
+        // sets the property value to |value|. Returns false in case of failure.
+        virtual bool setValue(const CppVariant&) = 0;
+    };
+
+    // Callback class for "void function(CppVariant*)"
+    class GetterCallback {
+    public:
+        virtual ~GetterCallback() {}
+        virtual void run(CppVariant*) = 0;
+    };
+
+    // The constructor should call BindMethod, BindProperty, and
+    // SetFallbackMethod as needed to set up the methods, properties, and
+    // fallback method.
+    CppBoundClass() : m_boundToFrame(false) {}
+    virtual ~CppBoundClass();
+
+    // Return a CppVariant representing this class, for use with BindProperty().
+    // The variant type is guaranteed to be NPVariantType_Object.
+    CppVariant* getAsCppVariant();
+
+    // Given a WebFrame, BindToJavascript builds the NPObject that will represent
+    // the class and binds it to the frame's window under the given name.  This
+    // should generally be called from the WebView delegate's
+    // WindowObjectCleared(). A class so bound will be accessible to JavaScript
+    // as window.<classname>. The owner of the CppBoundObject is responsible for
+    // keeping the object around while the frame is alive, and for destroying it
+    // afterwards.
+    void bindToJavascript(WebKit::WebFrame*, const WebKit::WebString& classname);
+
+    // Used by a test.  Returns true if a method with name |name| exists,
+    // regardless of whether a fallback is registered.
+    bool isMethodRegistered(const std::string&) const;
+
+protected:
+    // Callback for "void function(const CppArguemntList&, CppVariant*)"
+    class Callback {
+    public:
+        virtual ~Callback() {}
+        virtual void run(const CppArgumentList&, CppVariant*) = 0;
+    };
+
+    // Callback for "void T::method(const CppArguemntList&, CppVariant*)"
+    template <class T> class MemberCallback : public Callback {
+    public:
+        typedef void (T::*MethodType)(const CppArgumentList&, CppVariant*);
+        MemberCallback(T* object, MethodType method)
+            : m_object(object)
+            , m_method(method) {}
+        virtual ~MemberCallback() {}
+
+        virtual void run(const CppArgumentList& arguments, CppVariant* result)
+        {
+            (m_object->*m_method)(arguments, result);
+        }
+    private:
+        T* m_object;
+        MethodType m_method;
+    };
+
+    // Callback class for "void T::method(CppVariant*)"
+    template <class T> class MemberGetterCallback : public GetterCallback {
+    public:
+        typedef void (T::*MethodType)(CppVariant*);
+        MemberGetterCallback(T* object, MethodType method)
+            : m_object(object)
+            , m_method(method) {}
+        virtual ~MemberGetterCallback() {}
+
+        virtual void run(CppVariant* result) { (m_object->*m_method)(result); }
+    private:
+        T* m_object;
+        MethodType m_method;
+    };
+
+    // Bind the Javascript method called the string parameter to the C++ method.
+    void bindCallback(const std::string&, Callback*);
+
+    // A wrapper for bindCallback, to simplify the common case of binding a
+    // method on the current object.  Though not verified here, |method|
+    // must be a method of this CppBoundClass subclass.
+    template<class T>
+    void bindMethod(const std::string& name, void (T::*method)(const CppArgumentList&, CppVariant*))
+    {
+        Callback* callback = new MemberCallback<T>(static_cast<T*>(this), method);
+        bindCallback(name, callback);
+    }
+
+    // Bind Javascript property |name| to the C++ getter callback |callback|.
+    // This can be used to create read-only properties.
+    void bindGetterCallback(const std::string&, GetterCallback*);
+
+    // A wrapper for BindGetterCallback, to simplify the common case of binding a
+    // property on the current object.  Though not verified here, |method|
+    // must be a method of this CppBoundClass subclass.
+    template<class T>
+    void bindProperty(const std::string& name, void (T::*method)(CppVariant*))
+    {
+        GetterCallback* callback = new MemberGetterCallback<T>(static_cast<T*>(this), method);
+        bindGetterCallback(name, callback);
+    }
+
+    // Bind the Javascript property called |name| to a CppVariant.
+    void bindProperty(const std::string&, CppVariant*);
+
+    // Bind Javascript property called |name| to a PropertyCallback.
+    // CppBoundClass assumes control over the life time of the callback.
+    void bindProperty(const std::string&, PropertyCallback*);
+
+    // Set the fallback callback, which is called when when a callback is
+    // invoked that isn't bound.
+    // If it is 0 (its default value), a JavaScript exception is thrown in
+    // that case (as normally expected). If non 0, the fallback method is
+    // invoked and the script continues its execution.
+    // Passing 0 clears out any existing binding.
+    // It is used for tests and should probably only be used in such cases
+    // as it may cause unexpected behaviors (a JavaScript object with a
+    // fallback always returns true when checked for a method's
+    // existence).
+    void bindFallbackCallback(Callback* fallbackCallback)
+    {
+        m_fallbackCallback.set(fallbackCallback);
+    }
+
+    // A wrapper for BindFallbackCallback, to simplify the common case of
+    // binding a method on the current object.  Though not verified here,
+    // |method| must be a method of this CppBoundClass subclass.
+    // Passing 0 for |method| clears out any existing binding.
+    template<class T>
+    void bindFallbackMethod(void (T::*method)(const CppArgumentList&, CppVariant*))
+    {
+        if (method) {
+            Callback* callback = new MemberCallback<T>(static_cast<T*>(this), method);
+            bindFallbackCallback(callback);
+        } else
+            bindFallbackCallback(0);
+    }
+
+    // Some fields are protected because some tests depend on accessing them,
+    // but otherwise they should be considered private.
+
+    typedef HashMap<NPIdentifier, PropertyCallback*> PropertyList;
+    typedef HashMap<NPIdentifier, Callback*> MethodList;
+    // These maps associate names with property and method pointers to be
+    // exposed to JavaScript.
+    PropertyList m_properties;
+    MethodList m_methods;
+
+    // The callback gets invoked when a call is made to an nonexistent method.
+    OwnPtr<Callback> m_fallbackCallback;
+
+private:
+    // NPObject callbacks.
+    friend struct CppNPObject;
+    bool hasMethod(NPIdentifier) const;
+    bool invoke(NPIdentifier, const NPVariant* args, size_t argCount,
+                NPVariant* result);
+    bool hasProperty(NPIdentifier) const;
+    bool getProperty(NPIdentifier, NPVariant* result) const;
+    bool setProperty(NPIdentifier, const NPVariant*);
+
+    // A lazily-initialized CppVariant representing this class.  We retain 1
+    // reference to this object, and it is released on deletion.
+    CppVariant m_selfVariant;
+
+    // True if our np_object has been bound to a WebFrame, in which case it must
+    // be unregistered with V8 when we delete it.
+    bool m_boundToFrame;
+};
+
+#endif // CppBoundClass_h
diff --git a/WebKitTools/DumpRenderTree/chromium/CppVariant.cpp b/WebKitTools/DumpRenderTree/chromium/CppVariant.cpp
new file mode 100644
index 0000000..ef04bf3
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/chromium/CppVariant.cpp
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CppVariant.h"
+
+#include "base/string_util.h"
+#include "public/WebBindings.h"
+#include <limits>
+#include <wtf/Assertions.h>
+
+using namespace WebKit;
+using namespace std;
+
+CppVariant::CppVariant()
+{
+    type = NPVariantType_Null;
+}
+
+// Note that Set() performs a deep copy, which is necessary to safely
+// call FreeData() on the value in the destructor.
+CppVariant::CppVariant(const CppVariant& original)
+{
+    type = NPVariantType_Null;
+    set(original);
+}
+
+// See comment for copy constructor, above.
+CppVariant& CppVariant::operator=(const CppVariant& original)
+{
+    if (&original != this)
+        set(original);
+    return *this;
+}
+
+CppVariant::~CppVariant()
+{
+    freeData();
+}
+
+void CppVariant::freeData()
+{
+    WebBindings::releaseVariantValue(this);
+}
+
+bool CppVariant::isEqual(const CppVariant& other) const
+{
+    if (type != other.type)
+        return false;
+
+    switch (type) {
+    case NPVariantType_Bool:
+        return (value.boolValue == other.value.boolValue);
+    case NPVariantType_Int32:
+        return (value.intValue == other.value.intValue);
+    case NPVariantType_Double:
+        return (value.doubleValue == other.value.doubleValue);
+    case NPVariantType_String: {
+        const NPString *this_value = &value.stringValue;
+        const NPString *other_value = &other.value.stringValue;
+        uint32_t len = this_value->UTF8Length;
+        return len == other_value->UTF8Length
+            && !strncmp(this_value->UTF8Characters,
+                        other_value->UTF8Characters, len);
+    }
+    case NPVariantType_Null:
+    case NPVariantType_Void:
+        return true;
+    case NPVariantType_Object: {
+        NPObject* thisValue = value.objectValue;
+        NPObject* otherValue = other.value.objectValue;
+        return thisValue->_class == otherValue->_class
+            && thisValue->referenceCount == otherValue->referenceCount;
+    }
+    }
+    return false;
+}
+
+void CppVariant::copyToNPVariant(NPVariant* result) const
+{
+    result->type = type;
+    switch (type) {
+    case NPVariantType_Bool:
+        result->value.boolValue = value.boolValue;
+        break;
+    case NPVariantType_Int32:
+        result->value.intValue = value.intValue;
+        break;
+    case NPVariantType_Double:
+        result->value.doubleValue = value.doubleValue;
+        break;
+    case NPVariantType_String:
+        WebBindings::initializeVariantWithStringCopy(result, &value.stringValue);
+        break;
+    case NPVariantType_Null:
+    case NPVariantType_Void:
+        // Nothing to set.
+        break;
+    case NPVariantType_Object:
+        result->type = NPVariantType_Object;
+        result->value.objectValue = WebBindings::retainObject(value.objectValue);
+        break;
+    }
+}
+
+void CppVariant::set(const NPVariant& newValue)
+{
+    freeData();
+    switch (newValue.type) {
+    case NPVariantType_Bool:
+        set(newValue.value.boolValue);
+        break;
+    case NPVariantType_Int32:
+        set(newValue.value.intValue);
+        break;
+    case NPVariantType_Double:
+        set(newValue.value.doubleValue);
+        break;
+    case NPVariantType_String:
+        set(newValue.value.stringValue);
+        break;
+    case NPVariantType_Null:
+    case NPVariantType_Void:
+        type = newValue.type;
+        break;
+    case NPVariantType_Object:
+        set(newValue.value.objectValue);
+        break;
+    }
+}
+
+void CppVariant::setNull()
+{
+    freeData();
+    type = NPVariantType_Null;
+}
+
+void CppVariant::set(bool newValue)
+{
+    freeData();
+    type = NPVariantType_Bool;
+    value.boolValue = newValue;
+}
+
+void CppVariant::set(int32_t newValue)
+{
+    freeData();
+    type = NPVariantType_Int32;
+    value.intValue = newValue;
+}
+
+void CppVariant::set(double newValue)
+{
+    freeData();
+    type = NPVariantType_Double;
+    value.doubleValue = newValue;
+}
+
+// The newValue must be a null-terminated string.
+void CppVariant::set(const char* newValue)
+{
+    freeData();
+    type = NPVariantType_String;
+    NPString newString = {newValue,
+                          static_cast<uint32_t>(strlen(newValue))};
+    WebBindings::initializeVariantWithStringCopy(this, &newString);
+}
+
+void CppVariant::set(const string& newValue)
+{
+    freeData();
+    type = NPVariantType_String;
+    NPString newString = {newValue.data(),
+                          static_cast<uint32_t>(newValue.size())};
+    WebBindings::initializeVariantWithStringCopy(this, &newString);
+}
+
+void CppVariant::set(const NPString& newValue)
+{
+    freeData();
+    type = NPVariantType_String;
+    WebBindings::initializeVariantWithStringCopy(this, &newValue);
+}
+
+void CppVariant::set(NPObject* newValue)
+{
+    freeData();
+    type = NPVariantType_Object;
+    value.objectValue = WebBindings::retainObject(newValue);
+}
+
+string CppVariant::toString() const
+{
+    ASSERT(isString());
+    return string(value.stringValue.UTF8Characters,
+                  value.stringValue.UTF8Length);
+}
+
+int32_t CppVariant::toInt32() const
+{
+    if (isInt32())
+        return value.intValue;
+    if (isDouble())
+        return static_cast<int32_t>(value.doubleValue);
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+double CppVariant::toDouble() const
+{
+    if (isInt32())
+        return static_cast<double>(value.intValue);
+    if (isDouble())
+        return value.doubleValue;
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+bool CppVariant::toBoolean() const
+{
+    ASSERT(isBool());
+    return value.boolValue;
+}
+
+Vector<string> CppVariant::toStringVector() const
+{
+
+    ASSERT(isObject());
+    Vector<string> stringVector;
+    NPObject* npValue = value.objectValue;
+    NPIdentifier lengthId = WebBindings::getStringIdentifier("length");
+
+    if (!WebBindings::hasProperty(0, npValue, lengthId))
+        return stringVector;
+
+    NPVariant lengthValue;
+    if (!WebBindings::getProperty(0, npValue, lengthId, &lengthValue))
+        return stringVector;
+
+    int length = 0;
+    // The length is a double in some cases.
+    if (NPVARIANT_IS_DOUBLE(lengthValue))
+        length = static_cast<int>(NPVARIANT_TO_DOUBLE(lengthValue));
+    else if (NPVARIANT_IS_INT32(lengthValue))
+        length = NPVARIANT_TO_INT32(lengthValue);
+    WebBindings::releaseVariantValue(&lengthValue);
+
+    // For sanity, only allow 100 items.
+    length = min(100, length);
+    for (int i = 0; i < length; ++i) {
+        // Get each of the items.
+        string index = StringPrintf("%d", i);
+        NPIdentifier indexId = WebBindings::getStringIdentifier(index.c_str());
+        if (!WebBindings::hasProperty(0, npValue, indexId))
+            continue;
+        NPVariant indexValue;
+        if (!WebBindings::getProperty(0, npValue, indexId, &indexValue))
+            continue;
+        if (NPVARIANT_IS_STRING(indexValue)) {
+            string item(NPVARIANT_TO_STRING(indexValue).UTF8Characters,
+                        NPVARIANT_TO_STRING(indexValue).UTF8Length);
+            stringVector.append(item);
+        }
+        WebBindings::releaseVariantValue(&indexValue);
+    }
+    return stringVector;
+}
+
+bool CppVariant::invoke(const string& method, const CppVariant* arguments,
+                        uint32_t argumentCount, CppVariant& result) const
+{
+    ASSERT(isObject());
+    NPIdentifier methodName = WebBindings::getStringIdentifier(method.c_str());
+    NPObject* npObject = value.objectValue;
+    if (!WebBindings::hasMethod(0, npObject, methodName))
+        return false;
+    NPVariant r;
+    bool status = WebBindings::invoke(0, npObject, methodName, arguments, argumentCount, &r);
+    result.set(r);
+    return status;
+}
diff --git a/WebKitTools/DumpRenderTree/chromium/CppVariant.h b/WebKitTools/DumpRenderTree/chromium/CppVariant.h
new file mode 100644
index 0000000..d34a163
--- /dev/null
+++ b/WebKitTools/DumpRenderTree/chromium/CppVariant.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+  This file contains the declaration for CppVariant, a type used by C++ classes
+  that are to be bound to JavaScript objects.
+
+  CppVariant exists primarily as an interface between C++ callers and the
+  corresponding NPVariant type.  CppVariant also provides a number of
+  convenience constructors and accessors, so that the NPVariantType values
+  don't need to be exposed, and a destructor to free any memory allocated for
+  string values.
+*/
+
+#ifndef CppVariant_h
+#define CppVariant_h
+
+#include "base/basictypes.h"
+#include "public/WebBindings.h"
+#include <string>
+#include <wtf/Vector.h>
+
+class CppVariant : public NPVariant {
+public:
+    CppVariant();
+    ~CppVariant();
+    void setNull();
+    void set(bool);
+    void set(int32_t);
+    void set(double);
+
+    // Note that setting a CppVariant to a string value involves copying the
+    // string data, which must be freed with a call to freeData() when the
+    // CppVariant is set to a different value or is no longer needed.  Normally
+    // this is handled by the other set() methods and by the destructor.
+    void set(const char*); // Must be a null-terminated string.
+    void set(const std::string&);
+    void set(const NPString&);
+    void set(const NPVariant&);
+
+    // Note that setting a CppVariant to an NPObject involves ref-counting
+    // the actual object. freeData() should only be called if the CppVariant
+    // is no longer needed. The other set() methods handle this internally.
+    // Also, the object's NPClass is expected to be a static object: neither
+    // the NP runtime nor CppVariant will ever free it.
+    void set(NPObject*_value);
+
+    // These three methods all perform deep copies of any string data.  This
+    // allows local CppVariants to be released by the destructor without
+    // corrupting their sources. In performance-critical code, or when strings
+    // are very long, avoid creating new CppVariants.
+    // In case of NPObject as the data, the copying involves ref-counting
+    // as opposed to deep-copying. The ref-counting ensures that sources don't
+    // get corrupted when the copies get destroyed.
+    void copyToNPVariant(NPVariant* result) const;
+    CppVariant& operator=(const CppVariant& original);
+    CppVariant(const CppVariant& original);
+
+    // Calls NPN_ReleaseVariantValue, which frees any string data
+    // held by the object and sets its type to null.
+    // In case of NPObject, the NPN_ReleaseVariantValue decrements
+    // the ref-count (releases when ref-count becomes 0)
+    void freeData();
+
+    // Compares this CppVariant's type and value to another's.  They must be
+    // identical in both type and value to be considered equal.  For string and
+    // object types, a deep comparison is performed; that is, the contents of the
+    // strings, or the classes and refcounts of the objects, must be the same,
+    // but they need not be the same pointers.
+    bool isEqual(const CppVariant&) const;
+
+    // The value of a CppVariant may be read directly from its NPVariant (but
+    // should only be set using one of the set() methods above). Although the
+    // type of a CppVariant is likewise public, it can be accessed through these
+    // functions rather than directly if a caller wishes to avoid dependence on
+    // the NPVariantType values.
+    bool isBool() const { return (type == NPVariantType_Bool); }
+    bool isInt32() const { return (type == NPVariantType_Int32); }
+    bool isDouble() const { return (type == NPVariantType_Double); }
+    bool isNumber() const { return (isInt32() || isDouble()); }
+    bool isString() const { return (type == NPVariantType_String); }
+    bool isVoid() const { return (type == NPVariantType_Void); }
+    bool isNull() const { return (type == NPVariantType_Null); }
+    bool isEmpty() const { return (isVoid() || isNull()); }
+    bool isObject() const { return (type == NPVariantType_Object); }
+
+    // Converters.  The CppVariant must be of a type convertible to these values.
+    // For example, toInt32() works only if isNumber() is true.
+    std::string toString() const;
+    int32_t toInt32() const;
+    double toDouble() const;
+    bool toBoolean() const;
+    // Returns a vector of strings for the specified argument. This is useful
+    // for converting a JavaScript array of strings into a vector of strings.
+    Vector<std::string> toStringVector() const;
+
+    // Invoke method of the given name on an object with the supplied arguments.
+    // The first argument should be the object on which the method is to be
+    // invoked.  Returns whether the method was successfully invoked.  If the
+    // method was invoked successfully, any return value is stored in the
+    // CppVariant specified by result.
+    bool invoke(const std::string&, const CppVariant* arguments,
+                uint32_t argumentCount, CppVariant& result) const;
+};
+
+#endif // CppVariant_h

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list