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
51namespace 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
71template<typename Owner>
72class UserMessageEncoder {
73public:
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
233protected:
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
260template<typename Owner>
261class UserMessageDecoder {
262public:
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
527protected:
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
539