1 /*
2  Copyright 2010 Sun Microsystems, Inc.
3  All rights reserved. Use is subject to license terms.
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License, version 2.0,
7  as published by the Free Software Foundation.
8 
9  This program is also distributed with certain software (including
10  but not limited to OpenSSL) that is licensed under separate terms,
11  as designated in a particular file or component or in included license
12  documentation.  The authors of MySQL hereby grant you an additional
13  permission to link the program and your derivative works with the
14  separately licensed software that they have included with MySQL.
15 
16  This program is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  GNU General Public License, version 2.0, for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with this program; if not, write to the Free Software
23  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
24 */
25 /*
26  * jtie_tconv_value_impl.hpp
27  */
28 
29 #ifndef jtie_tconv_value_impl_hpp
30 #define jtie_tconv_value_impl_hpp
31 
32 #include <assert.h> // not using namespaces yet
33 #include <jni.h>
34 
35 #include "jtie_tconv_value.hpp"
36 #include "jtie_tconv_impl.hpp"
37 #include "helpers.hpp"
38 
39 // ---------------------------------------------------------------------------
40 // Java <-> C basic type conversions
41 // ---------------------------------------------------------------------------
42 
43 // Implements primitive type parameter conversions.
44 template< typename J, typename C >
45 struct ParamBasicT {
46     static C
convertParamBasicT47     convert(cstatus & s, J j, JNIEnv * env) {
48         TRACE("C ParamBasicT.convert(cstatus &, J, JNIEnv *)");
49         (void)env;
50         s = 0;
51         // XXX assert(static_cast< J >(static_cast< C >(j)) == j);
52         return static_cast< C >(j); // may convert to unsigned type
53     }
54 
55     static void
releaseParamBasicT56     release(C c, J j, JNIEnv * env) {
57         TRACE("void ParamBasicT.release(C, J, JNIEnv *)");
58         (void)c; (void)j; (void)env;
59     }
60 
61 private:
62     // prohibit instantiation
ParamBasicTParamBasicT63     ParamBasicT() {
64         // prohibit unsupported template specializations
65         is_valid_primitive_type_mapping< J, C >();
66     }
67 };
68 
69 // Implements primitive type result conversions.
70 template< typename J, typename C >
71 struct ResultBasicT {
72     static J
convertResultBasicT73     convert(C c, JNIEnv * env) {
74         TRACE("J ResultBasicT.convert(C, JNIEnv *)");
75         (void)env;
76         // XXX assert(static_cast< C >(static_cast< J >(c)) == c);
77         return static_cast< J >(c); // may convert to signed type
78     }
79 
80 private:
81     // prohibit instantiation
ResultBasicTResultBasicT82     ResultBasicT() {
83         // prohibit unsupported template specializations
84         is_valid_primitive_type_mapping< J, C >();
85     }
86 };
87 
88 // ---------------------------------------------------------------------------
89 // Specializations for basic type conversions
90 // ---------------------------------------------------------------------------
91 
92 // Avoid mapping types by broad, generic rules, which easily results in
93 // template instantiation ambiguities for non-primitive types.  Therefore,
94 // we enumerate all specicializations for primitive types.
95 
96 // Lessons learned:
97 //
98 // Cannot extend Param/Result specializations for const types by a generic
99 // rule on the base class (no template match with this indirection)
100 //   template<> struct ParamBasicT< J, C const > : ParamBasicT< J, C > {};
101 //   template<> struct ResultBasicT< J, C const > : ResultBasicT< J, C > {};
102 // but have to specialize Param/Result directly
103 //   template<> struct Param< J, C const > : ParamBasicT< J, C > {};
104 //   template<> struct Result< J, C const > : ResultBasicT< J, C > {};
105 //
106 // Specializations must be defined over intrinsic types, not aliases
107 //
108 // Datatype     LP64    ILP64   LLP64   ILP32   LP32
109 // char         8       8       8       8       8
110 // short        16      16      16      16      16
111 // int          32      64      32      32      16
112 // long         64      64      32      32      32
113 // long long                    64
114 // pointer      64      64      64      32      32
115 
116 // extend set of valid primitive type mappings for const value specializations
117 template < typename J, typename C >
118 struct is_valid_primitive_type_mapping< const J, C > {};
119 template < typename J, typename C >
120 struct is_valid_primitive_type_mapping< J, const C > {};
121 template < typename J, typename C >
122 struct is_valid_primitive_type_mapping< const J, const C > {};
123 
124 // also provides specializations for 'const'
125 // template clutter can be reduced a bit: const value types do not need extra
126 // specializations of their implementation
127 //   ... : ParamBasicT< J, C const > {};
128 //   ... : ResultBasicT< J, C const > {};
129 // but can be derived from their non-const specializations
130 #define JTIE_SPECIALIZE_BASIC_TYPE_MAPPING( J, C )                      \
131     template<> struct is_valid_primitive_type_mapping< J, C > {};       \
132     template<> struct Param< J, C > : ParamBasicT< J, C > {};           \
133     template<> struct Result< J, C > : ResultBasicT< J, C > {};         \
134     template<> struct Param< J, C const > : ParamBasicT< J, C > {};     \
135     template<> struct Result< J, C const > : ResultBasicT< J, C > {};
136 
137 // ---------------------------------------------------------------------------
138 // Specializations for boolean conversions
139 // ---------------------------------------------------------------------------
140 
141 // Implements boolean type parameter conversions.
142 template<>
143 struct ParamBasicT< jboolean, bool > {
144     static bool
convertParamBasicT145     convert(cstatus & s, jboolean j, JNIEnv * env) {
146         TRACE("bool ParamBasicT.convert(cstatus &, jboolean, JNIEnv *)");
147         (void)env;
148         s = 0;
149         // Java v C: jboolean is unsigned 8-bit, so, beware of truncation
150         return (j == JNI_TRUE);
151     }
152 
153     static void
releaseParamBasicT154     release(bool c, jboolean j, JNIEnv * env) {
155         TRACE("void ParamBasicT.release(bool, jboolean, JNIEnv *)");
156         (void)c; (void)j; (void)env;
157     }
158 };
159 
160 // Implements boolean type result conversions.
161 template<>
162 struct ResultBasicT< jboolean, bool > {
163     static jboolean
convertResultBasicT164     convert(bool c, JNIEnv * env) {
165         TRACE("jboolean ResultBasicT.convert(bool, JNIEnv *)");
166         (void)env;
167         // Java v C: jboolean is unsigned 8-bit, so, beware of truncation
168         // on some platforms, JNI_TRUE/FALSE seems top be defined as int
169         return static_cast< jboolean >(c ? JNI_TRUE : JNI_FALSE);
170     }
171 };
172 
173 JTIE_SPECIALIZE_BASIC_TYPE_MAPPING(jboolean, bool)
174 
175 // ---------------------------------------------------------------------------
176 // Specializations for exact-width number type conversions
177 // ---------------------------------------------------------------------------
178 
179 JTIE_SPECIALIZE_BASIC_TYPE_MAPPING(jbyte, char)
180 JTIE_SPECIALIZE_BASIC_TYPE_MAPPING(jbyte, signed char)
181 JTIE_SPECIALIZE_BASIC_TYPE_MAPPING(jbyte, unsigned char)
182 
183 JTIE_SPECIALIZE_BASIC_TYPE_MAPPING(jfloat, float)
184 JTIE_SPECIALIZE_BASIC_TYPE_MAPPING(jdouble, double)
185 
186 // ---------------------------------------------------------------------------
187 // Specializations for variable-width number type conversions
188 // ---------------------------------------------------------------------------
189 
190 // Datatype      LP32   ILP32   LP64    ILP64   LLP64
191 // char          8      8       8       8       8
192 // short         16     16      16      16      16
193 // int           16     32      32      64      32
194 // long          32     32      64      64      32
195 // long long                                    64
196 // pointer       32     32      64      64      64
197 
198 // jshort in LP32, ILP32, LP64, ILP64, LLP64
199 JTIE_SPECIALIZE_BASIC_TYPE_MAPPING(jshort, signed short)
200 JTIE_SPECIALIZE_BASIC_TYPE_MAPPING(jshort, unsigned short)
201 
202 // jshort in LP32
203 JTIE_SPECIALIZE_BASIC_TYPE_MAPPING(jshort, signed int)
204 JTIE_SPECIALIZE_BASIC_TYPE_MAPPING(jshort, unsigned int)
205 
206 // jint in ILP32, LP64, LLP64
207 JTIE_SPECIALIZE_BASIC_TYPE_MAPPING(jint, signed int)
208 JTIE_SPECIALIZE_BASIC_TYPE_MAPPING(jint, unsigned int)
209 
210 // jint in LP32, ILP32, LLP64
211 JTIE_SPECIALIZE_BASIC_TYPE_MAPPING(jint, signed long)
212 JTIE_SPECIALIZE_BASIC_TYPE_MAPPING(jint, unsigned long)
213 
214 // jlong in ILP64
215 JTIE_SPECIALIZE_BASIC_TYPE_MAPPING(jlong, signed int)
216 JTIE_SPECIALIZE_BASIC_TYPE_MAPPING(jlong, unsigned int)
217 
218 // jlong in LP64, ILP64
219 JTIE_SPECIALIZE_BASIC_TYPE_MAPPING(jlong, signed long)
220 JTIE_SPECIALIZE_BASIC_TYPE_MAPPING(jlong, unsigned long)
221 
222 // jlong in LLP64
223 JTIE_SPECIALIZE_BASIC_TYPE_MAPPING(jlong, signed long long)
224 JTIE_SPECIALIZE_BASIC_TYPE_MAPPING(jlong, unsigned long long)
225 
226 // jdouble
227 JTIE_SPECIALIZE_BASIC_TYPE_MAPPING(jdouble, long double)
228 
229 // ---------------------------------------------------------------------------
230 
231 #endif // jtie_tconv_value_impl_hpp
232