1 /*
2  Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License, version 2.0,
6  as published by the Free Software Foundation.
7 
8  This program is also distributed with certain software (including
9  but not limited to OpenSSL) that is licensed under separate terms,
10  as designated in a particular file or component or in included license
11  documentation.  The authors of MySQL hereby grant you an additional
12  permission to link the program and your derivative works with the
13  separately licensed software that they have included with MySQL.
14 
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  GNU General Public License, version 2.0, for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with this program; if not, write to the Free Software
22  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
23 */
24 /*
25  * jtie_tconv_object.hpp
26  */
27 
28 #ifndef jtie_tconv_object_hpp
29 #define jtie_tconv_object_hpp
30 
31 #include <jni.h>
32 
33 #include "jtie_tconv.hpp"
34 #include "jtie_tconv_idcache_impl.hpp"
35 
36 // ---------------------------------------------------------------------------
37 // Java object <-> C class object type conversions
38 // ---------------------------------------------------------------------------
39 
40 /**
41  * A root class representing Java peer classes in type mappings.
42  *
43  * Rationale: A dedicated type, distinct from JNI's _jobject, allows for
44  * better control of template resolution (avoiding ambiguities) and
45  * instantiation (reducing clutter).  To allow for pointer compatibility
46  * by static type conversion, this type derives from _jobject.
47  */
48 struct _jtie_Object : _jobject {
49 };
50 
51 // XXX, document: type specifying an Object mapping with a class name
52 
53 // trait type wrapping named-parametrized Object mappings for specialization
54 // XXX make use of
55 //   JTIE_DEFINE_METHOD_MEMBER_INFO( _jtie_ObjectMapper< T > )
56 // to replace
57 //   static const char * const class_name;
58 //   static const char * const member_name;
59 //   static const char * const member_descriptor;
60 //   typedef _jmethodID * memberID_t;
61 template< typename J >
62 struct _jtie_ObjectMapper : _jtie_Object {
63     // the name of the Java peer class in the JVM format (i.e., '/'-separated)
64     static const char * const class_name;
65 
66     // the name, descriptor, and JNI type of the class's no-arg c'tor
67     static const char * const member_name;
68     static const char * const member_descriptor;
69     typedef _jmethodID * memberID_t;
70 };
71 
72 // XXX static initialization <-> multiple compilation units <-> jtie_lib.hpp
73 template< typename J >
74 const char * const _jtie_ObjectMapper< J >::class_name
75     = J::class_name; // XXX static initialization order dependency?
76 
77 template< typename J >
78 const char * const _jtie_ObjectMapper< J >::member_name
79     = "<init>";
80 
81 template< typename J >
82 const char * const _jtie_ObjectMapper< J >::member_descriptor
83     = "()V";
84 
85 // Design note:
86 //
87 // As of pre-C++0x, string literals cannot be used as template arguments
88 // which must be integral constants with external linkage.
89 //
90 // So, we cannot declare:
91 //
92 //    template< const char * >
93 //    struct _jtie_ClassNamedObject : _jtie_Object {
94 //        static const char * const java_internal_class_name;
95 //    };
96 //
97 // As a feasible workaround, we require the application to provide a
98 // trait type for each class, e.g.
99 //
100 //    struct _m_A : _jobject {
101 //        static const char * const java_internal_class_name;
102 //    };
103 //    const char * const _m_A::java_internal_class_name = "myjapi/A";
104 //
105 // and we retrieve the class name from there.
106 
107 /**
108  * Defines the trait type aliases for the mapping of a
109  * user-defined Java class to a C++ class.
110  *
111  * The macro takes these arguments:
112  *   C: The name of the C++ class to which the Java class is mapped.
113  *   T: A name tag, identifying the Java peer class in this mapping.
114  *
115  * The type aliases with suffix _t or _ct serve the use of the class as
116  * target for [const] member access (field access or method calls); the
117  * aliases ending on _p (pointer) or _r (reference), and their const
118  * variations, allow for use as parameter or result types.
119  *
120  * Naming convention:
121  *   type alias:                specifies a mapping:
122  *   ttrait_<T>_t               J <->       C
123  *   ttrait_<T>_ct              J <-> const C
124  *   ttrait_<T>_r               J <->       C &
125  *   ttrait_<T>_cr              J <-> const C &
126  *   ttrait_<T>_p               J <->       C *
127  *   ttrait_<T>_cp              J <-> const C *
128  *   ttrait_<T>_pc              J <->       C * const
129  *   ttrait_<T>_cpc             J <-> const C * const
130  *
131  * Implementation note: Using a macro instead of a class template with
132  * type members (via typedefs) has the benefit of allowing for direct
133  * use of the defined type names, while each use of a type member needs
134  * to be prepended with the C++ keyword "typename".
135  */
136 #define JTIE_DEFINE_PEER_CLASS_MAPPING( C, T )                          \
137     struct T {                                                          \
138         static const char * const class_name;                           \
139     };                                                                  \
140     typedef ttrait< jobject, C, _jtie_ObjectMapper< T > *               \
141                     > ttrait_##T##_t;                                   \
142     typedef ttrait< jobject, const C, _jtie_ObjectMapper< T > *         \
143                     > ttrait_##T##_ct;                                  \
144     typedef ttrait< jobject, C &, _jtie_ObjectMapper< T > *             \
145                     > ttrait_##T##_r;                                   \
146     typedef ttrait< jobject, const C &, _jtie_ObjectMapper< T > *       \
147                     > ttrait_##T##_cr;                                  \
148     typedef ttrait< jobject, C *, _jtie_ObjectMapper< T > *             \
149                     > ttrait_##T##_p;                                   \
150     typedef ttrait< jobject, const C *, _jtie_ObjectMapper< T > *       \
151                     > ttrait_##T##_cp;                                  \
152     typedef ttrait< jobject, C * const, _jtie_ObjectMapper< T > *       \
153                     > ttrait_##T##_pc;                                  \
154     typedef ttrait< jobject, const C * const, _jtie_ObjectMapper< T > * \
155                     > ttrait_##T##_cpc;
156 
157 #if 0 // XXX cleanup this unsupported mapping
158 
159  * Naming convention:
160  *   type alias:                specifies a mapping:
161  *   ttrait_<T>_a               J <->       C *
162  *   ttrait_<T>_ca              J <-> const C *
163  *   ttrait_<T>_ac              J <->       C * const
164  *   ttrait_<T>_cac             J <-> const C * const
165 
166 /**
167  * Defines the trait type aliases for the mapping of a
168  * Java array to a C++ pointer.
169  *
170  * The macro takes these arguments:
171  *   J: A JNI array type name (representing a basic Java array type).
172  *   C: A basic C++ type name.
173  *   T: A name tag for this mapping.
174  *
175  * Naming convention:
176  *   type alias:                specifies a mapping:
177  *   ttrait_<T>_0p_a            J <->       C *       (of unspecified length)
178  *   ttrait_<T>_0cp_a           J <-> const C *       (of unspecified length)
179  *   ttrait_<T>_0pc_a           J <->       C * const (of unspecified length)
180  *   ttrait_<T>_0cpc_a          J <-> const C * const (of unspecified length)
181  */
182 #define JTIE_DEFINE_ARRAY_PTR_TYPE_MAPPING( J, C, T )                   \
183     typedef ttrait< J *, C *                                            \
184                     > ttrait_##T##_0p_a;                                \
185     typedef ttrait< J *, const C *                                      \
186                     > ttrait_##T##_0cp_a;                               \
187     typedef ttrait< J *, C * const                                      \
188                     > ttrait_##T##_0pc_a;                               \
189     typedef ttrait< J *, const C * const                                \
190                     > ttrait_##T##_0cpc_a;
191 
192 /**
193  * Defines the trait type aliases for the mapping of a
194  * Java array to a C++ array.
195  *
196  * The macro takes these arguments:
197  *   J: A JNI array type name (representing a basic Java array type).
198  *   C: A basic C++ type name.
199  *   T: A name tag for this mapping.
200  *
201  * Naming convention:
202  *   type alias:                specifies a mapping:
203  *   ttrait_<T>_1p_a            J <->       C *       (of array length 1)
204  *   ttrait_<T>_1cp_a           J <-> const C *       (of array length 1)
205  *   ttrait_<T>_1pc_a           J <->       C * const (of array length 1)
206  *   ttrait_<T>_1cpc_a          J <-> const C * const (of array length 1)
207  */
208 #define JTIE_DEFINE_ARRAY_PTR_LENGTH1_TYPE_MAPPING( J, C, T )           \
209     typedef ttrait< J *, C *, _jtie_j_ArrayMapper< _jtie_j_BoundedArray< J, 1 > > * \
210                     > ttrait_##T##_1p_a;                                \
211     typedef ttrait< J *, const C *, _jtie_j_ArrayMapper< _jtie_j_BoundedArray< J, 1 > > * \
212                     > ttrait_##T##_1cp_a;                               \
213     typedef ttrait< J *, C * const, _jtie_j_ArrayMapper< _jtie_j_BoundedArray< J, 1 > > * \
214                     > ttrait_##T##_1pc_a;                               \
215     typedef ttrait< J *, const C * const, _jtie_j_ArrayMapper< _jtie_j_BoundedArray< J, 1 > > * \
216                     > ttrait_##T##_1cpc_a;
217 
218 // XXX and this is how it's done
219     typedef ttrait< jobjectArray, C *,                                  \
220                     _jtie_j_ArrayMapper<                                \
221                       _jtie_j_BoundedArray<                             \
222                         _jtie_ObjectMapper< J >,                        \
223                         1 >                                             \
224                       > *                                               \
225                     > ttrait_##J##_1a;                                  \
226 
227 #endif // XXX cleanup this unsupported mapping
228 
229 // XXX to document
230 // XXX static initialization <-> multiple compilation units <-> jtie_lib.hpp
231 // XXX replace
232 //   template struct MemberId< _jtie_ObjectMapper< T > >;
233 //   template struct MemberIdCache< _jtie_ObjectMapper< T > >;
234 // with
235 //   JTIE_INSTANTIATE_CLASS_MEMBER_INFO_X(_jtie_ObjectMapper< T >,
236 //                                        JCN, "<init>", "()V")
237 #define JTIE_INSTANTIATE_PEER_CLASS_MAPPING( T, JCN )           \
238     const char * const T::class_name = JCN;                     \
239     template struct _jtie_ObjectMapper< T >;                    \
240     template struct MemberId< _jtie_ObjectMapper< T > >;        \
241     template struct MemberIdCache< _jtie_ObjectMapper< T > >;
242 
243 // ---------------------------------------------------------------------------
244 
245 #endif // jtie_tconv_object_hpp
246