909532dfbfae17e48f10ca687e7a81229896dc03
[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<Optional<T>> {
65     static void encode(Encoder& encoder, const 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, Optional<T>& optional)
77     {
78         bool isEngaged;
79         if (!decoder.decode(isEngaged))
80             return false;
81         
82         if (!isEngaged) {
83             optional = WTF::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 decodedSize;
159         if (!decoder.decode(decodedSize))
160             return false;
161
162         auto size = safeCast<size_t>(decodedSize);
163
164         // Since we know the total size of the elements, we can allocate the vector in
165         // one fell swoop. Before allocating we must however make sure that the decoder buffer
166         // is big enough.
167         if (!decoder.bufferIsLargeEnoughToContain<T>(size))
168             return false;
169
170         Vector<T, inlineCapacity> temp;
171         temp.grow(size);
172
173         decoder.decodeFixedLengthData(reinterpret_cast<uint8_t*>(temp.data()), size * sizeof(T));
174
175         vector.swap(temp);
176         return true;
177     }
178 };
179
180 template<typename T, size_t inlineCapacity> struct Coder<Vector<T, inlineCapacity>> : VectorCoder<std::is_arithmetic<T>::value, T, inlineCapacity> { };
181
182 template<typename KeyArg, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg> struct Coder<HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg>> {
183     typedef HashMap<KeyArg, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> HashMapType;
184
185     static void encode(Encoder& encoder, const HashMapType& hashMap)
186     {
187         encoder << static_cast<uint64_t>(hashMap.size());
188         for (typename HashMapType::const_iterator it = hashMap.begin(), end = hashMap.end(); it != end; ++it)
189             encoder << *it;
190     }
191
192     static bool decode(Decoder& decoder, HashMapType& hashMap)
193     {
194         uint64_t hashMapSize;
195         if (!decoder.decode(hashMapSize))
196             return false;
197
198         HashMapType tempHashMap;
199         tempHashMap.reserveInitialCapacity(static_cast<unsigned>(hashMapSize));
200         for (uint64_t i = 0; i < hashMapSize; ++i) {
201             KeyArg key;
202             MappedArg value;
203             if (!decoder.decode(key))
204                 return false;
205             if (!decoder.decode(value))
206                 return false;
207
208             if (!tempHashMap.add(key, value).isNewEntry) {
209                 // The hash map already has the specified key, bail.
210                 return false;
211             }
212         }
213
214         hashMap.swap(tempHashMap);
215         return true;
216     }
217 };
218
219 template<typename KeyArg, typename HashArg, typename KeyTraitsArg> struct Coder<HashSet<KeyArg, HashArg, KeyTraitsArg>> {
220     typedef HashSet<KeyArg, HashArg, KeyTraitsArg> HashSetType;
221
222     static void encode(Encoder& encoder, const HashSetType& hashSet)
223     {
224         encoder << static_cast<uint64_t>(hashSet.size());
225         for (typename HashSetType::const_iterator it = hashSet.begin(), end = hashSet.end(); it != end; ++it)
226             encoder << *it;
227     }
228
229     static bool decode(Decoder& decoder, HashSetType& hashSet)
230     {
231         uint64_t hashSetSize;
232         if (!decoder.decode(hashSetSize))
233             return false;
234
235         HashSetType tempHashSet;
236         for (uint64_t i = 0; i < hashSetSize; ++i) {
237             KeyArg key;
238             if (!decoder.decode(key))
239                 return false;
240
241             if (!tempHashSet.add(key).isNewEntry) {
242                 // The hash map already has the specified key, bail.
243                 return false;
244             }
245         }
246
247         hashSet.swap(tempHashSet);
248         return true;
249     }
250 };
251
252 template<> struct Coder<Seconds> {
253     static void encode(Encoder& encoder, const Seconds& seconds)
254     {
255         encoder << seconds.value();
256     }
257
258     static bool decode(Decoder& decoder, Seconds& result)
259     {
260         double value;
261         if (!decoder.decode(value))
262             return false;
263
264         result = Seconds(value);
265         return true;
266     }
267 };
268
269 template<> struct Coder<WallTime> {
270     static void encode(Encoder& encoder, const WallTime& time)
271     {
272         encoder << time.secondsSinceEpoch().value();
273     }
274
275     static bool decode(Decoder& decoder, WallTime& result)
276     {
277         double value;
278         if (!decoder.decode(value))
279             return false;
280
281         result = WallTime::fromRawSeconds(value);
282         return true;
283     }
284 };
285
286 template<> struct Coder<AtomString> {
287     WTF_EXPORT_PRIVATE static void encode(Encoder&, const AtomString&);
288     WTF_EXPORT_PRIVATE static bool decode(Decoder&, AtomString&);
289 };
290
291 template<> struct Coder<CString> {
292     WTF_EXPORT_PRIVATE static void encode(Encoder&, const CString&);
293     WTF_EXPORT_PRIVATE static bool decode(Decoder&, CString&);
294 };
295
296 template<> struct Coder<String> {
297     WTF_EXPORT_PRIVATE static void encode(Encoder&, const String&);
298     WTF_EXPORT_PRIVATE static bool decode(Decoder&, String&);
299 };
300
301 template<> struct Coder<SHA1::Digest> {
302     WTF_EXPORT_PRIVATE static void encode(Encoder&, const SHA1::Digest&);
303     WTF_EXPORT_PRIVATE static bool decode(Decoder&, SHA1::Digest&);
304 };
305
306 }
307 }