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
44namespace 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
59template<typename Owner>
60class UserMessageEncoder {
61public:
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()->isBackedBySharedMemory()) {
131                encoder->encode(false);
132                return true;
133            }
134
135            ShareableBitmap::Handle handle;
136            if (!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
161protected:
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
185template<typename Owner>
186class UserMessageDecoder {
187public:
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
323protected:
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
335