123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368 |
- /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
- #ifndef mozilla_dom_indexeddb_key_h__
- #define mozilla_dom_indexeddb_key_h__
- #include "js/RootingAPI.h"
- #include "nsString.h"
- class mozIStorageStatement;
- class mozIStorageValueArray;
- namespace IPC {
- template <typename> struct ParamTraits;
- } // namespace IPC
- namespace mozilla {
- namespace dom {
- namespace indexedDB {
- class Key
- {
- friend struct IPC::ParamTraits<Key>;
- nsCString mBuffer;
- public:
- enum {
- eTerminator = 0,
- eFloat = 0x10,
- eDate = 0x20,
- eString = 0x30,
- eBinary = 0x40,
- eArray = 0x50,
- eMaxType = eArray
- };
- static const uint8_t kMaxArrayCollapse = uint8_t(3);
- static const uint8_t kMaxRecursionDepth = uint8_t(64);
- Key()
- {
- Unset();
- }
- explicit
- Key(const nsACString& aBuffer)
- : mBuffer(aBuffer)
- { }
- Key&
- operator=(const nsAString& aString)
- {
- SetFromString(aString);
- return *this;
- }
- Key&
- operator=(int64_t aInt)
- {
- SetFromInteger(aInt);
- return *this;
- }
- bool
- operator==(const Key& aOther) const
- {
- Assert(!mBuffer.IsVoid() && !aOther.mBuffer.IsVoid());
- return mBuffer.Equals(aOther.mBuffer);
- }
- bool
- operator!=(const Key& aOther) const
- {
- Assert(!mBuffer.IsVoid() && !aOther.mBuffer.IsVoid());
- return !mBuffer.Equals(aOther.mBuffer);
- }
- bool
- operator<(const Key& aOther) const
- {
- Assert(!mBuffer.IsVoid() && !aOther.mBuffer.IsVoid());
- return Compare(mBuffer, aOther.mBuffer) < 0;
- }
- bool
- operator>(const Key& aOther) const
- {
- Assert(!mBuffer.IsVoid() && !aOther.mBuffer.IsVoid());
- return Compare(mBuffer, aOther.mBuffer) > 0;
- }
- bool
- operator<=(const Key& aOther) const
- {
- Assert(!mBuffer.IsVoid() && !aOther.mBuffer.IsVoid());
- return Compare(mBuffer, aOther.mBuffer) <= 0;
- }
- bool
- operator>=(const Key& aOther) const
- {
- Assert(!mBuffer.IsVoid() && !aOther.mBuffer.IsVoid());
- return Compare(mBuffer, aOther.mBuffer) >= 0;
- }
- void
- Unset()
- {
- mBuffer.SetIsVoid(true);
- }
- bool
- IsUnset() const
- {
- return mBuffer.IsVoid();
- }
- bool
- IsFloat() const
- {
- return !IsUnset() && *BufferStart() == eFloat;
- }
- bool
- IsDate() const
- {
- return !IsUnset() && *BufferStart() == eDate;
- }
- bool
- IsString() const
- {
- return !IsUnset() && *BufferStart() == eString;
- }
- bool
- IsBinary() const
- {
- return !IsUnset() && *BufferStart() == eBinary;
- }
- bool
- IsArray() const
- {
- return !IsUnset() && *BufferStart() >= eArray;
- }
- double
- ToFloat() const
- {
- Assert(IsFloat());
- const unsigned char* pos = BufferStart();
- double res = DecodeNumber(pos, BufferEnd());
- Assert(pos >= BufferEnd());
- return res;
- }
- double
- ToDateMsec() const
- {
- Assert(IsDate());
- const unsigned char* pos = BufferStart();
- double res = DecodeNumber(pos, BufferEnd());
- Assert(pos >= BufferEnd());
- return res;
- }
- void
- ToString(nsString& aString) const
- {
- Assert(IsString());
- const unsigned char* pos = BufferStart();
- DecodeString(pos, BufferEnd(), aString);
- Assert(pos >= BufferEnd());
- }
- void
- SetFromString(const nsAString& aString)
- {
- mBuffer.Truncate();
- EncodeString(aString, 0);
- TrimBuffer();
- }
- void
- SetFromInteger(int64_t aInt)
- {
- mBuffer.Truncate();
- EncodeNumber(double(aInt), eFloat);
- TrimBuffer();
- }
- nsresult
- SetFromJSVal(JSContext* aCx, JS::Handle<JS::Value> aVal, bool aCallGetters);
- nsresult
- ToJSVal(JSContext* aCx, JS::MutableHandle<JS::Value> aVal) const;
- nsresult
- ToJSVal(JSContext* aCx, JS::Heap<JS::Value>& aVal) const;
- nsresult
- AppendItem(JSContext* aCx,
- bool aFirstOfArray,
- JS::Handle<JS::Value> aVal,
- bool aCallGetters);
- nsresult
- ToLocaleBasedKey(Key& aTarget, const nsCString& aLocale) const;
- void
- FinishArray()
- {
- TrimBuffer();
- }
- const nsCString&
- GetBuffer() const
- {
- return mBuffer;
- }
- nsresult
- BindToStatement(mozIStorageStatement* aStatement,
- const nsACString& aParamName) const;
- nsresult
- SetFromStatement(mozIStorageStatement* aStatement, uint32_t aIndex);
- nsresult
- SetFromValueArray(mozIStorageValueArray* aValues, uint32_t aIndex);
- static int16_t
- CompareKeys(const Key& aFirst, const Key& aSecond)
- {
- int32_t result = Compare(aFirst.mBuffer, aSecond.mBuffer);
- if (result < 0) {
- return -1;
- }
- if (result > 0) {
- return 1;
- }
- return 0;
- }
- private:
- const unsigned char*
- BufferStart() const
- {
- return reinterpret_cast<const unsigned char*>(mBuffer.BeginReading());
- }
- const unsigned char*
- BufferEnd() const
- {
- return reinterpret_cast<const unsigned char*>(mBuffer.EndReading());
- }
- // Encoding helper. Trims trailing zeros off of mBuffer as a post-processing
- // step.
- void
- TrimBuffer()
- {
- const char* end = mBuffer.EndReading() - 1;
- while (!*end) {
- --end;
- }
- mBuffer.Truncate(end + 1 - mBuffer.BeginReading());
- }
- // Encoding functions. These append the encoded value to the end of mBuffer
- nsresult
- EncodeJSVal(JSContext* aCx,
- JS::Handle<JS::Value> aVal,
- uint8_t aTypeOffset,
- bool aCallGetters);
- void
- EncodeString(const nsAString& aString, uint8_t aTypeOffset);
- template <typename T>
- void
- EncodeString(const T* aStart, const T* aEnd, uint8_t aTypeOffset);
- template <typename T>
- void
- EncodeAsString(const T* aStart, const T* aEnd, uint8_t aType);
- nsresult
- EncodeLocaleString(const nsDependentString& aString, uint8_t aTypeOffset,
- const nsCString& aLocale);
- void
- EncodeNumber(double aFloat, uint8_t aType);
- void
- EncodeBinary(JSObject* aObject, bool aIsViewObject, uint8_t aTypeOffset);
- // Decoding functions. aPos points into mBuffer and is adjusted to point
- // past the consumed value.
- static nsresult
- DecodeJSVal(const unsigned char*& aPos,
- const unsigned char* aEnd,
- JSContext* aCx,
- JS::MutableHandle<JS::Value> aVal);
- static void
- DecodeString(const unsigned char*& aPos,
- const unsigned char* aEnd,
- nsString& aString);
- static double
- DecodeNumber(const unsigned char*& aPos, const unsigned char* aEnd);
- static JSObject*
- DecodeBinary(const unsigned char*& aPos,
- const unsigned char* aEnd,
- JSContext* aCx);
- nsresult
- EncodeJSValInternal(JSContext* aCx,
- JS::Handle<JS::Value> aVal,
- uint8_t aTypeOffset,
- uint16_t aRecursionDepth,
- bool aCallGetters);
- static nsresult
- DecodeJSValInternal(const unsigned char*& aPos,
- const unsigned char* aEnd,
- JSContext* aCx,
- uint8_t aTypeOffset,
- JS::MutableHandle<JS::Value> aVal,
- uint16_t aRecursionDepth);
- template <typename T>
- nsresult
- SetFromSource(T* aSource, uint32_t aIndex);
- void
- Assert(bool aCondition) const
- #ifdef DEBUG
- ;
- #else
- { }
- #endif
- };
- } // namespace indexedDB
- } // namespace dom
- } // namespace mozilla
- #endif // mozilla_dom_indexeddb_key_h__
|