storage/variantToSQLiteT_impl.h
author Gregory Szorc <gps@mozilla.com>
Fri, 27 Oct 2017 14:55:31 -0700
changeset 442301 5e5ee518a4b9d43e72c879e9d124aa432fb06e1a
parent 343115 d71d5a7a70d2c45f430a119c1b0edcfc8f83f664
child 497580 079e9287971001d839030ce8e60bb175018da76c
permissions -rw-r--r--
Bug 1412431 - Remove support for MOZ_PREFLIGHT and MOZ_POSTFLIGHT; r=nalexander These variables are unused in the repo. The %_ALL variation is used for sccache, however. The last use of these variables was removed when support for MacOS universal builds was removed. Someone somewhere may be relying on this functionality. But I don't think it is worth continuing to support in client.mk. If someone really needs it, we can reintroduce support for the feature elsewhere, like in mach or via mozconfig support somehow. MozReview-Commit-ID: 4KznCmK3JTN

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// Note: we are already in the namepace mozilla::storage

// Note 2: whoever #includes this file must provide implementations of
// sqlite3_T_* prior.

////////////////////////////////////////////////////////////////////////////////
//// variantToSQLiteT Implementation

template <typename T>
int
variantToSQLiteT(T aObj,
                 nsIVariant *aValue)
{
  // Allow to return nullptr not wrapped to nsIVariant for speed.
  if (!aValue)
    return sqlite3_T_null(aObj);

  uint16_t valueType;
  aValue->GetDataType(&valueType);
  switch (valueType) {
    case nsIDataType::VTYPE_INT8:
    case nsIDataType::VTYPE_INT16:
    case nsIDataType::VTYPE_INT32:
    case nsIDataType::VTYPE_UINT8:
    case nsIDataType::VTYPE_UINT16:
    {
      int32_t value;
      nsresult rv = aValue->GetAsInt32(&value);
      NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH);
      return sqlite3_T_int(aObj, value);
    }
    case nsIDataType::VTYPE_UINT32: // Try to preserve full range
    case nsIDataType::VTYPE_INT64:
    // Data loss possible, but there is no unsigned types in SQLite
    case nsIDataType::VTYPE_UINT64:
    {
      int64_t value;
      nsresult rv = aValue->GetAsInt64(&value);
      NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH);
      return sqlite3_T_int64(aObj, value);
    }
    case nsIDataType::VTYPE_FLOAT:
    case nsIDataType::VTYPE_DOUBLE:
    {
      double value;
      nsresult rv = aValue->GetAsDouble(&value);
      NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH);
      return sqlite3_T_double(aObj, value);
    }
    case nsIDataType::VTYPE_BOOL:
    {
      bool value;
      nsresult rv = aValue->GetAsBool(&value);
      NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH);
      return sqlite3_T_int(aObj, value ? 1 : 0);
    }
    case nsIDataType::VTYPE_CHAR:
    case nsIDataType::VTYPE_CHAR_STR:
    case nsIDataType::VTYPE_STRING_SIZE_IS:
    case nsIDataType::VTYPE_UTF8STRING:
    case nsIDataType::VTYPE_CSTRING:
    {
      nsAutoCString value;
      // GetAsAUTF8String should never perform conversion when coming from
      // 8-bit string types, and thus can accept strings with arbitrary encoding
      // (including UTF8 and ASCII).
      nsresult rv = aValue->GetAsAUTF8String(value);
      NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH);
      return sqlite3_T_text(aObj, value);
    }
    case nsIDataType::VTYPE_WCHAR:
    case nsIDataType::VTYPE_DOMSTRING:
    case nsIDataType::VTYPE_WCHAR_STR:
    case nsIDataType::VTYPE_WSTRING_SIZE_IS:
    case nsIDataType::VTYPE_ASTRING:
    {
      nsAutoString value;
      // GetAsAString does proper conversion to UCS2 from all string-like types.
      // It can be used universally without problems (unless someone implements
      // their own variant, but that's their problem).
      nsresult rv = aValue->GetAsAString(value);
      NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH);
      return sqlite3_T_text16(aObj, value);
    }
    case nsIDataType::VTYPE_VOID:
    case nsIDataType::VTYPE_EMPTY:
    case nsIDataType::VTYPE_EMPTY_ARRAY:
      return sqlite3_T_null(aObj);
    case nsIDataType::VTYPE_ARRAY:
    {
      uint16_t arrayType;
      nsIID iid;
      uint32_t count;
      void *data;
      nsresult rv = aValue->GetAsArray(&arrayType, &iid, &count, &data);
      NS_ENSURE_SUCCESS(rv, SQLITE_MISMATCH);

      // Check to make sure it's a supported type.
      NS_ASSERTION(arrayType == nsIDataType::VTYPE_UINT8,
                   "Invalid type passed!  You may leak!");
      if (arrayType != nsIDataType::VTYPE_UINT8) {
        // Technically this could leak with certain data types, but somebody was
        // being stupid passing us this anyway.
        free(data);
        return SQLITE_MISMATCH;
      }

      // Finally do our thing.  The function should free the array accordingly!
      int rc = sqlite3_T_blob(aObj, data, count);
      return rc;
    }
    // Maybe, it'll be possible to convert these
    // in future too.
    case nsIDataType::VTYPE_ID:
    case nsIDataType::VTYPE_INTERFACE:
    case nsIDataType::VTYPE_INTERFACE_IS:
    default:
      return SQLITE_MISMATCH;
  }
  return SQLITE_OK;
}