47bce57f3dbde90654ba28b538b0e5f202a3f488
[WebKit-https.git] / Source / WebKit2 / Shared / UserMessageCoders.h
1 /*
2  * Copyright (C) 2010 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #ifndef UserMessageCoders_h
27 #define UserMessageCoders_h
28
29 #include "ArgumentDecoder.h"
30 #include "ArgumentEncoder.h"
31 #include "DataReference.h"
32 #include "ImmutableArray.h"
33 #include "ImmutableDictionary.h"
34 #include "ShareableBitmap.h"
35 #include "WebCertificateInfo.h"
36 #include "WebCoreArgumentCoders.h"
37 #include "WebData.h"
38 #include "WebGeometry.h"
39 #include "WebImage.h"
40 #include "WebNumber.h"
41 #include "WebRenderObject.h"
42 #include "WebSerializedScriptValue.h"
43 #include "WebString.h"
44 #include "WebURL.h"
45 #include "WebURLRequest.h"
46 #include "WebUserContentURLPattern.h"
47
48 namespace WebKit {
49
50 //   - Null -> Null
51 //   - Array -> Array
52 //   - Dictionary -> Dictionary
53 //   - SerializedScriptValue -> SerializedScriptValue
54 //   - String -> String
55 //   - UserContentURLPattern -> UserContentURLPattern
56 //   - WebCertificateInfo -> WebCertificateInfo
57 //   - WebData -> WebData
58 //   - WebDouble -> WebDouble
59 //   - WebImage -> WebImage
60 //   - WebRenderObject -> WebRenderObject
61 //   - WebUInt64 -> WebUInt64
62 //   - WebURL -> WebURL
63 //   - WebURLRequest -> WebURLRequest
64
65 template<typename Owner>
66 class UserMessageEncoder {
67 public:
68     bool baseEncode(CoreIPC::ArgumentEncoder* encoder, APIObject::Type& type) const 
69     {
70         if (!m_root) {
71             encoder->encodeUInt32(APIObject::TypeNull);
72             return true;
73         }
74
75         type = m_root->type();
76         encoder->encodeUInt32(type);
77
78         switch (type) {
79         case APIObject::TypeArray: {
80             ImmutableArray* array = static_cast<ImmutableArray*>(m_root);
81             encoder->encode(static_cast<uint64_t>(array->size()));
82             for (size_t i = 0; i < array->size(); ++i)
83                 encoder->encode(Owner(array->at(i)));
84             return true;
85         }
86         case APIObject::TypeDictionary: {
87             ImmutableDictionary* dictionary = static_cast<ImmutableDictionary*>(m_root);
88             const ImmutableDictionary::MapType& map = dictionary->map();
89             encoder->encode(static_cast<uint64_t>(map.size()));
90
91             ImmutableDictionary::MapType::const_iterator it = map.begin();
92             ImmutableDictionary::MapType::const_iterator end = map.end();
93             for (; it != end; ++it) {
94                 encoder->encode(it->first);
95                 encoder->encode(Owner(it->second.get()));
96             }
97             return true;
98         }
99         case APIObject::TypeString: {
100             WebString* string = static_cast<WebString*>(m_root);
101             encoder->encode(string->string());
102             return true;
103         }
104         case APIObject::TypeSerializedScriptValue: {
105             WebSerializedScriptValue* scriptValue = static_cast<WebSerializedScriptValue*>(m_root);
106             encoder->encodeVariableLengthByteArray(scriptValue->dataReference());
107             return true;
108         }
109         case APIObject::TypeBoolean: {
110             WebBoolean* booleanObject = static_cast<WebBoolean*>(m_root);
111             encoder->encode(booleanObject->value());
112             return true;
113         }
114         case APIObject::TypeDouble: {
115             WebDouble* doubleObject = static_cast<WebDouble*>(m_root);
116             encoder->encode(doubleObject->value());
117             return true;
118         }
119         case APIObject::TypeUInt64: {
120             WebUInt64* uint64Object = static_cast<WebUInt64*>(m_root);
121             encoder->encode(uint64Object->value());
122             return true;
123         }
124         case APIObject::TypePoint: {
125             WebPoint* pointObject = static_cast<WebPoint*>(m_root);
126             encoder->encode(pointObject->point().x);
127             encoder->encode(pointObject->point().y);
128             return true;
129         }
130         case APIObject::TypeSize: {
131             WebSize* sizeObject = static_cast<WebSize*>(m_root);
132             encoder->encode(sizeObject->size().width);
133             encoder->encode(sizeObject->size().height);
134             return true;
135         }
136         case APIObject::TypeRect: {
137             WebRect* rectObject = static_cast<WebRect*>(m_root);
138             encoder->encode(rectObject->rect().origin.x);
139             encoder->encode(rectObject->rect().origin.y);
140             encoder->encode(rectObject->rect().size.width);
141             encoder->encode(rectObject->rect().size.height);
142             return true;
143         }
144         case APIObject::TypeRenderObject: {
145             WebRenderObject* renderObject = static_cast<WebRenderObject*>(m_root);
146             encoder->encode(renderObject->name());
147             encoder->encode(renderObject->absolutePosition());
148             encoder->encode(renderObject->frameRect());
149             encoder->encode(Owner(renderObject->children().get()));
150             return true;
151         }
152         case APIObject::TypeURL: {
153             WebURL* urlObject = static_cast<WebURL*>(m_root);
154             encoder->encode(urlObject->string());
155             return true;
156         }
157         case APIObject::TypeURLRequest: {
158             WebURLRequest* urlRequestObject = static_cast<WebURLRequest*>(m_root);
159             encoder->encode(urlRequestObject->resourceRequest());
160             return true;
161         }
162         case APIObject::TypeUserContentURLPattern: {
163             WebUserContentURLPattern* urlPattern = static_cast<WebUserContentURLPattern*>(m_root);
164             encoder->encode(urlPattern->patternString());
165             return true;
166         }
167         case APIObject::TypeImage: {
168             WebImage* image = static_cast<WebImage*>(m_root);
169
170             ShareableBitmap::Handle handle;
171             if (!image->bitmap() || !image->bitmap()->isBackedBySharedMemory() || !image->bitmap()->createHandle(handle)) {
172                 // Initial false indicates no allocated bitmap or is not shareable.
173                 encoder->encode(false);
174                 return true;
175             }
176
177             // Initial true indicates a bitmap was allocated and is shareable.
178             encoder->encode(true);
179
180             encoder->encode(handle);
181             return true;
182         }
183         case APIObject::TypeData: {
184             WebData* data = static_cast<WebData*>(m_root);
185             encoder->encodeVariableLengthByteArray(data->dataReference());
186             return true;
187         }
188         case APIObject::TypeCertificateInfo: {
189             WebCertificateInfo* certificateInfo = static_cast<WebCertificateInfo*>(m_root);
190             encoder->encode(certificateInfo->platformCertificateInfo());
191             return true;
192         }
193         default:
194             break;
195         }
196
197         return false;
198     }
199
200 protected:
201     UserMessageEncoder(APIObject* root) 
202         : m_root(root)
203     {
204     }
205
206     APIObject* m_root;
207 };
208
209
210 // Handles
211 //   - Null -> Null
212 //   - Array -> Array
213 //   - Dictionary -> Dictionary
214 //   - SerializedScriptValue -> SerializedScriptValue
215 //   - String -> String
216 //   - UserContentURLPattern -> UserContentURLPattern
217 //   - WebCertificateInfo -> WebCertificateInfo
218 //   - WebData -> WebData
219 //   - WebDouble -> WebDouble
220 //   - WebImage -> WebImage
221 //   - WebUInt64 -> WebUInt64
222 //   - WebURL -> WebURL
223 //   - WebURLRequest -> WebURLRequest
224
225 template<typename Owner>
226 class UserMessageDecoder {
227 public:
228     static bool baseDecode(CoreIPC::ArgumentDecoder* decoder, Owner& coder, APIObject::Type& type)
229     {
230         uint32_t typeAsUInt32;
231         if (!decoder->decode(typeAsUInt32))
232             return false;
233
234         type = static_cast<APIObject::Type>(typeAsUInt32);
235
236         switch (type) {
237         case APIObject::TypeArray: {
238             uint64_t size;
239             if (!decoder->decode(size))
240                 return false;
241
242             Vector<RefPtr<APIObject> > vector;
243             for (size_t i = 0; i < size; ++i) {
244                 RefPtr<APIObject> element;
245                 Owner messageCoder(coder, element);
246                 if (!decoder->decode(messageCoder))
247                     return false;
248                 vector.append(element.release());
249             }
250
251             coder.m_root = ImmutableArray::adopt(vector);
252             break;
253         }
254         case APIObject::TypeDictionary: {
255             uint64_t size;
256             if (!decoder->decode(size))
257                 return false;
258
259             ImmutableDictionary::MapType map;
260             for (size_t i = 0; i < size; ++i) {
261                 String key;
262                 if (!decoder->decode(key))
263                     return false;
264
265                 RefPtr<APIObject> element;
266                 Owner messageCoder(coder, element);
267                 if (!decoder->decode(messageCoder))
268                     return false;
269
270                 std::pair<ImmutableDictionary::MapType::iterator, bool> result = map.set(key, element.release());
271                 if (!result.second)
272                     return false;
273             }
274
275             coder.m_root = ImmutableDictionary::adopt(map);
276             break;
277         }
278         case APIObject::TypeString: {
279             String string;
280             if (!decoder->decode(string))
281                 return false;
282             coder.m_root = WebString::create(string);
283             break;
284         }
285         case APIObject::TypeSerializedScriptValue: {
286             CoreIPC::DataReference dataReference;
287             if (!decoder->decodeVariableLengthByteArray(dataReference))
288                 return false;
289             
290             Vector<uint8_t> vector = dataReference.vector();
291             coder.m_root = WebSerializedScriptValue::adopt(vector);
292             break;
293         }
294         case APIObject::TypeDouble: {
295             double value;
296             if (!decoder->decode(value))
297                 return false;
298             coder.m_root = WebDouble::create(value);
299             break;
300         }
301         case APIObject::TypeUInt64: {
302             uint64_t value;
303             if (!decoder->decode(value))
304                 return false;
305             coder.m_root = WebUInt64::create(value);
306             break;
307         }
308         case APIObject::TypeBoolean: {
309             bool value;
310             if (!decoder->decode(value))
311                 return false;
312             coder.m_root = WebBoolean::create(value);
313             break;
314         }
315         case APIObject::TypeSize: {
316             double width;
317             double height;
318             if (!decoder->decode(width))
319                 return false;
320             if (!decoder->decode(height))
321                 return false;
322             coder.m_root = WebSize::create(WKSizeMake(width, height));
323             break;
324         }
325         case APIObject::TypePoint: {
326             double x;
327             double y;
328             if (!decoder->decode(x))
329                 return false;
330             if (!decoder->decode(y))
331                 return false;
332             coder.m_root = WebPoint::create(WKPointMake(x, y));
333             break;
334         }
335         case APIObject::TypeRect: {
336             double x;
337             double y;
338             double width;
339             double height;
340             if (!decoder->decode(x))
341                 return false;
342             if (!decoder->decode(y))
343                 return false;
344             if (!decoder->decode(width))
345                 return false;
346             if (!decoder->decode(height))
347                 return false;
348             coder.m_root = WebRect::create(WKRectMake(x, y, width, height));
349             break;
350         }
351         case APIObject::TypeRenderObject: {
352             String name;
353             WebCore::IntPoint absolutePosition;
354             WebCore::IntRect frameRect;
355             RefPtr<APIObject> children;
356             
357             if (!decoder->decode(name))
358                 return false;
359             if (!decoder->decode(absolutePosition))
360                 return false;
361             if (!decoder->decode(frameRect))
362                 return false;
363             Owner messageCoder(coder, children);
364             if (!decoder->decode(messageCoder))
365                 return false;
366             if (children->type() != APIObject::TypeArray)
367                 return false;
368             coder.m_root = WebRenderObject::create(name, absolutePosition, frameRect, WTF::static_pointer_cast<MutableArray>(children));
369             break;
370         }
371         case APIObject::TypeURL: {
372             String string;
373             if (!decoder->decode(string))
374                 return false;
375             coder.m_root = WebURL::create(string);
376             break;
377         }
378         case APIObject::TypeURLRequest: {
379             WebCore::ResourceRequest request;
380             if (!decoder->decode(request))
381                 return false;
382             coder.m_root = WebURLRequest::create(request);
383             break;
384         }
385         case APIObject::TypeUserContentURLPattern: {
386             String string;
387             if (!decoder->decode(string))
388                 return false;
389             coder.m_root = WebUserContentURLPattern::create(string);
390             break;
391         }
392         case APIObject::TypeImage: {
393             bool didEncode = false;
394             if (!decoder->decode(didEncode))
395                 return false;
396
397             if (!didEncode)
398                 break;
399
400             ShareableBitmap::Handle handle;
401             if (!decoder->decode(handle))
402                 return false;
403
404             coder.m_root = WebImage::create(ShareableBitmap::create(handle));
405             return true;
406         }
407         case APIObject::TypeData: {
408             CoreIPC::DataReference dataReference;
409             if (!decoder->decodeVariableLengthByteArray(dataReference))
410                 return false;
411             coder.m_root = WebData::create(dataReference.data(), dataReference.size());
412             break;
413         }
414         case APIObject::TypeCertificateInfo: {
415             PlatformCertificateInfo platformCertificateInfo;
416             if (!decoder->decode(platformCertificateInfo))
417                 return false;
418             coder.m_root = WebCertificateInfo::create(platformCertificateInfo);
419             break;
420         }
421         default:
422             break;
423         }
424
425         return true;
426     }
427
428 protected:
429     UserMessageDecoder(RefPtr<APIObject>& root)
430         : m_root(root)
431     {
432     }
433
434     RefPtr<APIObject>& m_root;
435 };
436
437 } // namespace WebKit
438
439 #endif // UserMessageCoders_h