Allow modern decoding of Vectors
[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     static std::optional<OptionSet<T>> decode(Decoder& decoder)
74     {
75         std::optional<uint64_t> value;
76         decoder >> value;
77         if (!value)
78             return std::nullopt;
79         return OptionSet<T>::fromRaw(*value);
80     }
81 };
82
83 template<typename T> struct ArgumentCoder<std::optional<T>> {
84     static void encode(Encoder& encoder, const std::optional<T>& optional)
85     {
86         if (!optional) {
87             encoder << false;
88             return;
89         }
90
91         encoder << true;
92         encoder << optional.value();
93     }
94
95     static bool decode(Decoder& decoder, std::optional<T>& optional)
96     {
97         bool isEngaged;
98         if (!decoder.decode(isEngaged))
99             return false;
100
101         if (!isEngaged) {
102             optional = std::nullopt;
103             return true;
104         }
105
106         T value;
107         if (!decoder.decode(value))
108             return false;
109
110         optional = WTFMove(value);
111         return true;
112     }
113 };
114
115 template<typename T, typename U> struct ArgumentCoder<std::pair<T, U>> {
116     static void encode(Encoder& encoder, const std::pair<T, U>& pair)
117     {
118         encoder << pair.first << pair.second;
119     }
120
121     static bool decode(Decoder& decoder, std::pair<T, U>& pair)
122     {
123         T first;
124         if (!decoder.decode(first))
125             return false;
126
127         U second;
128         if (!decoder.decode(second))
129             return false;
130
131         pair.first = first;
132         pair.second = second;
133         return true;
134     }
135
136     static std::optional<std::pair<T, U>> decode(Decoder& decoder)
137     {
138         std::optional<T> first;
139         decoder >> first;
140         if (!first)
141             return std::nullopt;
142         
143         std::optional<U> second;
144         decoder >> second;
145         if (!second)
146             return std::nullopt;
147         
148         return {{ WTFMove(*first), WTFMove(*second) }};
149     }
150 };
151
152 template<size_t index, typename... Elements>
153 struct TupleCoder {
154     static void encode(Encoder& encoder, const std::tuple<Elements...>& tuple)
155     {
156         encoder << std::get<sizeof...(Elements) - index>(tuple);
157         TupleCoder<index - 1, Elements...>::encode(encoder, tuple);
158     }
159
160     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>
161     static bool decode(Decoder& decoder, std::tuple<Elements...>& tuple)
162     {
163         if (!decoder.decode(std::get<sizeof...(Elements) - index>(tuple)))
164             return false;
165         return TupleCoder<index - 1, Elements...>::decode(decoder, tuple);
166     }
167     
168     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>
169     static bool decode(Decoder& decoder, std::tuple<Elements...>& tuple)
170     {
171         std::optional<U> optional;
172         decoder >> optional;
173         if (!optional)
174             return false;
175         std::get<sizeof...(Elements) - index>(tuple) = WTFMove(*optional);
176         return TupleCoder<index - 1, Elements...>::decode(decoder, tuple);
177     }
178 };
179
180 template<typename... Elements>
181 struct TupleCoder<0, Elements...> {
182     static void encode(Encoder&, const std::tuple<Elements...>&)
183     {
184     }
185
186     static bool decode(Decoder&, std::tuple<Elements...>&)
187     {
188         return true;
189     }
190 };
191
192 template<typename... Elements> struct ArgumentCoder<std::tuple<Elements...>> {
193     static void encode(Encoder& encoder, const std::tuple<Elements...>& tuple)
194     {
195         TupleCoder<sizeof...(Elements), Elements...>::encode(encoder, tuple);
196     }
197
198     static bool decode(Decoder& decoder, std::tuple<Elements...>& tuple)
199     {
200         return TupleCoder<sizeof...(Elements), Elements...>::decode(decoder, tuple);
201     }
202 };
203
204
205 template<typename Rep, typename Period> struct ArgumentCoder<std::chrono::duration<Rep, Period>> {
206     static void encode(Encoder& encoder, const std::chrono::duration<Rep, Period>& duration)
207     {
208         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.");
209         encoder << static_cast<int64_t>(duration.count());
210     }
211
212     static bool decode(Decoder& decoder, std::chrono::duration<Rep, Period>& result)
213     {
214         int64_t count;
215         if (!decoder.decode(count))
216             return false;
217         result = std::chrono::duration<Rep, Period>(static_cast<Rep>(count));
218         return true;
219     }
220 };
221
222 template<typename KeyType, typename ValueType> struct ArgumentCoder<WTF::KeyValuePair<KeyType, ValueType>> {
223     static void encode(Encoder& encoder, const WTF::KeyValuePair<KeyType, ValueType>& pair)
224     {
225         encoder << pair.key << pair.value;
226     }
227
228     static bool decode(Decoder& decoder, WTF::KeyValuePair<KeyType, ValueType>& pair)
229     {
230         KeyType key;
231         if (!decoder.decode(key))
232             return false;
233
234         ValueType value;
235         if (!decoder.decode(value))
236             return false;
237
238         pair.key = key;
239         pair.value = value;
240         return true;
241     }
242 };
243
244 template<bool fixedSizeElements, typename T, size_t inlineCapacity> struct VectorArgumentCoder;
245
246 template<typename T, size_t inlineCapacity> struct VectorArgumentCoder<false, T, inlineCapacity> {
247     static void encode(Encoder& encoder, const Vector<T, inlineCapacity>& vector)
248     {
249         encoder << static_cast<uint64_t>(vector.size());
250         for (size_t i = 0; i < vector.size(); ++i)
251             encoder << vector[i];
252     }
253
254     static bool decode(Decoder& decoder, Vector<T, inlineCapacity>& vector)
255     {
256         std::optional<Vector<T, inlineCapacity>> optional;
257         decoder >> optional;
258         if (!optional)
259             return false;
260         vector = WTFMove(*optional);
261         return true;
262     }
263
264     static std::optional<Vector<T, inlineCapacity>> decode(Decoder& decoder)
265     {
266         uint64_t size;
267         if (!decoder.decode(size))
268             return std::nullopt;
269
270         Vector<T, inlineCapacity> vector;
271         for (size_t i = 0; i < size; ++i) {
272             std::optional<T> element;
273             decoder >> element;
274             if (!element)
275                 return std::nullopt;
276             vector.append(WTFMove(*element));
277         }
278         vector.shrinkToFit();
279         return WTFMove(vector);
280     }
281 };
282
283 template<typename T, size_t inlineCapacity> struct VectorArgumentCoder<true, T, inlineCapacity> {
284     static void encode(Encoder& encoder, const Vector<T, inlineCapacity>& vector)
285     {
286         encoder << static_cast<uint64_t>(vector.size());
287         encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(vector.data()), vector.size() * sizeof(T), alignof(T));
288     }
289     
290     static bool decode(Decoder& decoder, Vector<T, inlineCapacity>& vector)
291     {
292         uint64_t size;
293         if (!decoder.decode(size))
294             return false;
295
296         // Since we know the total size of the elements, we can allocate the vector in
297         // one fell swoop. Before allocating we must however make sure that the decoder buffer
298         // is big enough.
299         if (!decoder.bufferIsLargeEnoughToContain<T>(size)) {
300             decoder.markInvalid();
301             return false;
302         }
303
304         Vector<T, inlineCapacity> temp;
305         temp.grow(size);
306
307         decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(temp.data()), size * sizeof(T), alignof(T));
308
309         vector.swap(temp);
310         return true;
311     }
312     
313     static std::optional<Vector<T, inlineCapacity>> decode(Decoder& decoder)
314     {
315         uint64_t size;
316         if (!decoder.decode(size))
317             return std::nullopt;
318         
319         // Since we know the total size of the elements, we can allocate the vector in
320         // one fell swoop. Before allocating we must however make sure that the decoder buffer
321         // is big enough.
322         if (!decoder.bufferIsLargeEnoughToContain<T>(size)) {
323             decoder.markInvalid();
324             return std::nullopt;
325         }
326         
327         Vector<T, inlineCapacity> vector;
328         vector.grow(size);
329         
330         decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(vector.data()), size * sizeof(T), alignof(T));
331         
332         return vector;
333     }
334 };
335
336 template<typename T, size_t inlineCapacity> struct ArgumentCoder<Vector<T, inlineCapacity>> : VectorArgumentCoder<std::is_arithmetic<T>::value, T, inlineCapacity> { };
337
338 template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg> struct ArgumentCoder<HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>> {
339     typedef HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> HashMapType;
340
341     static void encode(Encoder& encoder, const HashMapType& hashMap)
342     {
343         encoder << static_cast<uint64_t>(hashMap.size());
344         for (typename HashMapType::const_iterator it = hashMap.begin(), end = hashMap.end(); it != end; ++it)
345             encoder << *it;
346     }
347
348     static bool decode(Decoder& decoder, HashMapType& hashMap)
349     {
350         uint64_t hashMapSize;
351         if (!decoder.decode(hashMapSize))
352             return false;
353
354         HashMapType tempHashMap;
355         for (uint64_t i = 0; i < hashMapSize; ++i) {
356             KeyArg key;
357             MappedArg value;
358             if (!decoder.decode(key))
359                 return false;
360             if (!decoder.decode(value))
361                 return false;
362
363             if (!tempHashMap.add(key, value).isNewEntry) {
364                 // The hash map already has the specified key, bail.
365                 decoder.markInvalid();
366                 return false;
367             }
368         }
369
370         hashMap.swap(tempHashMap);
371         return true;
372     }
373
374     static std::optional<HashMapType> decode(Decoder& decoder)
375     {
376         uint64_t hashMapSize;
377         if (!decoder.decode(hashMapSize))
378             return std::nullopt;
379         
380         HashMapType hashMap;
381         for (uint64_t i = 0; i < hashMapSize; ++i) {
382             KeyArg key;
383             MappedArg value;
384             if (!decoder.decode(key))
385                 return std::nullopt;
386             if (!decoder.decode(value))
387                 return std::nullopt;
388             
389             if (!hashMap.add(key, value).isNewEntry) {
390                 // The hash map already has the specified key, bail.
391                 decoder.markInvalid();
392                 return std::nullopt;
393             }
394         }
395         
396         return WTFMove(hashMap);
397     }
398 };
399
400 template<typename KeyArg, typename HashArg, typename KeyTraitsArg> struct ArgumentCoder<HashSet<KeyArg, HashArg, KeyTraitsArg>> {
401     typedef HashSet<KeyArg, HashArg, KeyTraitsArg> HashSetType;
402
403     static void encode(Encoder& encoder, const HashSetType& hashSet)
404     {
405         encoder << static_cast<uint64_t>(hashSet.size());
406         for (typename HashSetType::const_iterator it = hashSet.begin(), end = hashSet.end(); it != end; ++it)
407             encoder << *it;
408     }
409
410     static bool decode(Decoder& decoder, HashSetType& hashSet)
411     {
412         uint64_t hashSetSize;
413         if (!decoder.decode(hashSetSize))
414             return false;
415
416         HashSetType tempHashSet;
417         for (uint64_t i = 0; i < hashSetSize; ++i) {
418             KeyArg key;
419             if (!decoder.decode(key))
420                 return false;
421
422             if (!tempHashSet.add(key).isNewEntry) {
423                 // The hash map already has the specified key, bail.
424                 decoder.markInvalid();
425                 return false;
426             }
427         }
428
429         hashSet.swap(tempHashSet);
430         return true;
431     }
432 };
433
434 template<typename KeyArg, typename HashArg, typename KeyTraitsArg> struct ArgumentCoder<HashCountedSet<KeyArg, HashArg, KeyTraitsArg>> {
435     typedef HashCountedSet<KeyArg, HashArg, KeyTraitsArg> HashCountedSetType;
436     
437     static void encode(Encoder& encoder, const HashCountedSetType& hashCountedSet)
438     {
439         encoder << static_cast<uint64_t>(hashCountedSet.size());
440         
441         for (auto entry : hashCountedSet) {
442             encoder << entry.key;
443             encoder << entry.value;
444         }
445     }
446     
447     static bool decode(Decoder& decoder, HashCountedSetType& hashCountedSet)
448     {
449         uint64_t hashCountedSetSize;
450         if (!decoder.decode(hashCountedSetSize))
451             return false;
452         
453         HashCountedSetType tempHashCountedSet;
454         for (uint64_t i = 0; i < hashCountedSetSize; ++i) {
455             KeyArg key;
456             if (!decoder.decode(key))
457                 return false;
458             
459             unsigned count;
460             if (!decoder.decode(count))
461                 return false;
462             
463             if (!tempHashCountedSet.add(key, count).isNewEntry) {
464                 // The hash counted set already has the specified key, bail.
465                 decoder.markInvalid();
466                 return false;
467             }
468         }
469         
470         hashCountedSet.swap(tempHashCountedSet);
471         return true;
472     }
473 };
474
475 template<typename ValueType, typename ErrorType> struct ArgumentCoder<WTF::Expected<ValueType, ErrorType>> {
476     static void encode(Encoder& encoder, const WTF::Expected<ValueType, ErrorType>& expected)
477     {
478         if (!expected.hasValue()) {
479             encoder << false;
480             encoder << expected.error();
481             return;
482         }
483         encoder << true;
484         encoder << expected.value();
485     }
486
487     static std::optional<WTF::Expected<ValueType, ErrorType>> decode(Decoder& decoder)
488     {
489         std::optional<bool> hasValue;
490         decoder >> hasValue;
491         if (!hasValue)
492             return std::nullopt;
493         
494         if (*hasValue) {
495             std::optional<ValueType> value;
496             decoder >> value;
497             if (!value)
498                 return std::nullopt;
499             
500             WTF::Expected<ValueType, ErrorType> expected(WTFMove(*value));
501             return WTFMove(expected);
502         }
503         std::optional<ErrorType> error;
504         decoder >> error;
505         if (!error)
506             return std::nullopt;
507         return { makeUnexpected(WTFMove(*error)) };
508     }
509 };
510
511 template<> struct ArgumentCoder<std::chrono::system_clock::time_point> {
512     static void encode(Encoder&, const std::chrono::system_clock::time_point&);
513     static bool decode(Decoder&, std::chrono::system_clock::time_point&);
514     static std::optional<std::chrono::system_clock::time_point> decode(Decoder&);
515 };
516
517 template<> struct ArgumentCoder<AtomicString> {
518     static void encode(Encoder&, const AtomicString&);
519     static bool decode(Decoder&, AtomicString&);
520 };
521
522 template<> struct ArgumentCoder<CString> {
523     static void encode(Encoder&, const CString&);
524     static bool decode(Decoder&, CString&);
525 };
526
527 template<> struct ArgumentCoder<String> {
528     static void encode(Encoder&, const String&);
529     static bool decode(Decoder&, String&);
530     static std::optional<String> decode(Decoder&);
531 };
532
533 template<> struct ArgumentCoder<SHA1::Digest> {
534     static void encode(Encoder&, const SHA1::Digest&);
535     static bool decode(Decoder&, SHA1::Digest&);
536 };
537
538 } // namespace IPC