Classdesc 3.44
javaClass_base.h
Go to the documentation of this file.
1/*
2 @copyright Russell Standish 2000-2013
3 @author Russell Standish
4 This file is part of Classdesc
5
6 Open source licensed under the MIT license. See LICENSE for details.
7*/
8
14#ifndef CLASSDESC_JAVACLASS_BASE_H
15#define CLASSDESC_JAVACLASS_BASE_H
16
17#include "javaClass.h"
18#include "javaClassDescriptor.h"
19#include "object.h"
20#include "poly.h"
21#include <memory>
22#include <jni.h>
23
24// for debugging use
25//namespace std
26//{
27// template <class T, class C, class traits>
28// basic_ostream<C,traits>& operator<<(basic_ostream<C,traits>& o, const T& x)
29// {o<<"<unknown type>"; return o;}
30//}
31
32namespace classdesc
33{
34 template <class T> const char* javaClassName();
35 template <> inline const char* javaClassName<int>() {return "java/lang/Integer";}
36 template <> inline const char* javaClassName<float>() {return "java/lang/Float";}
37
38 template <class T> T getJavaVal(JNIEnv *env, jobject o);
39 template <> inline int getJavaVal<int>(JNIEnv *env, jobject o) {
40 return env->CallIntMethod(o,
41 env->GetMethodID(env->GetObjectClass(o), "intValue", "()I"));
42 }
43 template <> inline float getJavaVal<float>(JNIEnv *env, jobject o) {
44 return env->CallFloatMethod(o,
45 env->GetMethodID(env->GetObjectClass(o), "floatValue", "()F"));
46 }
47 template <> inline std::string getJavaVal<std::string>(JNIEnv *env,jobject o)
48 {
49 return std::string(env->GetStringUTFChars(static_cast<jstring>(o),NULL));
50 }
51
52 template <class T> T getJavaVal(jvalue v);
53 template <> inline bool getJavaVal<bool>(jvalue v) {return v.z;}
54 template <> inline char getJavaVal<char>(jvalue v) {return v.b;}
55 template <> inline unsigned short getJavaVal<unsigned short>(jvalue v) {return v.c;}
56 template <> inline short getJavaVal<short>(jvalue v) {return v.s;}
57 template <> inline int getJavaVal<int>(jvalue v) {return v.i;}
58 template <> inline long getJavaVal<long>(jvalue v) {return v.j;}
59 template <> inline float getJavaVal<float>(jvalue v) {return v.f;}
60 template <> inline double getJavaVal<double>(jvalue v) {return v.d;}
61
63 struct ArgRef_base: virtual public object //Object<ArgRef_base,0>
64 {
65 virtual jobject get_jobject(JNIEnv *env) const=0;
66 virtual jint get_jint(JNIEnv *env) const {return 0;}
67 virtual jfloat get_jfloat(JNIEnv *env) const {return 0;}
68 virtual ~ArgRef_base() {};
69 };
70
76 template <class T>
77 class ArgRef: virtual public Object<ArgRef<T>,ArgRef_base>
78 {
79 T value;
80 friend class RetRef;
81 public:
82 ArgRef() {}
83 ArgRef(const T& x): value(x) {}
84 jobject get_jobject(JNIEnv *env) const {
85 jclass clss=env->FindClass(javaClassName<T>());
86 return env->NewObject(clss,
87 env->GetMethodID(
88 clss,"<init>",
89 (std::string("(")+descriptor<T>()+")V").c_str()),
90 value);
91 }
92 jint get_jint(JNIEnv *env) const {return jint(value);}
93 jfloat get_jfloat(JNIEnv *env) const {return jfloat(value);}
94
95 T* getRef() {return &value;}
96 };
97
98 template <>
99 class ArgRef<void>: virtual public Object<ArgRef<void>,ArgRef_base>
100 {
101 public:
102 jobject get_jobject(JNIEnv *env) const {return NULL;}
103 void* getRef() {return NULL;}
104 };
105}
106#ifdef _CLASSDESC
107#pragma omit pack classdesc::ArgRef
108#pragma omit unpack classdesc::ArgRef
109#pragma omit javaClass classdesc::ArgRef
110#pragma omit javaClass classdesc::ArgRef_base
111#endif
112
113namespace classdesc_access
114{
115 //no sensible serialisation for this
116 template <class T>
117 struct access_pack<classdesc::ArgRef<T> >:
118 public classdesc::NullDescriptor<classdesc::pack_t> {};
119
120 template <class T>
121 struct access_unpack<classdesc::ArgRef<T> >:
122 public classdesc::NullDescriptor<classdesc::unpack_t> {};
123}
124
125namespace classdesc
126{
127 //utility class for casting jobjects into C++ types
128 class Arg
129 {
130 JNIEnv *env;
131 jvalue val;
132 bool is_jobject;
133 public:
134
135 Arg(): env(NULL), is_jobject(true) {val.l=NULL;}
136 Arg(JNIEnv *env, jobject object): env(env), is_jobject(true) {val.l=object;}
137 // Arg(JNIEnv *env, jboolean v): env(env), is_jobject(false) {val.z=v;}
138 Arg(JNIEnv *env, jbyte v): env(env), is_jobject(false) {val.b=v;}
139 Arg(JNIEnv *env, jchar v): env(env), is_jobject(false) {val.c=v;}
140 Arg(JNIEnv *env, jint v): env(env), is_jobject(false) {val.i=v;}
141 Arg(JNIEnv *env, jlong v): env(env), is_jobject(false) {val.j=v;}
142 Arg(JNIEnv *env, jfloat v): env(env), is_jobject(false) {val.f=v;}
143 Arg(JNIEnv *env, jdouble v): env(env), is_jobject(false) {val.d=v;}
144
145 template <class T> T get() const {
146 if (is_jobject)
147 return getJavaVal<T>(env,val.l);
148 else
149 return getJavaVal<T>(val);
150 }
151
152 //TODO: factor out get<T>()
153 operator float() {return get<float>();}
154 operator int() {return get<int>();}
155 operator std::string() {return get<std::string>();}
156
157 //TODO: handle reference arguments
158 };
159
161 class RetVal: public poly<ArgRef_base>
162 {
163 public:
164 template <class T> T* getRef() {
166 return cast<ArgRef<T> >().getRef();
167 }
168 };
169
171 template <class Jtype>
172 struct JNItype
173 {
174 template <class CppType>
175 static Jtype from(JNIEnv *env, const CppType& x) {return JNItype(x);}
176 };
177
180 template <>
181 struct JNItype<jobject>
182 {
183 template <class CppType>
184 static jobject from(JNIEnv *env, const CppType& x)
185 {
186 jclass cls=env->FindClass("ConcreteCppObject");
187 jmethodID constructor=env->GetMethodID(cls,"<init>","()V");
188 jobject obj=env->NewObject(cls,constructor);
189 jfieldID fld=env->GetFieldID(cls,"register","Ljava/lang/Object;");
190 env->SetObjectField(obj,fld,reinterpret_cast<jobject>(new CppType(x)));
191 return obj;
192 }
193 template <class CppType>
194 static jobject from(JNIEnv *env, CppType& x)
195 {
196 jclass cls=env->FindClass("ConcreteCppObject");
197 jmethodID constructor=env->GetMethodID(cls,"<init>","()V");
198 jobject obj=env->NewObject(cls,constructor);
199 jfieldID fld=env->GetFieldID(cls,"register","Ljava/lang/Object;");
200 env->SetObjectField(obj,fld,reinterpret_cast<jobject>(&x));
201 return obj;
202 }
203 };
204
206 template <>
207 struct JNItype<jstring>
208 {
209 static jstring from(JNIEnv *env, const char* x)
210 {
211 std::vector<jchar> tmp(x, x+strlen(x));
212 return env->NewString(tmp.data(), strlen(x));
213 }
214 static jstring from(JNIEnv *env, const std::string& x)
215 {
216 return from(env, x.c_str());
217 }
218 };
219}
220
221#ifdef _CLASSDESC
222#pragma omit pack classdesc::Arg
223#pragma omit unpack classdesc::Arg
224#endif
225
226namespace classdesc_access
227{
228 //no sensible serialisation for this
229 template <>
231 {
232 void operator()(classdesc::pack_t& t, const classdesc::string& d, classdesc::Arg& a) {}
233 };
234
235 template <>
237 {
238 void operator()(classdesc::pack_t& t, const classdesc::string& d, classdesc::Arg& a) {}
239 };
240}
241
242namespace classdesc
243{
248 class ArgVector: public std::vector<Arg>
249 {
250 public:
251 ArgVector(size_t n=0): std::vector<Arg>(n) {}
252 ArgVector(JNIEnv* env, jobjectArray& args)
253 {
254 for (size_t i=0; args && i<size_t(env->GetArrayLength(args)); ++i)
255 push_back(classdesc::Arg(env, env->GetObjectArrayElement(args,i)));
256 }
257 };
258
260 {
261 virtual void operator()(RetVal& ret, ArgVector& args)=0;
262 };
263
264 typedef poly<Functional_base> Functional_ptr;
265
270 template <class F>
271 class Functional: public Object<Functional<F>, Functional_base>
272 {
273 F f;
274public:
275 Functional(const F& f): f(f) {}
276 void operator()(RetVal& r, ArgVector& args) {
277 apply(r.getRef<typename functional::Return<F>::T>(), f, args);}
278 };
279}
280
281#ifdef _CLASSDESC
282#pragma omit pack classdesc::Functional
283#pragma omit unpack classdesc::Functional
284#endif
285
286namespace classdesc_access
287{
288 //no sensible serialisation for this
289 template <class F>
290 struct access_pack<classdesc::Functional<F> >:
291 public classdesc::NullDescriptor<classdesc::pack_t> {};
292
293 template <class F>
294 struct access_unpack<classdesc::Functional<F> >:
295 public classdesc::NullDescriptor<classdesc::unpack_t> {};
296
297}
298
299namespace classdesc
300{
301 struct javaClass_t: public ClassFile
302 {
303 javaClass_t() {magic=0xCAFEBABE; minor_version=0; major_version=50;}
304 // add a functor to the method database
305 virtual void add_functor(const std::string& name, Functional_ptr f,
306 const std::string& sig)
307 {}
308 };
309
310#ifdef _CLASSDESC
311#pragma omit javaClass classdesc::javaClass_t
312#endif
313
314 template <class C, class M>
316 javaClass(javaClass_t& cl, const string& desc, C& obj, M mem)
317 {
318 using namespace classdesc;
319 std::string method_name(desc);
320 if (method_name.find('.')!=std::string::npos)
321 method_name=method_name.substr(method_name.rfind('.')+1);
322 cl.addMethod(method_name, descriptor<M>());
323// cl.addMethod(method_name, std::string("([Ljava/lang/Object;)")+
324// descriptor<typename functional::Return<M>::T>());
325 cl.add_functor(std::string(desc),
326 Functional_ptr().addObject<Functional<
329 descriptor<M>()
330 );
331 }
332
333 template <class T, class B>
334 void javaClass(javaClass_t& cl, const string& desc, Object<T,B>& obj)
335 {
336 //TODO: maybe we want to add some default object properties here
337 }
338
339 template <class T>
340 class getter_setter: public Object<getter_setter<T>,Functional_base>
341 {
342 T& m;
343 public:
344 getter_setter(T& m): m(m) {}
345 void operator()(RetVal& r, ArgVector& args) {
346 if (args.size()) m=args[0].get<T>();
347 *r.getRef<T>()=m;
348 }
349 };
350}
351
352#ifdef _CLASSDESC
353#pragma omit pack classdesc::getter_setter
354#pragma omit unpack classdesc::getter_setter
355#pragma omit javaClass classdesc::object
356#pragma omit javaClass classdesc::Object
357#endif
358
359namespace classdesc_access
360{
361 //no sensible serialisation for this
362 template <class F>
364 classdesc::NullDescriptor<classdesc::pack_t> {};
365
366 template <class F>
368 classdesc::NullDescriptor<classdesc::unpack_t> {};
369}
370
371namespace classdesc
372{
373 // handle data members
374 template <class T>
375 typename enable_if<is_fundamental<T>, void>::T
376 javaClass(javaClass_t& cl, const string& desc, T& obj, dummy<1> d=0)
377 {
378 std::string desc1(desc), ivar_name, class_name;
379 std::string::size_type last_dot=desc1.rfind('.');
380
381 if (last_dot==std::string::npos)
382 ivar_name=desc1;
383 else
384 {
385 ivar_name=desc1.substr(last_dot+1);
386 class_name=desc1.substr(0,last_dot);
387 }
388 cl.addMethod(ivar_name, classdesc::descriptor<T (*)(T)>());
389 cl.add_functor(desc1, getter_setter<T>(obj), descriptor<T (*)(T)>());
390
391 //capitalise for java getter/setter conventions
392 ivar_name[0]=toupper(ivar_name[0]);
393 cl.addMethod(std::string("get")+ivar_name, descriptor<T (*)()>());
394 cl.add_functor(class_name+".get"+ivar_name, getter_setter<T>(obj), descriptor<T (*)()>());
395 cl.addMethod(std::string("set")+ivar_name, descriptor<void (*)(T)>());
396 cl.add_functor(class_name+".set"+ivar_name, getter_setter<T>(obj), descriptor<void (*)(T)>());
397}
398
399 // helper class to indicate specific javaClass not provided in this file
400 template <class T>
401 struct is_leftOver {static const bool value=!is_fundamental<T>::value;};
402
403 template <class T>
404 typename enable_if< is_leftOver<T>, void>::T
405 javaClass(javaClass_t& cl, const string& desc, T& arg, dummy<0> d=0);
406
407 template <class T>
408 void javaClass(javaClass_t& cl,const string& d, const T& a)
409 {javaClass(cl,d,const_cast<T&>(a));}
410
411 template <class T>
412 void javaClass(javaClass_t& cl,const string& d, is_const_static i, T a)
413 {
414 T tmp(a);
415 javaClass(cl,d,tmp);
416 }
417
418 template <class T>
419 void javaClass_type(javaClass_t& cl,const string& d, is_const_static i, T a)
420 {
421 }
422
423 template <class T>
424 void javaClass_onbase(javaClass_t& cl,const string& d,T a)
425 {javaClass(cl,d,a);}
426
427
428
429}
430 // const members, just discard constness as we're just doing descriptors
431// template <class C, class R>
432// void javaClass(javaClass_t& cl, const string& desc, C& obj, R (C::*mem)() const)
433// {
434// typedef R (C::*NonConstMember)();
435// javaClass(cl,desc,obj,NonConstMember(0));
436// }
437
438// template <class C, class R>
439// void javaClass(javaClass_t& cl, const string& desc, C& obj, R (C::*mem)())
440// {
441// method_info mi;
442// mi.access_flags=JVM_ACC_PUBLIC;
443// mi.name_index=cl->constant_pool.size();
444// cl->constant_pool.push_back(
445// cp_info(JVM_CONSTANT_Utf8, std::string(desc)));
446// mi.descriptor_index=cl->constant_pool.size();
447// cl->constant_pool.push_back(
448// cp_info(JVM_CONSTANT_Utf8, descriptor<R (C::*)()>()));
449// cl->methods.push_back(mi);
450// }
451
452 //ignore anything we don't know
453namespace classdesc_access
454{
455 template <class T> struct access_javaClass
456 {
457 void operator()(classdesc::javaClass_t& cl, const classdesc::string& desc, T& arg) {}
458 };
459}
460
461
462
463using classdesc::javaClass;
464
465#endif
Definition javaClass_base.h:249
Definition javaClass_base.h:129
Definition javaClass_base.h:272
Handle the return value.
Definition javaClass_base.h:162
Definition function.h:84
Definition javaClass_base.h:341
Definition classdesc.h:923
Definition pack_base.h:138
Definition poly.h:44
poly addObject()
Definition poly.h:68
U & cast()
Definition poly.h:85
support for Java signatures
Java classfile representation.
Contains access_* structs, and nothing else. These structs are used to gain access to private members...
Definition classdesc_access.h:20
Contains definitions related to classdesc functionality.
base class for ArgRef
Definition javaClass_base.h:64
void addMethod(const std::string &method_name, const std::string &descriptor)
add a method
Definition javaClass.h:721
Definition javaClass_base.h:260
Convert a C++ type to a Java JNI type.
Definition javaClass_base.h:173
helper for constructing null descriptors
Definition classdesc.h:1106
Definition object.h:77
Definition classdesc.h:299
controlled template specialisation: stolen from boost::enable_if.
Definition classdesc.h:282
Return::T (or ::type) is the return type of F
Definition function.h:45
Definition javaClass_base.h:401
Definition javaClass_base.h:302
Definition object.h:29
Definition javaClass_base.h:456
class to allow access to private members
Definition classdesc_access.h:21
class to allow access to private members
Definition classdesc_access.h:22