1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_indexeddb_key_h__
8 #define mozilla_dom_indexeddb_key_h__
10 #include "mozilla/dom/indexedDB/IndexedDatabase.h"
12 #include "mozIStorageStatement.h"
17 template <typename T
> struct ParamTraits
;
20 BEGIN_INDEXEDDB_NAMESPACE
24 friend struct IPC::ParamTraits
<Key
>;
32 Key
& operator=(const nsAString
& aString
)
34 SetFromString(aString
);
38 Key
& operator=(int64_t aInt
)
44 bool operator==(const Key
& aOther
) const
46 NS_ASSERTION(!mBuffer
.IsVoid() && !aOther
.mBuffer
.IsVoid(),
47 "Don't compare unset keys!");
49 return mBuffer
.Equals(aOther
.mBuffer
);
52 bool operator!=(const Key
& aOther
) const
54 NS_ASSERTION(!mBuffer
.IsVoid() && !aOther
.mBuffer
.IsVoid(),
55 "Don't compare unset keys!");
57 return !mBuffer
.Equals(aOther
.mBuffer
);
60 bool operator<(const Key
& aOther
) const
62 NS_ASSERTION(!mBuffer
.IsVoid() && !aOther
.mBuffer
.IsVoid(),
63 "Don't compare unset keys!");
65 return Compare(mBuffer
, aOther
.mBuffer
) < 0;
68 bool operator>(const Key
& aOther
) const
70 NS_ASSERTION(!mBuffer
.IsVoid() && !aOther
.mBuffer
.IsVoid(),
71 "Don't compare unset keys!");
73 return Compare(mBuffer
, aOther
.mBuffer
) > 0;
76 bool operator<=(const Key
& aOther
) const
78 NS_ASSERTION(!mBuffer
.IsVoid() && !aOther
.mBuffer
.IsVoid(),
79 "Don't compare unset keys!");
81 return Compare(mBuffer
, aOther
.mBuffer
) <= 0;
84 bool operator>=(const Key
& aOther
) const
86 NS_ASSERTION(!mBuffer
.IsVoid() && !aOther
.mBuffer
.IsVoid(),
87 "Don't compare unset keys!");
89 return Compare(mBuffer
, aOther
.mBuffer
) >= 0;
95 mBuffer
.SetIsVoid(true);
100 return mBuffer
.IsVoid();
105 return !IsUnset() && mBuffer
.First() == eFloat
;
110 return !IsUnset() && mBuffer
.First() == eDate
;
113 bool IsString() const
115 return !IsUnset() && mBuffer
.First() == eString
;
120 return !IsUnset() && mBuffer
.First() >= eArray
;
123 double ToFloat() const
125 NS_ASSERTION(IsFloat(), "Why'd you call this?");
126 const unsigned char* pos
= BufferStart();
127 double res
= DecodeNumber(pos
, BufferEnd());
128 NS_ASSERTION(pos
>= BufferEnd(), "Should consume whole buffer");
132 double ToDateMsec() const
134 NS_ASSERTION(IsDate(), "Why'd you call this?");
135 const unsigned char* pos
= BufferStart();
136 double res
= DecodeNumber(pos
, BufferEnd());
137 NS_ASSERTION(pos
>= BufferEnd(), "Should consume whole buffer");
141 void ToString(nsString
& aString
) const
143 NS_ASSERTION(IsString(), "Why'd you call this?");
144 const unsigned char* pos
= BufferStart();
145 DecodeString(pos
, BufferEnd(), aString
);
146 NS_ASSERTION(pos
>= BufferEnd(), "Should consume whole buffer");
149 void SetFromString(const nsAString
& aString
)
152 EncodeString(aString
, 0);
156 void SetFromInteger(int64_t aInt
)
159 EncodeNumber(double(aInt
), eFloat
);
163 nsresult
SetFromJSVal(JSContext
* aCx
,
164 JS::Handle
<JS::Value
> aVal
)
168 if (aVal
.isNull() || aVal
.isUndefined()) {
173 nsresult rv
= EncodeJSVal(aCx
, aVal
, 0);
183 nsresult
ToJSVal(JSContext
* aCx
,
184 JS::MutableHandle
<JS::Value
> aVal
) const
191 const unsigned char* pos
= BufferStart();
192 nsresult rv
= DecodeJSVal(pos
, BufferEnd(), aCx
, 0, aVal
);
193 NS_ENSURE_SUCCESS(rv
, rv
);
195 NS_ASSERTION(pos
>= BufferEnd(),
196 "Didn't consume whole buffer");
201 nsresult
ToJSVal(JSContext
* aCx
,
202 JS::Heap
<JS::Value
>& aVal
) const
204 JS::Rooted
<JS::Value
> value(aCx
);
205 nsresult rv
= ToJSVal(aCx
, &value
);
206 if (NS_SUCCEEDED(rv
)) {
212 nsresult
AppendItem(JSContext
* aCx
,
214 JS::Handle
<JS::Value
> aVal
)
216 nsresult rv
= EncodeJSVal(aCx
, aVal
, aFirstOfArray
? eMaxType
: 0);
230 const nsCString
& GetBuffer() const
235 nsresult
BindToStatement(mozIStorageStatement
* aStatement
,
236 const nsACString
& aParamName
) const
238 nsresult rv
= aStatement
->BindBlobByName(aParamName
,
239 reinterpret_cast<const uint8_t*>(mBuffer
.get()), mBuffer
.Length());
241 return NS_SUCCEEDED(rv
) ? NS_OK
: NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR
;
244 nsresult
SetFromStatement(mozIStorageStatement
* aStatement
,
248 uint32_t dataLength
= 0;
250 nsresult rv
= aStatement
->GetBlob(aIndex
, &dataLength
, &data
);
251 NS_ENSURE_SUCCESS(rv
, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR
);
254 reinterpret_cast<char*>(const_cast<uint8_t*>(data
)), dataLength
);
260 int16_t CompareKeys(Key
& aFirst
, Key
& aSecond
)
262 int32_t result
= Compare(aFirst
.mBuffer
, aSecond
.mBuffer
);
276 const unsigned char* BufferStart() const
278 return reinterpret_cast<const unsigned char*>(mBuffer
.BeginReading());
281 const unsigned char* BufferEnd() const
283 return reinterpret_cast<const unsigned char*>(mBuffer
.EndReading());
295 // Encoding helper. Trims trailing zeros off of mBuffer as a post-processing
299 const char* end
= mBuffer
.EndReading() - 1;
304 mBuffer
.Truncate(end
+ 1 - mBuffer
.BeginReading());
307 // Encoding functions. These append the encoded value to the end of mBuffer
308 inline nsresult
EncodeJSVal(JSContext
* aCx
, JS::Handle
<JS::Value
> aVal
,
311 return EncodeJSValInternal(aCx
, aVal
, aTypeOffset
, 0);
313 void EncodeString(const nsAString
& aString
, uint8_t aTypeOffset
);
314 void EncodeNumber(double aFloat
, uint8_t aType
);
316 // Decoding functions. aPos points into mBuffer and is adjusted to point
317 // past the consumed value.
318 static inline nsresult
DecodeJSVal(const unsigned char*& aPos
,
319 const unsigned char* aEnd
, JSContext
* aCx
,
320 uint8_t aTypeOffset
, JS::MutableHandle
<JS::Value
> aVal
)
322 return DecodeJSValInternal(aPos
, aEnd
, aCx
, aTypeOffset
, aVal
, 0);
325 static void DecodeString(const unsigned char*& aPos
,
326 const unsigned char* aEnd
,
328 static double DecodeNumber(const unsigned char*& aPos
,
329 const unsigned char* aEnd
);
334 nsresult
EncodeJSValInternal(JSContext
* aCx
, JS::Handle
<JS::Value
> aVal
,
335 uint8_t aTypeOffset
, uint16_t aRecursionDepth
);
337 static nsresult
DecodeJSValInternal(const unsigned char*& aPos
,
338 const unsigned char* aEnd
,
339 JSContext
* aCx
, uint8_t aTypeOffset
,
340 JS::MutableHandle
<JS::Value
> aVal
, uint16_t aRecursionDepth
);
343 END_INDEXEDDB_NAMESPACE
345 #endif /* mozilla_dom_indexeddb_key_h__ */