Add WTF::move()
[WebKit-https.git] / Source / WebKit2 / Shared / UserData.cpp
1 /*
2  * Copyright (C) 2013 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 #include "config.h"
27 #include "UserData.h"
28
29 #include "APIArray.h"
30 #include "APIData.h"
31 #include "APIError.h"
32 #include "APIFrameHandle.h"
33 #include "APIGeometry.h"
34 #include "APINumber.h"
35 #include "APIString.h"
36 #include "APIURL.h"
37 #include "APIURLRequest.h"
38 #include "APIURLResponse.h"
39 #include "ArgumentCoders.h"
40 #include "ArgumentEncoder.h"
41 #include "MutableDictionary.h"
42 #include "WebSerializedScriptValue.h"
43
44 namespace WebKit {
45
46 UserData::UserData(API::Object* object)
47     : m_object(object)
48 {
49 }
50
51 UserData::~UserData()
52 {
53 }
54
55 RefPtr<API::Object> UserData::transform(API::Object* object, const std::function<RefPtr<API::Object> (const API::Object&)> transformer)
56 {
57     if (!object)
58         return nullptr;
59
60     if (object->type() == API::Object::Type::Array) {
61         auto& array = static_cast<API::Array&>(*object);
62
63         Vector<RefPtr<API::Object>> elements;
64         elements.reserveInitialCapacity(array.elements().size());
65         for (const auto& element : array.elements())
66             elements.uncheckedAppend(transform(element.get(), transformer));
67
68         return API::Array::create(WTF::move(elements));
69     }
70
71     if (object->type() == API::Object::Type::Dictionary) {
72         auto& dictionary = static_cast<ImmutableDictionary&>(*object);
73
74         ImmutableDictionary::MapType map;
75         for (const auto& keyValuePair : dictionary.map())
76             map.add(keyValuePair.key, transform(keyValuePair.value.get(), transformer));
77
78         return ImmutableDictionary::create(WTF::move(map));
79     }
80
81     if (auto transformedObject = transformer(*object))
82         return transformedObject;
83
84     return object;
85 }
86
87 void UserData::encode(IPC::ArgumentEncoder& encoder) const
88 {
89     encode(encoder, m_object.get());
90 }
91
92 bool UserData::decode(IPC::ArgumentDecoder& decoder, UserData& userData)
93 {
94     return decode(decoder, userData.m_object);
95 }
96
97 void UserData::encode(IPC::ArgumentEncoder& encoder, const API::Object* object) const
98 {
99     if (!object) {
100         encoder.encodeEnum(API::Object::Type::Null);
101         return;
102     }
103
104     encode(encoder, *object);
105 }
106
107 void UserData::encode(IPC::ArgumentEncoder& encoder, const API::Object& object) const
108 {
109     API::Object::Type type = object.type();
110     encoder.encodeEnum(type);
111
112     switch (object.type()) {
113     case API::Object::Type::Array: {
114         auto& array = static_cast<const API::Array&>(object);
115         encoder << static_cast<uint64_t>(array.size());
116         for (size_t i = 0; i < array.size(); ++i)
117             encode(encoder, array.at(i));
118         break;
119     }
120
121     case API::Object::Type::Boolean:
122         static_cast<const API::Boolean&>(object).encode(encoder);
123         break;
124
125     case API::Object::Type::Data:
126         static_cast<const API::Data&>(object).encode(encoder);
127         break;
128     
129     case API::Object::Type::Dictionary: {
130         auto& dictionary = static_cast<const ImmutableDictionary&>(object);
131         auto& map = dictionary.map();
132
133         encoder << static_cast<uint64_t>(map.size());
134         for (const auto& keyValuePair : map) {
135             encoder << keyValuePair.key;
136             encode(encoder, keyValuePair.value.get());
137         }
138         break;
139     }
140
141     case API::Object::Type::Double:
142         static_cast<const API::Double&>(object).encode(encoder);
143         break;
144
145     case API::Object::Type::Error:
146         static_cast<const API::Error&>(object).encode(encoder);
147         break;
148
149     case API::Object::Type::FrameHandle: {
150         auto& frameHandle = static_cast<const API::FrameHandle&>(object);
151         encoder << frameHandle.frameID();
152         break;
153     }
154
155     case API::Object::Type::Point:
156         static_cast<const API::Point&>(object).encode(encoder);
157         break;
158
159     case API::Object::Type::Rect:
160         static_cast<const API::Rect&>(object).encode(encoder);
161         break;
162
163     case API::Object::Type::SerializedScriptValue: {
164         auto& serializedScriptValue = static_cast<const WebSerializedScriptValue&>(object);
165         encoder << serializedScriptValue.dataReference();
166         break;
167     }
168
169     case API::Object::Type::Size:
170         static_cast<const API::Size&>(object).encode(encoder);
171         break;
172
173     case API::Object::Type::String: {
174         auto& string = static_cast<const API::String&>(object);
175         encoder << string.string();
176         break;
177     }
178
179     case API::Object::Type::URL: {
180         static_cast<const API::URL&>(object).encode(encoder);
181         break;
182     }
183
184     case API::Object::Type::URLRequest:
185         static_cast<const API::URLRequest&>(object).encode(encoder);
186         break;
187
188     case API::Object::Type::URLResponse:
189         static_cast<const API::URLResponse&>(object).encode(encoder);
190         break;
191
192     case API::Object::Type::UInt64:
193         static_cast<const API::UInt64&>(object).encode(encoder);
194         break;
195
196     default:
197         ASSERT_NOT_REACHED();
198     }
199 }
200
201 bool UserData::decode(IPC::ArgumentDecoder& decoder, RefPtr<API::Object>& result)
202 {
203     API::Object::Type type;
204     if (!decoder.decodeEnum(type))
205         return false;
206
207     switch (type) {
208     case API::Object::Type::Array: {
209         uint64_t size;
210         if (!decoder.decode(size))
211             return false;
212
213         Vector<RefPtr<API::Object>> elements;
214         for (size_t i = 0; i < size; ++i) {
215             RefPtr<API::Object> element;
216             if (!decode(decoder, element))
217                 return false;
218
219             elements.append(WTF::move(element));
220         }
221
222         result = API::Array::create(WTF::move(elements));
223         break;
224     }
225
226     case API::Object::Type::Boolean:
227         if (!API::Boolean::decode(decoder, result))
228             return false;
229         break;
230
231     case API::Object::Type::Data:
232         if (!API::Data::decode(decoder, result))
233             return false;
234         break;
235
236     case API::Object::Type::Dictionary: {
237         uint64_t size;
238         if (!decoder.decode(size))
239             return false;
240
241         ImmutableDictionary::MapType map;
242         for (size_t i = 0; i < size; ++i) {
243             String key;
244             if (!decoder.decode(key))
245                 return false;
246
247             RefPtr<API::Object> value;
248             if (!decode(decoder, value))
249                 return false;
250
251             if (!map.add(WTF::move(key), WTF::move(value)).isNewEntry)
252                 return false;
253         }
254
255         result = ImmutableDictionary::create(WTF::move(map));
256         break;
257     }
258
259     case API::Object::Type::Double:
260         if (!API::Double::decode(decoder, result))
261             return false;
262         break;
263
264     case API::Object::Type::Error:
265         if (!API::Error::decode(decoder, result))
266             return false;
267         break;
268
269     case API::Object::Type::FrameHandle: {
270         uint64_t frameID;
271         if (!decoder.decode(frameID))
272             return false;
273
274         result = API::FrameHandle::create(frameID);
275         break;
276     }
277
278     case API::Object::Type::Null:
279         result = nullptr;
280         break;
281         
282     case API::Object::Type::Point:
283         if (!API::Point::decode(decoder, result))
284             return false;
285         break;
286
287     case API::Object::Type::Rect:
288         if (!API::Rect::decode(decoder, result))
289             return false;
290         break;
291
292     case API::Object::Type::SerializedScriptValue: {
293         IPC::DataReference dataReference;
294         if (!decoder.decode(dataReference))
295             return false;
296
297         auto vector = dataReference.vector();
298         result = WebSerializedScriptValue::adopt(vector);
299         break;
300     }
301
302     case API::Object::Type::Size:
303         if (!API::Size::decode(decoder, result))
304             return false;
305         break;
306
307     case API::Object::Type::String: {
308         String string;
309         if (!decoder.decode(string))
310             return false;
311
312         result = API::String::create(string);
313         break;
314     }
315
316     case API::Object::Type::URL:
317         if (!API::URL::decode(decoder, result))
318             return false;
319         break;
320
321     case API::Object::Type::URLRequest:
322         if (!API::URLRequest::decode(decoder, result))
323             return false;
324         break;
325
326     case API::Object::Type::URLResponse:
327         if (!API::URLResponse::decode(decoder, result))
328             return false;
329         break;
330
331     case API::Object::Type::UInt64:
332         if (!API::UInt64::decode(decoder, result))
333             return false;
334         break;
335
336     default:
337         ASSERT_NOT_REACHED();
338     }
339
340     return true;
341 }
342
343 } // namespace WebKit