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
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/
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
16 * The Original Code is mozilla.org code.
18 * The Initial Developer of the Original Code is
20 * Portions created by the Initial Developer are Copyright (C) 2008
21 * the Initial Developer. All Rights Reserved.
24 * Shawn Wilsher <me@shawnwilsher.com> (Original Author)
25 * Drew Willcoxon <adw@mozilla.com>
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.
39 * ***** END LICENSE BLOCK ***** */
41 #ifndef mozilla_storage_Variant_h__
42 #define mozilla_storage_Variant_h__
46 #include "nsIVariant.h"
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)
65 ////////////////////////////////////////////////////////////////////////////////
68 class Variant_base
: public nsIVariant
75 virtual ~Variant_base() { }
78 ////////////////////////////////////////////////////////////////////////////////
85 template <typename DataType
>
88 static inline PRUint16
type() { return nsIDataType::VTYPE_EMPTY
; }
91 template <typename DataType
>
92 struct variant_storage_traits
94 typedef DataType ConstructorType
;
95 typedef DataType StorageType
;
96 static inline StorageType
storage_conversion(ConstructorType aData
) { return aData
; }
99 #define NO_CONVERSION return NS_ERROR_CANNOT_CONVERT_DATA;
101 template <typename DataType
>
102 struct variant_integer_traits
104 typedef typename variant_storage_traits
<DataType
>::StorageType StorageType
;
105 static inline nsresult
asInt32(StorageType
, PRInt32
*) { NO_CONVERSION
}
106 static inline nsresult
asInt64(StorageType
, PRInt64
*) { NO_CONVERSION
}
109 template <typename DataType
>
110 struct variant_float_traits
112 typedef typename variant_storage_traits
<DataType
>::StorageType StorageType
;
113 static inline nsresult
asDouble(StorageType
, double *) { NO_CONVERSION
}
116 template <typename DataType
>
117 struct variant_text_traits
119 typedef typename variant_storage_traits
<DataType
>::StorageType StorageType
;
120 static inline nsresult
asUTF8String(StorageType
, nsACString
&) { NO_CONVERSION
}
121 static inline nsresult
asString(StorageType
, nsAString
&) { NO_CONVERSION
}
124 template <typename DataType
>
125 struct variant_blob_traits
127 typedef typename variant_storage_traits
<DataType
>::StorageType StorageType
;
128 static inline nsresult
asArray(StorageType
, PRUint16
*, PRUint32
*, void **)
139 struct variant_traits
<PRInt64
>
141 static inline PRUint16
type() { return nsIDataType::VTYPE_INT64
; }
144 struct variant_integer_traits
<PRInt64
>
146 static inline nsresult
asInt32(PRInt64 aValue
,
149 if (aValue
> PR_INT32_MAX
|| aValue
< PR_INT32_MIN
)
150 return NS_ERROR_CANNOT_CONVERT_DATA
;
152 *_result
= static_cast<PRInt32
>(aValue
);
155 static inline nsresult
asInt64(PRInt64 aValue
,
162 // xpcvariant just calls get double for integers...
164 struct variant_float_traits
<PRInt64
>
166 static inline nsresult
asDouble(PRInt64 aValue
,
169 *_result
= double(aValue
);
179 struct variant_traits
<double>
181 static inline PRUint16
type() { return nsIDataType::VTYPE_DOUBLE
; }
184 struct variant_float_traits
<double>
186 static inline nsresult
asDouble(double aValue
,
199 struct variant_traits
<nsString
>
201 static inline PRUint16
type() { return nsIDataType::VTYPE_ASTRING
; }
204 struct variant_storage_traits
<nsString
>
206 typedef const nsAString
& ConstructorType
;
207 typedef nsString StorageType
;
208 static inline StorageType
storage_conversion(ConstructorType aText
)
210 return StorageType(aText
);
214 struct variant_text_traits
<nsString
>
216 static inline nsresult
asUTF8String(const nsString
&aValue
,
219 CopyUTF16toUTF8(aValue
, _result
);
222 static inline nsresult
asString(const nsString
&aValue
,
231 struct variant_traits
<nsCString
>
233 static inline PRUint16
type() { return nsIDataType::VTYPE_UTF8STRING
; }
236 struct variant_storage_traits
<nsCString
>
238 typedef const nsACString
& ConstructorType
;
239 typedef nsCString StorageType
;
240 static inline StorageType
storage_conversion(ConstructorType aText
)
242 return StorageType(aText
);
246 struct variant_text_traits
<nsCString
>
248 static inline nsresult
asUTF8String(const nsCString
&aValue
,
254 static inline nsresult
asString(const nsCString
&aValue
,
257 CopyUTF8toUTF16(aValue
, _result
);
267 struct variant_traits
<PRUint8
[]>
269 static inline PRUint16
type() { return nsIDataType::VTYPE_ARRAY
; }
272 struct variant_storage_traits
<PRUint8
[]>
274 typedef std::pair
<const void *, int> ConstructorType
;
275 typedef nsTArray
<PRUint8
> StorageType
;
276 static inline StorageType
storage_conversion(ConstructorType aBlob
)
278 nsTArray
<PRUint8
> data(aBlob
.second
);
279 (void)data
.AppendElements(static_cast<const PRUint8
*>(aBlob
.first
),
285 struct variant_blob_traits
<PRUint8
[]>
287 static inline nsresult
asArray(nsTArray
<PRUint8
> &aData
,
292 // For empty blobs, we return nsnull.
293 if (aData
.Length() == 0) {
295 *_type
= nsIDataType::VTYPE_UINT8
;
300 // Otherwise, we copy the array.
301 *_result
= nsMemory::Clone(aData
.Elements(), aData
.Length() * sizeof(PRUint8
));
302 NS_ENSURE_TRUE(*_result
, NS_ERROR_OUT_OF_MEMORY
);
305 *_type
= nsIDataType::VTYPE_UINT8
;
306 *_size
= aData
.Length();
315 class NullVariant
: public Variant_base
318 NS_IMETHOD
GetDataType(PRUint16
*_type
)
320 NS_ENSURE_ARG_POINTER(_type
);
321 *_type
= nsIDataType::VTYPE_EMPTY
;
325 NS_IMETHOD
GetAsAUTF8String(nsACString
&_str
)
327 // Return a void string.
329 _str
.SetIsVoid(PR_TRUE
);
333 NS_IMETHOD
GetAsAString(nsAString
&_str
)
335 // Return a void string.
337 _str
.SetIsVoid(PR_TRUE
);
342 ////////////////////////////////////////////////////////////////////////////////
343 //// Template Implementation
345 template <typename DataType
>
346 class Variant
: public Variant_base
349 Variant(typename variant_storage_traits
<DataType
>::ConstructorType aData
)
350 : mData(variant_storage_traits
<DataType
>::storage_conversion(aData
))
354 NS_IMETHOD
GetDataType(PRUint16
*_type
)
356 *_type
= variant_traits
<DataType
>::type();
359 NS_IMETHOD
GetAsInt32(PRInt32
*_integer
)
361 return variant_integer_traits
<DataType
>::asInt32(mData
, _integer
);
364 NS_IMETHOD
GetAsInt64(PRInt64
*_integer
)
366 return variant_integer_traits
<DataType
>::asInt64(mData
, _integer
);
369 NS_IMETHOD
GetAsDouble(double *_double
)
371 return variant_float_traits
<DataType
>::asDouble(mData
, _double
);
374 NS_IMETHOD
GetAsAUTF8String(nsACString
&_str
)
376 return variant_text_traits
<DataType
>::asUTF8String(mData
, _str
);
379 NS_IMETHOD
GetAsAString(nsAString
&_str
)
381 return variant_text_traits
<DataType
>::asString(mData
, _str
);
384 NS_IMETHOD
GetAsArray(PRUint16
*_type
,
389 return variant_blob_traits
<DataType
>::asArray(mData
, _type
, _size
, _data
);
393 typename variant_storage_traits
<DataType
>::StorageType mData
;
396 ////////////////////////////////////////////////////////////////////////////////
397 //// Handy typedefs! Use these for the right mapping.
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
;
405 } // namespace storage
406 } // namespace mozilla
408 #include "Variant_inl.h"
410 #endif // mozilla_storage_Variant_h__