blob: 5134a178cba37dd9d729abede41fc282f1f01f61 [file] [log] [blame]
beidson@apple.com0f1c94b2014-01-22 23:48:27 +00001/*
2 * Copyright (C) 2014 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#ifndef IDBKeyData_h
27#define IDBKeyData_h
28
29#if ENABLE(INDEXED_DATABASE)
30
31#include "IDBKey.h"
beidson@apple.com52fdb462015-10-27 20:39:40 +000032#include <wtf/text/StringHash.h>
beidson@apple.com0f1c94b2014-01-22 23:48:27 +000033
34namespace WebCore {
35
beidson@apple.comfbba7562014-01-29 16:17:51 +000036class KeyedDecoder;
37class KeyedEncoder;
38
beidson@apple.com658cdf12015-10-27 05:22:55 +000039class IDBKeyData {
40public:
beidson@apple.com0f1c94b2014-01-22 23:48:27 +000041 IDBKeyData()
beidson@apple.com658cdf12015-10-27 05:22:55 +000042 : m_type(KeyType::Invalid)
43 , m_isNull(true)
beidson@apple.com0f1c94b2014-01-22 23:48:27 +000044 {
45 }
46
commit-queue@webkit.org8cc75642014-08-22 18:25:37 +000047 WEBCORE_EXPORT IDBKeyData(const IDBKey*);
beidson@apple.com0f1c94b2014-01-22 23:48:27 +000048
beidson@apple.com426c8a72014-02-08 00:30:50 +000049 static IDBKeyData minimum()
50 {
51 IDBKeyData result;
beidson@apple.com658cdf12015-10-27 05:22:55 +000052 result.m_type = KeyType::Min;
53 result.m_isNull = false;
beidson@apple.com426c8a72014-02-08 00:30:50 +000054 return result;
55 }
56
57 static IDBKeyData maximum()
58 {
59 IDBKeyData result;
beidson@apple.com658cdf12015-10-27 05:22:55 +000060 result.m_type = KeyType::Max;
61 result.m_isNull = false;
beidson@apple.com426c8a72014-02-08 00:30:50 +000062 return result;
63 }
64
commit-queue@webkit.org8cc75642014-08-22 18:25:37 +000065 WEBCORE_EXPORT PassRefPtr<IDBKey> maybeCreateIDBKey() const;
beidson@apple.com0f1c94b2014-01-22 23:48:27 +000066
67 IDBKeyData isolatedCopy() const;
68
commit-queue@webkit.org8cc75642014-08-22 18:25:37 +000069 WEBCORE_EXPORT void encode(KeyedEncoder&) const;
70 WEBCORE_EXPORT static bool decode(KeyedDecoder&, IDBKeyData&);
beidson@apple.comfbba7562014-01-29 16:17:51 +000071
beidson@apple.com88750bc2014-01-30 22:23:24 +000072 // compare() has the same semantics as strcmp().
73 // - Returns negative if this IDBKeyData is less than other.
74 // - Returns positive if this IDBKeyData is greater than other.
75 // - Returns zero if this IDBKeyData is equal to other.
commit-queue@webkit.org8cc75642014-08-22 18:25:37 +000076 WEBCORE_EXPORT int compare(const IDBKeyData& other) const;
beidson@apple.com88750bc2014-01-30 22:23:24 +000077
beidson@apple.comc32b9b62014-02-05 23:59:52 +000078 void setArrayValue(const Vector<IDBKeyData>&);
79 void setStringValue(const String&);
80 void setDateValue(double);
commit-queue@webkit.org8cc75642014-08-22 18:25:37 +000081 WEBCORE_EXPORT void setNumberValue(double);
beidson@apple.comc32b9b62014-02-05 23:59:52 +000082
beidson@apple.com78ff9672015-09-15 16:36:19 +000083 template<class Encoder> void encode(Encoder&) const;
84 template<class Decoder> static bool decode(Decoder&, IDBKeyData&);
85
beidson@apple.com6f271112014-02-01 05:01:15 +000086#ifndef NDEBUG
commit-queue@webkit.org8cc75642014-08-22 18:25:37 +000087 WEBCORE_EXPORT String loggingString() const;
beidson@apple.com6f271112014-02-01 05:01:15 +000088#endif
89
beidson@apple.com658cdf12015-10-27 05:22:55 +000090 bool isNull() const { return m_isNull; }
beidson@apple.com52fdb462015-10-27 20:39:40 +000091 bool isValid() const { return m_type != KeyType::Invalid; }
beidson@apple.com658cdf12015-10-27 05:22:55 +000092 KeyType type() const { return m_type; }
93
beidson@apple.com52fdb462015-10-27 20:39:40 +000094 bool operator<(const IDBKeyData&) const;
95 bool operator==(const IDBKeyData& other) const;
96 bool operator!=(const IDBKeyData& other) const
97 {
98 return !(*this == other);
99 }
100
101 unsigned hash() const
102 {
103 Vector<unsigned> hashCodes;
104 hashCodes.append(static_cast<unsigned>(m_type));
105 hashCodes.append(m_isNull ? 1 : 0);
106 hashCodes.append(m_isDeletedValue ? 1 : 0);
107 switch (m_type) {
108 case KeyType::Invalid:
109 case KeyType::Max:
110 case KeyType::Min:
111 break;
112 case KeyType::Number:
113 case KeyType::Date:
114 hashCodes.append(StringHasher::hashMemory<sizeof(double)>(&m_numberValue));
115 break;
116 case KeyType::String:
117 hashCodes.append(StringHash::hash(m_stringValue));
118 break;
119 case KeyType::Array:
120 for (auto& key : m_arrayValue)
121 hashCodes.append(key.hash());
122 break;
123 }
124
beidson@apple.com52fdb462015-10-27 20:39:40 +0000125 return StringHasher::hashMemory(hashCodes.data(), hashCodes.size() * sizeof(unsigned));
126 }
127
128 static IDBKeyData deletedValue();
129 bool isDeletedValue() const { return m_isDeletedValue; }
130
beidson@apple.com2309c9f2015-11-13 00:24:11 +0000131 String string() const
132 {
133 ASSERT(m_type == KeyType::String);
134 return m_stringValue;
135 }
136
137 double date() const
138 {
139 ASSERT(m_type == KeyType::Date);
140 return m_numberValue;
141 }
142
143 double number() const
144 {
145 ASSERT(m_type == KeyType::Number);
146 return m_numberValue;
147 }
148
149 const Vector<IDBKeyData>& array() const
150 {
151 ASSERT(m_type == KeyType::Array);
152 return m_arrayValue;
153 }
154
beidson@apple.com658cdf12015-10-27 05:22:55 +0000155private:
156 KeyType m_type;
157 Vector<IDBKeyData> m_arrayValue;
158 String m_stringValue;
159 double m_numberValue { 0 };
160 bool m_isNull { false };
beidson@apple.com52fdb462015-10-27 20:39:40 +0000161 bool m_isDeletedValue { false };
162};
163
164struct IDBKeyDataHash {
165 static unsigned hash(const IDBKeyData& a) { return a.hash(); }
166 static bool equal(const IDBKeyData& a, const IDBKeyData& b) { return a == b; }
167 static const bool safeToCompareToEmptyOrDeleted = false;
168};
169
170struct IDBKeyDataHashTraits : public WTF::CustomHashTraits<IDBKeyData> {
171 static const bool emptyValueIsZero = false;
172 static const bool hasIsEmptyValueFunction = true;
173
174 static void constructDeletedValue(IDBKeyData& key)
175 {
176 key = IDBKeyData::deletedValue();
177 }
178
179 static bool isDeletedValue(const IDBKeyData& key)
180 {
181 return key.isDeletedValue();
182 }
183
184 static IDBKeyData emptyValue()
185 {
186 return IDBKeyData();
187 }
188
189 static bool isEmptyValue(const IDBKeyData& key)
190 {
191 return key.isNull();
192 }
beidson@apple.com0f1c94b2014-01-22 23:48:27 +0000193};
194
beidson@apple.com78ff9672015-09-15 16:36:19 +0000195template<class Encoder>
196void IDBKeyData::encode(Encoder& encoder) const
197{
beidson@apple.com658cdf12015-10-27 05:22:55 +0000198 encoder << m_isNull;
199 if (m_isNull)
beidson@apple.com78ff9672015-09-15 16:36:19 +0000200 return;
201
beidson@apple.com658cdf12015-10-27 05:22:55 +0000202 encoder.encodeEnum(m_type);
beidson@apple.com78ff9672015-09-15 16:36:19 +0000203
beidson@apple.com658cdf12015-10-27 05:22:55 +0000204 switch (m_type) {
beidson@apple.com78ff9672015-09-15 16:36:19 +0000205 case KeyType::Invalid:
206 break;
207 case KeyType::Array:
beidson@apple.com658cdf12015-10-27 05:22:55 +0000208 encoder << m_arrayValue;
beidson@apple.com78ff9672015-09-15 16:36:19 +0000209 break;
210 case KeyType::String:
beidson@apple.com658cdf12015-10-27 05:22:55 +0000211 encoder << m_stringValue;
beidson@apple.com78ff9672015-09-15 16:36:19 +0000212 break;
213 case KeyType::Date:
214 case KeyType::Number:
beidson@apple.com658cdf12015-10-27 05:22:55 +0000215 encoder << m_numberValue;
beidson@apple.com78ff9672015-09-15 16:36:19 +0000216 break;
217 case KeyType::Max:
218 case KeyType::Min:
219 // MaxType and MinType are only used for comparison to other keys.
220 // They should never be encoded/decoded.
221 ASSERT_NOT_REACHED();
222 break;
223 }
224}
225
226template<class Decoder>
227bool IDBKeyData::decode(Decoder& decoder, IDBKeyData& keyData)
228{
beidson@apple.com658cdf12015-10-27 05:22:55 +0000229 if (!decoder.decode(keyData.m_isNull))
beidson@apple.com78ff9672015-09-15 16:36:19 +0000230 return false;
231
beidson@apple.com658cdf12015-10-27 05:22:55 +0000232 if (keyData.m_isNull)
beidson@apple.com78ff9672015-09-15 16:36:19 +0000233 return true;
234
beidson@apple.com658cdf12015-10-27 05:22:55 +0000235 if (!decoder.decodeEnum(keyData.m_type))
beidson@apple.com78ff9672015-09-15 16:36:19 +0000236 return false;
237
beidson@apple.com658cdf12015-10-27 05:22:55 +0000238 switch (keyData.m_type) {
beidson@apple.com78ff9672015-09-15 16:36:19 +0000239 case KeyType::Invalid:
240 break;
241 case KeyType::Array:
beidson@apple.com658cdf12015-10-27 05:22:55 +0000242 if (!decoder.decode(keyData.m_arrayValue))
beidson@apple.com78ff9672015-09-15 16:36:19 +0000243 return false;
244 break;
245 case KeyType::String:
beidson@apple.com658cdf12015-10-27 05:22:55 +0000246 if (!decoder.decode(keyData.m_stringValue))
beidson@apple.com78ff9672015-09-15 16:36:19 +0000247 return false;
248 break;
249 case KeyType::Date:
250 case KeyType::Number:
beidson@apple.com658cdf12015-10-27 05:22:55 +0000251 if (!decoder.decode(keyData.m_numberValue))
beidson@apple.com78ff9672015-09-15 16:36:19 +0000252 return false;
253 break;
254 case KeyType::Max:
255 case KeyType::Min:
256 // MaxType and MinType are only used for comparison to other keys.
257 // They should never be encoded/decoded.
258 ASSERT_NOT_REACHED();
259 decoder.markInvalid();
260 return false;
261 }
262
263 return true;
264}
265
beidson@apple.com0f1c94b2014-01-22 23:48:27 +0000266} // namespace WebCore
267
268#endif // ENABLE(INDEXED_DATABASE)
269#endif // IDBKeyData_h