LCOV - app.info - storage/src/Variant.h

LCOV - code coverage report
| Current view: | directory - storage/src - Variant.h (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 91 | 61 | 67.0 %
| Date: | 2012-07-07 | Functions: | 99 | 44 | 44.4 %

           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               0 : {
          70                 : public:
          71                 :   NS_DECL_ISUPPORTS
          72                 :   NS_DECL_NSIVARIANT
          73                 :
          74                 : protected:
          75               0 :   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          385517 :   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          283280 :   static inline PRUint16 type() { return nsIDataType::VTYPE_INT64; }
         142                 : };
         143                 : template < >
         144                 : struct variant_integer_traits<PRInt64>
         145                 : {
         146           22650 :   static inline nsresult asInt32(PRInt64 aValue,
         147                 :                                  PRInt32 *_result)
         148                 :   {
         149           22650 :     if (aValue > PR_INT32_MAX || aValue < PR_INT32_MIN)
         150               0 :       return NS_ERROR_CANNOT_CONVERT_DATA;
         151                 :
         152           22650 :     *_result = static_cast<PRInt32>(aValue);
         153           22650 :     return NS_OK;
         154                 :   }
         155          270839 :   static inline nsresult asInt64(PRInt64 aValue,
         156                 :                                  PRInt64 *_result)
         157                 :   {
         158          270839 :     *_result = aValue;
         159          270839 :     return NS_OK;
         160                 :   }
         161                 : };
         162                 : // xpcvariant just calls get double for integers...
         163                 : template < >
         164                 : struct variant_float_traits<PRInt64>
         165                 : {
         166           46822 :   static inline nsresult asDouble(PRInt64 aValue,
         167                 :                                   double *_result)
         168                 :   {
         169           46822 :     *_result = double(aValue);
         170           46822 :     return NS_OK;
         171                 :   }
         172                 : };
         173                 :
         174                 : /**
         175                 :  * FLOAT types
         176                 :  */
         177                 :
         178                 : template < >
         179                 : struct variant_traits<double>
         180                 : {
         181           12239 :   static inline PRUint16 type() { return nsIDataType::VTYPE_DOUBLE; }
         182                 : };
         183                 : template < >
         184                 : struct variant_float_traits<double>
         185                 : {
         186           12235 :   static inline nsresult asDouble(double aValue,
         187                 :                                   double *_result)
         188                 :   {
         189           12235 :     *_result = aValue;
         190           12235 :     return NS_OK;
         191                 :   }
         192                 : };
         193                 :
         194                 : /**
         195                 :  * TEXT types
         196                 :  */
         197                 :
         198                 : template < >
         199                 : struct variant_traits<nsString>
         200                 : {
         201           72524 :   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          146613 :   static inline StorageType storage_conversion(ConstructorType aText)
         209                 :   {
         210          146613 :     return StorageType(aText);
         211                 :   }
         212                 : };
         213                 : template < >
         214                 : struct variant_text_traits<nsString>
         215                 : {
         216           56880 :   static inline nsresult asUTF8String(const nsString &aValue,
         217                 :                                       nsACString &_result)
         218                 :   {
         219           56880 :     CopyUTF16toUTF8(aValue, _result);
         220           56880 :     return NS_OK;
         221                 :   }
         222           72520 :   static inline nsresult asString(const nsString &aValue,
         223                 :                                   nsAString &_result)
         224                 :   {
         225           72520 :     _result = aValue;
         226           72520 :     return NS_OK;
         227                 :   }
         228                 : };
         229                 :
         230                 : template < >
         231                 : struct variant_traits<nsCString>
         232                 : {
         233          108388 :   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          108388 :   static inline StorageType storage_conversion(ConstructorType aText)
         241                 :   {
         242          108388 :     return StorageType(aText);
         243                 :   }
         244                 : };
         245                 : template < >
         246                 : struct variant_text_traits<nsCString>
         247                 : {
         248          108388 :   static inline nsresult asUTF8String(const nsCString &aValue,
         249                 :                                       nsACString &_result)
         250                 :   {
         251          108388 :     _result = aValue;
         252          108388 :     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               0 :   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               0 :   static inline StorageType storage_conversion(ConstructorType aBlob)
         277                 :   {
         278               0 :     StorageType data(aBlob.second);
         279                 :     (void)data.AppendElements(static_cast<const PRUint8 *>(aBlob.first),
         280               0 :                               aBlob.second);
         281                 :     return data;
         282                 :   }
         283                 : };
         284                 : template < >
         285                 : struct variant_blob_traits<PRUint8[]>
         286                 : {
         287               0 :   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               0 :     if (aData.Length() == 0) {
         294               0 :       *_result = nsnull;
         295               0 :       *_type = nsIDataType::VTYPE_UINT8;
         296               0 :       *_size = 0;
         297               0 :       return NS_OK;
         298                 :     }
         299                 :
         300                 :     // Otherwise, we copy the array.
         301               0 :     *_result = nsMemory::Clone(aData.Elements(), aData.Length() * sizeof(PRUint8));
         302               0 :     NS_ENSURE_TRUE(*_result, NS_ERROR_OUT_OF_MEMORY);
         303                 :
         304                 :     // Set type and size
         305               0 :     *_type = nsIDataType::VTYPE_UINT8;
         306               0 :     *_size = aData.Length();
         307               0 :     return NS_OK;
         308                 :   }
         309                 : };
         310                 :
         311                 : /**
         312                 :  * NULL type
         313                 :  */
         314                 :
         315                 : class NullVariant : public Variant_base
         316          345905 : {
         317                 : public:
         318           59488 :   NS_IMETHOD GetDataType(PRUint16 *_type)
         319                 :   {
         320           59488 :     NS_ENSURE_ARG_POINTER(_type);
         321           59488 :     *_type = nsIDataType::VTYPE_EMPTY;
         322           59488 :     return NS_OK;
         323                 :   }
         324                 :
         325               4 :   NS_IMETHOD GetAsAUTF8String(nsACString &_str)
         326                 :   {
         327                 :     // Return a void string.
         328               4 :     _str.Truncate(0);
         329               4 :     _str.SetIsVoid(true);
         330               4 :     return NS_OK;
         331                 :   }
         332                 :
         333               2 :   NS_IMETHOD GetAsAString(nsAString &_str)
         334                 :   {
         335                 :     // Return a void string.
         336               2 :     _str.Truncate(0);
         337               2 :     _str.SetIsVoid(true);
         338               2 :     return NS_OK;
         339                 :   }
         340                 : };
         341                 :
         342                 : ////////////////////////////////////////////////////////////////////////////////
         343                 : //// Template Implementation
         344                 :
         345                 : template <typename DataType>
         346                 : class Variant : public Variant_base
         347         2562072 : {
         348                 : public:
         349          640518 :   Variant(typename variant_storage_traits<DataType>::ConstructorType aData)
         350          640518 :     : mData(variant_storage_traits<DataType>::storage_conversion(aData))
         351                 :   {
         352          640518 :   }
         353                 :
         354          476432 :   NS_IMETHOD GetDataType(PRUint16 *_type)
         355                 :   {
         356          476432 :     *_type = variant_traits<DataType>::type();
         357          476431 :     return NS_OK;
         358                 :   }
         359           22650 :   NS_IMETHOD GetAsInt32(PRInt32 *_integer)
         360                 :   {
         361           22650 :     return variant_integer_traits<DataType>::asInt32(mData, _integer);
         362                 :   }
         363                 :
         364          270837 :   NS_IMETHOD GetAsInt64(PRInt64 *_integer)
         365                 :   {
         366          270837 :     return variant_integer_traits<DataType>::asInt64(mData, _integer);
         367                 :   }
         368                 :
         369           59057 :   NS_IMETHOD GetAsDouble(double *_double)
         370                 :   {
         371           59057 :     return variant_float_traits<DataType>::asDouble(mData, _double);
         372                 :   }
         373                 :
         374          165268 :   NS_IMETHOD GetAsAUTF8String(nsACString &_str)
         375                 :   {
         376          165268 :     return variant_text_traits<DataType>::asUTF8String(mData, _str);
         377                 :   }
         378                 :
         379           72520 :   NS_IMETHOD GetAsAString(nsAString &_str)
         380                 :   {
         381           72520 :     return variant_text_traits<DataType>::asString(mData, _str);
         382                 :   }
         383                 :
         384               0 :   NS_IMETHOD GetAsArray(PRUint16 *_type,
         385                 :                         nsIID *,
         386                 :                         PRUint32 *_size,
         387                 :                         void **_data)
         388                 :   {
         389               0 :     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