tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

variantToSQLiteT_impl.h (4759B)


      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/. */
      6 
      7 // Note: we are already in the namepace mozilla::storage
      8 
      9 // Note 2: whoever #includes this file must provide implementations of
     10 // sqlite3_T_* prior.
     11 
     12 ////////////////////////////////////////////////////////////////////////////////
     13 //// variantToSQLiteT Implementation
     14 
     15 template <typename T>
     16 int variantToSQLiteT(T aObj, nsIVariant* aValue) {
     17  // Allow to return nullptr not wrapped to nsIVariant for speed.
     18  if (!aValue) return sqlite3_T_null(aObj);
     19 
     20  uint16_t valueType = aValue->GetDataType();
     21  switch (valueType) {
     22    case nsIDataType::VTYPE_INT8:
     23    case nsIDataType::VTYPE_INT16:
     24    case nsIDataType::VTYPE_INT32:
     25    case nsIDataType::VTYPE_UINT8:
     26    case nsIDataType::VTYPE_UINT16: {
     27      int32_t value;
     28      nsresult rv = aValue->GetAsInt32(&value);
     29      NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH);
     30      return sqlite3_T_int(aObj, value);
     31    }
     32    case nsIDataType::VTYPE_UINT32:  // Try to preserve full range
     33    case nsIDataType::VTYPE_INT64:
     34    // Data loss possible, but there is no unsigned types in SQLite
     35    case nsIDataType::VTYPE_UINT64: {
     36      int64_t value;
     37      nsresult rv = aValue->GetAsInt64(&value);
     38      NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH);
     39      return sqlite3_T_int64(aObj, value);
     40    }
     41    case nsIDataType::VTYPE_FLOAT:
     42    case nsIDataType::VTYPE_DOUBLE: {
     43      double value;
     44      nsresult rv = aValue->GetAsDouble(&value);
     45      NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH);
     46      return sqlite3_T_double(aObj, value);
     47    }
     48    case nsIDataType::VTYPE_BOOL: {
     49      bool value;
     50      nsresult rv = aValue->GetAsBool(&value);
     51      NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH);
     52      return sqlite3_T_int(aObj, value ? 1 : 0);
     53    }
     54    case nsIDataType::VTYPE_CHAR:
     55    case nsIDataType::VTYPE_CHAR_STR:
     56    case nsIDataType::VTYPE_STRING_SIZE_IS:
     57    case nsIDataType::VTYPE_UTF8STRING:
     58    case nsIDataType::VTYPE_CSTRING: {
     59      nsAutoCString value;
     60      // GetAsAUTF8String should never perform conversion when coming from
     61      // 8-bit string types, and thus can accept strings with arbitrary encoding
     62      // (including UTF8 and ASCII).
     63      nsresult rv = aValue->GetAsAUTF8String(value);
     64      NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH);
     65      return sqlite3_T_text(aObj, value);
     66    }
     67    case nsIDataType::VTYPE_WCHAR:
     68    case nsIDataType::VTYPE_WCHAR_STR:
     69    case nsIDataType::VTYPE_WSTRING_SIZE_IS:
     70    case nsIDataType::VTYPE_ASTRING: {
     71      nsAutoString value;
     72      // GetAsAString does proper conversion to UCS2 from all string-like types.
     73      // It can be used universally without problems (unless someone implements
     74      // their own variant, but that's their problem).
     75      nsresult rv = aValue->GetAsAString(value);
     76      NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH);
     77      return sqlite3_T_text16(aObj, value);
     78    }
     79    case nsIDataType::VTYPE_VOID:
     80    case nsIDataType::VTYPE_EMPTY:
     81    case nsIDataType::VTYPE_EMPTY_ARRAY:
     82      return sqlite3_T_null(aObj);
     83    case nsIDataType::VTYPE_ARRAY: {
     84      uint16_t arrayType;
     85      nsIID iid;
     86      uint32_t count;
     87      void* data;
     88      nsresult rv = aValue->GetAsArray(&arrayType, &iid, &count, &data);
     89      NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH);
     90      if (arrayType == nsIDataType::VTYPE_UINT8) {
     91        // The function should free the array accordingly!
     92        return sqlite3_T_blob(aObj, data, count);
     93      }
     94      // Empty array is handled as NULL.
     95      if (count == 0) {
     96        return sqlite3_T_null(aObj);
     97      }
     98      if (arrayType == nsIDataType::VTYPE_INT32 ||
     99          arrayType == nsIDataType::VTYPE_INT64) {
    100        return sqlite3_T_array(aObj, data, count, CARRAY_INT64);
    101      }
    102      if (arrayType == nsIDataType::VTYPE_FLOAT ||
    103          arrayType == nsIDataType::VTYPE_DOUBLE) {
    104        return sqlite3_T_array(aObj, data, count, CARRAY_DOUBLE);
    105      }
    106      if (arrayType == nsIDataType::VTYPE_UTF8STRING) {
    107        return sqlite3_T_array(aObj, data, count, CARRAY_TEXT);
    108      }
    109 
    110      MOZ_DIAGNOSTIC_CRASH("Unsupported type in Storage bound array");
    111      // Technically this could leak with certain data types, but somebody was
    112      // being incautious passing us this anyway.
    113      free(data);
    114      return SQLITE_MISMATCH;
    115    }
    116    // Maybe, it'll be possible to convert these
    117    // in future too.
    118    case nsIDataType::VTYPE_ID:
    119    case nsIDataType::VTYPE_INTERFACE:
    120    case nsIDataType::VTYPE_INTERFACE_IS:
    121    default:
    122      return SQLITE_MISMATCH;
    123  }
    124  return SQLITE_OK;
    125 }