Add WTF::move()
[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 "APIArray.h"
30 #include "APIData.h"
31 #include "APIError.h"
32 #include "APIGeometry.h"
33 #include "APINumber.h"
34 #include "APIString.h"
35 #include "APIURL.h"
36 #include "APIURLRequest.h"
37 #include "APIURLResponse.h"
38 #include "ArgumentDecoder.h"
39 #include "ArgumentEncoder.h"
40 #include "DataReference.h"
41 #include "ImmutableDictionary.h"
42 #include "ShareableBitmap.h"
43 #include "WebCertificateInfo.h"
44 #include "WebCoreArgumentCoders.h"
45 #include "WebImage.h"
46 #include "WebRenderLayer.h"
47 #include "WebRenderObject.h"
48 #include "WebSerializedScriptValue.h"
49 #include "WebUserContentURLPattern.h"
50
51 namespace WebKit {
52
53 //   - Null -> Null
54 //   - API::Array -> API::Array
55 //   - Dictionary -> Dictionary
56 //   - SerializedScriptValue -> SerializedScriptValue
57 //   - API::String -> API::String
58 //   - UserContentURLPattern -> UserContentURLPattern
59 //   - WebCertificateInfo -> WebCertificateInfo
60 //   - API::Data -> API::Data
61 //   - API::Double -> API::Double
62 //   - WebImage -> WebImage
63 //   - WebRenderLayer -> WebRenderLayer
64 //   - WebRenderObject -> WebRenderObject
65 //   - API::UInt64 -> API::UInt64
66 //   - API::URL -> API::URL
67 //   - API::URLRequest -> API::URLRequest
68 //   - API::URLResponse -> API::URLResponse
69 //   - API::Error -> API::Error
70
71 template<typename Owner>
72 class UserMessageEncoder {
73 public:
74     bool baseEncode(IPC::ArgumentEncoder& encoder, const Owner& coder, API::Object::Type& type) const
75     {
76         if (!m_root) {
77             encoder << static_cast<uint32_t>(API::Object::Type::Null);
78             return true;
79         }
80
81         type = m_root->type();
82         encoder << static_cast<uint32_t>(type);
83
84         switch (type) {
85         case API::Object::Type::Array: {
86             API::Array* array = static_cast<API::Array*>(m_root);
87             encoder << static_cast<uint64_t>(array->size());
88             for (size_t i = 0; i < array->size(); ++i)
89                 encoder << Owner(coder, array->at(i));
90             return true;
91         }
92         case API::Object::Type::Dictionary: {
93             ImmutableDictionary* dictionary = static_cast<ImmutableDictionary*>(m_root);
94             const ImmutableDictionary::MapType& map = dictionary->map();
95             encoder << static_cast<uint64_t>(map.size());
96
97             ImmutableDictionary::MapType::const_iterator it = map.begin();
98             ImmutableDictionary::MapType::const_iterator end = map.end();
99             for (; it != end; ++it) {
100                 encoder << it->key;
101                 encoder << Owner(coder, it->value.get());
102             }
103             return true;
104         }
105         case API::Object::Type::String: {
106             API::String* string = static_cast<API::String*>(m_root);
107             encoder << string->string();
108             return true;
109         }
110         case API::Object::Type::SerializedScriptValue: {
111             WebSerializedScriptValue* scriptValue = static_cast<WebSerializedScriptValue*>(m_root);
112             encoder << scriptValue->dataReference();
113             return true;
114         }
115         case API::Object::Type::Boolean: {
116             API::Boolean* booleanObject = static_cast<API::Boolean*>(m_root);
117             encoder << booleanObject->value();
118             return true;
119         }
120         case API::Object::Type::Double: {
121             API::Double* doubleObject = static_cast<API::Double*>(m_root);
122             encoder << doubleObject->value();
123             return true;
124         }
125         case API::Object::Type::UInt64: {
126             API::UInt64* uint64Object = static_cast<API::UInt64*>(m_root);
127             encoder << uint64Object->value();
128             return true;
129         }
130         case API::Object::Type::Point: {
131             API::Point* pointObject = static_cast<API::Point*>(m_root);
132             encoder << pointObject->point().x;
133             encoder << pointObject->point().y;
134             return true;
135         }
136         case API::Object::Type::Size: {
137             API::Size* sizeObject = static_cast<API::Size*>(m_root);
138             encoder << sizeObject->size().width;
139             encoder << sizeObject->size().height;
140             return true;
141         }
142         case API::Object::Type::Rect: {
143             API::Rect* rectObject = static_cast<API::Rect*>(m_root);
144             encoder << rectObject->rect().origin.x;
145             encoder << rectObject->rect().origin.y;
146             encoder << rectObject->rect().size.width;
147             encoder << rectObject->rect().size.height;
148             return true;
149         }
150         case API::Object::Type::RenderLayer: {
151             WebRenderLayer* renderLayer = static_cast<WebRenderLayer*>(m_root);
152             encoder << Owner(coder, renderLayer->renderer());
153             encoder << renderLayer->isReflection();
154             encoder << renderLayer->isClipping();
155             encoder << renderLayer->isClipped();
156             encoder << static_cast<uint32_t>(renderLayer->compositingLayerType());
157             encoder << renderLayer->absoluteBoundingBox();
158             encoder << Owner(coder, renderLayer->negativeZOrderList());
159             encoder << Owner(coder, renderLayer->normalFlowList());
160             encoder << Owner(coder, renderLayer->positiveZOrderList());
161             return true;
162         }
163         case API::Object::Type::RenderObject: {
164             WebRenderObject* renderObject = static_cast<WebRenderObject*>(m_root);
165             encoder << renderObject->name();
166             encoder << renderObject->elementTagName();
167             encoder << renderObject->elementID();
168             encoder << Owner(coder, renderObject->elementClassNames());
169             encoder << renderObject->absolutePosition();
170             encoder << renderObject->frameRect();
171             encoder << Owner(coder, renderObject->children());
172             return true;
173         }
174         case API::Object::Type::URL: {
175             API::URL* urlObject = static_cast<API::URL*>(m_root);
176             encoder << urlObject->string();
177             return true;
178         }
179         case API::Object::Type::URLRequest: {
180             API::URLRequest* urlRequestObject = static_cast<API::URLRequest*>(m_root);
181             encoder << urlRequestObject->resourceRequest();
182             return true;
183         }
184         case API::Object::Type::URLResponse: {
185             API::URLResponse* urlResponseObject = static_cast<API::URLResponse*>(m_root);
186             encoder << urlResponseObject->resourceResponse();
187             return true;
188         }
189         case API::Object::Type::UserContentURLPattern: {
190             WebUserContentURLPattern* urlPattern = static_cast<WebUserContentURLPattern*>(m_root);
191             encoder << urlPattern->patternString();
192             return true;
193         }
194         case API::Object::Type::Image: {
195             WebImage* image = static_cast<WebImage*>(m_root);
196
197             ShareableBitmap::Handle handle;
198             ASSERT(!image->bitmap() || image->bitmap()->isBackedBySharedMemory());            
199             if (!image->bitmap() || !image->bitmap()->isBackedBySharedMemory() || !image->bitmap()->createHandle(handle)) {
200                 // Initial false indicates no allocated bitmap or is not shareable.
201                 encoder << false;
202                 return true;
203             }
204
205             // Initial true indicates a bitmap was allocated and is shareable.
206             encoder << true;
207
208             encoder << handle;
209             return true;
210         }
211         case API::Object::Type::Data: {
212             API::Data* data = static_cast<API::Data*>(m_root);
213             encoder << data->dataReference();
214             return true;
215         }
216         case API::Object::Type::CertificateInfo: {
217             WebCertificateInfo* certificateInfo = static_cast<WebCertificateInfo*>(m_root);
218             encoder << certificateInfo->certificateInfo();
219             return true;
220         }
221         case API::Object::Type::Error: {
222             API::Error* errorObject = static_cast<API::Error*>(m_root);
223             encoder << errorObject->platformError();
224             return true;
225         }
226         default:
227             break;
228         }
229
230         return false;
231     }
232
233 protected:
234     UserMessageEncoder(API::Object* root) 
235         : m_root(root)
236     {
237     }
238
239     API::Object* m_root;
240 };
241
242
243 // Handles
244 //   - Null -> Null
245 //   - API::Array -> API::Array
246 //   - Dictionary -> Dictionary
247 //   - SerializedScriptValue -> SerializedScriptValue
248 //   - API::String -> API::String
249 //   - UserContentURLPattern -> UserContentURLPattern
250 //   - WebCertificateInfo -> WebCertificateInfo
251 //   - API::Data -> API::Data
252 //   - API::Double -> API::Double
253 //   - WebImage -> WebImage
254 //   - API::UInt64 -> API::UInt64
255 //   - API::URL -> API::URL
256 //   - API::URLRequest -> API::URLRequest
257 //   - API::URLResponse -> API::URLResponse
258 //   - API::Error -> API::Error
259
260 template<typename Owner>
261 class UserMessageDecoder {
262 public:
263     static bool baseDecode(IPC::ArgumentDecoder& decoder, Owner& coder, API::Object::Type& type)
264     {
265         uint32_t typeAsUInt32;
266         if (!decoder.decode(typeAsUInt32))
267             return false;
268
269         type = static_cast<API::Object::Type>(typeAsUInt32);
270
271         switch (type) {
272         case API::Object::Type::Array: {
273             uint64_t size;
274             if (!decoder.decode(size))
275                 return false;
276
277             Vector<RefPtr<API::Object>> vector;
278             for (size_t i = 0; i < size; ++i) {
279                 RefPtr<API::Object> element;
280                 Owner messageCoder(coder, element);
281                 if (!decoder.decode(messageCoder))
282                     return false;
283                 vector.append(element.release());
284             }
285
286             coder.m_root = API::Array::create(WTF::move(vector));
287             break;
288         }
289         case API::Object::Type::Dictionary: {
290             uint64_t size;
291             if (!decoder.decode(size))
292                 return false;
293
294             ImmutableDictionary::MapType map;
295             for (size_t i = 0; i < size; ++i) {
296                 String key;
297                 if (!decoder.decode(key))
298                     return false;
299
300                 RefPtr<API::Object> element;
301                 Owner messageCoder(coder, element);
302                 if (!decoder.decode(messageCoder))
303                     return false;
304
305                 ImmutableDictionary::MapType::AddResult result = map.set(key, element.release());
306                 if (!result.isNewEntry)
307                     return false;
308             }
309
310             coder.m_root = ImmutableDictionary::create(WTF::move(map));
311             break;
312         }
313         case API::Object::Type::String: {
314             String string;
315             if (!decoder.decode(string))
316                 return false;
317             coder.m_root = API::String::create(string);
318             break;
319         }
320         case API::Object::Type::SerializedScriptValue: {
321             IPC::DataReference dataReference;
322             if (!decoder.decode(dataReference))
323                 return false;
324             
325             Vector<uint8_t> vector = dataReference.vector();
326             coder.m_root = WebSerializedScriptValue::adopt(vector);
327             break;
328         }
329         case API::Object::Type::Double: {
330             double value;
331             if (!decoder.decode(value))
332                 return false;
333             coder.m_root = API::Double::create(value);
334             break;
335         }
336         case API::Object::Type::UInt64: {
337             uint64_t value;
338             if (!decoder.decode(value))
339                 return false;
340             coder.m_root = API::UInt64::create(value);
341             break;
342         }
343         case API::Object::Type::Boolean: {
344             bool value;
345             if (!decoder.decode(value))
346                 return false;
347             coder.m_root = API::Boolean::create(value);
348             break;
349         }
350         case API::Object::Type::Size: {
351             double width;
352             double height;
353             if (!decoder.decode(width))
354                 return false;
355             if (!decoder.decode(height))
356                 return false;
357             coder.m_root = API::Size::create(WKSizeMake(width, height));
358             break;
359         }
360         case API::Object::Type::Point: {
361             double x;
362             double y;
363             if (!decoder.decode(x))
364                 return false;
365             if (!decoder.decode(y))
366                 return false;
367             coder.m_root = API::Point::create(WKPointMake(x, y));
368             break;
369         }
370         case API::Object::Type::Rect: {
371             double x;
372             double y;
373             double width;
374             double height;
375             if (!decoder.decode(x))
376                 return false;
377             if (!decoder.decode(y))
378                 return false;
379             if (!decoder.decode(width))
380                 return false;
381             if (!decoder.decode(height))
382                 return false;
383             coder.m_root = API::Rect::create(WKRectMake(x, y, width, height));
384             break;
385         }
386         case API::Object::Type::RenderLayer: {
387             RefPtr<API::Object> renderer;
388             bool isReflection;
389             bool isClipping;
390             bool isClipped;
391             uint32_t compositingLayerTypeAsUInt32;
392             WebCore::IntRect absoluteBoundingBox;
393             RefPtr<API::Object> negativeZOrderList;
394             RefPtr<API::Object> normalFlowList;
395             RefPtr<API::Object> positiveZOrderList;
396
397             Owner rendererCoder(coder, renderer);
398             if (!decoder.decode(rendererCoder))
399                 return false;
400             if (renderer->type() != API::Object::Type::RenderObject)
401                 return false;
402             if (!decoder.decode(isReflection))
403                 return false;
404             if (!decoder.decode(isClipping))
405                 return false;
406             if (!decoder.decode(isClipped))
407                 return false;
408             if (!decoder.decode(compositingLayerTypeAsUInt32))
409                 return false;
410             if (!decoder.decode(absoluteBoundingBox))
411                 return false;
412             Owner negativeZOrderListCoder(coder, negativeZOrderList);
413             if (!decoder.decode(negativeZOrderListCoder))
414                 return false;
415             Owner normalFlowListCoder(coder, normalFlowList);
416             if (!decoder.decode(normalFlowListCoder))
417                 return false;
418             Owner positiveZOrderListCoder(coder, positiveZOrderList);
419             if (!decoder.decode(positiveZOrderListCoder))
420                 return false;
421             coder.m_root = WebRenderLayer::create(static_pointer_cast<WebRenderObject>(renderer), isReflection, isClipping, isClipped, static_cast<WebRenderLayer::CompositingLayerType>(compositingLayerTypeAsUInt32),
422                 absoluteBoundingBox, static_pointer_cast<API::Array>(negativeZOrderList), static_pointer_cast<API::Array>(normalFlowList),
423                 static_pointer_cast<API::Array>(positiveZOrderList));
424             break;
425         }
426         case API::Object::Type::RenderObject: {
427             String name;
428             String elementTagName;
429             String elementID;
430             RefPtr<API::Object> elementClassNames;
431             WebCore::IntPoint absolutePosition;
432             WebCore::IntRect frameRect;
433             RefPtr<API::Object> children;
434             
435             if (!decoder.decode(name))
436                 return false;
437             if (!decoder.decode(elementTagName))
438                 return false;
439             if (!decoder.decode(elementID))
440                 return false;
441             Owner classNamesCoder(coder, elementClassNames);
442             if (!decoder.decode(classNamesCoder))
443                 return false;
444             if (!decoder.decode(absolutePosition))
445                 return false;
446             if (!decoder.decode(frameRect))
447                 return false;
448             Owner messageCoder(coder, children);
449             if (!decoder.decode(messageCoder))
450                 return false;
451             if (children && children->type() != API::Object::Type::Array)
452                 return false;
453             coder.m_root = WebRenderObject::create(name, elementTagName, elementID, static_pointer_cast<API::Array>(elementClassNames), absolutePosition, frameRect, static_pointer_cast<API::Array>(children));
454             break;
455         }
456         case API::Object::Type::URL: {
457             String string;
458             if (!decoder.decode(string))
459                 return false;
460             coder.m_root = API::URL::create(string);
461             break;
462         }
463         case API::Object::Type::URLRequest: {
464             WebCore::ResourceRequest request;
465             if (!decoder.decode(request))
466                 return false;
467             coder.m_root = API::URLRequest::create(request);
468             break;
469         }
470         case API::Object::Type::URLResponse: {
471             WebCore::ResourceResponse response;
472             if (!decoder.decode(response))
473                 return false;
474             coder.m_root = API::URLResponse::create(response);
475             break;
476         }
477         case API::Object::Type::UserContentURLPattern: {
478             String string;
479             if (!decoder.decode(string))
480                 return false;
481             coder.m_root = WebUserContentURLPattern::create(string);
482             break;
483         }
484         case API::Object::Type::Image: {
485             bool didEncode = false;
486             if (!decoder.decode(didEncode))
487                 return false;
488
489             if (!didEncode)
490                 break;
491
492             ShareableBitmap::Handle handle;
493             if (!decoder.decode(handle))
494                 return false;
495
496             coder.m_root = WebImage::create(ShareableBitmap::create(handle));
497             return true;
498         }
499         case API::Object::Type::Data: {
500             IPC::DataReference dataReference;
501             if (!decoder.decode(dataReference))
502                 return false;
503             coder.m_root = API::Data::create(dataReference.data(), dataReference.size());
504             break;
505         }
506         case API::Object::Type::CertificateInfo: {
507             WebCore::CertificateInfo certificateInfo;
508             if (!decoder.decode(certificateInfo))
509                 return false;
510             coder.m_root = WebCertificateInfo::create(certificateInfo);
511             break;
512         }
513         case API::Object::Type::Error: {
514             WebCore::ResourceError resourceError;
515             if (!decoder.decode(resourceError))
516                 return false;
517             coder.m_root = API::Error::create(resourceError);
518             break;
519         }
520         default:
521             break;
522         }
523
524         return true;
525     }
526
527 protected:
528     UserMessageDecoder(RefPtr<API::Object>& root)
529         : m_root(root)
530     {
531     }
532
533     RefPtr<API::Object>& m_root;
534 };
535
536 } // namespace WebKit
537
538 #endif // UserMessageCoders_h