Remove std::chrono completely
[WebKit.git] / Source / WTF / wtf / persistence / PersistentCoders.h
1 /*
2  * Copyright (C) 2010, 2014-2015 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 <utility>
29 #include <wtf/Forward.h>
30 #include <wtf/HashMap.h>
31 #include <wtf/HashSet.h>
32 #include <wtf/SHA1.h>
33 #include <wtf/Seconds.h>
34 #include <wtf/Vector.h>
35 #include <wtf/WallTime.h>
36 #include <wtf/persistence/PersistentDecoder.h>
37 #include <wtf/persistence/PersistentEncoder.h>
38
39 namespace WTF {
40 namespace Persistence {
41
42 template<typename T, typename U> struct Coder<std::pair<T, U>> {
43     static void encode(Encoder& encoder, const std::pair<T, U>& pair)
44     {
45         encoder << pair.first << pair.second;
46     }
47
48     static bool decode(Decoder& decoder, std::pair<T, U>& pair)
49     {
50         T first;
51         if (!decoder.decode(first))
52             return false;
53
54         U second;
55         if (!decoder.decode(second))
56             return false;
57
58         pair.first = first;
59         pair.second = second;
60         return true;
61     }
62 };
63
64 template<typename T> struct Coder<std::optional<T>> {
65     static void encode(Encoder& encoder, const std::optional<T>& optional)
66     {
67         if (!optional) {
68             encoder << false;
69             return;
70         }
71         
72         encoder << true;
73         encoder << optional.value();
74     }
75     
76     static bool decode(Decoder& decoder, std::optional<T>& optional)
77     {
78         bool isEngaged;
79         if (!decoder.decode(isEngaged))
80             return false;
81         
82         if (!isEngaged) {
83             optional = std::nullopt;
84             return true;
85         }
86         
87         T value;
88         if (!decoder.decode(value))
89             return false;
90         
91         optional = WTFMove(value);
92         return true;
93     }
94 };
95
96 template<typename KeyType, typename ValueType> struct Coder<WTF::KeyValuePair<KeyType, ValueType>> {
97     static void encode(Encoder& encoder, const WTF::KeyValuePair<KeyType, ValueType>& pair)
98     {
99         encoder << pair.key << pair.value;
100     }
101
102     static bool decode(Decoder& decoder, WTF::KeyValuePair<KeyType, ValueType>& pair)
103     {
104         KeyType key;
105         if (!decoder.decode(key))
106             return false;
107
108         ValueType value;
109         if (!decoder.decode(value))
110             return false;
111
112         pair.key = key;
113         pair.value = value;
114         return true;
115     }
116 };
117
118 template<bool fixedSizeElements, typename T, size_t inlineCapacity> struct VectorCoder;
119
120 template<typename T, size_t inlineCapacity> struct VectorCoder<false, T, inlineCapacity> {
121     static void encode(Encoder& encoder, const Vector<T, inlineCapacity>& vector)
122     {
123         encoder << static_cast<uint64_t>(vector.size());
124         for (size_t i = 0; i < vector.size(); ++i)
125             encoder << vector[i];
126     }
127
128     static bool decode(Decoder& decoder, Vector<T, inlineCapacity>& vector)
129     {
130         uint64_t size;
131         if (!decoder.decode(size))
132             return false;
133
134         Vector<T, inlineCapacity> tmp;
135         for (size_t i = 0; i < size; ++i) {
136             T element;
137             if (!decoder.decode(element))
138                 return false;
139             
140             tmp.append(WTFMove(element));
141         }
142
143         tmp.shrinkToFit();
144         vector.swap(tmp);
145         return true;
146     }
147 };
148
149 template<typename T, size_t inlineCapacity> struct VectorCoder<true, T, inlineCapacity> {
150     static void encode(Encoder& encoder, const Vector<T, inlineCapacity>& vector)
151     {
152         encoder << static_cast<uint64_t>(vector.size());
153         encoder.encodeFixedLengthData(reinterpret_cast<const uint8_t*>(vector.data()), vector.size() * sizeof(T), alignof(T));
154     }
155     
156     static bool decode(Decoder& decoder, Vector<T, inlineCapacity>& vector)
157     {
158         uint64_t size;
159         if (!decoder.decode(size))
160             return false;
161
162         // Since we know the total size of the elements, we can allocate the vector in
163         // one fell swoop. Before allocating we must however make sure that the decoder buffer
164         // is big enough.
165         if (!decoder.bufferIsLargeEnoughToContain<T>(size))
166             return false;
167
168         Vector<T, inlineCapacity> temp;
169         temp.grow(size);
170
171         decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(temp.data()), size * sizeof(T));
172
173         vector.swap(temp);
174         return true;
175     }
176 };
177
178 template<typename T, size_t inlineCapacity> struct Coder<Vector<T, inlineCapacity>> : VectorCoder<std::is_arithmetic<T>::value, T, inlineCapacity> { };
179
180 template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg> struct Coder<HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>> {
181     typedef HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> HashMapType;
182
183     static void encode(Encoder& encoder, const HashMapType& hashMap)
184     {
185         encoder << static_cast<uint64_t>(hashMap.size());
186         for (typename HashMapType::const_iterator it = hashMap.begin(), end = hashMap.end(); it != end; ++it)
187             encoder << *it;
188     }
189
190     static bool decode(Decoder& decoder, HashMapType& hashMap)
191     {
192         uint64_t hashMapSize;
193         if (!decoder.decode(hashMapSize))
194             return false;
195
196         HashMapType tempHashMap;
197         for (uint64_t i = 0; i < hashMapSize; ++i) {
198             KeyArg key;
199             MappedArg value;
200             if (!decoder.decode(key))
201                 return false;
202             if (!decoder.decode(value))
203                 return false;
204
205             if (!tempHashMap.add(key, value).isNewEntry) {
206                 // The hash map already has the specified key, bail.
207                 return false;
208             }
209         }
210
211         hashMap.swap(tempHashMap);
212         return true;
213     }
214 };
215
216 template<typename KeyArg, typename HashArg, typename KeyTraitsArg> struct Coder<HashSet<KeyArg, HashArg, KeyTraitsArg>> {
217     typedef HashSet<KeyArg, HashArg, KeyTraitsArg> HashSetType;
218
219     static void encode(Encoder& encoder, const HashSetType& hashSet)
220     {
221         encoder << static_cast<uint64_t>(hashSet.size());
222         for (typename HashSetType::const_iterator it = hashSet.begin(), end = hashSet.end(); it != end; ++it)
223             encoder << *it;
224     }
225
226     static bool decode(Decoder& decoder, HashSetType& hashSet)
227     {
228         uint64_t hashSetSize;
229         if (!decoder.decode(hashSetSize))
230             return false;
231
232         HashSetType tempHashSet;
233         for (uint64_t i = 0; i < hashSetSize; ++i) {
234             KeyArg key;
235             if (!decoder.decode(key))
236                 return false;
237
238             if (!tempHashSet.add(key).isNewEntry) {
239                 // The hash map already has the specified key, bail.
240                 return false;
241             }
242         }
243
244         hashSet.swap(tempHashSet);
245         return true;
246     }
247 };
248
249 template<> struct Coder<Seconds> {
250     static void encode(Encoder& encoder, const Seconds& seconds)
251     {
252         encoder << seconds.value();
253     }
254
255     static bool decode(Decoder& decoder, Seconds& result)
256     {
257         double value;
258         if (!decoder.decode(value))
259             return false;
260
261         result = Seconds(value);
262         return true;
263     }
264 };
265
266 template<> struct Coder<WallTime> {
267     static void encode(Encoder& encoder, const WallTime& time)
268     {
269         encoder << time.secondsSinceEpoch().value();
270     }
271
272     static bool decode(Decoder& decoder, WallTime& result)
273     {
274         double value;
275         if (!decoder.decode(value))
276             return false;
277
278         result = WallTime::fromRawSeconds(value);
279         return true;
280     }
281 };
282
283 template<> struct Coder<AtomicString> {
284     WTF_EXPORT_PRIVATE static void encode(Encoder&, const AtomicString&);
285     WTF_EXPORT_PRIVATE static bool decode(Decoder&, AtomicString&);
286 };
287
288 template<> struct Coder<CString> {
289     WTF_EXPORT_PRIVATE static void encode(Encoder&, const CString&);
290     WTF_EXPORT_PRIVATE static bool decode(Decoder&, CString&);
291 };
292
293 template<> struct Coder<String> {
294     WTF_EXPORT_PRIVATE static void encode(Encoder&, const String&);
295     WTF_EXPORT_PRIVATE static bool decode(Decoder&, String&);
296 };
297
298 template<> struct Coder<SHA1::Digest> {
299     WTF_EXPORT_PRIVATE static void encode(Encoder&, const SHA1::Digest&);
300     WTF_EXPORT_PRIVATE static bool decode(Decoder&, SHA1::Digest&);
301 };
302
303 }
304 }