Modified: trunk/Source/WebKit2/ChangeLog (177764 => 177765)
--- trunk/Source/WebKit2/ChangeLog 2014-12-27 19:36:56 UTC (rev 177764)
+++ trunk/Source/WebKit2/ChangeLog 2014-12-27 20:10:43 UTC (rev 177765)
@@ -1,3 +1,19 @@
+2014-12-27 Anders Carlsson <[email protected]>
+
+ Implement encoding and decoding of ObjCObjectGraph objects
+ https://bugs.webkit.org/show_bug.cgi?id=139965
+
+ Reviewed by Oliver Hunt.
+
+ * Shared/UserData.cpp:
+ (WebKit::UserData::encode):
+ (WebKit::UserData::decode):
+ * Shared/mac/ObjCObjectGraph.h:
+ * Shared/mac/ObjCObjectGraph.mm:
+ (WebKit::typeFromObject):
+ (WebKit::ObjCObjectGraph::encode):
+ (WebKit::ObjCObjectGraph::decode):
+
2014-12-27 Dan Bernstein <[email protected]>
[Cocoa] WKWebProcessPlugInLoadDelegate uses the deprecated WKRenderingProgressEvents enum
Modified: trunk/Source/WebKit2/Shared/UserData.cpp (177764 => 177765)
--- trunk/Source/WebKit2/Shared/UserData.cpp 2014-12-27 19:36:56 UTC (rev 177764)
+++ trunk/Source/WebKit2/Shared/UserData.cpp 2014-12-27 20:10:43 UTC (rev 177765)
@@ -49,6 +49,10 @@
#include "WebRenderLayer.h"
#include "WebRenderObject.h"
+#if PLATFORM(COCOA)
+#include "ObjCObjectGraph.h"
+#endif
+
namespace WebKit {
UserData::UserData()
@@ -312,6 +316,12 @@
break;
}
+#if PLATFORM(COCOA)
+ case API::Object::Type::ObjCObjectGraph:
+ static_cast<const ObjCObjectGraph&>(object).encode(encoder);
+ break;
+#endif
+
default:
ASSERT_NOT_REACHED();
}
@@ -567,6 +577,13 @@
break;
}
+#if PLATFORM(COCOA)
+ case API::Object::Type::ObjCObjectGraph:
+ if (!ObjCObjectGraph::decode(decoder, result))
+ return false;
+ break;
+#endif
+
default:
ASSERT_NOT_REACHED();
}
Modified: trunk/Source/WebKit2/Shared/mac/ObjCObjectGraph.h (177764 => 177765)
--- trunk/Source/WebKit2/Shared/mac/ObjCObjectGraph.h 2014-12-27 19:36:56 UTC (rev 177764)
+++ trunk/Source/WebKit2/Shared/mac/ObjCObjectGraph.h 2014-12-27 20:10:43 UTC (rev 177765)
@@ -29,6 +29,13 @@
#include "APIObject.h"
#include <wtf/RetainPtr.h>
+namespace IPC {
+class ArgumentDecoder;
+class ArgumentEncoder;
+}
+
+typedef struct objc_object* id;
+
namespace WebKit {
class ObjCObjectGraph : public API::ObjectImpl<API::Object::Type::ObjCObjectGraph> {
@@ -47,7 +54,13 @@
};
static RetainPtr<id> transform(id, const Transformer&);
+ void encode(IPC::ArgumentEncoder&) const;
+ static bool decode(IPC::ArgumentDecoder&, RefPtr<API::Object>&);
+
private:
+ static void encode(IPC::ArgumentEncoder&, id);
+ static bool decode(IPC::ArgumentDecoder&, RetainPtr<id>&);
+
explicit ObjCObjectGraph(id rootObject)
: m_rootObject(rootObject)
{
Modified: trunk/Source/WebKit2/Shared/mac/ObjCObjectGraph.mm (177764 => 177765)
--- trunk/Source/WebKit2/Shared/mac/ObjCObjectGraph.mm 2014-12-27 19:36:56 UTC (rev 177764)
+++ trunk/Source/WebKit2/Shared/mac/ObjCObjectGraph.mm 2014-12-27 20:10:43 UTC (rev 177765)
@@ -23,9 +23,18 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include "config.h"
-#include "ObjCObjectGraph.h"
+#import "config.h"
+#import "ObjCObjectGraph.h"
+#import "ArgumentCodersMac.h"
+#import "ArgumentDecoder.h"
+#import "ArgumentEncoder.h"
+#import <wtf/Optional.h>
+
+#if WK_API_ENABLED
+#import "WKBrowsingContextHandleInternal.h"
+#endif
+
namespace WebKit {
static bool shouldTransformGraph(id object, const ObjCObjectGraph::Transformer& transformer)
@@ -85,4 +94,229 @@
return transformGraph(object, transformer);
}
+enum class ObjCType {
+ Null,
+
+ NSArray,
+ NSData,
+ NSDate,
+ NSDictionary,
+ NSNumber,
+ NSString,
+
+#if WK_API_ENABLED
+ WKBrowsingContextHandle,
+#endif
+};
+
+static Optional<ObjCType> typeFromObject(id object)
+{
+ ASSERT(object);
+
+ if (dynamic_objc_cast<NSArray>(object))
+ return ObjCType::NSArray;
+ if (dynamic_objc_cast<NSData>(object))
+ return ObjCType::NSData;
+ if (dynamic_objc_cast<NSDate>(object))
+ return ObjCType::NSDate;
+ if (dynamic_objc_cast<NSDictionary>(object))
+ return ObjCType::NSDictionary;
+ if (dynamic_objc_cast<NSNumber>(object))
+ return ObjCType::NSNumber;
+ if (dynamic_objc_cast<NSString>(object))
+ return ObjCType::NSString;
+
+#if WK_API_ENABLED
+ if (dynamic_objc_cast<WKBrowsingContextHandle>(object))
+ return ObjCType::WKBrowsingContextHandle;
+#endif
+
+ return Nullopt;
}
+
+void ObjCObjectGraph::encode(IPC::ArgumentEncoder& encoder, id object)
+{
+ if (!object) {
+ encoder << static_cast<uint32_t>(ObjCType::Null);
+ return;
+ }
+
+ auto type = typeFromObject(object);
+ if (!type)
+ [NSException raise:NSInvalidArgumentException format:@"Can not encode objects of class type '%@'", static_cast<NSString *>(NSStringFromClass([object class]))];
+
+ encoder << static_cast<uint32_t>(type.value());
+
+ switch (type.value()) {
+ case ObjCType::NSArray: {
+ NSArray *array = object;
+
+ encoder << static_cast<uint64>(array.count);
+ for (id element in array)
+ encode(encoder, element);
+ break;
+ }
+
+ case ObjCType::NSData:
+ IPC::encode(encoder, static_cast<NSData *>(object));
+ break;
+
+ case ObjCType::NSDate:
+ IPC::encode(encoder, static_cast<NSDate *>(object));
+ break;
+
+ case ObjCType::NSDictionary: {
+ NSDictionary *dictionary = object;
+
+ encoder << static_cast<uint64_t>(dictionary.count);
+ [dictionary enumerateKeysAndObjectsUsingBlock:[&encoder](id key, id object, BOOL *stop) {
+ encode(encoder, key);
+ encode(encoder, object);
+ }];
+ break;
+ }
+
+ case ObjCType::NSNumber:
+ IPC::encode(encoder, static_cast<NSNumber *>(object));
+ break;
+
+ case ObjCType::NSString:
+ IPC::encode(encoder, static_cast<NSString *>(object));
+ break;
+
+#if WK_API_ENABLED
+ case ObjCType::WKBrowsingContextHandle:
+ encoder << static_cast<WKBrowsingContextHandle *>(object).pageID;
+ break;
+#endif
+
+ default:
+ ASSERT_NOT_REACHED();
+ }
+}
+
+void ObjCObjectGraph::encode(IPC::ArgumentEncoder& encoder) const
+{
+ encode(encoder, m_rootObject.get());
+}
+
+bool ObjCObjectGraph::decode(IPC::ArgumentDecoder& decoder, RetainPtr<id>& result)
+{
+ uint32_t typeAsUInt32;
+ if (!decoder.decode(typeAsUInt32))
+ return false;
+
+ auto type = static_cast<ObjCType>(typeAsUInt32);
+
+ switch (type) {
+ case ObjCType::Null:
+ result = nullptr;
+ break;
+
+ case ObjCType::NSArray: {
+ uint64_t size;
+ if (!decoder.decode(size))
+ return false;
+
+ auto array = adoptNS([[NSMutableArray alloc] init]);
+ for (uint64_t i = 0; i < size; ++i) {
+ RetainPtr<id> element;
+ if (!decode(decoder, element))
+ return false;
+ [array addObject:element.get()];
+ }
+
+ result = WTF::move(array);
+ break;
+ }
+
+ case ObjCType::NSData: {
+ RetainPtr<NSData> data;
+ if (!IPC::decode(decoder, data))
+ return false;
+
+ result = WTF::move(data);
+ break;
+ }
+
+ case ObjCType::NSDate: {
+ RetainPtr<NSDate> date;
+ if (!IPC::decode(decoder, date))
+ return false;
+
+ result = WTF::move(date);
+ break;
+ }
+
+ case ObjCType::NSDictionary: {
+ uint64_t size;
+ if (!decoder.decode(size))
+ return false;
+
+ auto dictionary = adoptNS([[NSMutableDictionary alloc] init]);
+ for (uint64_t i = 0; i < size; ++i) {
+ RetainPtr<id> key;
+ if (!decode(decoder, key))
+ return false;
+
+ RetainPtr<id> object;
+ if (!decode(decoder, object))
+ return false;
+
+ @try {
+ [dictionary setObject:object.get() forKey:key.get()];
+ } @catch (id) {
+ return false;
+ }
+ }
+
+ result = WTF::move(dictionary);
+ break;
+ }
+
+ case ObjCType::NSNumber: {
+ RetainPtr<NSNumber> number;
+ if (!IPC::decode(decoder, number))
+ return false;
+
+ result = WTF::move(number);
+ break;
+ }
+
+ case ObjCType::NSString: {
+ RetainPtr<NSString> string;
+ if (!IPC::decode(decoder, string))
+ return false;
+
+ result = WTF::move(string);
+ break;
+ }
+
+#if WK_API_ENABLED
+ case ObjCType::WKBrowsingContextHandle: {
+ uint64_t pageID;
+ if (!decoder.decode(pageID))
+ return false;
+
+ result = adoptNS([[WKBrowsingContextHandle alloc] _initWithPageID:pageID]);
+ break;
+ }
+#endif
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+bool ObjCObjectGraph::decode(IPC::ArgumentDecoder& decoder, RefPtr<API::Object>& result)
+{
+ RetainPtr<id> rootObject;
+ if (!decode(decoder, rootObject))
+ return false;
+
+ result = ObjCObjectGraph::create(rootObject.get());
+ return true;
+}
+
+}