michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ : michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsError.h" michael@0: #include "nsMemory.h" michael@0: #include "nsString.h" michael@0: michael@0: #include "mozStoragePrivateHelpers.h" michael@0: #include "mozStorageArgValueArray.h" michael@0: michael@0: namespace mozilla { michael@0: namespace storage { michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: //// ArgValueArray michael@0: michael@0: ArgValueArray::ArgValueArray(int32_t aArgc, michael@0: sqlite3_value **aArgv) michael@0: : mArgc(aArgc) michael@0: , mArgv(aArgv) michael@0: { michael@0: } michael@0: michael@0: NS_IMPL_ISUPPORTS( michael@0: ArgValueArray, michael@0: mozIStorageValueArray michael@0: ) michael@0: michael@0: //////////////////////////////////////////////////////////////////////////////// michael@0: //// mozIStorageValueArray michael@0: michael@0: NS_IMETHODIMP michael@0: ArgValueArray::GetNumEntries(uint32_t *_size) michael@0: { michael@0: *_size = mArgc; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: ArgValueArray::GetTypeOfIndex(uint32_t aIndex, michael@0: int32_t *_type) michael@0: { michael@0: ENSURE_INDEX_VALUE(aIndex, mArgc); michael@0: michael@0: int t = ::sqlite3_value_type(mArgv[aIndex]); michael@0: switch (t) { michael@0: case SQLITE_INTEGER: michael@0: *_type = VALUE_TYPE_INTEGER; michael@0: break; michael@0: case SQLITE_FLOAT: michael@0: *_type = VALUE_TYPE_FLOAT; michael@0: break; michael@0: case SQLITE_TEXT: michael@0: *_type = VALUE_TYPE_TEXT; michael@0: break; michael@0: case SQLITE_BLOB: michael@0: *_type = VALUE_TYPE_BLOB; michael@0: break; michael@0: case SQLITE_NULL: michael@0: *_type = VALUE_TYPE_NULL; michael@0: break; michael@0: default: michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: ArgValueArray::GetInt32(uint32_t aIndex, michael@0: int32_t *_value) michael@0: { michael@0: ENSURE_INDEX_VALUE(aIndex, mArgc); michael@0: michael@0: *_value = ::sqlite3_value_int(mArgv[aIndex]); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: ArgValueArray::GetInt64(uint32_t aIndex, michael@0: int64_t *_value) michael@0: { michael@0: ENSURE_INDEX_VALUE(aIndex, mArgc); michael@0: michael@0: *_value = ::sqlite3_value_int64(mArgv[aIndex]); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: ArgValueArray::GetDouble(uint32_t aIndex, michael@0: double *_value) michael@0: { michael@0: ENSURE_INDEX_VALUE(aIndex, mArgc); michael@0: michael@0: *_value = ::sqlite3_value_double(mArgv[aIndex]); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: ArgValueArray::GetUTF8String(uint32_t aIndex, michael@0: nsACString &_value) michael@0: { michael@0: ENSURE_INDEX_VALUE(aIndex, mArgc); michael@0: michael@0: if (::sqlite3_value_type(mArgv[aIndex]) == SQLITE_NULL) { michael@0: // NULL columns should have IsVoid set to distinguish them from an empty michael@0: // string. michael@0: _value.Truncate(0); michael@0: _value.SetIsVoid(true); michael@0: } michael@0: else { michael@0: _value.Assign(reinterpret_cast(::sqlite3_value_text(mArgv[aIndex])), michael@0: ::sqlite3_value_bytes(mArgv[aIndex])); michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: ArgValueArray::GetString(uint32_t aIndex, michael@0: nsAString &_value) michael@0: { michael@0: ENSURE_INDEX_VALUE(aIndex, mArgc); michael@0: michael@0: if (::sqlite3_value_type(mArgv[aIndex]) == SQLITE_NULL) { michael@0: // NULL columns should have IsVoid set to distinguish them from an empty michael@0: // string. michael@0: _value.Truncate(0); michael@0: _value.SetIsVoid(true); michael@0: } else { michael@0: _value.Assign(static_cast(::sqlite3_value_text16(mArgv[aIndex])), michael@0: ::sqlite3_value_bytes16(mArgv[aIndex]) / 2); michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: ArgValueArray::GetBlob(uint32_t aIndex, michael@0: uint32_t *_size, michael@0: uint8_t **_blob) michael@0: { michael@0: ENSURE_INDEX_VALUE(aIndex, mArgc); michael@0: michael@0: int size = ::sqlite3_value_bytes(mArgv[aIndex]); michael@0: void *blob = nsMemory::Clone(::sqlite3_value_blob(mArgv[aIndex]), size); michael@0: NS_ENSURE_TRUE(blob, NS_ERROR_OUT_OF_MEMORY); michael@0: michael@0: *_blob = static_cast(blob); michael@0: *_size = size; michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: ArgValueArray::GetIsNull(uint32_t aIndex, michael@0: bool *_isNull) michael@0: { michael@0: // GetTypeOfIndex will check aIndex for us, so we don't have to. michael@0: int32_t type; michael@0: nsresult rv = GetTypeOfIndex(aIndex, &type); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: *_isNull = (type == VALUE_TYPE_NULL); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: ArgValueArray::GetSharedUTF8String(uint32_t aIndex, michael@0: uint32_t *_length, michael@0: const char **_string) michael@0: { michael@0: if (_length) michael@0: *_length = ::sqlite3_value_bytes(mArgv[aIndex]); michael@0: michael@0: *_string = reinterpret_cast(::sqlite3_value_text(mArgv[aIndex])); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: ArgValueArray::GetSharedString(uint32_t aIndex, michael@0: uint32_t *_length, michael@0: const char16_t **_string) michael@0: { michael@0: if (_length) michael@0: *_length = ::sqlite3_value_bytes(mArgv[aIndex]); michael@0: michael@0: *_string = static_cast(::sqlite3_value_text16(mArgv[aIndex])); michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: ArgValueArray::GetSharedBlob(uint32_t aIndex, michael@0: uint32_t *_size, michael@0: const uint8_t **_blob) michael@0: { michael@0: *_size = ::sqlite3_value_bytes(mArgv[aIndex]); michael@0: *_blob = static_cast(::sqlite3_value_blob(mArgv[aIndex])); michael@0: return NS_OK; michael@0: } michael@0: michael@0: } // namespace storage michael@0: } // namespace mozilla