storage/src/Variant.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     2  * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
     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_storage_Variant_h__
     8 #define mozilla_storage_Variant_h__
    10 #include <utility>
    12 #include "nsIVariant.h"
    13 #include "nsString.h"
    14 #include "nsTArray.h"
    16 /**
    17  * This class is used by the storage module whenever an nsIVariant needs to be
    18  * returned.  We provide traits for the basic sqlite types to make use easier.
    19  * The following types map to the indicated sqlite type:
    20  * int64_t   -> INTEGER (use IntegerVariant)
    21  * double    -> FLOAT (use FloatVariant)
    22  * nsString  -> TEXT (use TextVariant)
    23  * nsCString -> TEXT (use UTF8TextVariant)
    24  * uint8_t[] -> BLOB (use BlobVariant)
    25  * nullptr   -> NULL (use NullVariant)
    26  */
    28 namespace mozilla {
    29 namespace storage {
    31 ////////////////////////////////////////////////////////////////////////////////
    32 //// Base Class
    34 class Variant_base : public nsIVariant
    35 {
    36 public:
    37   NS_DECL_THREADSAFE_ISUPPORTS
    38   NS_DECL_NSIVARIANT
    40 protected:
    41   virtual ~Variant_base() { }
    42 };
    44 ////////////////////////////////////////////////////////////////////////////////
    45 //// Traits
    47 /**
    48  * Generics
    49  */
    51 template <typename DataType>
    52 struct variant_traits
    53 {
    54   static inline uint16_t type() { return nsIDataType::VTYPE_EMPTY; }
    55 };
    57 template <typename DataType, bool Adopting=false>
    58 struct variant_storage_traits
    59 {
    60   typedef DataType ConstructorType;
    61   typedef DataType StorageType;
    62   static inline void storage_conversion(const ConstructorType aData, StorageType* _storage)
    63   {
    64     *_storage = aData;
    65   }
    67   static inline void destroy(const StorageType& _storage)
    68   { }
    69 };
    71 #define NO_CONVERSION return NS_ERROR_CANNOT_CONVERT_DATA;
    73 template <typename DataType, bool Adopting=false>
    74 struct variant_integer_traits
    75 {
    76   typedef typename variant_storage_traits<DataType, Adopting>::StorageType StorageType;
    77   static inline nsresult asInt32(const StorageType &, int32_t *) { NO_CONVERSION }
    78   static inline nsresult asInt64(const StorageType &, int64_t *) { NO_CONVERSION }
    79 };
    81 template <typename DataType, bool Adopting=false>
    82 struct variant_float_traits
    83 {
    84   typedef typename variant_storage_traits<DataType, Adopting>::StorageType StorageType;
    85   static inline nsresult asDouble(const StorageType &, double *) { NO_CONVERSION }
    86 };
    88 template <typename DataType, bool Adopting=false>
    89 struct variant_text_traits
    90 {
    91   typedef typename variant_storage_traits<DataType, Adopting>::StorageType StorageType;
    92   static inline nsresult asUTF8String(const StorageType &, nsACString &) { NO_CONVERSION }
    93   static inline nsresult asString(const StorageType &, nsAString &) { NO_CONVERSION }
    94 };
    96 template <typename DataType, bool Adopting=false>
    97 struct variant_blob_traits
    98 {
    99   typedef typename variant_storage_traits<DataType, Adopting>::StorageType StorageType;
   100   static inline nsresult asArray(const StorageType &, uint16_t *, uint32_t *, void **)
   101   { NO_CONVERSION }
   102 };
   104 #undef NO_CONVERSION
   106 /**
   107  * INTEGER types
   108  */
   110 template < >
   111 struct variant_traits<int64_t>
   112 {
   113   static inline uint16_t type() { return nsIDataType::VTYPE_INT64; }
   114 };
   115 template < >
   116 struct variant_integer_traits<int64_t>
   117 {
   118   static inline nsresult asInt32(int64_t aValue,
   119                                  int32_t *_result)
   120   {
   121     if (aValue > INT32_MAX || aValue < INT32_MIN)
   122       return NS_ERROR_CANNOT_CONVERT_DATA;
   124     *_result = static_cast<int32_t>(aValue);
   125     return NS_OK;
   126   }
   127   static inline nsresult asInt64(int64_t aValue,
   128                                  int64_t *_result)
   129   {
   130     *_result = aValue;
   131     return NS_OK;
   132   }
   133 };
   134 // xpcvariant just calls get double for integers...
   135 template < >
   136 struct variant_float_traits<int64_t>
   137 {
   138   static inline nsresult asDouble(int64_t aValue,
   139                                   double *_result)
   140   {
   141     *_result = double(aValue);
   142     return NS_OK;
   143   }
   144 };
   146 /**
   147  * FLOAT types
   148  */
   150 template < >
   151 struct variant_traits<double>
   152 {
   153   static inline uint16_t type() { return nsIDataType::VTYPE_DOUBLE; }
   154 };
   155 template < >
   156 struct variant_float_traits<double>
   157 {
   158   static inline nsresult asDouble(double aValue,
   159                                   double *_result)
   160   {
   161     *_result = aValue;
   162     return NS_OK;
   163   }
   164 };
   166 /**
   167  * TEXT types
   168  */
   170 template < >
   171 struct variant_traits<nsString>
   172 {
   173   static inline uint16_t type() { return nsIDataType::VTYPE_ASTRING; }
   174 };
   175 template < >
   176 struct variant_storage_traits<nsString>
   177 {
   178   typedef const nsAString & ConstructorType;
   179   typedef nsString StorageType;
   180   static inline void storage_conversion(ConstructorType aText, StorageType* _outData)
   181   {
   182     *_outData = aText;
   183   }
   184   static inline void destroy(const StorageType& _outData)
   185   { }
   186 };
   187 template < >
   188 struct variant_text_traits<nsString>
   189 {
   190   static inline nsresult asUTF8String(const nsString &aValue,
   191                                       nsACString &_result)
   192   {
   193     CopyUTF16toUTF8(aValue, _result);
   194     return NS_OK;
   195   }
   196   static inline nsresult asString(const nsString &aValue,
   197                                   nsAString &_result)
   198   {
   199     _result = aValue;
   200     return NS_OK;
   201   }
   202 };
   204 template < >
   205 struct variant_traits<nsCString>
   206 {
   207   static inline uint16_t type() { return nsIDataType::VTYPE_UTF8STRING; }
   208 };
   209 template < >
   210 struct variant_storage_traits<nsCString>
   211 {
   212   typedef const nsACString & ConstructorType;
   213   typedef nsCString StorageType;
   214   static inline void storage_conversion(ConstructorType aText, StorageType* _outData)
   215   {
   216     *_outData = aText;
   217   }
   218   static inline void destroy(const StorageType &aData)
   219   { }
   220 };
   221 template < >
   222 struct variant_text_traits<nsCString>
   223 {
   224   static inline nsresult asUTF8String(const nsCString &aValue,
   225                                       nsACString &_result)
   226   {
   227     _result = aValue;
   228     return NS_OK;
   229   }
   230   static inline nsresult asString(const nsCString &aValue,
   231                                   nsAString &_result)
   232   {
   233     CopyUTF8toUTF16(aValue, _result);
   234     return NS_OK;
   235   }
   236 };
   238 /**
   239  * BLOB types
   240  */
   242 template < >
   243 struct variant_traits<uint8_t[]>
   244 {
   245   static inline uint16_t type() { return nsIDataType::VTYPE_ARRAY; }
   246 };
   247 template < >
   248 struct variant_storage_traits<uint8_t[], false>
   249 {
   250   typedef std::pair<const void *, int> ConstructorType;
   251   typedef FallibleTArray<uint8_t> StorageType;
   252   static inline void storage_conversion(ConstructorType aBlob, StorageType* _outData)
   253   {
   254     _outData->Clear();
   255     _outData->SetCapacity(aBlob.second);
   256     (void)_outData->AppendElements(static_cast<const uint8_t *>(aBlob.first),
   257                                    aBlob.second);
   258   }
   259   static inline void destroy(const StorageType& _outData)
   260   { }
   261 };
   262 template < >
   263 struct variant_storage_traits<uint8_t[], true>
   264 {
   265   typedef std::pair<uint8_t *, int> ConstructorType;
   266   typedef std::pair<uint8_t *, int> StorageType;
   267   static inline void storage_conversion(ConstructorType aBlob, StorageType* _outData)
   268   {
   269     *_outData = aBlob;
   270   }
   271   static inline void destroy(StorageType &aData)
   272   {
   273     if (aData.first) {
   274       NS_Free(aData.first);
   275       aData.first = nullptr;
   276     }
   277   }
   278 };
   279 template < >
   280 struct variant_blob_traits<uint8_t[], false>
   281 {
   282   static inline nsresult asArray(FallibleTArray<uint8_t> &aData,
   283                                  uint16_t *_type,
   284                                  uint32_t *_size,
   285                                  void **_result)
   286   {
   287     // For empty blobs, we return nullptr.
   288     if (aData.Length() == 0) {
   289       *_result = nullptr;
   290       *_type = nsIDataType::VTYPE_UINT8;
   291       *_size = 0;
   292       return NS_OK;
   293     }
   295     // Otherwise, we copy the array.
   296     *_result = nsMemory::Clone(aData.Elements(), aData.Length() * sizeof(uint8_t));
   297     NS_ENSURE_TRUE(*_result, NS_ERROR_OUT_OF_MEMORY);
   299     // Set type and size
   300     *_type = nsIDataType::VTYPE_UINT8;
   301     *_size = aData.Length();
   302     return NS_OK;
   303   }
   304 };
   306 template < >
   307 struct variant_blob_traits<uint8_t[], true>
   308 {
   309   static inline nsresult asArray(std::pair<uint8_t *, int> &aData,
   310                                  uint16_t *_type,
   311                                  uint32_t *_size,
   312                                  void **_result)
   313   {
   314     // For empty blobs, we return nullptr.
   315     if (aData.second == 0) {
   316       *_result = nullptr;
   317       *_type = nsIDataType::VTYPE_UINT8;
   318       *_size = 0;
   319       return NS_OK;
   320     }
   322     // Otherwise, transfer the data out.
   323     *_result = aData.first;
   324     aData.first = nullptr;
   325     MOZ_ASSERT(*_result); // We asked for it twice, better not use adopting!
   327     // Set type and size
   328     *_type = nsIDataType::VTYPE_UINT8;
   329     *_size = aData.second;
   330     return NS_OK;
   331   }
   332 };
   334 /**
   335  * nullptr type
   336  */
   338 class NullVariant : public Variant_base
   339 {
   340 public:
   341   NS_IMETHOD GetDataType(uint16_t *_type)
   342   {
   343     NS_ENSURE_ARG_POINTER(_type);
   344     *_type = nsIDataType::VTYPE_EMPTY;
   345     return NS_OK;
   346   }
   348   NS_IMETHOD GetAsAUTF8String(nsACString &_str)
   349   {
   350     // Return a void string.
   351     _str.Truncate(0);
   352     _str.SetIsVoid(true);
   353     return NS_OK;
   354   }
   356   NS_IMETHOD GetAsAString(nsAString &_str)
   357   {
   358     // Return a void string.
   359     _str.Truncate(0);
   360     _str.SetIsVoid(true);
   361     return NS_OK;
   362   }
   363 };
   365 ////////////////////////////////////////////////////////////////////////////////
   366 //// Template Implementation
   368 template <typename DataType, bool Adopting=false>
   369 class Variant : public Variant_base
   370 {
   371   ~Variant()
   372   {
   373     variant_storage_traits<DataType, Adopting>::destroy(mData);
   374   }
   376 public:
   377   Variant(const typename variant_storage_traits<DataType, Adopting>::ConstructorType aData)
   378   {
   379     variant_storage_traits<DataType, Adopting>::storage_conversion(aData, &mData);
   380   }
   382   NS_IMETHOD GetDataType(uint16_t *_type)
   383   {
   384     *_type = variant_traits<DataType>::type();
   385     return NS_OK;
   386   }
   387   NS_IMETHOD GetAsInt32(int32_t *_integer)
   388   {
   389     return variant_integer_traits<DataType, Adopting>::asInt32(mData, _integer);
   390   }
   392   NS_IMETHOD GetAsInt64(int64_t *_integer)
   393   {
   394     return variant_integer_traits<DataType, Adopting>::asInt64(mData, _integer);
   395   }
   397   NS_IMETHOD GetAsDouble(double *_double)
   398   {
   399     return variant_float_traits<DataType, Adopting>::asDouble(mData, _double);
   400   }
   402   NS_IMETHOD GetAsAUTF8String(nsACString &_str)
   403   {
   404     return variant_text_traits<DataType, Adopting>::asUTF8String(mData, _str);
   405   }
   407   NS_IMETHOD GetAsAString(nsAString &_str)
   408   {
   409     return variant_text_traits<DataType, Adopting>::asString(mData, _str);
   410   }
   412   NS_IMETHOD GetAsArray(uint16_t *_type,
   413                         nsIID *,
   414                         uint32_t *_size,
   415                         void **_data)
   416   {
   417     return variant_blob_traits<DataType, Adopting>::asArray(mData, _type, _size, _data);
   418   }
   420 private:
   421   typename variant_storage_traits<DataType, Adopting>::StorageType mData;
   422 };
   424 ////////////////////////////////////////////////////////////////////////////////
   425 //// Handy typedefs!  Use these for the right mapping.
   427 typedef Variant<int64_t> IntegerVariant;
   428 typedef Variant<double> FloatVariant;
   429 typedef Variant<nsString> TextVariant;
   430 typedef Variant<nsCString> UTF8TextVariant;
   431 typedef Variant<uint8_t[], false> BlobVariant;
   432 typedef Variant<uint8_t[], true> AdoptedBlobVariant;
   434 } // namespace storage
   435 } // namespace mozilla
   437 #include "Variant_inl.h"
   439 #endif // mozilla_storage_Variant_h__

mercurial