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