blob: fe9767b0e11e0dfb8e111ba0b99fce6f66dbdb5c [file] [log] [blame]
Robert Varga81d99ac2016-01-30 18:30:36 +01001/*
2 * Copyright (c) 2016 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16/*
17 * Utilities for accessing Java classes/method/fields in an efficient
18 * manner.
19 */
20
21/*
22 * A potentially-uninitialized reference to a Java class
23 */
24typedef struct vppjni_class {
25 // Fully-Qualified Class Name
26 const char *fqcn;
27 // Constructor signature
28 const char *init_sig;
29 // Global reference to class handle
30 jclass jclass;
31 // Constructor method handle
32 jmethodID jinit;
33 // Next item in linked list
34 struct vppjni_class *next;
35} vppjni_class_t;
36
37typedef struct jenv_field {
38 // Field name
39 const char *name;
40 // Field type
41 const char *type;
42 // Defining class reference
43 const vppjni_class_t *clsref;
44 // Field handle
45 jfieldID jfield;
46 // Next item in linked list
47 struct jenv_field *next;
48} vppjni_field_t;
49
50#define VPPJNI_CLASS_SYMBOL(name) vppjni_class_##name
51#define VPPJNI_CLASS_INIT(name) vppjni_class_##name##_init
52#define BIND_JAPI_CLASS(name, sig) \
53 static vppjni_class_t VPPJNI_CLASS_SYMBOL(name); \
54 static void VPPJNI_CLASS_INIT(name)(void) __attribute__((__constructor__)); \
55 static void VPPJNI_CLASS_INIT(name)() \
56 { \
57 VPPJNI_CLASS_SYMBOL(name).fqcn = "org/openvpp/vppjapi/" #name; \
58 VPPJNI_CLASS_SYMBOL(name).init_sig = sig; \
59 vppjni_register_class(&VPPJNI_CLASS_SYMBOL(name)); \
60 } \
61 static __attribute__((unused)) jobject name##Array(JNIEnv *env, jsize length) \
62 { \
63 return (*env)->NewObjectArray(env, length, VPPJNI_CLASS_SYMBOL(name).jclass, NULL); \
64 } \
65 static jobject name##Object(JNIEnv *env, ...) \
66 { \
67 va_list ap; \
68 va_start(ap, env); \
69 jobject obj = vppjni_new_object(env, &VPPJNI_CLASS_SYMBOL(name), ap); \
70 va_end(ap); \
71 return obj; \
72 }
73
74#define VPPJNI_FIELD_SYMBOL(cls, name) vppjni_field_##cls##_##name
75#define VPPJNI_FIELD_INIT(cls, name) vppjni_field_##cls##_##name##_init
76#define BIND_JAPI_FIELD(cls, field, sig) \
77 static vppjni_field_t VPPJNI_FIELD_SYMBOL(cls, field); \
78 static void VPPJNI_FIELD_INIT(cls, field)(void) __attribute__((__constructor__)); \
79 static void VPPJNI_FIELD_INIT(cls, field)() \
80 { \
81 VPPJNI_FIELD_SYMBOL(cls, field).name = #field; \
82 VPPJNI_FIELD_SYMBOL(cls, field).type = sig; \
83 VPPJNI_FIELD_SYMBOL(cls, field).clsref = &VPPJNI_CLASS_SYMBOL(cls); \
84 vppjni_register_field(&VPPJNI_FIELD_SYMBOL(cls, field)); \
85 }
86#define BIND_JAPI_BOOL_FIELD(cls, field) \
87 BIND_JAPI_FIELD(cls, field, "Z"); \
88 static void set_##cls##_##field(JNIEnv *env, jobject obj, jboolean value) \
89 { \
90 (*env)->SetBooleanField(env, obj, VPPJNI_FIELD_SYMBOL(cls, field).jfield, value); \
91 }
92#define BIND_JAPI_BYTE_FIELD(cls, field) \
93 BIND_JAPI_FIELD(cls, field, "B"); \
94 static void set_##cls##_##field(JNIEnv *env, jobject obj, jbyte value) \
95 { \
96 (*env)->SetByteField(env, obj, VPPJNI_FIELD_SYMBOL(cls, field).jfield, value); \
97 }
98#define BIND_JAPI_INT_FIELD(cls, field) \
99 BIND_JAPI_FIELD(cls, field, "I"); \
100 static void set_##cls##_##field(JNIEnv *env, jobject obj, jint value) \
101 { \
102 (*env)->SetIntField(env, obj, VPPJNI_FIELD_SYMBOL(cls, field).jfield, value); \
103 }
104#define BIND_JAPI_OBJ_FIELD(cls, field, sig) \
105 BIND_JAPI_FIELD(cls, field, sig); \
106 static void set_##cls##_##field(JNIEnv *env, jobject obj, jobject value) \
107 { \
108 (*env)->SetObjectField(env, obj, VPPJNI_FIELD_SYMBOL(cls, field).jfield, value); \
109 }
110#define BIND_JAPI_STRING_FIELD(cls, field) \
111 BIND_JAPI_OBJ_FIELD(cls, field, "Ljava/lang/String;")
112
113jobject vppjni_new_object(JNIEnv *env, const vppjni_class_t *ptr, va_list ap);
114void vppjni_register_class(vppjni_class_t *ptr);
115void vppjni_register_field(vppjni_field_t *ptr);
116int vppjni_init(JNIEnv *env);
117void vppjni_uninit(JNIEnv *env);
118