Begin transition to modern IPC decoding
[WebKit-https.git] / Source / WebKit / Platform / IPC / ArgumentCoders.h
1 /*
2  * Copyright (C) 2010-2016 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 #pragma once
27
28 #include "Decoder.h"
29 #include "Encoder.h"
30 #include <utility>
31 #include <wtf/Expected.h>
32 #include <wtf/Forward.h>
33 #include <wtf/HashCountedSet.h>
34 #include <wtf/HashMap.h>
35 #include <wtf/HashSet.h>
36 #include <wtf/OptionSet.h>
37 #include <wtf/Optional.h>
38 #include <wtf/SHA1.h>
39 #include <wtf/Variant.h>
40 #include <wtf/Vector.h>
41
42 namespace IPC {
43
44 // An argument coder works on POD types
45 template<typename T> struct SimpleArgumentCoder {
46     static void encode(Encoder& encoder, const T& t)
47     {
48         encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(&t), sizeof(T), alignof(T));
49     }
50
51     static bool decode(Decoder& decoder, T& t)
52     {
53         return decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(&t), sizeof(T), alignof(T));
54     }
55 };
56
57 template<typename T> struct ArgumentCoder<OptionSet<T>> {
58     static void encode(Encoder& encoder, const OptionSet<T>& optionSet)
59     {
60         encoder << (static_cast<uint64_t>(optionSet.toRaw()));
61     }
62
63     static bool decode(Decoder& decoder, OptionSet<T>& optionSet)
64     {
65         uint64_t value;
66         if (!decoder.decode(value))
67             return false;
68
69         optionSet = OptionSet<T>::fromRaw(value);
70         return true;
71     }
72 };
73
74 template<typename T> struct ArgumentCoder<std::optional<T>> {
75     static void encode(Encoder& encoder, const std::optional<T>& optional)
76     {
77         if (!optional) {
78             encoder << false;
79             return;
80         }
81
82         encoder << true;
83         encoder << optional.value();
84     }
85
86     static bool decode(Decoder& decoder, std::optional<T>& optional)
87     {
88         bool isEngaged;
89         if (!decoder.decode(isEngaged))
90             return false;
91
92         if (!isEngaged) {
93             optional = std::nullopt;
94             return true;
95         }
96
97         T value;
98         if (!decoder.decode(value))
99             return false;
100
101         optional = WTFMove(value);
102         return true;
103     }
104 };
105
106 template<typename T, typename U> struct ArgumentCoder<std::pair<T, U>> {
107     static void encode(Encoder& encoder, const std::pair<T, U>& pair)
108     {
109         encoder << pair.first << pair.second;
110     }
111
112     static bool decode(Decoder& decoder, std::pair<T, U>& pair)
113     {
114         T first;
115         if (!decoder.decode(first))
116             return false;
117
118         U second;
119         if (!decoder.decode(second))
120             return false;
121
122         pair.first = first;
123         pair.second = second;
124         return true;
125     }
126 };
127
128 template<size_t index, typename... Elements>
129 struct TupleCoder {
130     static void encode(Encoder& encoder, const std::tuple<Elements...>& tuple)
131     {
132         encoder << std::get<sizeof...(Elements) - index>(tuple);
133         TupleCoder<index - 1, Elements...>::encode(encoder, tuple);
134     }
135
136     template<typename U = typename std::remove_reference<typename std::tuple_element<sizeof...(Elements) - index, std::tuple<Elements...>>::type>::type, std::enable_if_t<!UsesModernDecoder<U>::value>* = nullptr>
137     static bool decode(Decoder& decoder, std::tuple<Elements...>& tuple)
138     {
139         if (!decoder.decode(std::get<sizeof...(Elements) - index>(tuple)))
140             return false;
141         return TupleCoder<index - 1, Elements...>::decode(decoder, tuple);
142     }
143     
144     template<typename U = typename std::remove_reference<typename std::tuple_element<sizeof...(Elements) - index, std::tuple<Elements...>>::type>::type, std::enable_if_t<UsesModernDecoder<U>::value>* = nullptr>
145     static bool decode(Decoder& decoder, std::tuple<Elements...>& tuple)
146     {
147         std::optional<U> optional;
148         decoder >> optional;
149         if (!optional)
150             return false;
151         std::get<sizeof...(Elements) - index>(tuple) = WTFMove(*optional);
152         return TupleCoder<index - 1, Elements...>::decode(decoder, tuple);
153     }
154 };
155
156 template<typename... Elements>
157 struct TupleCoder<0, Elements...> {
158     static void encode(Encoder&, const std::tuple<Elements...>&)
159     {
160     }
161
162     static bool decode(Decoder&, std::tuple<Elements...>&)
163     {
164         return true;
165     }
166 };
167
168 template<typename... Elements> struct ArgumentCoder<std::tuple<Elements...>> {
169     static void encode(Encoder& encoder, const std::tuple<Elements...>& tuple)
170     {
171         TupleCoder<sizeof...(Elements), Elements...>::encode(encoder, tuple);
172     }
173
174     static bool decode(Decoder& decoder, std::tuple<Elements...>& tuple)
175     {
176         return TupleCoder<sizeof...(Elements), Elements...>::decode(decoder, tuple);
177     }
178 };
179
180
181 template<typename Rep, typename Period> struct ArgumentCoder<std::chrono::duration<Rep, Period>> {
182     static void encode(Encoder& encoder, const std::chrono::duration<Rep, Period>& duration)
183     {
184         static_assert(std::is_integral<Rep>::value && std::is_signed<Rep>::value && sizeof(Rep) <= sizeof(int64_t), "Serialization of this Rep type is not supported yet. Only signed integer type which can be fit in an int64_t is currently supported.");
185         encoder << static_cast<int64_t>(duration.count());
186     }
187
188     static bool decode(Decoder& decoder, std::chrono::duration<Rep, Period>& result)
189     {
190         int64_t count;
191         if (!decoder.decode(count))
192             return false;
193         result = std::chrono::duration<Rep, Period>(static_cast<Rep>(count));
194         return true;
195     }
196 };
197
198 template<typename KeyType, typename ValueType> struct ArgumentCoder<WTF::KeyValuePair<KeyType, ValueType>> {
199     static void encode(Encoder& encoder, const WTF::KeyValuePair<KeyType, ValueType>& pair)
200     {
201         encoder << pair.key << pair.value;
202     }
203
204     static bool decode(Decoder& decoder, WTF::KeyValuePair<KeyType, ValueType>& pair)
205     {
206         KeyType key;
207         if (!decoder.decode(key))
208             return false;
209
210         ValueType value;
211         if (!decoder.decode(value))
212             return false;
213
214         pair.key = key;
215         pair.value = value;
216         return true;
217     }
218 };
219
220 template<bool fixedSizeElements, typename T, size_t inlineCapacity> struct VectorArgumentCoder;
221
222 template<typename T, size_t inlineCapacity> struct VectorArgumentCoder<false, T, inlineCapacity> {
223     static void encode(Encoder& encoder, const Vector<T, inlineCapacity>& vector)
224     {
225         encoder << static_cast<uint64_t>(vector.size());
226         for (size_t i = 0; i < vector.size(); ++i)
227             encoder << vector[i];
228     }
229
230     static bool decode(Decoder& decoder, Vector<T, inlineCapacity>& vector)
231     {
232         uint64_t size;
233         if (!decoder.decode(size))
234             return false;
235
236         Vector<T, inlineCapacity> tmp;
237         for (size_t i = 0; i < size; ++i) {
238             T element;
239             if (!decoder.decode(element))
240                 return false;
241             
242             tmp.append(WTFMove(element));
243         }
244
245         tmp.shrinkToFit();
246         vector.swap(tmp);
247         return true;
248     }
249 };
250
251 template<typename T, size_t inlineCapacity> struct VectorArgumentCoder<true, T, inlineCapacity> {
252     static void encode(Encoder& encoder, const Vector<T, inlineCapacity>& vector)
253     {
254         encoder << static_cast<uint64_t>(vector.size());
255         encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(vector.data()), vector.size() * sizeof(T), alignof(T));
256     }
257     
258     static bool decode(Decoder& decoder, Vector<T, inlineCapacity>& vector)
259     {
260         uint64_t size;
261         if (!decoder.decode(size))
262             return false;
263
264         // Since we know the total size of the elements, we can allocate the vector in
265         // one fell swoop. Before allocating we must however make sure that the decoder buffer
266         // is big enough.
267         if (!decoder.bufferIsLargeEnoughToContain<T>(size)) {
268             decoder.markInvalid();
269             return false;
270         }
271
272         Vector<T, inlineCapacity> temp;
273         temp.grow(size);
274
275         decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(temp.data()), size * sizeof(T), alignof(T));
276
277         vector.swap(temp);
278         return true;
279     }
280 };
281
282 template<typename T, size_t inlineCapacity> struct ArgumentCoder<Vector<T, inlineCapacity>> : VectorArgumentCoder<std::is_arithmetic<T>::value, T, inlineCapacity> { };
283
284 template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg> struct ArgumentCoder<HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>> {
285     typedef HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> HashMapType;
286
287     static void encode(Encoder& encoder, const HashMapType& hashMap)
288     {
289         encoder << static_cast<uint64_t>(hashMap.size());
290         for (typename HashMapType::const_iterator it = hashMap.begin(), end = hashMap.end(); it != end; ++it)
291             encoder << *it;
292     }
293
294     static bool decode(Decoder& decoder, HashMapType& hashMap)
295     {
296         uint64_t hashMapSize;
297         if (!decoder.decode(hashMapSize))
298             return false;
299
300         HashMapType tempHashMap;
301         for (uint64_t i = 0; i < hashMapSize; ++i) {
302             KeyArg key;
303             MappedArg value;
304             if (!decoder.decode(key))
305                 return false;
306             if (!decoder.decode(value))
307                 return false;
308
309             if (!tempHashMap.add(key, value).isNewEntry) {
310                 // The hash map already has the specified key, bail.
311                 decoder.markInvalid();
312                 return false;
313             }
314         }
315
316         hashMap.swap(tempHashMap);
317         return true;
318     }
319 };
320
321 template<typename KeyArg, typename HashArg, typename KeyTraitsArg> struct ArgumentCoder<HashSet<KeyArg, HashArg, KeyTraitsArg>> {
322     typedef HashSet<KeyArg, HashArg, KeyTraitsArg> HashSetType;
323
324     static void encode(Encoder& encoder, const HashSetType& hashSet)
325     {
326         encoder << static_cast<uint64_t>(hashSet.size());
327         for (typename HashSetType::const_iterator it = hashSet.begin(), end = hashSet.end(); it != end; ++it)
328             encoder << *it;
329     }
330
331     static bool decode(Decoder& decoder, HashSetType& hashSet)
332     {
333         uint64_t hashSetSize;
334         if (!decoder.decode(hashSetSize))
335             return false;
336
337         HashSetType tempHashSet;
338         for (uint64_t i = 0; i < hashSetSize; ++i) {
339             KeyArg key;
340             if (!decoder.decode(key))
341                 return false;
342
343             if (!tempHashSet.add(key).isNewEntry) {
344                 // The hash map already has the specified key, bail.
345                 decoder.markInvalid();
346                 return false;
347             }
348         }
349
350         hashSet.swap(tempHashSet);
351         return true;
352     }
353 };
354
355 template<typename KeyArg, typename HashArg, typename KeyTraitsArg> struct ArgumentCoder<HashCountedSet<KeyArg, HashArg, KeyTraitsArg>> {
356     typedef HashCountedSet<KeyArg, HashArg, KeyTraitsArg> HashCountedSetType;
357     
358     static void encode(Encoder& encoder, const HashCountedSetType& hashCountedSet)
359     {
360         encoder << static_cast<uint64_t>(hashCountedSet.size());
361         
362         for (auto entry : hashCountedSet) {
363             encoder << entry.key;
364             encoder << entry.value;
365         }
366     }
367     
368     static bool decode(Decoder& decoder, HashCountedSetType& hashCountedSet)
369     {
370         uint64_t hashCountedSetSize;
371         if (!decoder.decode(hashCountedSetSize))
372             return false;
373         
374         HashCountedSetType tempHashCountedSet;
375         for (uint64_t i = 0; i < hashCountedSetSize; ++i) {
376             KeyArg key;
377             if (!decoder.decode(key))
378                 return false;
379             
380             unsigned count;
381             if (!decoder.decode(count))
382                 return false;
383             
384             if (!tempHashCountedSet.add(key, count).isNewEntry) {
385                 // The hash counted set already has the specified key, bail.
386                 decoder.markInvalid();
387                 return false;
388             }
389         }
390         
391         hashCountedSet.swap(tempHashCountedSet);
392         return true;
393     }
394 };
395
396 template<typename ValueType, typename ErrorType> struct ArgumentCoder<WTF::Expected<ValueType, ErrorType>> {
397     static void encode(Encoder& encoder, const WTF::Expected<ValueType, ErrorType>& expected)
398     {
399         if (!expected.hasValue()) {
400             encoder << false;
401             encoder << expected.error();
402             return;
403         }
404         encoder << true;
405         encoder << expected.value();
406     }
407
408     static bool decode(Decoder& decoder, WTF::Expected<ValueType, ErrorType>& expected)
409     {
410         bool hasValue;
411         if (!decoder.decode(hasValue))
412             return false;
413
414         if (!hasValue) {
415             ErrorType error;
416             if (!decoder.decode(error))
417                 return false;
418             expected = WTF::UnexpectedType<ErrorType> { WTFMove(error) };
419             return true;
420         }
421         ValueType value;
422         if (!decoder.decode(value))
423             return false;
424
425         expected = WTFMove(value);
426         return true;
427     }
428 };
429
430
431 template<> struct ArgumentCoder<std::chrono::system_clock::time_point> {
432     static void encode(Encoder&, const std::chrono::system_clock::time_point&);
433     static bool decode(Decoder&, std::chrono::system_clock::time_point&);
434 };
435
436 template<> struct ArgumentCoder<AtomicString> {
437     static void encode(Encoder&, const AtomicString&);
438     static bool decode(Decoder&, AtomicString&);
439 };
440
441 template<> struct ArgumentCoder<CString> {
442     static void encode(Encoder&, const CString&);
443     static bool decode(Decoder&, CString&);
444 };
445
446 template<> struct ArgumentCoder<String> {
447     static void encode(Encoder&, const String&);
448     static bool decode(Decoder&, String&);
449 };
450
451 template<> struct ArgumentCoder<SHA1::Digest> {
452     static void encode(Encoder&, const SHA1::Digest&);
453     static bool decode(Decoder&, SHA1::Digest&);
454 };
455
456 } // namespace IPC