<https://bugs.webkit.org/show_bug.cgi?id=62666>
[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 "ImmutableArray.h"
32 #include "ImmutableDictionary.h"
33 #include "ShareableBitmap.h"
34 #include "WebCertificateInfo.h"
35 #include "WebCoreArgumentCoders.h"
36 #include "WebData.h"
37 #include "WebImage.h"
38 #include "WebNumber.h"
39 #include "WebSerializedScriptValue.h"
40 #include "WebString.h"
41 #include "WebURL.h"
42 #include "WebUserContentURLPattern.h"
43
44 namespace WebKit {
45
46 //   - Null -> Null
47 //   - Array -> Array
48 //   - Dictionary -> Dictionary
49 //   - SerializedScriptValue -> SerializedScriptValue
50 //   - String -> String
51 //   - UserContentURLPattern -> UserContentURLPattern
52 //   - WebCertificateInfo -> WebCertificateInfo
53 //   - WebData -> WebData
54 //   - WebDouble -> WebDouble
55 //   - WebImage -> WebImage
56 //   - WebUInt64 -> WebUInt64
57 //   - WebURL -> WebURL
58
59 template<typename Owner>
60 class UserMessageEncoder {
61 public:
62     bool baseEncode(CoreIPC::ArgumentEncoder* encoder, APIObject::Type& type) const 
63     {
64         if (!m_root) {
65             encoder->encodeUInt32(APIObject::TypeNull);
66             return true;
67         }
68
69         type = m_root->type();
70         encoder->encodeUInt32(type);
71
72         switch (type) {
73         case APIObject::TypeArray: {
74             ImmutableArray* array = static_cast<ImmutableArray*>(m_root);
75             encoder->encode(static_cast<uint64_t>(array->size()));
76             for (size_t i = 0; i < array->size(); ++i)
77                 encoder->encode(Owner(array->at(i)));
78             return true;
79         }
80         case APIObject::TypeDictionary: {
81             ImmutableDictionary* dictionary = static_cast<ImmutableDictionary*>(m_root);
82             const ImmutableDictionary::MapType& map = dictionary->map();
83             encoder->encode(static_cast<uint64_t>(map.size()));
84
85             ImmutableDictionary::MapType::const_iterator it = map.begin();
86             ImmutableDictionary::MapType::const_iterator end = map.end();
87             for (; it != end; ++it) {
88                 encoder->encode(it->first);
89                 encoder->encode(Owner(it->second.get()));
90             }
91             return true;
92         }
93         case APIObject::TypeString: {
94             WebString* string = static_cast<WebString*>(m_root);
95             encoder->encode(string->string());
96             return true;
97         }
98         case APIObject::TypeSerializedScriptValue: {
99             WebSerializedScriptValue* scriptValue = static_cast<WebSerializedScriptValue*>(m_root);
100             encoder->encodeBytes(scriptValue->data().data(), scriptValue->data().size());
101             return true;
102         }
103         case APIObject::TypeDouble: {
104             WebDouble* doubleObject = static_cast<WebDouble*>(m_root);
105             encoder->encode(doubleObject->value());
106             return true;
107         }
108         case APIObject::TypeUInt64: {
109             WebUInt64* uint64Object = static_cast<WebUInt64*>(m_root);
110             encoder->encode(uint64Object->value());
111             return true;
112         }
113         case APIObject::TypeBoolean: {
114             WebBoolean* booleanObject = static_cast<WebBoolean*>(m_root);
115             encoder->encode(booleanObject->value());
116             return true;
117         }
118         case APIObject::TypeURL: {
119             WebURL* urlObject = static_cast<WebURL*>(m_root);
120             encoder->encode(urlObject->string());
121             return true;
122         }
123         case APIObject::TypeUserContentURLPattern: {
124             WebUserContentURLPattern* urlPattern = static_cast<WebUserContentURLPattern*>(m_root);
125             encoder->encode(urlPattern->patternString());
126             return true;
127         }
128         case APIObject::TypeImage: {
129             WebImage* image = static_cast<WebImage*>(m_root);
130             if (!image->bitmap() || !image->bitmap()->isBackedBySharedMemory()) {
131                 encoder->encode(false);
132                 return true;
133             }
134
135             ShareableBitmap::Handle handle;
136             if (!image->bitmap() || !image->bitmap()->createHandle(handle))
137                 return false;
138
139             encoder->encode(true);
140             
141             encoder->encode(handle);
142             return true;
143         }
144         case APIObject::TypeData: {
145             WebData* data = static_cast<WebData*>(m_root);
146             encoder->encodeBytes(data->bytes(), data->size());
147             return true;
148         }
149         case APIObject::TypeCertificateInfo: {
150             WebCertificateInfo* certificateInfo = static_cast<WebCertificateInfo*>(m_root);
151             encoder->encode(certificateInfo->platformCertificateInfo());
152             return true;
153         }
154         default:
155             break;
156         }
157
158         return false;
159     }
160
161 protected:
162     UserMessageEncoder(APIObject* root) 
163         : m_root(root)
164     {
165     }
166
167     APIObject* m_root;
168 };
169
170
171 // Handles
172 //   - Null -> Null
173 //   - Array -> Array
174 //   - Dictionary -> Dictionary
175 //   - SerializedScriptValue -> SerializedScriptValue
176 //   - String -> String
177 //   - UserContentURLPattern -> UserContentURLPattern
178 //   - WebCertificateInfo -> WebCertificateInfo
179 //   - WebData -> WebData
180 //   - WebDouble -> WebDouble
181 //   - WebImage -> WebImage
182 //   - WebUInt64 -> WebUInt64
183 //   - WebURL -> WebURL
184
185 template<typename Owner>
186 class UserMessageDecoder {
187 public:
188     static bool baseDecode(CoreIPC::ArgumentDecoder* decoder, Owner& coder, APIObject::Type& type)
189     {
190         uint32_t typeAsUInt32;
191         if (!decoder->decode(typeAsUInt32))
192             return false;
193
194         type = static_cast<APIObject::Type>(typeAsUInt32);
195
196         switch (type) {
197         case APIObject::TypeArray: {
198             uint64_t size;
199             if (!decoder->decode(size))
200                 return false;
201
202             Vector<RefPtr<APIObject> > vector;
203             for (size_t i = 0; i < size; ++i) {
204                 RefPtr<APIObject> element;
205                 Owner messageCoder(coder, element);
206                 if (!decoder->decode(messageCoder))
207                     return false;
208                 vector.append(element.release());
209             }
210
211             coder.m_root = ImmutableArray::adopt(vector);
212             break;
213         }
214         case APIObject::TypeDictionary: {
215             uint64_t size;
216             if (!decoder->decode(size))
217                 return false;
218
219             ImmutableDictionary::MapType map;
220             for (size_t i = 0; i < size; ++i) {
221                 String key;
222                 if (!decoder->decode(key))
223                     return false;
224
225                 RefPtr<APIObject> element;
226                 Owner messageCoder(coder, element);
227                 if (!decoder->decode(messageCoder))
228                     return false;
229
230                 std::pair<ImmutableDictionary::MapType::iterator, bool> result = map.set(key, element.release());
231                 if (!result.second)
232                     return false;
233             }
234
235             coder.m_root = ImmutableDictionary::adopt(map);
236             break;
237         }
238         case APIObject::TypeString: {
239             String string;
240             if (!decoder->decode(string))
241                 return false;
242             coder.m_root = WebString::create(string);
243             break;
244         }
245         case APIObject::TypeSerializedScriptValue: {
246             Vector<uint8_t> buffer;
247             if (!decoder->decodeBytes(buffer))
248                 return false;
249             coder.m_root = WebSerializedScriptValue::adopt(buffer);
250             break;
251         }
252         case APIObject::TypeDouble: {
253             double value;
254             if (!decoder->decode(value))
255                 return false;
256             coder.m_root = WebDouble::create(value);
257             break;
258         }
259         case APIObject::TypeUInt64: {
260             uint64_t value;
261             if (!decoder->decode(value))
262                 return false;
263             coder.m_root = WebUInt64::create(value);
264             break;
265         }
266         case APIObject::TypeBoolean: {
267             bool value;
268             if (!decoder->decode(value))
269                 return false;
270             coder.m_root = WebBoolean::create(value);
271             break;
272         }
273         case APIObject::TypeURL: {
274             String string;
275             if (!decoder->decode(string))
276                 return false;
277             coder.m_root = WebURL::create(string);
278             break;
279         }
280         case APIObject::TypeUserContentURLPattern: {
281             String string;
282             if (!decoder->decode(string))
283                 return false;
284             coder.m_root = WebUserContentURLPattern::create(string);
285             break;
286         }
287         case APIObject::TypeImage: {
288             bool didEncode = false;
289             if (!decoder->decode(didEncode))
290                 return false;
291
292             if (!didEncode)
293                 break;
294
295             ShareableBitmap::Handle handle;
296             if (!decoder->decode(handle))
297                 return false;
298
299             coder.m_root = WebImage::create(ShareableBitmap::create(handle));
300             return true;
301         }
302         case APIObject::TypeData: {
303             Vector<uint8_t> buffer;
304             if (!decoder->decodeBytes(buffer))
305                 return false;
306             coder.m_root = WebData::create(buffer);
307             break;
308         }
309         case APIObject::TypeCertificateInfo: {
310             PlatformCertificateInfo platformCertificateInfo;
311             if (!decoder->decode(platformCertificateInfo))
312                 return false;
313             coder.m_root = WebCertificateInfo::create(platformCertificateInfo);
314             break;
315         }
316         default:
317             break;
318         }
319
320         return true;
321     }
322
323 protected:
324     UserMessageDecoder(RefPtr<APIObject>& root)
325         : m_root(root)
326     {
327     }
328
329     RefPtr<APIObject>& m_root;
330 };
331
332 } // namespace WebKit
333
334 #endif // UserMessageCoders_h