storage/src/variantToSQLiteT_impl.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/storage/src/variantToSQLiteT_impl.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,127 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     1.5 + * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
     1.6 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +// Note: we are already in the namepace mozilla::storage
    1.11 +
    1.12 +// Note 2: whoever #includes this file must provide implementations of
    1.13 +// sqlite3_T_* prior.
    1.14 +
    1.15 +////////////////////////////////////////////////////////////////////////////////
    1.16 +//// variantToSQLiteT Implementation
    1.17 +
    1.18 +template <typename T>
    1.19 +int
    1.20 +variantToSQLiteT(T aObj,
    1.21 +                 nsIVariant *aValue)
    1.22 +{
    1.23 +  // Allow to return nullptr not wrapped to nsIVariant for speed.
    1.24 +  if (!aValue)
    1.25 +    return sqlite3_T_null(aObj);
    1.26 +
    1.27 +  uint16_t type;
    1.28 +  (void)aValue->GetDataType(&type);
    1.29 +  switch (type) {
    1.30 +    case nsIDataType::VTYPE_INT8:
    1.31 +    case nsIDataType::VTYPE_INT16:
    1.32 +    case nsIDataType::VTYPE_INT32:
    1.33 +    case nsIDataType::VTYPE_UINT8:
    1.34 +    case nsIDataType::VTYPE_UINT16:
    1.35 +    {
    1.36 +      int32_t value;
    1.37 +      nsresult rv = aValue->GetAsInt32(&value);
    1.38 +      NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH);
    1.39 +      return sqlite3_T_int(aObj, value);
    1.40 +    }
    1.41 +    case nsIDataType::VTYPE_UINT32: // Try to preserve full range
    1.42 +    case nsIDataType::VTYPE_INT64:
    1.43 +    // Data loss possible, but there is no unsigned types in SQLite
    1.44 +    case nsIDataType::VTYPE_UINT64:
    1.45 +    {
    1.46 +      int64_t value;
    1.47 +      nsresult rv = aValue->GetAsInt64(&value);
    1.48 +      NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH);
    1.49 +      return sqlite3_T_int64(aObj, value);
    1.50 +    }
    1.51 +    case nsIDataType::VTYPE_FLOAT:
    1.52 +    case nsIDataType::VTYPE_DOUBLE:
    1.53 +    {
    1.54 +      double value;
    1.55 +      nsresult rv = aValue->GetAsDouble(&value);
    1.56 +      NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH);
    1.57 +      return sqlite3_T_double(aObj, value);
    1.58 +    }
    1.59 +    case nsIDataType::VTYPE_BOOL:
    1.60 +    {
    1.61 +      bool value;
    1.62 +      nsresult rv = aValue->GetAsBool(&value);
    1.63 +      NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH);
    1.64 +      return sqlite3_T_int(aObj, value ? 1 : 0);
    1.65 +    }
    1.66 +    case nsIDataType::VTYPE_CHAR:
    1.67 +    case nsIDataType::VTYPE_CHAR_STR:
    1.68 +    case nsIDataType::VTYPE_STRING_SIZE_IS:
    1.69 +    case nsIDataType::VTYPE_UTF8STRING:
    1.70 +    case nsIDataType::VTYPE_CSTRING:
    1.71 +    {
    1.72 +      nsAutoCString value;
    1.73 +      // GetAsAUTF8String should never perform conversion when coming from
    1.74 +      // 8-bit string types, and thus can accept strings with arbitrary encoding
    1.75 +      // (including UTF8 and ASCII).
    1.76 +      nsresult rv = aValue->GetAsAUTF8String(value);
    1.77 +      NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH);
    1.78 +      return sqlite3_T_text(aObj, value);
    1.79 +    }
    1.80 +    case nsIDataType::VTYPE_WCHAR:
    1.81 +    case nsIDataType::VTYPE_DOMSTRING:
    1.82 +    case nsIDataType::VTYPE_WCHAR_STR:
    1.83 +    case nsIDataType::VTYPE_WSTRING_SIZE_IS:
    1.84 +    case nsIDataType::VTYPE_ASTRING:
    1.85 +    {
    1.86 +      nsAutoString value;
    1.87 +      // GetAsAString does proper conversion to UCS2 from all string-like types.
    1.88 +      // It can be used universally without problems (unless someone implements
    1.89 +      // their own variant, but that's their problem).
    1.90 +      nsresult rv = aValue->GetAsAString(value);
    1.91 +      NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH);
    1.92 +      return sqlite3_T_text16(aObj, value);
    1.93 +    }
    1.94 +    case nsIDataType::VTYPE_VOID:
    1.95 +    case nsIDataType::VTYPE_EMPTY:
    1.96 +    case nsIDataType::VTYPE_EMPTY_ARRAY:
    1.97 +      return sqlite3_T_null(aObj);
    1.98 +    case nsIDataType::VTYPE_ARRAY:
    1.99 +    {
   1.100 +      uint16_t type;
   1.101 +      nsIID iid;
   1.102 +      uint32_t count;
   1.103 +      void *data;
   1.104 +      nsresult rv = aValue->GetAsArray(&type, &iid, &count, &data);
   1.105 +      NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH);
   1.106 +
   1.107 +      // Check to make sure it's a supported type.
   1.108 +      NS_ASSERTION(type == nsIDataType::VTYPE_UINT8,
   1.109 +                   "Invalid type passed!  You may leak!");
   1.110 +      if (type != nsIDataType::VTYPE_UINT8) {
   1.111 +        // Technically this could leak with certain data types, but somebody was
   1.112 +        // being stupid passing us this anyway.
   1.113 +        NS_Free(data);
   1.114 +        return SQLITE_MISMATCH;
   1.115 +      }
   1.116 +
   1.117 +      // Finally do our thing.  The function should free the array accordingly!
   1.118 +      int rc = sqlite3_T_blob(aObj, data, count);
   1.119 +      return rc;
   1.120 +    }
   1.121 +    // Maybe, it'll be possible to convert these
   1.122 +    // in future too.
   1.123 +    case nsIDataType::VTYPE_ID:
   1.124 +    case nsIDataType::VTYPE_INTERFACE:
   1.125 +    case nsIDataType::VTYPE_INTERFACE_IS:
   1.126 +    default:
   1.127 +      return SQLITE_MISMATCH;
   1.128 +  }
   1.129 +  return SQLITE_OK;
   1.130 +}

mercurial