LCOV - code coverage report
Current view: directory - objdir/dist/include/mozilla/storage - Variant.h (source / functions) Found Hit Coverage
Test: app.info Lines: 65 26 40.0 %
Date: 2012-06-02 Functions: 57 10 17.5 %

       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                 :  * ***** BEGIN LICENSE BLOCK *****
       4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       5                 :  *
       6                 :  * The contents of this file are subject to the Mozilla Public License Version
       7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       8                 :  * the License. You may obtain a copy of the License at
       9                 :  * http://www.mozilla.org/MPL/
      10                 :  *
      11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      13                 :  * for the specific language governing rights and limitations under the
      14                 :  * License.
      15                 :  *
      16                 :  * The Original Code is mozilla.org code.
      17                 :  *
      18                 :  * The Initial Developer of the Original Code is
      19                 :  * Mozilla Corporation
      20                 :  * Portions created by the Initial Developer are Copyright (C) 2008
      21                 :  * the Initial Developer. All Rights Reserved.
      22                 :  *
      23                 :  * Contributor(s):
      24                 :  *   Shawn Wilsher <me@shawnwilsher.com> (Original Author)
      25                 :  *   Drew Willcoxon <adw@mozilla.com>
      26                 :  *
      27                 :  * Alternatively, the contents of this file may be used under the terms of
      28                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      29                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      30                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      31                 :  * of those above. If you wish to allow use of your version of this file only
      32                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      33                 :  * use your version of this file under the terms of the MPL, indicate your
      34                 :  * decision by deleting the provisions above and replace them with the notice
      35                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      36                 :  * the provisions above, a recipient may use your version of this file under
      37                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      38                 :  *
      39                 :  * ***** END LICENSE BLOCK ***** */
      40                 : 
      41                 : #ifndef mozilla_storage_Variant_h__
      42                 : #define mozilla_storage_Variant_h__
      43                 : 
      44                 : #include <utility>
      45                 : 
      46                 : #include "nsIVariant.h"
      47                 : #include "nsString.h"
      48                 : #include "nsTArray.h"
      49                 : 
      50                 : /**
      51                 :  * This class is used by the storage module whenever an nsIVariant needs to be
      52                 :  * returned.  We provide traits for the basic sqlite types to make use easier.
      53                 :  * The following types map to the indicated sqlite type:
      54                 :  * PRInt64   -> INTEGER (use IntegerVariant)
      55                 :  * double    -> FLOAT (use FloatVariant)
      56                 :  * nsString  -> TEXT (use TextVariant)
      57                 :  * nsCString -> TEXT (use UTF8TextVariant)
      58                 :  * PRUint8[] -> BLOB (use BlobVariant)
      59                 :  * nsnull    -> NULL (use NullVariant)
      60                 :  */
      61                 : 
      62                 : namespace mozilla {
      63                 : namespace storage {
      64                 : 
      65                 : ////////////////////////////////////////////////////////////////////////////////
      66                 : //// Base Class
      67                 : 
      68                 : class Variant_base : public nsIVariant
      69          718341 : {
      70                 : public:
      71                 :   NS_DECL_ISUPPORTS
      72                 :   NS_DECL_NSIVARIANT
      73                 : 
      74                 : protected:
      75         1436682 :   virtual ~Variant_base() { }
      76                 : };
      77                 : 
      78                 : ////////////////////////////////////////////////////////////////////////////////
      79                 : //// Traits
      80                 : 
      81                 : /**
      82                 :  * Generics
      83                 :  */
      84                 : 
      85                 : template <typename DataType>
      86                 : struct variant_traits
      87                 : {
      88                 :   static inline PRUint16 type() { return nsIDataType::VTYPE_EMPTY; }
      89                 : };
      90                 : 
      91                 : template <typename DataType>
      92                 : struct variant_storage_traits
      93                 : {
      94                 :   typedef DataType ConstructorType;
      95                 :   typedef DataType StorageType;
      96               0 :   static inline StorageType storage_conversion(ConstructorType aData) { return aData; }
      97                 : };
      98                 : 
      99                 : #define NO_CONVERSION return NS_ERROR_CANNOT_CONVERT_DATA;
     100                 : 
     101                 : template <typename DataType>
     102                 : struct variant_integer_traits
     103                 : {
     104                 :   typedef typename variant_storage_traits<DataType>::StorageType StorageType;
     105               0 :   static inline nsresult asInt32(StorageType, PRInt32 *) { NO_CONVERSION }
     106               0 :   static inline nsresult asInt64(StorageType, PRInt64 *) { NO_CONVERSION }
     107                 : };
     108                 : 
     109                 : template <typename DataType>
     110                 : struct variant_float_traits
     111                 : {
     112                 :   typedef typename variant_storage_traits<DataType>::StorageType StorageType;
     113               0 :   static inline nsresult asDouble(StorageType, double *) { NO_CONVERSION }
     114                 : };
     115                 : 
     116                 : template <typename DataType>
     117                 : struct variant_text_traits
     118                 : {
     119                 :   typedef typename variant_storage_traits<DataType>::StorageType StorageType;
     120               0 :   static inline nsresult asUTF8String(StorageType, nsACString &) { NO_CONVERSION }
     121               0 :   static inline nsresult asString(StorageType, nsAString &) { NO_CONVERSION }
     122                 : };
     123                 : 
     124                 : template <typename DataType>
     125                 : struct variant_blob_traits
     126                 : {
     127                 :   typedef typename variant_storage_traits<DataType>::StorageType StorageType;
     128               0 :   static inline nsresult asArray(StorageType, PRUint16 *, PRUint32 *, void **)
     129               0 :   { NO_CONVERSION }
     130                 : };
     131                 : 
     132                 : #undef NO_CONVERSION
     133                 : 
     134                 : /**
     135                 :  * INTEGER types
     136                 :  */
     137                 : 
     138                 : template < >
     139                 : struct variant_traits<PRInt64>
     140                 : {
     141               0 :   static inline PRUint16 type() { return nsIDataType::VTYPE_INT64; }
     142                 : };
     143                 : template < >
     144                 : struct variant_integer_traits<PRInt64>
     145                 : {
     146               0 :   static inline nsresult asInt32(PRInt64 aValue,
     147                 :                                  PRInt32 *_result)
     148                 :   {
     149               0 :     if (aValue > PR_INT32_MAX || aValue < PR_INT32_MIN)
     150               0 :       return NS_ERROR_CANNOT_CONVERT_DATA;
     151                 : 
     152               0 :     *_result = static_cast<PRInt32>(aValue);
     153               0 :     return NS_OK;
     154                 :   }
     155               0 :   static inline nsresult asInt64(PRInt64 aValue,
     156                 :                                  PRInt64 *_result)
     157                 :   {
     158               0 :     *_result = aValue;
     159               0 :     return NS_OK;
     160                 :   }
     161                 : };
     162                 : // xpcvariant just calls get double for integers...
     163                 : template < >
     164                 : struct variant_float_traits<PRInt64>
     165                 : {
     166               0 :   static inline nsresult asDouble(PRInt64 aValue,
     167                 :                                   double *_result)
     168                 :   {
     169               0 :     *_result = double(aValue);
     170               0 :     return NS_OK;
     171                 :   }
     172                 : };
     173                 : 
     174                 : /**
     175                 :  * FLOAT types
     176                 :  */
     177                 : 
     178                 : template < >
     179                 : struct variant_traits<double>
     180                 : {
     181                 :   static inline PRUint16 type() { return nsIDataType::VTYPE_DOUBLE; }
     182                 : };
     183                 : template < >
     184                 : struct variant_float_traits<double>
     185                 : {
     186                 :   static inline nsresult asDouble(double aValue,
     187                 :                                   double *_result)
     188                 :   {
     189                 :     *_result = aValue;
     190                 :     return NS_OK;
     191                 :   }
     192                 : };
     193                 : 
     194                 : /**
     195                 :  * TEXT types
     196                 :  */
     197                 : 
     198                 : template < >
     199                 : struct variant_traits<nsString>
     200                 : {
     201                 :   static inline PRUint16 type() { return nsIDataType::VTYPE_ASTRING; }
     202                 : };
     203                 : template < >
     204                 : struct variant_storage_traits<nsString>
     205                 : {
     206                 :   typedef const nsAString & ConstructorType;
     207                 :   typedef nsString StorageType;
     208                 :   static inline StorageType storage_conversion(ConstructorType aText)
     209                 :   {
     210                 :     return StorageType(aText);
     211                 :   }
     212                 : };
     213                 : template < >
     214                 : struct variant_text_traits<nsString>
     215                 : {
     216                 :   static inline nsresult asUTF8String(const nsString &aValue,
     217                 :                                       nsACString &_result)
     218                 :   {
     219                 :     CopyUTF16toUTF8(aValue, _result);
     220                 :     return NS_OK;
     221                 :   }
     222                 :   static inline nsresult asString(const nsString &aValue,
     223                 :                                   nsAString &_result)
     224                 :   {
     225                 :     _result = aValue;
     226                 :     return NS_OK;
     227                 :   }
     228                 : };
     229                 : 
     230                 : template < >
     231                 : struct variant_traits<nsCString>
     232                 : {
     233               0 :   static inline PRUint16 type() { return nsIDataType::VTYPE_UTF8STRING; }
     234                 : };
     235                 : template < >
     236                 : struct variant_storage_traits<nsCString>
     237                 : {
     238                 :   typedef const nsACString & ConstructorType;
     239                 :   typedef nsCString StorageType;
     240               0 :   static inline StorageType storage_conversion(ConstructorType aText)
     241                 :   {
     242               0 :     return StorageType(aText);
     243                 :   }
     244                 : };
     245                 : template < >
     246                 : struct variant_text_traits<nsCString>
     247                 : {
     248               0 :   static inline nsresult asUTF8String(const nsCString &aValue,
     249                 :                                       nsACString &_result)
     250                 :   {
     251               0 :     _result = aValue;
     252               0 :     return NS_OK;
     253                 :   }
     254               0 :   static inline nsresult asString(const nsCString &aValue,
     255                 :                                   nsAString &_result)
     256                 :   {
     257               0 :     CopyUTF8toUTF16(aValue, _result);
     258               0 :     return NS_OK;
     259                 :   }
     260                 : };
     261                 : 
     262                 : /**
     263                 :  * BLOB types
     264                 :  */
     265                 : 
     266                 : template < >
     267                 : struct variant_traits<PRUint8[]>
     268                 : {
     269            8052 :   static inline PRUint16 type() { return nsIDataType::VTYPE_ARRAY; }
     270                 : };
     271                 : template < >
     272                 : struct variant_storage_traits<PRUint8[]>
     273                 : {
     274                 :   typedef std::pair<const void *, int> ConstructorType;
     275                 :   typedef FallibleTArray<PRUint8> StorageType;
     276            8075 :   static inline StorageType storage_conversion(ConstructorType aBlob)
     277                 :   {
     278            8075 :     StorageType data(aBlob.second);
     279                 :     (void)data.AppendElements(static_cast<const PRUint8 *>(aBlob.first),
     280            8075 :                               aBlob.second);
     281                 :     return data;
     282                 :   }
     283                 : };
     284                 : template < >
     285                 : struct variant_blob_traits<PRUint8[]>
     286                 : {
     287            8051 :   static inline nsresult asArray(FallibleTArray<PRUint8> &aData,
     288                 :                                  PRUint16 *_type,
     289                 :                                  PRUint32 *_size,
     290                 :                                  void **_result)
     291                 :   {
     292                 :     // For empty blobs, we return nsnull.
     293            8051 :     if (aData.Length() == 0) {
     294              29 :       *_result = nsnull;
     295              29 :       *_type = nsIDataType::VTYPE_UINT8;
     296              29 :       *_size = 0;
     297              29 :       return NS_OK;
     298                 :     }
     299                 : 
     300                 :     // Otherwise, we copy the array.
     301            8022 :     *_result = nsMemory::Clone(aData.Elements(), aData.Length() * sizeof(PRUint8));
     302            8022 :     NS_ENSURE_TRUE(*_result, NS_ERROR_OUT_OF_MEMORY);
     303                 : 
     304                 :     // Set type and size
     305            8022 :     *_type = nsIDataType::VTYPE_UINT8;
     306            8022 :     *_size = aData.Length();
     307            8022 :     return NS_OK;
     308                 :   }
     309                 : };
     310                 : 
     311                 : /**
     312                 :  * NULL type
     313                 :  */
     314                 : 
     315                 : class NullVariant : public Variant_base
     316                 : {
     317                 : public:
     318                 :   NS_IMETHOD GetDataType(PRUint16 *_type)
     319                 :   {
     320                 :     NS_ENSURE_ARG_POINTER(_type);
     321                 :     *_type = nsIDataType::VTYPE_EMPTY;
     322                 :     return NS_OK;
     323                 :   }
     324                 : 
     325                 :   NS_IMETHOD GetAsAUTF8String(nsACString &_str)
     326                 :   {
     327                 :     // Return a void string.
     328                 :     _str.Truncate(0);
     329                 :     _str.SetIsVoid(true);
     330                 :     return NS_OK;
     331                 :   }
     332                 : 
     333                 :   NS_IMETHOD GetAsAString(nsAString &_str)
     334                 :   {
     335                 :     // Return a void string.
     336                 :     _str.Truncate(0);
     337                 :     _str.SetIsVoid(true);
     338                 :     return NS_OK;
     339                 :   }
     340                 : };
     341                 : 
     342                 : ////////////////////////////////////////////////////////////////////////////////
     343                 : //// Template Implementation
     344                 : 
     345                 : template <typename DataType>
     346                 : class Variant : public Variant_base
     347           32300 : {
     348                 : public:
     349            8075 :   Variant(typename variant_storage_traits<DataType>::ConstructorType aData)
     350            8075 :     : mData(variant_storage_traits<DataType>::storage_conversion(aData))
     351                 :   {
     352            8075 :   }
     353                 : 
     354            8052 :   NS_IMETHOD GetDataType(PRUint16 *_type)
     355                 :   {
     356            8052 :     *_type = variant_traits<DataType>::type();
     357            8052 :     return NS_OK;
     358                 :   }
     359               0 :   NS_IMETHOD GetAsInt32(PRInt32 *_integer)
     360                 :   {
     361               0 :     return variant_integer_traits<DataType>::asInt32(mData, _integer);
     362                 :   }
     363                 : 
     364               0 :   NS_IMETHOD GetAsInt64(PRInt64 *_integer)
     365                 :   {
     366               0 :     return variant_integer_traits<DataType>::asInt64(mData, _integer);
     367                 :   }
     368                 : 
     369               0 :   NS_IMETHOD GetAsDouble(double *_double)
     370                 :   {
     371               0 :     return variant_float_traits<DataType>::asDouble(mData, _double);
     372                 :   }
     373                 : 
     374               0 :   NS_IMETHOD GetAsAUTF8String(nsACString &_str)
     375                 :   {
     376               0 :     return variant_text_traits<DataType>::asUTF8String(mData, _str);
     377                 :   }
     378                 : 
     379               0 :   NS_IMETHOD GetAsAString(nsAString &_str)
     380                 :   {
     381               0 :     return variant_text_traits<DataType>::asString(mData, _str);
     382                 :   }
     383                 : 
     384            8051 :   NS_IMETHOD GetAsArray(PRUint16 *_type,
     385                 :                         nsIID *,
     386                 :                         PRUint32 *_size,
     387                 :                         void **_data)
     388                 :   {
     389            8051 :     return variant_blob_traits<DataType>::asArray(mData, _type, _size, _data);
     390                 :   }
     391                 : 
     392                 : private:
     393                 :   typename variant_storage_traits<DataType>::StorageType mData;
     394                 : };
     395                 : 
     396                 : ////////////////////////////////////////////////////////////////////////////////
     397                 : //// Handy typedefs!  Use these for the right mapping.
     398                 : 
     399                 : typedef Variant<PRInt64> IntegerVariant;
     400                 : typedef Variant<double> FloatVariant;
     401                 : typedef Variant<nsString> TextVariant;
     402                 : typedef Variant<nsCString> UTF8TextVariant;
     403                 : typedef Variant<PRUint8[]> BlobVariant;
     404                 : 
     405                 : } // namespace storage
     406                 : } // namespace mozilla
     407                 : 
     408                 : #include "Variant_inl.h"
     409                 : 
     410                 : #endif // mozilla_storage_Variant_h__

Generated by: LCOV version 1.7